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();