🦾 Migrating getAnimeServers and getEpisodes

pull/33/head
capitanwesler 4 years ago
parent 0fea12c350
commit afa20d36df

@ -59,9 +59,9 @@
"ts-node-dev": "^1.1.1" "ts-node-dev": "^1.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/cheerio": "^0.22.24",
"@types/cors": "^2.8.10", "@types/cors": "^2.8.10",
"@types/express": "^4.17.11", "@types/express": "^4.17.11",
"@types/got": "^9.6.11",
"@types/node": "^14.14.31", "@types/node": "^14.14.31",
"@types/tough-cookie": "^4.0.0", "@types/tough-cookie": "^4.0.0",
"@typescript-eslint/eslint-plugin": "^4.15.2", "@typescript-eslint/eslint-plugin": "^4.15.2",

@ -1,6 +1,8 @@
import { NextFunction, Request, Response } from 'express'; import { NextFunction, Request, Response } from 'express';
import { requestGot } from '../utils/requestCall'; import { requestGot } from '../utils/requestCall';
import { animeFlvInfo, jkanimeInfo, videoServersJK } from '../utils/util';
import { transformUrlServer } from '../utils/transformerUrl'; import { transformUrlServer } from '../utils/transformerUrl';
import AnimeModel, { Anime as ModelA } from '../database/models/anime.model';
import urls from '../utils/urls'; import urls from '../utils/urls';
/* /*
@ -189,6 +191,7 @@ export default class AnimeController {
const { type, page, url } = req.params; const { type, page, url } = req.params;
let data: any; let data: any;
if (['movie', 'ova', 'tv', 'special'].indexOf(type) !== -1) {
try { try {
data = await requestGot( data = await requestGot(
`${urls.BASE_ANIMEFLV_JELU}${ `${urls.BASE_ANIMEFLV_JELU}${
@ -226,5 +229,42 @@ export default class AnimeController {
} else { } else {
res.status(500).json({ message: 'Aruppi lost in the shell' }); res.status(500).json({ message: 'Aruppi lost in the shell' });
} }
} else {
next();
}
}
async getEpisodes(req: Request, res: Response, next: NextFunction) {
const { title } = req.params;
let searchAnime: ModelA | null;
try {
searchAnime = await AnimeModel.findOne({ title: { $eq: title } });
} catch (err) {
return next(err);
}
if (!searchAnime?.jkanime) {
res.status(200).json({ episodes: await animeFlvInfo(searchAnime?.id) });
} else {
res.status(200).json({ episodes: await jkanimeInfo(searchAnime?.id) });
}
}
async getServers(req: Request, res: Response, next: NextFunction) {
const { id } = req.params;
if (isNaN(parseInt(id.split('/')[0]))) {
res.status(200).json({ servers: await videoServersJK(id) });
} else {
const data: any = await requestGot(
`${urls.BASE_ANIMEFLV_JELU}GetAnimeServers/${id}`,
{ parse: true, scrapy: false },
);
console.log(data);
res.status(200).json({ servers: await transformUrlServer(data.servers) });
}
} }
} }

@ -74,6 +74,11 @@ routes.get('/api/v4/top/:type/:page/:subtype?/', animeController.top);
routes.get('/api/v4/allAnimes', animeController.getAllAnimes); routes.get('/api/v4/allAnimes', animeController.getAllAnimes);
routes.get('/api/v4/lastEpisodes', animeController.getLastEpisodes); routes.get('/api/v4/lastEpisodes', animeController.getLastEpisodes);
routes.get('/api/v4/:url/:type/:page', animeController.getContent); routes.get('/api/v4/:url/:type/:page', animeController.getContent);
routes.get('/api/v4/getEpisodes/:title', animeController.getEpisodes);
routes.get(
'/api/v4/getAnimeServers/:id([^/]+/[^/]+)',
animeController.getServers,
);
/* Directory Controller */ /* Directory Controller */
routes.get( routes.get(

@ -150,10 +150,13 @@ const getPosterAndType = async (
}; };
export const getRelatedAnimesFLV = async (id: string) => { export const getRelatedAnimesFLV = async (id: string) => {
const $ = await requestGot(`${urls.BASE_ANIMEFLV}/anime/${id}`, { const $: cheerio.Root = await requestGot(
`${urls.BASE_ANIMEFLV}/anime/${id}`,
{
parse: false, parse: false,
scrapy: true, scrapy: true,
}); },
);
let listRelated: any = {}; let listRelated: any = {};
let relatedAnimes: RelatedAnime[] = []; let relatedAnimes: RelatedAnime[] = [];
@ -184,10 +187,13 @@ export const getRelatedAnimesFLV = async (id: string) => {
}; };
export const getRelatedAnimesMAL = async (mal_id: number) => { export const getRelatedAnimesMAL = async (mal_id: number) => {
const $ = await requestGot(`https://myanimelist.net/anime/${mal_id}`, { const $: cheerio.Root = await requestGot(
`https://myanimelist.net/anime/${mal_id}`,
{
parse: false, parse: false,
scrapy: true, scrapy: true,
}); },
);
let listRelated: any = {}; let listRelated: any = {};
let relatedAnimes: RelatedAnime[] = []; let relatedAnimes: RelatedAnime[] = [];
@ -196,7 +202,7 @@ export const getRelatedAnimesMAL = async (mal_id: number) => {
$('table.anime_detail_related_anime') $('table.anime_detail_related_anime')
.find('tbody tr') .find('tbody tr')
.each((index: number, element: any) => { .each((index: number, element: any) => {
if ($(element).find('td').eq(0) !== 'Adaptation:') { if ($(element).find('td').eq(0).text() !== 'Adaptation:') {
listRelated[$(element).find('td').eq(1).text()] = $(element) listRelated[$(element).find('td').eq(1).text()] = $(element)
.find('td') .find('td')
.children('a') .children('a')
@ -224,3 +230,182 @@ export const getRelatedAnimesMAL = async (mal_id: number) => {
return []; return [];
} }
}; };
export const animeFlvInfo = async (id: string | undefined) => {
let $: cheerio.Root;
let anime_info: string[] = [];
let anime_eps: string[] = [];
let nextEpisodeDate: string | null;
let episodes: any[] = [];
try {
$ = await requestGot(`${urls.BASE_ANIMEFLV}/anime/${id}`, {
scrapy: true,
parse: false,
});
} catch (err) {
return err;
}
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],
);
}
}
if (anime_info.length === 4) {
nextEpisodeDate = anime_info[3];
} else {
nextEpisodeDate = null;
}
episodes.push({ nextEpisodeDate });
for (const episode of anime_eps) {
episodes.push({
episode: episode[0],
id: `${episode[1]}/${id}-${episode[0]}`,
});
}
return episodes;
};
export const jkanimeInfo = async (id: string | undefined) => {
let $: cheerio.Root;
let nextEpisodeDate: string | null;
let imageLink: string | undefined;
let episodesList: any[] = [];
let countEpisodes: string[] = [];
try {
$ = await requestGot(`${urls.BASE_JKANIME}${id}`, {
scrapy: true,
parse: false,
});
} catch (err) {
return err;
}
countEpisodes = $('div.navigation a')
.map((index: number, element: cheerio.Element) => {
return $(element).text();
})
.get();
const episodesCount: string = countEpisodes[countEpisodes.length - 1].split(
'-',
)[1];
nextEpisodeDate = $('div.proxep p').text() || null;
episodesList.push({ nextEpisodeDate });
for (let i = 1; i <= parseInt(episodesCount); i++) {
episodesList.push({
episode: i,
id: `${id}/${i}`,
});
}
return episodesList;
};
export const videoServersJK = async (id: string) => {
let $: cheerio.Root;
let servers: any = {};
let script: string | null = '';
try {
$ = await requestGot(`${urls.BASE_JKANIME}${id}`, {
scrapy: true,
parse: false,
});
} catch (err) {
return err;
}
const serverNames: string[] = $('div#reproductor-box li')
.map((index: number, element: cheerio.Element) => {
return $(element).find('a').text();
})
.get();
$('script').each((index: number, element: cheerio.Element) => {
if ($(element).html()!.includes('var video = [];')) {
script = $(element).html();
}
});
try {
let videoUrls = script.match(/(?<=src=").*?(?=[\*"])/gi);
for (let i = 0; i < serverNames.length; i++) {
servers[serverNames[i]] = videoUrls![i];
}
} catch (err) {
return null;
}
let serverList = [];
for (let server in servers) {
if (serverNames[serverNames.indexOf(server)].toLowerCase() === 'desu') {
serverList.push({
id: serverNames[serverNames.indexOf(server)].toLowerCase(),
url:
(await desuServerUrl(servers[server])) !== null
? await desuServerUrl(servers[server])
: servers[server],
direct: false,
});
} else {
serverList.push({
id: serverNames[serverNames.indexOf(server)].toLowerCase(),
url: servers[server],
direct: false,
});
}
}
serverList = serverList.filter(x => x.id !== 'xtreme s' && x.id !== 'desuka');
return serverList;
};
async function desuServerUrl(url: string) {
let $: cheerio.Root;
try {
$ = await requestGot(url, { scrapy: true, parse: false });
} catch (err) {
return err;
}
let script: string | null = '';
$('script').each((index: number, element: cheerio.Element) => {
if ($(element).html()!.includes('var parts = {')) {
if ($(element).html()) {
script = $(element).html();
} else {
return null;
}
}
});
let result = script
.match(/swarmId: '(https:\/\/\S+)'/gi)!
.toString()
.split("'")[1];
return result;
}

@ -81,6 +81,13 @@
"@types/node" "*" "@types/node" "*"
"@types/responselike" "*" "@types/responselike" "*"
"@types/cheerio@^0.22.24":
version "0.22.24"
resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.24.tgz#fcee47074aa221ac0f31ede0c72c0800bf3bf0aa"
integrity sha512-iKXt/cwltGvN06Dd6zwQG1U35edPwId9lmcSeYfcxSNvvNg4vysnFB+iBQNjj06tSVV7MBj0GWMQ7dwb4Z+p8Q==
dependencies:
"@types/node" "*"
"@types/connect@*": "@types/connect@*":
version "3.4.34" version "3.4.34"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901"
@ -117,15 +124,6 @@
"@types/qs" "*" "@types/qs" "*"
"@types/serve-static" "*" "@types/serve-static" "*"
"@types/got@^9.6.11":
version "9.6.11"
resolved "https://registry.yarnpkg.com/@types/got/-/got-9.6.11.tgz#482b402cc5ee459481aeeadb08142ebb1a9afb26"
integrity sha512-dr3IiDNg5TDesGyuwTrN77E1Cd7DCdmCFtEfSGqr83jMMtcwhf/SGPbN2goY4JUWQfvxwY56+e5tjfi+oXeSdA==
dependencies:
"@types/node" "*"
"@types/tough-cookie" "*"
form-data "^2.5.0"
"@types/http-cache-semantics@*": "@types/http-cache-semantics@*":
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a"
@ -201,7 +199,7 @@
resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==
"@types/tough-cookie@*", "@types/tough-cookie@^4.0.0": "@types/tough-cookie@^4.0.0":
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d"
integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==
@ -391,11 +389,6 @@ astral-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
balanced-match@^1.0.0: balanced-match@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@ -598,13 +591,6 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
combined-stream@^1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
compose-middleware@^5.0.1: compose-middleware@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/compose-middleware/-/compose-middleware-5.0.1.tgz#4c0adb751afdde45d637a7a0b361095e510fafff" resolved "https://registry.yarnpkg.com/compose-middleware/-/compose-middleware-5.0.1.tgz#4c0adb751afdde45d637a7a0b361095e510fafff"
@ -761,11 +747,6 @@ define-properties@^1.1.3:
dependencies: dependencies:
object-keys "^1.0.12" object-keys "^1.0.12"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
denque@^1.4.1: denque@^1.4.1:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de" resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de"
@ -1272,15 +1253,6 @@ flatted@^2.0.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
form-data@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
forwarded@~0.1.2: forwarded@~0.1.2:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
@ -1810,7 +1782,7 @@ mime-db@1.46.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee"
integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==
mime-types@^2.1.12, mime-types@~2.1.24: mime-types@~2.1.24:
version "2.1.29" version "2.1.29"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2"
integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==

Loading…
Cancel
Save