update to v2.1
parent
3b9c6b09ef
commit
a5567caba3
@ -0,0 +1 @@
|
|||||||
|
*.md
|
@ -1,18 +1,237 @@
|
|||||||
# Monoschinos API REST
|
# Monoschinos API REST V2
|
||||||
|
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
> PATH: /lastest
|
||||||
|
|
||||||
|
|Querys|Params|
|
||||||
|
|-|-|
|
||||||
|
|none|none|
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "kimetsu-no-yaiba-yuukaku-hen-episodio-1",
|
||||||
|
"title": "Kimetsu no Yaiba: Yuukaku-hen",
|
||||||
|
"image": "https://monoschinos2.com/assets/img/serie/episodio/kimetsu-no-yaiba-yuukaku-hen-1-1638722630.jpg",
|
||||||
|
"type": "Anime",
|
||||||
|
"no": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "mushoku-tensei-isekai-ittara-honki-dasu-2nd-season-episodio-10",
|
||||||
|
"title": "Mushoku Tensei: Isekai Ittara Honki Dasu 2nd Season",
|
||||||
|
"image": "https://monoschinos2.com/assets/img/serie/episodio/mushoku-tensei-isekai-ittara-honki-dasu-2nd-season-10-1638721531.jpg",
|
||||||
|
"type": "Anime",
|
||||||
|
"no": 10
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
> PATH: /emision
|
||||||
|
|
||||||
|
|Querys|Params|
|
||||||
|
|-|-|
|
||||||
|
|`page`|none|
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "jojos-bizarre-adventure-stone-ocean-sub-espanol",
|
||||||
|
"title": "JoJo's Bizarre Adventure: Stone Ocean",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/jojos-bizarre-adventure-stone-ocean-1638350799.jpg?v=1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "kimetsu-no-yaiba-yuukaku-hen-sub-espanol",
|
||||||
|
"title": "Kimetsu no Yaiba: Yuukaku-hen",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/kimetsu-distrito-rojo.jpg?v=1"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
> PATH: /week
|
||||||
|
|
||||||
|
|Querys|Params|
|
||||||
|
|-|-|
|
||||||
|
|none|none|
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"day": "lunes",
|
||||||
|
"animes": [
|
||||||
|
{
|
||||||
|
"id": "shinka-no-mi-shiranai-uchi-ni-kachigumi-jinsei-sub-espanol",
|
||||||
|
"title": "Shinka no Mi: Shiranai Uchi ni Kachigumi Jinsei",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/shinka-no-mi-shiranai-uchi-ni-kachigumi-jinsei-1637559521.jpg?v=1"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
> PATH: /all
|
||||||
|
|
||||||
|
|Querys|Params|
|
||||||
|
|-|-|
|
||||||
|
|`page`|none|
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "mai-otome-zwei-sub-espanol",
|
||||||
|
"title": "Mai-Otome Zwei",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/mai-otome-zwei-1638649807.jpg?v=1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "mai-hime-sub-espanol",
|
||||||
|
"title": "Mai-HiME",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/mai-hime-1638591018.jpg?v=1"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
> PATH: /search/:id
|
||||||
|
|
||||||
|
|Querys|Params|
|
||||||
|
|-|-|
|
||||||
|
|none|`id`|
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "mai-otome-zwei-sub-espanol",
|
||||||
|
"title": "Mai-Otome Zwei",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/mai-otome-zwei-1638649807.jpg?v=1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "mai-hime-sub-espanol",
|
||||||
|
"title": "Mai-HiME",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/mai-hime-1638591018.jpg?v=1"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
```
|
```
|
||||||
## Monoschinos API REST
|
|
||||||
## Rewrite in typescript
|
|
||||||
|
|
||||||
|
|
||||||
|
> PATH: /filterBy
|
||||||
|
|
||||||
|
|Querys|Params|
|
||||||
|
|-|-|
|
||||||
|
|`pagina` , `categoria`, `fecha` ,`genero`, `letra`|none|
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "mai-otome-zwei-sub-espanol",
|
||||||
|
"title": "Mai-Otome Zwei",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/mai-otome-zwei-1638649807.jpg?v=1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "mai-hime-sub-espanol",
|
||||||
|
"title": "Mai-HiME",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/mai-hime-1638591018.jpg?v=1"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
* ### Dependencies
|
|
||||||
* Axios
|
|
||||||
* Morgan
|
|
||||||
* Cheerio
|
|
||||||
* Cors
|
|
||||||
* Dotenv
|
|
||||||
|
|
||||||
Documentation (soon)
|
> PATH: /ver/:id
|
||||||
|
|
||||||
|
|Querys|Params|
|
||||||
|
|-|-|
|
||||||
|
|none|`id`|
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"title": "Kaifuku Jutsushi no Yarinaoshi. 2 ",
|
||||||
|
"nextEpisodes": [
|
||||||
|
{
|
||||||
|
"image": "https://monoschinos2.com/assets/img/serie/episodio/kaifuku-jutsushi-no-yarinaoshi-3.png",
|
||||||
|
"date": "27 Ene 2021",
|
||||||
|
"title": "Kaifuku Jutsushi no Yarinaoshi",
|
||||||
|
"no": "Capitulo 3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ctrs": {
|
||||||
|
"next": true,
|
||||||
|
"prev": true
|
||||||
|
},
|
||||||
|
"sugestions": [
|
||||||
|
{
|
||||||
|
"image": "https://monoschinos2.com/thumbs/portada/gundamhathawayvisual-e1621256405818.jpg?v=1.1",
|
||||||
|
"date": "08 Jul 2021",
|
||||||
|
"title": "Mobile Suit Gundam: Hathaway's Flash",
|
||||||
|
"no": "Capitulo 1"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"videos": [
|
||||||
|
{
|
||||||
|
"title": "cloud",
|
||||||
|
"url": "https://monoschinos2.com/reproductor?url=https://repro.monoschinos2.com/aqua/cl?url=redo02.mp4"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"downloads": [
|
||||||
|
{
|
||||||
|
"title": "1fichier ",
|
||||||
|
"url": "https://1fichier.com/?yssqgolputegizq4xkhb"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
> PATH: /anime/:id
|
||||||
|
|
||||||
|
|Querys|Params|
|
||||||
|
|-|-|
|
||||||
|
|none|`id`|
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"banner": "https://monoschinos2.com/assets/img/serie/portada/portada_kimetsu-37.jpg",
|
||||||
|
"image": "https://monoschinos2.com/thumbs/imagen/crunchyroll-Demon-Slayer-Kimetsu-no-Yaiba-Mugen-Train-Arc.jpg?v=1",
|
||||||
|
"title": "Kimetsu no Yaiba: Mugen Ressha-hen (TV)",
|
||||||
|
"sinopsis": "Versión para televisión de la película Mugen Train que conecta el arco de Tanjiro Kamado, Resolve inquebrantable con el arco del distrito de entretenimiento , que presenta un episodio original de televisión nunca antes visto de Kyojuro Rengoku asumiendo una nueva misión en el camino hacia el tren Mugen.\nAdemás del episodio completamente nuevo, la serie también incluirá 70 escenas nuevas, nuevas pistas musicales, avances de episodios y nuevos temas musicales.\n",
|
||||||
|
"status": "Finalizado",
|
||||||
|
"date": 2021,
|
||||||
|
"rating": "4.8",
|
||||||
|
"genders": [
|
||||||
|
"Acción",
|
||||||
|
"Aventura",
|
||||||
|
"Gore",
|
||||||
|
"Shonen",
|
||||||
|
"Histórico"
|
||||||
|
],
|
||||||
|
"episodes": [
|
||||||
|
{
|
||||||
|
"image": "https://monoschinos2.com/thumbs/portada/portada_kimetsu-37.jpg?v=1.1",
|
||||||
|
"no": 1,
|
||||||
|
"id": "kimetsu-no-yaiba-mugen-ressha-hen-tv-episodio-1"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Author: Carlos Burelo
|
||||||
|
|
||||||
|
|
||||||
#### Based on original work by [atleugim](https://github.com/atleugim/monoschinos-api)
|
|
@ -1,19 +1,17 @@
|
|||||||
const page = 'https://monoschinos2.com';
|
const url = 'https://monoschinos2.com';
|
||||||
|
|
||||||
export const urls = {
|
export const api = {
|
||||||
main: page,
|
home: `${url}`,
|
||||||
emision: page + '/emision?page=',
|
all: (id) => `${url}/animes?p=${id}`,
|
||||||
search: page + '/search?q=',
|
emision: (id) => `${url}/emision?p=${id}`,
|
||||||
anime: page + '/anime',
|
calendar: `${url}/calendario`,
|
||||||
episode: page + '/ver',
|
search: (id, page) => `${url}/buscar?q=${id.replace(/\s/g, '+')}&p=${page}`,
|
||||||
gender: page + '/genero',
|
anime: (id) => `${url}/anime/${id}`,
|
||||||
letter: page + '/letra',
|
episode: (id) => `${url}/ver/${id}`,
|
||||||
ova: page + '/categoria/ova',
|
gender: (id) => `${url}/genero/${id}`,
|
||||||
|
filter: ({ categoria, fecha, genero, letra, pagina }) =>
|
||||||
|
`${url}/animes?categoria=${categoria}&genero=${genero}&fecha=${fecha}&letra=${letra}&p=${pagina}`,
|
||||||
};
|
};
|
||||||
|
export function attr(html, selector, attribute = 'src') {
|
||||||
/**
|
return html.querySelector(selector)?.attributes[attribute];
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
export function getAttr(html, selector, attr) {
|
|
||||||
return html.querySelector(selector).attributes[attr];
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
import { parse } from 'node-html-parser';
|
||||||
|
import { attr, api } from '../config.js';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export async function getCalendar(req, res) {
|
||||||
|
try {
|
||||||
|
const { data } = await axios.get(api.calendar);
|
||||||
|
const html = parse(data);
|
||||||
|
res.status(200).json(
|
||||||
|
html.querySelectorAll('.heromain [data-dia]').map((i) => {
|
||||||
|
const day = i.getAttribute('data-dia');
|
||||||
|
return {
|
||||||
|
day,
|
||||||
|
animes: i
|
||||||
|
.querySelectorAll('.col-md-6.col-lg-4.col-sm-12.for768')
|
||||||
|
.map((i) => {
|
||||||
|
return {
|
||||||
|
id: attr(i, 'a', 'href').split('/').pop() || null,
|
||||||
|
title: i.querySelector('.serisdtls a h3').text.trim() || null,
|
||||||
|
image: attr(i, '.seriesimg a img') || null,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ message: error.message });
|
||||||
|
}
|
||||||
|
}
|
@ -1,24 +1,22 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { attr, api } from '../config.js';
|
||||||
import { parse } from 'node-html-parser';
|
import { parse } from 'node-html-parser';
|
||||||
import { getAttr, urls } from '../config.js';
|
|
||||||
|
|
||||||
export async function getEmision(req, res) {
|
export async function getEmision(req, res) {
|
||||||
try {
|
try {
|
||||||
let { page = '1' } = req.query;
|
let { page = '1' } = req.query;
|
||||||
const { data } = await axios.get(`${urls.emision}${page}`);
|
const { data } = await axios.get(api.emision(page));
|
||||||
const html = parse(data);
|
const html = parse(data);
|
||||||
res.status(200).json(
|
res.status(200).json(
|
||||||
html.querySelectorAll('.heromain .row .col-md-4.col-lg-2.col-6').map((i) => {
|
html.querySelectorAll('.heromain .row .col-md-4.col-lg-2.col-6').map((i) => {
|
||||||
return {
|
return {
|
||||||
id: getAttr(i, 'a', 'href').split('/').pop() || null,
|
id: attr(i, 'a', 'href').split('/').pop() || null,
|
||||||
title: i.querySelector('.seristitles').text.trim() || null,
|
title: i.querySelector('.seristitles').text.trim() || null,
|
||||||
image: getAttr(i, '.animemainimg', 'src') || null,
|
image: attr(i, '.animemainimg') || null,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
res.status(500).json({
|
res.status(500).json({ message: error.message });
|
||||||
message: err.message,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { parse } from 'node-html-parser';
|
||||||
|
import { api, attr } from '../config.js';
|
||||||
|
|
||||||
|
export async function filterBy(req, res) {
|
||||||
|
try {
|
||||||
|
let {
|
||||||
|
categoria = 'false',
|
||||||
|
fecha = 'false',
|
||||||
|
genero = 'false',
|
||||||
|
letra = 'false',
|
||||||
|
pagina = '1',
|
||||||
|
} = req.query;
|
||||||
|
const { data } = await axios.get(`${api.filter({ categoria, fecha, genero, letra, pagina })}`);
|
||||||
|
const html = parse(data);
|
||||||
|
res.status(200).json(
|
||||||
|
html.querySelectorAll('.heromain .row .col-md-4.col-lg-2.col-6').map((i) => {
|
||||||
|
return {
|
||||||
|
id: attr(i, 'a', 'href').split('/').pop() || null,
|
||||||
|
title: i.querySelector('.seristitles').text.trim() || null,
|
||||||
|
image: attr(i, '.animemainimg', 'src') || null,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
message: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,35 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { parse } from 'node-html-parser';
|
|
||||||
import { urls, getAttr } from '../config.js';
|
|
||||||
|
|
||||||
export async function getBy(req, res) {
|
|
||||||
try {
|
|
||||||
const { gender, category, letter, year, page = '1', sort, order } = req.query;
|
|
||||||
let response;
|
|
||||||
if (gender) response = await axios.get(`${urls.main}/genero/${gender}?page=${page}`);
|
|
||||||
if (category) response = await axios.get(`${urls.main}/categoria/${category}?page=${page}`);
|
|
||||||
if (letter) response = await axios.get(`${urls.main}/letra/${letter}?page=${page}`);
|
|
||||||
if (year) response = await axios.get(`${urls.main}/year/${year}?page=${page}`);
|
|
||||||
const { data } = response;
|
|
||||||
const html = parse(data);
|
|
||||||
const animes = html.querySelectorAll('.animes .container .row article').map((i) => {
|
|
||||||
const id = getAttr(i, 'a', 'href');
|
|
||||||
return {
|
|
||||||
id: id.split('/').pop() || null,
|
|
||||||
title: i.querySelector('.Title').text.trim() || null,
|
|
||||||
image: getAttr(i, '.Image img', 'src') || null,
|
|
||||||
type: i.querySelector('.category.text-uppercase').text.trim() || null,
|
|
||||||
year: parseInt(i.querySelector('.fecha').text) || null,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const isAsc = order == 'asc';
|
|
||||||
const ordered = animes.sort((a, b) => {
|
|
||||||
return (a[sort] < b[sort] ? -1 : 1) * (isAsc ? 1 : -1);
|
|
||||||
});
|
|
||||||
res.status(200).json(sort ? ordered : animes);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({
|
|
||||||
message: err.message,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { parse } from 'node-html-parser';
|
|
||||||
import { urls } from '../config.js';
|
|
||||||
|
|
||||||
export async function getCategories(req, res) {
|
|
||||||
try {
|
|
||||||
const { data } = await axios.get(`${urls.main}/animes`);
|
|
||||||
const html = parse(data);
|
|
||||||
res.status(200).json(
|
|
||||||
html
|
|
||||||
.querySelectorAll('div[aria-labelledby="categoryMenuButton"] a')
|
|
||||||
.map((i) => {
|
|
||||||
return {
|
|
||||||
name: i.text.trim(),
|
|
||||||
id: i?.attributes['href'].replace('/categoria/', ''),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter((i) => i.id !== '')
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({
|
|
||||||
message: err.message,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { parse } from 'node-html-parser';
|
|
||||||
import { urls } from '../config.js';
|
|
||||||
|
|
||||||
export async function getGenders(req, res) {
|
|
||||||
try {
|
|
||||||
const { data } = await axios.get(`${urls.main}/animes`);
|
|
||||||
const html = parse(data);
|
|
||||||
res.status(200).json(
|
|
||||||
html
|
|
||||||
.querySelectorAll('div[aria-labelledby="genreMenuButton"] a')
|
|
||||||
.map((i) => {
|
|
||||||
return {
|
|
||||||
name: i.text.trim(),
|
|
||||||
id: i?.attributes['href'].replace('/genero/', ''),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter((i) => i.id !== '')
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({
|
|
||||||
message: err,
|
|
||||||
success: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { getAttr, urls } from '../config.js';
|
|
||||||
import { parse } from 'node-html-parser';
|
|
||||||
|
|
||||||
export async function getLastest(req, res) {
|
|
||||||
try {
|
|
||||||
const { data } = await axios.get(urls.main);
|
|
||||||
const html = parse(data);
|
|
||||||
res.json(
|
|
||||||
html.querySelectorAll('.row.row-cols-5 .col.col-md-6.col-lg-2.col-6').map((i) => {
|
|
||||||
const id = getAttr(i, 'a', 'href').split('/').pop();
|
|
||||||
return {
|
|
||||||
id: id || null,
|
|
||||||
title: i.querySelector('.animetitles').text || null,
|
|
||||||
image: getAttr(i, '.animeimghv', 'src') || null,
|
|
||||||
type: i.querySelector('.positioning button').text.trim() || null,
|
|
||||||
episode: parseInt(i.querySelector('.positioning h5').text.trim()) || null,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
return res.json({ error: error.message }).status(500);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { parse } from 'node-html-parser';
|
|
||||||
import { urls } from '../config.js';
|
|
||||||
|
|
||||||
export async function getYears(req, res) {
|
|
||||||
try {
|
|
||||||
const { data } = await axios.get(`${urls.main}/animes`);
|
|
||||||
const html = parse(data);
|
|
||||||
res.status(200).json(
|
|
||||||
html
|
|
||||||
.querySelectorAll('div[aria-labelledby="yearMenuButton"] a')
|
|
||||||
.map((i) => {
|
|
||||||
return {
|
|
||||||
name: i.text.trim(),
|
|
||||||
id: i?.attributes['href'].replace('/year/', ''),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter((i) => i.id !== '')
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
res.status(500).json({
|
|
||||||
message: err,
|
|
||||||
success: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,8 @@
|
|||||||
export * from './getLastest.js';
|
export * from './all.js';
|
||||||
export * from './getEmision.js';
|
export * from './calendar.js';
|
||||||
export * from './getAnime.js';
|
export * from './emision.js';
|
||||||
export * from './searchAnimes.js';
|
export * from './episode.js';
|
||||||
export * from './getAnimes.js';
|
export * from './filterBy.js';
|
||||||
export * from './getEpisode.js';
|
export * from './lastest.js';
|
||||||
export * from './getCategories.js';
|
export * from './search.js';
|
||||||
export * from './getGenders.js';
|
export * from './anime.js';
|
||||||
export * from './getYears.js';
|
|
||||||
export * from './getBy.js';
|
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { attr, api } from '../config.js';
|
||||||
|
import { parse } from 'node-html-parser';
|
||||||
|
|
||||||
|
export async function getLastest(req, res) {
|
||||||
|
try {
|
||||||
|
const { data } = await axios.get(api.home);
|
||||||
|
const html = parse(data);
|
||||||
|
res.json(
|
||||||
|
html
|
||||||
|
.querySelectorAll('.row.row-cols-5 .col.col-md-6.col-lg-2.col-6')
|
||||||
|
.map((i) => {
|
||||||
|
const id = attr(i, 'a', 'href').split('/').pop();
|
||||||
|
return {
|
||||||
|
id: id || null,
|
||||||
|
title: i.querySelector('.animetitles')?.text || null,
|
||||||
|
image: attr(i, '.animeimghv') || null,
|
||||||
|
type: i.querySelector('.positioning button').text.trim() || null,
|
||||||
|
no: parseInt(i.querySelector('.positioning h5').text.trim() || '0') || null,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ message: error.message });
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { parse } from 'node-html-parser';
|
||||||
|
import { api, attr } from '../config.js';
|
||||||
|
|
||||||
|
export async function searchAnime(req, res) {
|
||||||
|
try {
|
||||||
|
let { id } = req.params;
|
||||||
|
let { page = '1' } = req.query;
|
||||||
|
const { data } = await axios.get(api.search(id, page));
|
||||||
|
const html = parse(data);
|
||||||
|
res.json(
|
||||||
|
html.querySelectorAll('.heromain .row .col-md-4.col-lg-2.col-6').map((i) => {
|
||||||
|
return {
|
||||||
|
id: attr(i, 'a', 'href').split('/').pop() || null,
|
||||||
|
title: i.querySelector('.seristitles ').text || null,
|
||||||
|
image: attr(i, '.seriesimg .animemainimg', 'src') || null,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,27 +0,0 @@
|
|||||||
import { parse } from 'node-html-parser';
|
|
||||||
import axios from 'axios';
|
|
||||||
import { getAttr, urls } from '../config.js';
|
|
||||||
|
|
||||||
export async function searchAnime(req, res) {
|
|
||||||
try {
|
|
||||||
let { id } = req.params;
|
|
||||||
const { data } = await axios.get(`${urls.search}${id}`);
|
|
||||||
const html = parse(data);
|
|
||||||
res.json(
|
|
||||||
html.querySelectorAll('.animes .row article').map((i) => {
|
|
||||||
return {
|
|
||||||
id: getAttr(i, 'a', 'href').split('/').pop() || null,
|
|
||||||
title: i.querySelector('h3.Title').text || null,
|
|
||||||
image: getAttr(i, '.cover .img-fluid', 'src') || null,
|
|
||||||
type: i.querySelector('.category.text-uppercase').text.trim() || null,
|
|
||||||
year: parseInt(i.querySelector('.fecha').text) || null,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json({
|
|
||||||
id: 'intertal-server-error',
|
|
||||||
message: error.message,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,61 @@
|
|||||||
|
import { Router } from 'express';
|
||||||
|
const routes = Router();
|
||||||
|
|
||||||
|
import {
|
||||||
|
getEmision,
|
||||||
|
getLastest,
|
||||||
|
getCalendar,
|
||||||
|
getAnimes,
|
||||||
|
filterBy,
|
||||||
|
searchAnime,
|
||||||
|
getEpisode,
|
||||||
|
getAnime,
|
||||||
|
} from './controllers/index.js';
|
||||||
|
|
||||||
|
routes.get('/', (_, res) => {
|
||||||
|
res.json({
|
||||||
|
message: 'API Works',
|
||||||
|
author: 'Carlos Burelo',
|
||||||
|
repository: 'https://github.com/carlos-burelo/monoschinos-api-v2',
|
||||||
|
endpoints: {
|
||||||
|
lastest: '/lastest',
|
||||||
|
emision: '/emision',
|
||||||
|
calendar: '/week',
|
||||||
|
getAnimeByID: '/anime/:id',
|
||||||
|
getAnimesByPage: '/all',
|
||||||
|
getEpisodeByID: '/ver/:id',
|
||||||
|
searchAnimeByID: '/search/:id',
|
||||||
|
filterBy: {
|
||||||
|
path: '/filterBy',
|
||||||
|
querys: ['categoria', 'fecha', 'genero', 'letra', 'pagina'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
routes.get('/lastest', (req, res) => {
|
||||||
|
getLastest(req, res);
|
||||||
|
});
|
||||||
|
routes.get('/emision', (req, res) => {
|
||||||
|
getEmision(req, res);
|
||||||
|
});
|
||||||
|
routes.get('/week', (req, res) => {
|
||||||
|
getCalendar(req, res);
|
||||||
|
});
|
||||||
|
routes.get('/all', (req, res) => {
|
||||||
|
getAnimes(req, res);
|
||||||
|
});
|
||||||
|
routes.get('/filterBy', (req, res) => {
|
||||||
|
filterBy(req, res);
|
||||||
|
});
|
||||||
|
routes.get('/search/:id', (req, res) => {
|
||||||
|
searchAnime(req, res);
|
||||||
|
});
|
||||||
|
routes.get('/ver/:id', (req, res) => {
|
||||||
|
getEpisode(req, res);
|
||||||
|
});
|
||||||
|
routes.get('/anime/:id', (req, res) => {
|
||||||
|
getAnime(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default routes;
|
@ -1,80 +0,0 @@
|
|||||||
import { Router } from 'express';
|
|
||||||
const routes = Router();
|
|
||||||
|
|
||||||
import {
|
|
||||||
getEmision,
|
|
||||||
getGenders,
|
|
||||||
getLastest,
|
|
||||||
getAnime,
|
|
||||||
searchAnime,
|
|
||||||
getAnimes,
|
|
||||||
getEpisode,
|
|
||||||
getCategories,
|
|
||||||
getYears,
|
|
||||||
getBy,
|
|
||||||
} from '../controllers/index.js';
|
|
||||||
|
|
||||||
routes.get('/', (_, res) => {
|
|
||||||
res.json({
|
|
||||||
message: 'API Works',
|
|
||||||
author: 'Carlos Burelo',
|
|
||||||
repository: 'https://github.com/carlos-burelo/monoschinos-api-ts',
|
|
||||||
endpoints: {
|
|
||||||
lastest: '/lastest',
|
|
||||||
emision: '/emision',
|
|
||||||
getAnimeByID: '/anime/:id',
|
|
||||||
getAnimesByPage: '/animes/:page',
|
|
||||||
getEpisodeByID: '/ver/:id',
|
|
||||||
searchAnimeByID: '/search/:id',
|
|
||||||
getYears: '/years',
|
|
||||||
getGenders: '/genders',
|
|
||||||
getLetters: '/letter',
|
|
||||||
getCategories: '/categories',
|
|
||||||
getByParams: {
|
|
||||||
example: '/by?gender=drama&sort=title&order=asc',
|
|
||||||
filters: ['gender', 'year', 'category', 'letter'],
|
|
||||||
querys: {
|
|
||||||
sort: '&sort={prop}',
|
|
||||||
order: '&order=asc',
|
|
||||||
page: '&page={number}',
|
|
||||||
limit: '&limit=3...(soon)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
routes.get('/lastest', (req, res) => {
|
|
||||||
getLastest(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/emision', (req, res) => {
|
|
||||||
getEmision(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/anime/:id', (req, res) => {
|
|
||||||
getAnime(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/animes/:page', (req, res) => {
|
|
||||||
getAnimes(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/ver/:id', (req, res) => {
|
|
||||||
getEpisode(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/search/:id', (req, res) => {
|
|
||||||
searchAnime(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/genders', (req, res) => {
|
|
||||||
getGenders(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/categories', (req, res) => {
|
|
||||||
getCategories(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/years', (req, res) => {
|
|
||||||
getYears(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/letters', (req, res) => {
|
|
||||||
getLetters(req, res);
|
|
||||||
});
|
|
||||||
routes.get('/by', (req, res) => {
|
|
||||||
getBy(req, res);
|
|
||||||
});
|
|
||||||
export default routes;
|
|
Loading…
Reference in New Issue