From b0e5b4c7bc239fddc1abdeb246077b5059d2b794 Mon Sep 17 00:00:00 2001 From: capitanwesler Date: Wed, 14 Apr 2021 17:20:59 +0100 Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=90=A7=20Fixing=20genres=20to=20get?= =?UTF-8?q?=20them=20from=20the=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/DirectoryController.ts | 68 +++++++++++++++++++++----- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/src/controllers/DirectoryController.ts b/src/controllers/DirectoryController.ts index 78cc48b..2915a8d 100644 --- a/src/controllers/DirectoryController.ts +++ b/src/controllers/DirectoryController.ts @@ -402,30 +402,72 @@ export default class DirectoryController { async getAnimeGenres(req: Request, res: Response, next: NextFunction) { const { genre, order, page } = req.params; - let data: Genre[]; - let resultReq: any; + let result: any; + + const genres: any = { + accion: 'Acción', + 'artes-marciales': 'Artes Marciales', + aventura: 'Aventuras', + carreras: 'Carreras', + 'ciencia-ficcion': 'Ciencia Ficción', + comedia: 'Comedia', + demencia: 'Demencia', + demonios: 'Demonios', + deportes: 'Deportes', + drama: 'Drama', + ecchi: 'Ecchi', + escolares: 'Escolares', + espacial: 'Espacial', + fantasia: 'Fantasía', + harem: 'Harem', + historico: 'Historico', + infantil: 'Infantil', + josei: 'Josei', + juegos: 'Juegos', + magia: 'Magia', + mecha: 'Mecha', + militar: 'Militar', + misterio: 'Misterio', + musica: 'Música', + parodia: 'Parodia', + policia: 'Policía', + psicologico: 'Psicológico', + 'recuentos-de-la-vida': 'Recuentos de la vida', + romance: 'Romance', + samurai: 'Samurai', + seinen: 'Seinen', + shoujo: 'Shoujo', + shounen: 'Shounen', + sobrenatural: 'Sobrenatural', + superpoderes: 'Superpoderes', + suspenso: 'Suspenso', + terror: 'Terror', + vampiros: 'Vampiros', + yaoi: 'Yaoi', + yuri: 'Yuri', + }; try { if (genre === undefined && order === undefined && page === undefined) { - data = await GenreModel.find(); + result = await AnimeModel.aggregate([{ $sample: { size: 25 } }]); } else { - if (page !== undefined) { - resultReq = await requestGot( - `${urls.BASE_ANIMEFLV_JELU}Genres/${genre}/${order}/${page}`, - { parse: true, scrapy: false }, - ); + if (genres.hasOwnProperty(genre)) { + if (page !== undefined && parseInt(page) > 1) { + result = await AnimeModel.find({ genres: genres[genre] }) + .limit(25) + .skip(25 * parseInt(page)); + } else { + result = await AnimeModel.find({ genres: genres[genre] }).limit(25); + } } else { - resultReq = await requestGot( - `${urls.BASE_ANIMEFLV_JELU}Genres/${genre}/${order}/1`, - { parse: true, scrapy: false }, - ); + return res.status(500).json({ message: 'Aruppi lost in the shell' }); } } } catch (err) { return next(err); } - const animes: any[] = resultReq.animes.map((item: any) => { + const animes: any[] = result.map((item: any) => { return { id: item.id, title: item.title.trim(), From adad49eaae7b16c55a2d87fc1a104cc8eff5a420 Mon Sep 17 00:00:00 2001 From: capitanwesler Date: Wed, 14 Apr 2021 17:34:23 +0100 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=A6=8A=20Sorting=20genres=20by=20the?= =?UTF-8?q?=20order?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/DirectoryController.ts | 32 ++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/controllers/DirectoryController.ts b/src/controllers/DirectoryController.ts index 2915a8d..5d9549d 100644 --- a/src/controllers/DirectoryController.ts +++ b/src/controllers/DirectoryController.ts @@ -453,11 +453,35 @@ export default class DirectoryController { } else { if (genres.hasOwnProperty(genre)) { if (page !== undefined && parseInt(page) > 1) { - result = await AnimeModel.find({ genres: genres[genre] }) - .limit(25) - .skip(25 * parseInt(page)); + if (order === 'asc') { + result = await AnimeModel.find({ genres: genres[genre] }) + .limit(25) + .skip(25 * parseInt(page)) + .sort({ title: 'ascending' }); + } else if (order === 'desc') { + result = await AnimeModel.find({ genres: genres[genre] }) + .limit(25) + .skip(25 * parseInt(page)) + .sort({ title: 'descending' }); + } else { + result = await AnimeModel.find({ genres: genres[genre] }) + .limit(25) + .skip(25 * parseInt(page)); + } } else { - result = await AnimeModel.find({ genres: genres[genre] }).limit(25); + if (order === 'asc') { + result = await AnimeModel.find({ genres: genres[genre] }) + .limit(25) + .sort({ title: 'ascending' }); + } else if (order === 'desc') { + result = await AnimeModel.find({ genres: genres[genre] }) + .limit(25) + .sort({ title: 'descending' }); + } else { + result = await AnimeModel.find({ genres: genres[genre] }).limit( + 25, + ); + } } } else { return res.status(500).json({ message: 'Aruppi lost in the shell' }); From 77513c4820461a82a698b00f765c552e6c63ab0a Mon Sep 17 00:00:00 2001 From: capitanwesler Date: Fri, 16 Apr 2021 09:53:09 +0100 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=91=93=20Adding=20the=20lastEpisodes?= =?UTF-8?q?=20with=20animeflv=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/AnimeController.ts | 140 +++++++++++++++-------------- src/routes.ts | 2 +- 2 files changed, 76 insertions(+), 66 deletions(-) diff --git a/src/controllers/AnimeController.ts b/src/controllers/AnimeController.ts index 741fb71..6e80de8 100644 --- a/src/controllers/AnimeController.ts +++ b/src/controllers/AnimeController.ts @@ -250,7 +250,8 @@ export default class AnimeController { } async getLastEpisodes(req: Request, res: Response, next: NextFunction) { - // let data: any; + const { options } = req.params; + let data: any; let $: cheerio.Root; let episodes: Episode[] = []; let animeList: any[] = []; @@ -268,74 +269,83 @@ export default class AnimeController { } } - // @ANIMEFLV - // data = await requestGot( - // `${urls.BASE_ANIMEFLV_JELU}LatestEpisodesAdded`, - // { - // parse: true, - // scrapy: false, - // }, - // ); - - $ = await requestGot(`${urls.BASE_MONOSCHINOS}`, { - scrapy: true, - parse: false, - }); + switch (options) { + case 'monoschinos': + $ = await requestGot(`${urls.BASE_MONOSCHINOS}`, { + scrapy: true, + parse: false, + }); + break; + default: + data = await requestGot( + `${urls.BASE_ANIMEFLV_JELU}LatestEpisodesAdded`, + { + parse: true, + scrapy: false, + }, + ); + break; + } } catch (err) { return next(err); } - // @ANIMEFLV - // for (const episode of data.episodes) { - // const formattedEpisode: Episode = { - // id: '12345/' + episode.id, - // title: episode.title, - // image: episode.poster, - // episode: episode.episode, - // servers: await transformUrlServer(episode.servers), - // }; - - // episodes.push(formattedEpisode); - // } - - let getLastest: any = $('.container .caps .container')[0]; - - $(getLastest) - .find('.row article') - .each((index: number, element: cheerio.Element) => { - let el: cheerio.Cheerio = $(element); - let title: string | undefined = el - .find('.Title') - .html() - ?.split('\t')[0]; - let img: any = el.find('.Image img').attr('src'); - let type: any = el.find('.Image figure span').text(); - type = type.substring(1, type.length); - let nEpisode: any = el.find('.dataEpi .episode').text(); - nEpisode = parseInt(nEpisode.split('\n')[1]); - let id: any = el.find('a').attr('href'); - id = id.split('/')[4]; - id = id.split('-'); - id.splice(id.length - 2, 2); - id = `${id.join('-')}-episodio-${nEpisode}`; - - let anime = { - id: `ver/${id}`, - title, - image: img, - episode: nEpisode, - }; - - animeList.push(anime); - }); - for (const anime of animeList) { - episodes.push({ - id: anime.id, - title: anime.title, - image: await imageUrlToBase64(anime.image), - episode: anime.episode, - servers: await videoServersMonosChinos(anime.id), - }); + switch (options) { + case 'monoschinos': + let getLastest: any = $!('.container .caps .container')[0]; + + $!(getLastest) + .find('.row article') + .each((index: number, element: cheerio.Element) => { + let el: cheerio.Cheerio = $(element); + let title: string | undefined = el + .find('.Title') + .html() + ?.split('\t')[0]; + let img: any = el.find('.Image img').attr('src'); + let type: any = el.find('.Image figure span').text(); + type = type.substring(1, type.length); + let nEpisode: any = el.find('.dataEpi .episode').text(); + nEpisode = parseInt(nEpisode.split('\n')[1]); + let id: any = el.find('a').attr('href'); + id = id.split('/')[4]; + id = id.split('-'); + id.splice(id.length - 2, 2); + id = `${id.join('-')}-episodio-${nEpisode}`; + + let anime = { + id: `ver/${id}`, + title, + image: img, + episode: nEpisode, + }; + + animeList.push(anime); + }); + + for (const anime of animeList) { + episodes.push({ + id: anime.id, + title: anime.title, + image: await imageUrlToBase64(anime.image), + episode: anime.episode, + servers: await videoServersMonosChinos(anime.id), + }); + } + break; + default: + for (const episode of data.episodes) { + const formattedEpisode: Episode = { + id: '12345/' + episode.id, + title: episode.title, + image: episode.poster, + episode: episode.episode, + servers: await transformUrlServer(episode.servers), + }; + + episodes.push(formattedEpisode); + } + break; } if (episodes.length > 0) { diff --git a/src/routes.ts b/src/routes.ts index 6fca92e..a2d8444 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -72,7 +72,7 @@ routes.get('/api/v4/', (req: Request, res: Response) => { routes.get('/api/v4/schedule/:day', animeController.schedule); routes.get('/api/v4/top/:type/:subtype?/:page', animeController.top); routes.get('/api/v4/allAnimes', animeController.getAllAnimes); -routes.get('/api/v4/lastEpisodes', animeController.getLastEpisodes); +routes.get('/api/v4/lastEpisodes/:options?', animeController.getLastEpisodes); routes.get('/api/v4/movies/:type/:page', animeController.getContentMovie); routes.get('/api/v4/ova/:type/:page', animeController.getContentOva); routes.get('/api/v4/special/:type/:page', animeController.getContentSpecial); From f8ab77b289e517ad9001b11dccd7cfa8c417c052 Mon Sep 17 00:00:00 2001 From: capitanwesler Date: Fri, 16 Apr 2021 09:53:56 +0100 Subject: [PATCH 4/7] =?UTF-8?q?=F0=9F=91=93=20Changing=20the=20version=20c?= =?UTF-8?q?ontrol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- package.json | 2 +- src/routes.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cf4f3e6..a6cb2cd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# **Aruppi API** (v4.0.4) +# **Aruppi API** (v4.0.5) > This API has everything about Japan, from anime, music, radio, images, videos ... to japanese culture > diff --git a/package.json b/package.json index 63bb4e6..2c870cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aruppi", - "version": "4.0.4", + "version": "4.0.5", "description": "Aruppi is a custom API to obtain data from the Japanese culture for the mobile app", "main": "./src/api/api.ts", "scripts": { diff --git a/src/routes.ts b/src/routes.ts index a2d8444..b24e590 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -26,7 +26,7 @@ routes.get('/api/v4/', (req: Request, res: Response) => { res.json({ message: 'Aruppi /api - 🎏', author: 'Jéluchu', - version: '4.0.4', + version: '4.0.5', credits: 'The bitch loves /apis that offers data to Aruppi App', entries: [ { From 04b30632f8bb838039fe9206688f2a128e5a0147 Mon Sep 17 00:00:00 2001 From: capitanwesler Date: Fri, 16 Apr 2021 10:23:53 +0100 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=91=93=20Adding=20the=20changes=20to?= =?UTF-8?q?=20the=20other=20fonts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/AnimeController.ts | 4 +- src/utils/urls.ts | 2 +- src/utils/util.ts | 139 ++++++++++++++++++++++++----- 3 files changed, 122 insertions(+), 23 deletions(-) diff --git a/src/controllers/AnimeController.ts b/src/controllers/AnimeController.ts index 6e80de8..2b8d5b9 100644 --- a/src/controllers/AnimeController.ts +++ b/src/controllers/AnimeController.ts @@ -688,10 +688,10 @@ export default class AnimeController { switch (searchAnime?.source) { case 'animeflv': - episodes = await animeFlvInfo(searchAnime?.id); + episodes = await animeFlvInfo(searchAnime?.id, searchAnime?.mal_id); break; case 'jkanime': - episodes = await jkanimeInfo(searchAnime?.id); + episodes = await jkanimeInfo(searchAnime?.id, searchAnime?.mal_id); break; case 'monoschinos': episodes = await monoschinosInfo(searchAnime?.id, searchAnime?.mal_id); diff --git a/src/utils/urls.ts b/src/utils/urls.ts index 99c6bcc..94f7a7c 100644 --- a/src/utils/urls.ts +++ b/src/utils/urls.ts @@ -1,6 +1,6 @@ export default { BASE_ARUPPI: 'https://aruppi.jeluchu.xyz/', - BASE_ANIMEFLV: 'https://animeflv.net/', + BASE_ANIMEFLV: 'https://www3.animeflv.net/', BASE_MONOSCHINOS: 'https://monoschinos2.com/', BASE_JKANIME: 'https://jkanime.net/', BASE_ANIMEFLV_JELU: 'https://aruppi.jeluchu.xyz/apis/animeflv/v1/', diff --git a/src/utils/util.ts b/src/utils/util.ts index 8115108..dd7245b 100644 --- a/src/utils/util.ts +++ b/src/utils/util.ts @@ -406,14 +406,17 @@ export const getRelatedAnimesMAL = async (mal_id: number) => { } }; -export const animeFlvInfo = async (id: string | undefined) => { +export const animeFlvInfo = async (id: string | undefined, mal_id: number) => { let $: cheerio.Root; let anime_info: string[] = []; let anime_eps: string[] = []; - let nextEpisodeDate: string | null; - let episodes: any[] = []; + let episodesList: any[] = []; + let extraInfo: any; try { + /* Extra info of the anime */ + extraInfo = await animeExtraInfo(mal_id); + if (redisClient.connected) { const resultQueryRedis: any = await redisClient.get( `animeflvInfo_${hashStringMd5(id!)}`, @@ -430,10 +433,64 @@ export const animeFlvInfo = async (id: string | undefined) => { scrapy: true, parse: false, }); + + console.log($.html()); } catch (err) { return err; } + let broadCastDate = new Date(); + let dd: number, mm: string | number, yyyy: number; + + const airDay: any = { + Lunes: 1, + Martes: 2, + Miércoles: 3, + Jueves: 4, + Viernes: 5, + Sábados: 6, + Domingos: 7, + 'Sin emisión': 'default', + }; + + if (!extraInfo.aired.to) { + if (airDay.hasOwnProperty(extraInfo.broadcast)) { + if (broadCastDate.getDay() < airDay[extraInfo.broadcast]) { + for ( + let i = broadCastDate.getDay(); + i < airDay[extraInfo.broadcast]; + i++ + ) { + broadCastDate.setDate(broadCastDate.getDate() + 1); + } + } else { + let counter = broadCastDate.getDay() + 1; + + /* Adding one because of the day */ + broadCastDate.setDate(broadCastDate.getDate() + 1); + + while (counter !== airDay[extraInfo.broadcast]) { + if (counter === 7) { + counter = 0; + } + broadCastDate.setDate(broadCastDate.getDate() + 1); + counter++; + } + } + + dd = broadCastDate.getDate(); + mm = + broadCastDate.getMonth() + 1 < 10 + ? `0${broadCastDate.getMonth() + 1}` + : broadCastDate.getMonth() + 1; + yyyy = broadCastDate.getFullYear(); + + episodesList.push({ + nextEpisodeDate: `${yyyy}-${mm}-${dd}`, + }); + } + } + const scripts: cheerio.Element[] = $('script').toArray(); for (const script of scripts) { @@ -448,28 +505,20 @@ export const animeFlvInfo = async (id: string | undefined) => { } } - if (anime_info.length === 4) { - nextEpisodeDate = anime_info[3]; - } else { - nextEpisodeDate = null; - } - - episodes.push({ nextEpisodeDate }); - for (const episode of anime_eps) { - episodes.push({ + episodesList.push({ episode: episode[0], id: `${episode[1]}/${id}-${episode[0]}`, }); } - if (episodes.length > 0) { + if (episodesList.length > 0) { if (redisClient.connected) { /* Set the key in the redis cache. */ redisClient.set( `animeflvInfo_${hashStringMd5(id!)}`, - JSON.stringify(episodes), + JSON.stringify(episodesList), ); /* After 24hrs expire the key. */ @@ -480,20 +529,22 @@ export const animeFlvInfo = async (id: string | undefined) => { ); } - return episodes; + return episodesList; } else { return null; } }; -export const jkanimeInfo = async (id: string | undefined) => { +export const jkanimeInfo = async (id: string | undefined, mal_id: number) => { let $: cheerio.Root; - let nextEpisodeDate: string | null; - let imageLink: string | undefined; + let extraInfo: any; let episodesList: any[] = []; let countEpisodes: string[] = []; try { + /* Extra info of the anime */ + extraInfo = await animeExtraInfo(mal_id); + if (redisClient.connected) { const resultQueryRedis: any = await redisClient.get( `jkanimeInfo_${hashStringMd5(id!)}`, @@ -524,9 +575,57 @@ export const jkanimeInfo = async (id: string | undefined) => { '-', )[1]; - nextEpisodeDate = $('div.proxep p').text() || null; + let broadCastDate = new Date(); + let dd: number, mm: string | number, yyyy: number; + + const airDay: any = { + Lunes: 1, + Martes: 2, + Miércoles: 3, + Jueves: 4, + Viernes: 5, + Sábados: 6, + Domingos: 7, + 'Sin emisión': 'default', + }; - episodesList.push({ nextEpisodeDate }); + if (!extraInfo.aired.to) { + if (airDay.hasOwnProperty(extraInfo.broadcast)) { + if (broadCastDate.getDay() < airDay[extraInfo.broadcast]) { + for ( + let i = broadCastDate.getDay(); + i < airDay[extraInfo.broadcast]; + i++ + ) { + broadCastDate.setDate(broadCastDate.getDate() + 1); + } + } else { + let counter = broadCastDate.getDay() + 1; + + /* Adding one because of the day */ + broadCastDate.setDate(broadCastDate.getDate() + 1); + + while (counter !== airDay[extraInfo.broadcast]) { + if (counter === 7) { + counter = 0; + } + broadCastDate.setDate(broadCastDate.getDate() + 1); + counter++; + } + } + + dd = broadCastDate.getDate(); + mm = + broadCastDate.getMonth() + 1 < 10 + ? `0${broadCastDate.getMonth() + 1}` + : broadCastDate.getMonth() + 1; + yyyy = broadCastDate.getFullYear(); + + episodesList.push({ + nextEpisodeDate: `${yyyy}-${mm}-${dd}`, + }); + } + } for (let i = 1; i <= parseInt(episodesCount); i++) { episodesList.push({ From 3fc5ddab5d2e9b13c5ec8bd3a9e867c080205956 Mon Sep 17 00:00:00 2001 From: capitanwesler Date: Sun, 18 Apr 2021 17:30:56 +0100 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=A4=96=20Implementing=20TioAnime=20as?= =?UTF-8?q?=20source=20of=20anime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/AnimeController.ts | 76 +++--- src/controllers/DirectoryController.ts | 64 +---- src/utils/urls.ts | 1 + src/utils/util.ts | 315 ++++++++++++------------- 4 files changed, 191 insertions(+), 265 deletions(-) diff --git a/src/controllers/AnimeController.ts b/src/controllers/AnimeController.ts index 2b8d5b9..c76646e 100644 --- a/src/controllers/AnimeController.ts +++ b/src/controllers/AnimeController.ts @@ -1,12 +1,13 @@ import { NextFunction, Request, Response } from 'express'; import { requestGot } from '../utils/requestCall'; import { - animeFlvInfo, imageUrlToBase64, jkanimeInfo, monoschinosInfo, + tioanimeInfo, videoServersJK, videoServersMonosChinos, + videoServersTioAnime, } from '../utils/util'; import { transformUrlServer } from '../utils/transformerUrl'; import AnimeModel, { Anime as ModelA } from '../database/models/anime.model'; @@ -16,7 +17,6 @@ import { animeExtraInfo, getAnimeVideoPromo, getAnimeCharacters, - getRelatedAnimesFLV, getRelatedAnimesMAL, } from '../utils/util'; import urls from '../utils/urls'; @@ -687,15 +687,15 @@ export default class AnimeController { } switch (searchAnime?.source) { - case 'animeflv': - episodes = await animeFlvInfo(searchAnime?.id, searchAnime?.mal_id); - break; case 'jkanime': episodes = await jkanimeInfo(searchAnime?.id, searchAnime?.mal_id); break; case 'monoschinos': episodes = await monoschinosInfo(searchAnime?.id, searchAnime?.mal_id); break; + case 'tioanime': + episodes = await tioanimeInfo(searchAnime?.id, searchAnime?.mal_id); + break; default: episodes = undefined; break; @@ -741,19 +741,18 @@ export default class AnimeController { } } - if (isNaN(parseInt(id.split('/')[0]))) { - if (id.split('/')[0] === 'ver') { - data = await videoServersMonosChinos(id); - } else { - data = await videoServersJK(id); - } + if ( + id.split('/')[0] === 'ver' && + id.split('-').indexOf('espanol') !== -1 + ) { + data = await videoServersMonosChinos(id); + } else if (id.split('/')[0] === 'ver') { + data = await videoServersTioAnime(id); } else { - data = await requestGot( - `${urls.BASE_ANIMEFLV_JELU}GetAnimeServers/${id}`, - { parse: true, scrapy: false }, - ); + data = await videoServersJK(id); + } - data = await transformUrlServer(data.servers); + switch (id) { } if (data) { @@ -792,39 +791,18 @@ export default class AnimeController { return next(err); } - switch (animeQuery[0].source) { - case 'animeflv': - animeResult = { - title: animeQuery[0].title || null, - poster: animeQuery[0].poster || null, - synopsis: animeQuery[0].description || null, - type: animeQuery[0].type || null, - rating: animeQuery[0].score || null, - genres: animeQuery[0].genres || null, - moreInfo: [await animeExtraInfo(animeQuery[0].mal_id)], - promo: await getAnimeVideoPromo(animeQuery[0].mal_id), - characters: await getAnimeCharacters(animeQuery[0].mal_id), - related: await getRelatedAnimesFLV(animeQuery[0].id), - }; - break; - case 'jkanime': - animeResult = { - title: animeQuery[0].title || null, - poster: animeQuery[0].poster || null, - synopsis: animeQuery[0].description || null, - type: animeQuery[0].type || null, - rating: animeQuery[0].score || null, - genres: animeQuery[0].genres || null, - moreInfo: [await animeExtraInfo(animeQuery[0].mal_id)], - promo: await getAnimeVideoPromo(animeQuery[0].mal_id), - characters: await getAnimeCharacters(animeQuery[0].mal_id), - related: await getRelatedAnimesMAL(animeQuery[0].mal_id), - }; - break; - default: - animeResult = undefined; - break; - } + animeResult = { + title: animeQuery[0].title || null, + poster: animeQuery[0].poster || null, + synopsis: animeQuery[0].description || null, + type: animeQuery[0].type || null, + rating: animeQuery[0].score || null, + genres: animeQuery[0].genres || null, + moreInfo: [await animeExtraInfo(animeQuery[0].mal_id)], + promo: await getAnimeVideoPromo(animeQuery[0].mal_id), + characters: await getAnimeCharacters(animeQuery[0].mal_id), + related: await getRelatedAnimesMAL(animeQuery[0].mal_id), + }; if (animeResult) { res.set('Cache-Control', 'no-store'); diff --git a/src/controllers/DirectoryController.ts b/src/controllers/DirectoryController.ts index 5d9549d..2159d3d 100644 --- a/src/controllers/DirectoryController.ts +++ b/src/controllers/DirectoryController.ts @@ -8,7 +8,6 @@ import { animeExtraInfo, getAnimeVideoPromo, getAnimeCharacters, - getRelatedAnimesFLV, getRelatedAnimesMAL, } from '../utils/util'; import urls from '../utils/urls'; @@ -295,56 +294,19 @@ export default class DirectoryController { const extraInfo: any = await animeExtraInfo(resultQuery!.mal_id); - switch (resultQuery?.source) { - case 'animeflv': - resultAnime = { - title: resultQuery?.title, - poster: resultQuery?.poster, - synopsis: resultQuery?.description, - status: !extraInfo.aired.to ? 'En emisión' : 'Finalizado', - type: resultQuery?.type, - rating: resultQuery?.score, - genres: resultQuery?.genres, - moreInfo: [extraInfo], - promo: await getAnimeVideoPromo(resultQuery!.mal_id), - characters: await getAnimeCharacters(resultQuery!.mal_id), - related: await getRelatedAnimesFLV(resultQuery!.id), - }; - break; - case 'jkanime': - resultAnime = { - title: resultQuery?.title, - poster: resultQuery?.poster, - synopsis: resultQuery?.description, - status: !extraInfo.aired.to ? 'En emisión' : 'Finalizado', - type: resultQuery?.type, - rating: resultQuery?.score, - genres: resultQuery?.genres, - moreInfo: [extraInfo], - promo: await getAnimeVideoPromo(resultQuery!.mal_id), - characters: await getAnimeCharacters(resultQuery!.mal_id), - related: await getRelatedAnimesMAL(resultQuery!.mal_id), - }; - break; - case 'monoschinos': - resultAnime = { - title: resultQuery?.title, - poster: resultQuery?.poster, - synopsis: resultQuery?.description, - status: !extraInfo.aired.to ? 'En emisión' : 'Finalizado', - type: resultQuery?.type, - rating: resultQuery?.score, - genres: resultQuery?.genres, - moreInfo: [extraInfo], - promo: await getAnimeVideoPromo(resultQuery!.mal_id), - characters: await getAnimeCharacters(resultQuery!.mal_id), - related: await getRelatedAnimesMAL(resultQuery!.mal_id), - }; - break; - default: - resultAnime = undefined; - break; - } + resultAnime = { + title: resultQuery?.title, + poster: resultQuery?.poster, + synopsis: resultQuery?.description, + status: !extraInfo.aired.to ? 'En emisión' : 'Finalizado', + type: resultQuery?.type, + rating: resultQuery?.score, + genres: resultQuery?.genres, + moreInfo: [extraInfo], + promo: await getAnimeVideoPromo(resultQuery!.mal_id), + characters: await getAnimeCharacters(resultQuery!.mal_id), + related: await getRelatedAnimesMAL(resultQuery!.mal_id), + }; } catch (err) { return next(err); } diff --git a/src/utils/urls.ts b/src/utils/urls.ts index 94f7a7c..7271cce 100644 --- a/src/utils/urls.ts +++ b/src/utils/urls.ts @@ -2,6 +2,7 @@ export default { BASE_ARUPPI: 'https://aruppi.jeluchu.xyz/', BASE_ANIMEFLV: 'https://www3.animeflv.net/', BASE_MONOSCHINOS: 'https://monoschinos2.com/', + BASE_TIOANIME: 'https://tioanime.com/', BASE_JKANIME: 'https://jkanime.net/', BASE_ANIMEFLV_JELU: 'https://aruppi.jeluchu.xyz/apis/animeflv/v1/', BASE_YOUTUBE: 'https://aruppi.jeluchu.xyz/api/Youtube/?channelId=', diff --git a/src/utils/util.ts b/src/utils/util.ts index dd7245b..02a843d 100644 --- a/src/utils/util.ts +++ b/src/utils/util.ts @@ -259,75 +259,6 @@ const getPosterAndType = async ( return ''; }; -export const getRelatedAnimesFLV = async (id: string) => { - let $: cheerio.Root; - - try { - if (redisClient.connected) { - const resultQueryRedis: any = await redisClient.get( - `relatedFLV_${hashStringMd5(id)}`, - ); - - if (resultQueryRedis) { - const resultRedis: any = JSON.parse(resultQueryRedis); - - return resultRedis; - } - } - - $ = await requestGot(`${urls.BASE_ANIMEFLV}/anime/${id}`, { - parse: false, - scrapy: true, - }); - } catch (err) { - return err; - } - - let listRelated: any = {}; - let relatedAnimes: RelatedAnime[] = []; - - $('ul.ListAnmRel li a').each((index: number, element: any) => { - listRelated[$(element).text()] = $(element).attr('href'); - }); - - for (const related in listRelated) { - let posterUrl: any = await getPosterAndType( - listRelated[related].split('/')[2], - undefined, - ); - - if (posterUrl !== '') { - relatedAnimes.push({ - title: related, - type: posterUrl[1], - poster: posterUrl[0], - }); - } - } - - if (relatedAnimes.length > 0) { - if (redisClient.connected) { - /* Set the key in the redis cache. */ - - redisClient.set( - `relatedFLV_${hashStringMd5(id)}`, - JSON.stringify(relatedAnimes), - ); - - /* After 24hrs expire the key. */ - - redisClient.expireat( - `relatedFLV_${hashStringMd5(id)}`, - parseInt(`${+new Date() / 1000}`, 10) + 7200, - ); - } - - return relatedAnimes; - } else { - return []; - } -}; - export const getRelatedAnimesMAL = async (mal_id: number) => { let $: cheerio.Root; @@ -406,12 +337,11 @@ export const getRelatedAnimesMAL = async (mal_id: number) => { } }; -export const animeFlvInfo = async (id: string | undefined, mal_id: number) => { +export const jkanimeInfo = async (id: string | undefined, mal_id: number) => { let $: cheerio.Root; - let anime_info: string[] = []; - let anime_eps: string[] = []; - let episodesList: any[] = []; let extraInfo: any; + let episodesList: any[] = []; + let countEpisodes: string[] = []; try { /* Extra info of the anime */ @@ -419,7 +349,7 @@ export const animeFlvInfo = async (id: string | undefined, mal_id: number) => { if (redisClient.connected) { const resultQueryRedis: any = await redisClient.get( - `animeflvInfo_${hashStringMd5(id!)}`, + `jkanimeInfo_${hashStringMd5(id!)}`, ); if (resultQueryRedis) { @@ -429,16 +359,24 @@ export const animeFlvInfo = async (id: string | undefined, mal_id: number) => { } } - $ = await requestGot(`${urls.BASE_ANIMEFLV}/anime/${id}`, { + $ = await requestGot(`${urls.BASE_JKANIME}${id}`, { scrapy: true, parse: false, }); - - console.log($.html()); } catch (err) { return err; } + countEpisodes = $('div.anime__pagination a') + .map((index: number, element: cheerio.Element) => { + return $(element).text(); + }) + .get(); + + const episodesCount: string = countEpisodes[countEpisodes.length - 1].split( + '-', + )[1]; + let broadCastDate = new Date(); let dd: number, mm: string | number, yyyy: number; @@ -491,24 +429,10 @@ export const animeFlvInfo = async (id: string | undefined, mal_id: number) => { } } - const scripts: cheerio.Element[] = $('script').toArray(); - - for (const script of scripts) { - if ($(script).html()!.includes('anime_info')) { - anime_info = JSON.parse( - $(script).html()!.split('var anime_info = ')[1].split(';\n')[0], - ); - - anime_eps = JSON.parse( - $(script).html()!.split('var episodes = ')[1].split(';')[0], - ); - } - } - - for (const episode of anime_eps) { + for (let i = 1; i <= parseInt(episodesCount); i++) { episodesList.push({ - episode: episode[0], - id: `${episode[1]}/${id}-${episode[0]}`, + episode: i, + id: `${id}/${i}`, }); } @@ -517,14 +441,14 @@ export const animeFlvInfo = async (id: string | undefined, mal_id: number) => { /* Set the key in the redis cache. */ redisClient.set( - `animeflvInfo_${hashStringMd5(id!)}`, + `jkanimeInfo_${hashStringMd5(id!)}`, JSON.stringify(episodesList), ); /* After 24hrs expire the key. */ redisClient.expireat( - `animeflvInfo_${hashStringMd5(id!)}`, + `jkanimeInfo_${hashStringMd5(id!)}`, parseInt(`${+new Date() / 1000}`, 10) + 7200, ); } @@ -535,11 +459,13 @@ export const animeFlvInfo = async (id: string | undefined, mal_id: number) => { } }; -export const jkanimeInfo = async (id: string | undefined, mal_id: number) => { +export const monoschinosInfo = async ( + id: string | undefined, + mal_id: number, +) => { let $: cheerio.Root; + let episodeList: any[] = []; let extraInfo: any; - let episodesList: any[] = []; - let countEpisodes: string[] = []; try { /* Extra info of the anime */ @@ -547,7 +473,7 @@ export const jkanimeInfo = async (id: string | undefined, mal_id: number) => { if (redisClient.connected) { const resultQueryRedis: any = await redisClient.get( - `jkanimeInfo_${hashStringMd5(id!)}`, + `monoschinosInfo_${hashStringMd5(id!)}`, ); if (resultQueryRedis) { @@ -557,7 +483,7 @@ export const jkanimeInfo = async (id: string | undefined, mal_id: number) => { } } - $ = await requestGot(`${urls.BASE_JKANIME}${id}`, { + $ = await requestGot(`${urls.BASE_MONOSCHINOS}anime/${id}`, { scrapy: true, parse: false, }); @@ -565,16 +491,6 @@ export const jkanimeInfo = async (id: string | undefined, mal_id: number) => { return err; } - countEpisodes = $('div.anime__pagination a') - .map((index: number, element: cheerio.Element) => { - return $(element).text(); - }) - .get(); - - const episodesCount: string = countEpisodes[countEpisodes.length - 1].split( - '-', - )[1]; - let broadCastDate = new Date(); let dd: number, mm: string | number, yyyy: number; @@ -621,48 +537,59 @@ export const jkanimeInfo = async (id: string | undefined, mal_id: number) => { : broadCastDate.getMonth() + 1; yyyy = broadCastDate.getFullYear(); - episodesList.push({ + episodeList.push({ nextEpisodeDate: `${yyyy}-${mm}-${dd}`, }); } } - for (let i = 1; i <= parseInt(episodesCount); i++) { - episodesList.push({ - episode: i, - id: `${id}/${i}`, + $('.SerieCaps a').each((index: number, element: cheerio.Element) => { + let episode: number; + + $(element) + .attr('href') + ?.split('-') + .forEach((item: any) => { + if (!isNaN(item)) { + episode = parseInt(item); + } + }); + + episodeList.push({ + episode: episode!, + id: `${$(element).attr('href')?.split('/')[3]}/${ + $(element).attr('href')?.split('/')[4] + }`, }); - } + }); - if (episodesList.length > 0) { + if (episodeList.length > 0) { if (redisClient.connected) { /* Set the key in the redis cache. */ redisClient.set( - `jkanimeInfo_${hashStringMd5(id!)}`, - JSON.stringify(episodesList), + `monoschinosInfo_${hashStringMd5(id!)}`, + JSON.stringify(episodeList), ); /* After 24hrs expire the key. */ redisClient.expireat( - `jkanimeInfo_${hashStringMd5(id!)}`, + `monoschinosInfo_${hashStringMd5(id!)}`, parseInt(`${+new Date() / 1000}`, 10) + 7200, ); } - return episodesList; + return episodeList; } else { return null; } }; -export const monoschinosInfo = async ( - id: string | undefined, - mal_id: number, -) => { +export const tioanimeInfo = async (id: string | undefined, mal_id: number) => { let $: cheerio.Root; - let episodeList: any[] = []; + let episodesList: any[] = []; + let anime_eps: string[] = []; let extraInfo: any; try { @@ -671,7 +598,7 @@ export const monoschinosInfo = async ( if (redisClient.connected) { const resultQueryRedis: any = await redisClient.get( - `monoschinosInfo_${hashStringMd5(id!)}`, + `tioanimeInfo_${hashStringMd5(id!)}`, ); if (resultQueryRedis) { @@ -681,7 +608,7 @@ export const monoschinosInfo = async ( } } - $ = await requestGot(`${urls.BASE_MONOSCHINOS}anime/${id}`, { + $ = await requestGot(`${urls.BASE_TIOANIME}anime/${id}`, { scrapy: true, parse: false, }); @@ -735,53 +662,46 @@ export const monoschinosInfo = async ( : broadCastDate.getMonth() + 1; yyyy = broadCastDate.getFullYear(); - episodeList.push({ + episodesList.push({ nextEpisodeDate: `${yyyy}-${mm}-${dd}`, }); } } - $('.SerieCaps a').each((index: number, element: cheerio.Element) => { - let episode: number; + const scripts: cheerio.Element[] = $('script').toArray(); - $(element) - .attr('href') - ?.split('-') - .forEach((item: any) => { - if (!isNaN(item)) { - episode = parseInt(item); - } - }); + for (const script of scripts) { + if ($(script).html()!.includes('anime_info')) { + anime_eps = JSON.parse( + $(script).html()!.split('var episodes = ')[1].split(';')[0], + ); + } + } - episodeList.push({ - episode: episode!, - id: `${$(element).attr('href')?.split('/')[3]}/${ - $(element).attr('href')?.split('/')[4] - }`, + for (const episode of anime_eps) { + episodesList.push({ + episode: episode[0], + id: `ver/${id}-${episode}`, }); - }); - - if (episodeList.length > 0) { - if (redisClient.connected) { - /* Set the key in the redis cache. */ + } - redisClient.set( - `monoschinosInfo_${hashStringMd5(id!)}`, - JSON.stringify(episodeList), - ); + if (redisClient.connected) { + /* Set the key in the redis cache. */ - /* After 24hrs expire the key. */ + redisClient.set( + `tioanimeInfo_${hashStringMd5(id!)}`, + JSON.stringify(episodesList), + ); - redisClient.expireat( - `monoschinosInfo_${hashStringMd5(id!)}`, - parseInt(`${+new Date() / 1000}`, 10) + 7200, - ); - } + /* After 24hrs expire the key. */ - return episodeList; - } else { - return null; + redisClient.expireat( + `tioanimeInfo_${hashStringMd5(id!)}`, + parseInt(`${+new Date() / 1000}`, 10) + 7200, + ); } + + return episodesList; }; export const videoServersMonosChinos = async (id: string) => { @@ -870,6 +790,73 @@ export const videoServersMonosChinos = async (id: string) => { } }; +export const videoServersTioAnime = async (id: string) => { + let $: cheerio.Root; + let servers: any; + let videoServers: any[] = []; + + try { + if (redisClient.connected) { + const resultQueryRedis: any = await redisClient.get( + `videoServersTioAnime_${hashStringMd5(id)}`, + ); + + if (resultQueryRedis) { + const resultRedis: any = JSON.parse(resultQueryRedis); + + return resultRedis; + } + } + + $ = await requestGot(`${urls.BASE_TIOANIME}${id}`, { + scrapy: true, + parse: false, + }); + } catch (err) { + return err; + } + + const scripts: cheerio.Element[] = $('script').toArray(); + + for (const script of scripts) { + if ($(script).html()!.includes('var videos =')) { + servers = JSON.parse( + $(script).html()!.split('var videos = ')[1].split(';')[0], + ); + } + } + + for (const server of servers) { + videoServers.push({ + id: server[0].toLowerCase(), + url: server[1], + direct: false, + }); + } + + if (videoServers.length > 0) { + if (redisClient.connected) { + /* Set the key in the redis cache. */ + + redisClient.set( + `videoServersTioAnime_${hashStringMd5(id)}`, + JSON.stringify(videoServers), + ); + + /* After 24hrs expire the key. */ + + redisClient.expireat( + `videoServersTioAnime_${hashStringMd5(id)}`, + parseInt(`${+new Date() / 1000}`, 10) + 7200, + ); + } + + return videoServers; + } else { + return null; + } +}; + export const videoServersJK = async (id: string) => { let $: cheerio.Root; let servers: any = {}; @@ -902,8 +889,6 @@ export const videoServersJK = async (id: string) => { }) .get(); - console.log(serverNames); - $('script').each((index: number, element: cheerio.Element) => { if ($(element).html()!.includes('var video = [];')) { script = $(element).html(); From 6480c272aba194f63bd925d684ba9e0d7d242041 Mon Sep 17 00:00:00 2001 From: capitanwesler Date: Sun, 18 Apr 2021 17:31:45 +0100 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=91=BE=20Changing=20control=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- package.json | 2 +- src/routes.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a6cb2cd..dd3d405 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# **Aruppi API** (v4.0.5) +# **Aruppi API** (v4.0.6) > This API has everything about Japan, from anime, music, radio, images, videos ... to japanese culture > diff --git a/package.json b/package.json index 2c870cb..a44a99d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aruppi", - "version": "4.0.5", + "version": "4.0.6", "description": "Aruppi is a custom API to obtain data from the Japanese culture for the mobile app", "main": "./src/api/api.ts", "scripts": { diff --git a/src/routes.ts b/src/routes.ts index b24e590..d005e5c 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -26,7 +26,7 @@ routes.get('/api/v4/', (req: Request, res: Response) => { res.json({ message: 'Aruppi /api - 🎏', author: 'Jéluchu', - version: '4.0.5', + version: '4.0.6', credits: 'The bitch loves /apis that offers data to Aruppi App', entries: [ {