|
|
|
@ -4,7 +4,6 @@ import AnimeModel, {Anime} from '../database/models/anime.model';
|
|
|
|
|
import crypto from 'crypto';
|
|
|
|
|
import util from 'util';
|
|
|
|
|
import {redisClient} from '../database/connection';
|
|
|
|
|
import { stderr } from 'process';
|
|
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
redisClient.get = util.promisify(redisClient.get);
|
|
|
|
@ -35,7 +34,7 @@ interface RelatedAnime {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const animeExtraInfo = async (mal_id: number) => {
|
|
|
|
|
let info: any;
|
|
|
|
|
let data: any;
|
|
|
|
|
let broadcast: any;
|
|
|
|
|
|
|
|
|
|
const airDay: any = {
|
|
|
|
@ -69,40 +68,40 @@ export const animeExtraInfo = async (mal_id: number) => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info = await requestGot(`${urls.BASE_JIKAN}anime/${mal_id}`, {
|
|
|
|
|
data = await requestGot(`${urls.BASE_JIKAN}anime/${mal_id}`, {
|
|
|
|
|
parse: true,
|
|
|
|
|
scrapy: false,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (info.data.airing) {
|
|
|
|
|
broadcast = info.data.broadcast.string.split('at')[0].trim().toLowerCase() || null;
|
|
|
|
|
if (data.broadcast) {
|
|
|
|
|
broadcast = data.broadcast.split('at')[0].trim().toLowerCase() || null;
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (airDay.hasOwnProperty(broadcast)) {
|
|
|
|
|
info.data.broadcast = airDay[broadcast];
|
|
|
|
|
data.broadcast = airDay[broadcast];
|
|
|
|
|
} else {
|
|
|
|
|
info.data.broadcast = null;
|
|
|
|
|
data.broadcast = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const formattedObject: any = {
|
|
|
|
|
titleJapanese: info.data.titles.find((x: { type: string; }) => x.type === "Default").title,
|
|
|
|
|
source: info.data.source,
|
|
|
|
|
totalEpisodes: info.data.episodes,
|
|
|
|
|
titleJapanese: data.title_japanese,
|
|
|
|
|
source: data.source,
|
|
|
|
|
totalEpisodes: data.episodes,
|
|
|
|
|
aired: {
|
|
|
|
|
from: info.data.aired.from,
|
|
|
|
|
to: info.data.aired.to,
|
|
|
|
|
from: data.aired.from,
|
|
|
|
|
to: data.aired.to,
|
|
|
|
|
},
|
|
|
|
|
duration: info.data.duration.split('per')[0],
|
|
|
|
|
rank: info.data.rank,
|
|
|
|
|
broadcast: info.data.broadcast,
|
|
|
|
|
producers: info.data.producers.map((item: any) => item.name) || null,
|
|
|
|
|
licensors: info.data.licensors.map((item: any) => item.name) || null,
|
|
|
|
|
studios: info.data.studios.map((item: any) => item.name) || null,
|
|
|
|
|
openingThemes: info.data.opening_themes || null,
|
|
|
|
|
endingThemes: info.data.ending_themes || null,
|
|
|
|
|
duration: data.duration.split('per')[0],
|
|
|
|
|
rank: data.rank,
|
|
|
|
|
broadcast: data.broadcast,
|
|
|
|
|
producers: data.producers.map((item: any) => item.name) || null,
|
|
|
|
|
licensors: data.licensors.map((item: any) => item.name) || null,
|
|
|
|
|
studios: data.studios.map((item: any) => item.name) || null,
|
|
|
|
|
openingThemes: data.opening_themes || null,
|
|
|
|
|
endingThemes: data.ending_themes || null,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (formattedObject) {
|
|
|
|
@ -129,12 +128,12 @@ export const animeExtraInfo = async (mal_id: number) => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getAnimeVideoPromo = async (mal_id: number) => {
|
|
|
|
|
let info: any;
|
|
|
|
|
let data: any;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (redisClient.connected) {
|
|
|
|
|
const resultQueryRedis: any = await redisClient.get(
|
|
|
|
|
`getMALpromoInfo_${mal_id}`,
|
|
|
|
|
`promoInfo_${hashStringMd5(`${mal_id}`)}`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (resultQueryRedis) {
|
|
|
|
@ -144,7 +143,7 @@ export const getAnimeVideoPromo = async (mal_id: number) => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info = await requestGot(`${urls.BASE_JIKAN}anime/${mal_id}/videos`, {
|
|
|
|
|
data = await requestGot(`${urls.BASE_JIKAN}anime/${mal_id}/videos`, {
|
|
|
|
|
parse: true,
|
|
|
|
|
scrapy: false,
|
|
|
|
|
});
|
|
|
|
@ -152,11 +151,11 @@ export const getAnimeVideoPromo = async (mal_id: number) => {
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const promo: Promo[] = info.data.promo.map((item: any) => {
|
|
|
|
|
const promo: Promo[] = data.promo.map((item: Promo) => {
|
|
|
|
|
return {
|
|
|
|
|
title: item.title,
|
|
|
|
|
previewImage: item.trailer.images.image_url,
|
|
|
|
|
videoURL: item.trailer.url,
|
|
|
|
|
previewImage: item.image_url,
|
|
|
|
|
videoURL: item.video_url,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -165,15 +164,15 @@ export const getAnimeVideoPromo = async (mal_id: number) => {
|
|
|
|
|
/* Set the key in the redis cache. */
|
|
|
|
|
|
|
|
|
|
redisClient.set(
|
|
|
|
|
`getMALpromoInfo_${mal_id}`,
|
|
|
|
|
`promoInfo_${hashStringMd5(`${mal_id}`)}`,
|
|
|
|
|
JSON.stringify(promo),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/* After 2hrs expire the key. */
|
|
|
|
|
/* After 24hrs expire the key. */
|
|
|
|
|
|
|
|
|
|
redisClient.expire(
|
|
|
|
|
`getMALpromoInfo_${mal_id}`,
|
|
|
|
|
7200,
|
|
|
|
|
redisClient.expireat(
|
|
|
|
|
`promoInfo_${hashStringMd5(`${mal_id}`)}`,
|
|
|
|
|
parseInt(`${+new Date() / 1000}`, 10) + 7200,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -184,7 +183,7 @@ export const getAnimeVideoPromo = async (mal_id: number) => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getAnimeCharacters = async (mal_id: number) => {
|
|
|
|
|
let info: any;
|
|
|
|
|
let data: any;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (redisClient.connected) {
|
|
|
|
@ -199,19 +198,19 @@ export const getAnimeCharacters = async (mal_id: number) => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info = await requestGot(
|
|
|
|
|
`${urls.BASE_JIKAN}anime/${mal_id}/characters`,
|
|
|
|
|
data = await requestGot(
|
|
|
|
|
`${urls.BASE_JIKAN}anime/${mal_id}/characters_staff`,
|
|
|
|
|
{parse: true, scrapy: false},
|
|
|
|
|
);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const characters: Character[] = info.data.map((item: any) => {
|
|
|
|
|
const characters: Character[] = data.characters.map((item: any) => {
|
|
|
|
|
return {
|
|
|
|
|
id: item.character.mal_id,
|
|
|
|
|
name: item.character.name,
|
|
|
|
|
image: item.character.images.jpg.image_url,
|
|
|
|
|
id: item.mal_id,
|
|
|
|
|
name: item.name,
|
|
|
|
|
image: item.image_url,
|
|
|
|
|
role: item.role,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
@ -263,12 +262,12 @@ const getPosterAndType = async (
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getRelatedAnimesMAL = async (mal_id: number) => {
|
|
|
|
|
let info: any;
|
|
|
|
|
let $: cheerio.Root;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (redisClient.connected) {
|
|
|
|
|
const resultQueryRedis: any = await redisClient.get(
|
|
|
|
|
`getRelatedMAL_${mal_id}`,
|
|
|
|
|
`getRelatedMAL_${hashStringMd5(`${mal_id}`)}`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (resultQueryRedis) {
|
|
|
|
@ -278,52 +277,65 @@ export const getRelatedAnimesMAL = async (mal_id: number) => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info = await requestGot(`${urls.BASE_JIKAN}anime/${mal_id}/relations`, {
|
|
|
|
|
parse: true,
|
|
|
|
|
scrapy: false,
|
|
|
|
|
$ = await requestGot(`https://myanimelist.net/anime/${mal_id}`, {
|
|
|
|
|
parse: false,
|
|
|
|
|
scrapy: true,
|
|
|
|
|
});
|
|
|
|
|
} catch (err) {
|
|
|
|
|
stderr.write(`Error on getRelatedAnimesMAL http on mal_id: ${mal_id}\n`)
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const relatedAnimes = []
|
|
|
|
|
for (const relation_entry of info.data) {
|
|
|
|
|
for (const entry of relation_entry.entry){
|
|
|
|
|
if (entry.type != "anime")
|
|
|
|
|
break;
|
|
|
|
|
const queryRes: Anime | null = await AnimeModel.findOne({
|
|
|
|
|
mal_id: {$eq: entry.mal_id}
|
|
|
|
|
let listRelated: any = {};
|
|
|
|
|
let relatedAnimes: RelatedAnime[] = [];
|
|
|
|
|
|
|
|
|
|
if ($('table.anime_detail_related_anime').length > 0) {
|
|
|
|
|
$('table.anime_detail_related_anime')
|
|
|
|
|
.find('tbody tr')
|
|
|
|
|
.each((index: number, element: any) => {
|
|
|
|
|
if ($(element).find('td').eq(0).text() !== 'Adaptation:') {
|
|
|
|
|
listRelated[$(element).find('td').eq(1).text()] = $(element)
|
|
|
|
|
.find('td')
|
|
|
|
|
.children('a')
|
|
|
|
|
.attr('href');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (queryRes == null)
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
relatedAnimes.push({
|
|
|
|
|
title: queryRes!.title,
|
|
|
|
|
type: queryRes?.type,
|
|
|
|
|
poster: queryRes?.poster
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
for (const related in listRelated) {
|
|
|
|
|
let posterUrl: any = await getPosterAndType(
|
|
|
|
|
undefined,
|
|
|
|
|
listRelated[related].split('/')[2],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
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. */
|
|
|
|
|
if (relatedAnimes.length > 0) {
|
|
|
|
|
if (redisClient.connected) {
|
|
|
|
|
/* Set the key in the redis cache. */
|
|
|
|
|
|
|
|
|
|
redisClient.set(
|
|
|
|
|
`getRelatedMAL_${mal_id}`,
|
|
|
|
|
JSON.stringify(relatedAnimes),
|
|
|
|
|
);
|
|
|
|
|
redisClient.set(
|
|
|
|
|
`getRelatedMAL_${hashStringMd5(`${mal_id}`)}`,
|
|
|
|
|
JSON.stringify(relatedAnimes),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/* After 24hrs expire the key. */
|
|
|
|
|
|
|
|
|
|
/* After 1hr expire the key. */
|
|
|
|
|
redisClient.expireat(
|
|
|
|
|
`getRelatedMAL_${hashStringMd5(`${mal_id}`)}`,
|
|
|
|
|
parseInt(`${+new Date() / 1000}`, 10) + 7200,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
redisClient.expire(
|
|
|
|
|
`getRelatedMAL_${mal_id}`,
|
|
|
|
|
3600,
|
|
|
|
|
);
|
|
|
|
|
return relatedAnimes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return relatedAnimes;
|
|
|
|
|
} else {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -594,7 +606,6 @@ export const tioanimeInfo = async (id: string | undefined, mal_id: number) => {
|
|
|
|
|
$ = await requestGot(`${urls.BASE_TIOANIME}anime/${id}`, {
|
|
|
|
|
scrapy: true,
|
|
|
|
|
parse: false,
|
|
|
|
|
spoof: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/* Extra info of the anime */
|
|
|
|
@ -774,7 +785,6 @@ export const videoServersTioAnime = async (id: string) => {
|
|
|
|
|
$ = await requestGot(`${urls.BASE_TIOANIME}${id}`, {
|
|
|
|
|
scrapy: true,
|
|
|
|
|
parse: false,
|
|
|
|
|
spoof: true,
|
|
|
|
|
});
|
|
|
|
|
} catch (err) {
|
|
|
|
|
return err;
|
|
|
|
@ -931,7 +941,7 @@ async function desuServerUrl(url: string) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$ = await requestGot(url, {scrapy: true, parse: false, spoof: true});
|
|
|
|
|
$ = await requestGot(url, {scrapy: true, parse: false});
|
|
|
|
|
} catch (err) {
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
@ -1023,7 +1033,7 @@ export function getThemes(themes: any[]) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const imageUrlToBase64 = async (url: string) => {
|
|
|
|
|
let img: any = await requestGot(url,{spoof:false});
|
|
|
|
|
let img: any = await requestGot(url);
|
|
|
|
|
return img.rawBody.toString('base64');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|