Merge pull request #14 from aruppi/feature/improving

Fixing some issues with jkanime servers
pull/25/head^2
Jesús María 5 years ago committed by GitHub
commit 26c0d766cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,4 @@
# **Aruppi API** (v3.3.6) # **Aruppi API** (v3.3.7)
> This API has everything about Japan, from anime, music, radio, images, videos ... to japanese culture > This API has everything about Japan, from anime, music, radio, images, videos ... to japanese culture
> >

2
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "aruppi", "name": "aruppi",
"version": "3.3.6", "version": "3.3.7",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,6 +1,6 @@
{ {
"name": "aruppi", "name": "aruppi",
"version": "3.3.6", "version": "3.3.7",
"description": "Aruppi is a custom API to obtain data from the Japanese culture for the mobile app", "description": "Aruppi is a custom API to obtain data from the Japanese culture for the mobile app",
"main": "./src/api/api.js", "main": "./src/api/api.js",
"scripts": { "scripts": {

@ -16,11 +16,11 @@ const {
structureThemes, structureThemes,
videoServersJK, videoServersJK,
getThemes, getThemes,
getMALid getRelatedAnimes
} = require('../utils/index'); } = require('../utils/index');
const ThemeParser = require('../utils/animetheme'); const ThemeParser = require('../utils/animetheme');
const parserThemes = new ThemeParser() const parserThemes = new ThemeParser();
const { const {
BASE_ANIMEFLV_JELU, BASE_JIKAN, BASE_IVOOX, BASE_QWANT, BASE_YOUTUBE, BASE_THEMEMOE, BASE_ANIMEFLV, BASE_ARUPPI BASE_ANIMEFLV_JELU, BASE_JIKAN, BASE_IVOOX, BASE_QWANT, BASE_YOUTUBE, BASE_THEMEMOE, BASE_ANIMEFLV, BASE_ARUPPI
@ -75,17 +75,19 @@ const getAllAnimes = async () =>{
}; };
const getAllDirectory = async (genres) =>{ const getAllDirectory = async (genres) => {
let data let data;
if (genres === "sfw") {
if (genres === 'sfw') {
data = JSON.parse(JSON.stringify(require('../assets/directory.json'))).filter(function (item) { data = JSON.parse(JSON.stringify(require('../assets/directory.json'))).filter(function (item) {
return !item.genres.includes("Ecchi") && !item.genres.includes("ecchi"); return !item.genres.includes("Ecchi") && !item.genres.includes("ecchi");
}) });
} else { } else {
data = JSON.parse(JSON.stringify(require('../assets/directory.json'))); data = JSON.parse(JSON.stringify(require('../assets/directory.json')));
} }
return data.map(doc => ({ return data.map(doc => ({
id: doc.id, id: doc.id,
title: doc.title, title: doc.title,
@ -101,7 +103,7 @@ const getAllDirectory = async (genres) =>{
}; };
const getAnitakume = async () =>{ const getAnitakume = async () => {
const promises = [] const promises = []
@ -238,45 +240,25 @@ const getMoreInfo = async (title) =>{
try { try {
const promises = []
let data = JSON.parse(JSON.stringify(require('../assets/directory.json'))); let data = JSON.parse(JSON.stringify(require('../assets/directory.json')));
const res = data.filter(x => x.title === title || x.mal_title === title)[0]; let result = data.filter(anime => anime.title === title)[0];
if (!res.jkanime) { return {
promises.push({ title: result.title || null,
title: res.title || null, poster: result.poster || null,
poster: res.poster || null, synopsis: result.description || null,
synopsis: res.description || null, status: result.state || null,
status: res.state || null, type: result.type || null,
type: res.type || null, rating: result.score || null,
rating: res.score || null, genres: result.genres || null,
genres: res.genres || null, moreInfo: await animeExtraInfo(result.mal_title).then(info => info || null),
episodes: await animeflvInfo(res.id).then(episodes => episodes || null), promo: await getAnimeVideoPromo(result.mal_title).then(promo => promo || null),
moreInfo: await animeExtraInfo(res.mal_title).then(info => info || null), characters: await getAnimeCharacters(result.mal_title).then(characters => characters || null),
promo: await getAnimeVideoPromo(res.mal_title).then(promo => promo || null), related: await getRelatedAnimes(result.id)
characters: await getAnimeCharacters(res.mal_title).then(characters => characters || null)
});
} else {
promises.push({
title: res.title || null,
poster: res.poster || null,
synopsis: res.description || null,
status: res.state || null,
type: res.type || null,
rating: res.score || null,
genres: res.genres || null,
episodes: await jkanimeInfo(res.id).then(episodes => episodes || null),
moreInfo: await animeExtraInfo(res.mal_title).then(info => info || null),
promo: await getAnimeVideoPromo(res.mal_title).then(promo => promo || null),
characters: await getAnimeCharacters(res.mal_title).then(characters => characters || null)
});
} }
return promises;
} catch (e) { } catch (e) {
console.log(e) console.log(e);
} }
}; };
@ -285,25 +267,17 @@ const getEpisodes = async (title) =>{
try { try {
const promises = []
let data = JSON.parse(JSON.stringify(require('../assets/directory.json'))); let data = JSON.parse(JSON.stringify(require('../assets/directory.json')));
const res = data.filter(x => x.title === title || x.mal_title === title)[0]; const result = data.filter(x => x.title === title || x.mal_title === title)[0];
if (!res.jkanime) { if (!result.jkanime) {
promises.push({ return await animeflvInfo(result.id).then(episodes => episodes || null);
episodes: await animeflvInfo(res.id).then(episodes => episodes || null),
});
} else { } else {
promises.push({ return await jkanimeInfo(result.id).then(episodes => episodes || null);
episodes: await jkanimeInfo(res.id).then(episodes => episodes || null),
});
} }
return promises;
} catch (e) { } catch (e) {
console.log(e) console.log(e);
} }
}; };
@ -311,10 +285,15 @@ const getEpisodes = async (title) =>{
const getAnimeServers = async (id) => { const getAnimeServers = async (id) => {
if (isNaN(id.split('/')[0])) { if (isNaN(id.split('/')[0])) {
return await videoServersJK(id)
return await videoServersJK(id);
} else { } else {
const data = await homgot(`${BASE_ANIMEFLV_JELU}GetAnimeServers/${id}`, { parse: true }); const data = await homgot(`${BASE_ANIMEFLV_JELU}GetAnimeServers/${id}`, { parse: true });
return await transformUrlServer(data.servers); return await transformUrlServer(data.servers);
} }
}; };
@ -392,7 +371,7 @@ const getOpAndEd = async (title) => await structureThemes(await parserThemes.ser
const getThemesYear = async (year) => { const getThemesYear = async (year) => {
let data = [] let data = [];
if (year === undefined) { if (year === undefined) {
return await parserThemes.allYears(); return await parserThemes.allYears();
} else { } else {
@ -510,7 +489,7 @@ const getPlatforms = async (id) => {
const getProfilePlatform = async (id) => { const getProfilePlatform = async (id) => {
let data = await homgot(`${BASE_ARUPPI}res/documents/animelegal/platforms/${id}.json`, { parse: true }) let data = await homgot(`${BASE_ARUPPI}res/documents/animelegal/platforms/${id}.json`, { parse: true });
let channelId = { id: data[0].youtubeId, part: 'snippet,id', order: 'date', maxResults: '50', prop: 'items' }; let channelId = { id: data[0].youtubeId, part: 'snippet,id', order: 'date', maxResults: '50', prop: 'items' };
let videos = await getYoutubeVideos(channelId) let videos = await getYoutubeVideos(channelId)
@ -562,5 +541,6 @@ module.exports = {
getDestAnimePlatforms, getDestAnimePlatforms,
getPlatforms, getPlatforms,
getSectionYoutubeVideos, getSectionYoutubeVideos,
getProfilePlatform getProfilePlatform,
getRelatedAnimes
}; };

@ -1,27 +1,30 @@
const got = require('got'); const got = require('got'); // This is to make a HTTP request without doing AJAX
const cheerio = require('cheerio'); const cheerio = require('cheerio');
const { CookieJar} = require('tough-cookie'); const { CookieJar} = require('tough-cookie');
const cookieJar = new CookieJar(); const cookieJar = new CookieJar();
let response let response;
let data let data;
const homgot = async (url, options) => { const homgot = async (url, options) => {
if (options !== undefined) { if (options !== undefined) {
if (options.scrapy) { if (options.scrapy) {
response = await got(url, { cookieJar }) response = await got(url, { cookieJar });
data = await cheerio.load(response.body) data = await cheerio.load(response.body);
} }
if (options.parse) { if (options.parse) {
data = await got(url, { cookieJar }).json() data = await got(url, { cookieJar }).json();
} }
} else { } else {
data = await got.get(url, { cookieJar }); data = await got.get(url, { cookieJar });
} }
return data return data;
} }
module.exports = {homgot} module.exports = { homgot };

@ -269,14 +269,12 @@ router.get('/moreInfo/:title' , (req, res) =>{
let title = req.params.title; let title = req.params.title;
api.getMoreInfo(title) api.getMoreInfo(title)
.then(info =>{ .then(info => {
if (info.length > 0) { if (info !== undefined) {
res.status(200).json({ res.status(200).json(info);
info } else {
}); res.status(500).json({ message: 'Aruppi lost in the shell'});
} else ( }
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{ }).catch((err) =>{
console.error(err); console.error(err);
}); });
@ -288,13 +286,15 @@ router.get('/getEpisodes/:title' , (req, res) =>{
let title = req.params.title; let title = req.params.title;
api.getEpisodes(title) api.getEpisodes(title)
.then(episodes =>{ .then(episodes => {
if (episodes.length > 0) { if (episodes.length > 0) {
res.status(200).json(episodes); res.status(200).json({episodes});
} else ( } else {
res.status(500).json({ message: 'Aruppi lost in the shell'}) res.status(500).json({ message: 'Aruppi lost in the shell'});
) }
}).catch((err) =>{ }).catch((err) =>{
console.error(err); console.error(err);
}); });
@ -310,9 +310,9 @@ router.get('/getAnimeServers/:id([^/]+/[^/]+)' , (req, res) =>{
res.status(200).json({ res.status(200).json({
servers servers
}); });
} else ( } else {
res.status(500).json({ message: 'Aruppi lost in the shell'}) res.status(500).json({ message: 'Aruppi lost in the shell'});
) }
}).catch((err) =>{ }).catch((err) =>{
console.error(err); console.error(err);
}); });
@ -433,16 +433,17 @@ router.get('/allThemes', (req, res) =>{
router.get('/themes/:title' , (req, res) =>{ router.get('/themes/:title' , (req, res) =>{
let title = req.params.title; let title = req.params.title;
api.getOpAndEd(title) api.getOpAndEd(title)
.then(themes =>{ .then(themes => {
if (themes.length > 0) { if (themes) {
res.status(200).json({ res.status(200).json({
themes themes
}); });
} else ( } else {
res.status(500).json({ message: 'Aruppi lost in the shell'}) res.status(500).json({ message: 'Aruppi lost in the shell'});
) }
}).catch((err) =>{ }).catch((err) =>{
console.error(err); console.error(err);
}); });

@ -13,6 +13,8 @@ function shutdown() {
process.exit(); process.exit();
} }
// @TESTING
process.on('SIGINT', shutdown); process.on('SIGINT', shutdown);
process.on('SIGQUIT', shutdown); process.on('SIGQUIT', shutdown);
process.on('SIGTERM', shutdown); process.on('SIGTERM', shutdown);

@ -19,7 +19,7 @@ class ThemeParser {
return await this.parseLinks(); return await this.parseLinks();
} }
catch(err) { catch(err) {
throw err; console.log(err);
} }
} }
@ -30,18 +30,18 @@ class ThemeParser {
return await this.parseYears(); return await this.parseYears();
} }
catch(err) { catch(err) {
throw err; console.log(err);
} }
} }
async serie(query) { async serie(title) {
try { try {
this.animes = []; this.animes = [];
this.$ = await redditocall('anime_index'); this.$ = await redditocall('anime_index');
return await this.parseSerie(query); return await this.parseSerie(title);
} }
catch(err) { catch(err) {
throw err; console.log(err);
} }
} }
@ -52,7 +52,7 @@ class ThemeParser {
return await this.parseArtists(); return await this.parseArtists();
} }
catch(err) { catch(err) {
throw err; console.log(err);
} }
} }
@ -63,7 +63,7 @@ class ThemeParser {
return await this.parseArtist(); return await this.parseArtist();
} }
catch(err) { catch(err) {
throw err; console.log(err);
} }
} }
@ -74,13 +74,14 @@ class ThemeParser {
return await this.parseRandom(query); return await this.parseRandom(query);
} }
catch(err) { catch(err) {
throw err; console.log(err);
} }
} }
async year(date) { async year(date) {
let animes = []; let animes = [];
this.$ = await redditocall(date)
this.$ = await redditocall(date);
this.$('h3').each((i, el) => { this.$('h3').each((i, el) => {
let parsed = this.parseAnime(el); let parsed = this.parseAnime(el);
parsed.year = date; parsed.year = date;
@ -102,13 +103,13 @@ class ThemeParser {
let parsed = this.parseAnime(this.$('h3')[rand]); let parsed = this.parseAnime(this.$('h3')[rand]);
resolve(parsed); resolve(parsed);
}) });
} }
parseYears(){ parseYears() {
return new Promise(async resolve => { return new Promise(async resolve => {
let promises = [] let promises = [];
let data = this.$('h3 a'); let data = this.$('h3 a');
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
@ -119,15 +120,15 @@ class ThemeParser {
}) })
if (i === data.length - 1) { if (i === data.length - 1) {
resolve(promises) resolve(promises);
} }
} }
}) });
} }
parseArtists(){ parseArtists() {
return new Promise(async resolve => { return new Promise(async resolve => {
let promises = [] let promises = []
@ -169,22 +170,31 @@ class ThemeParser {
}) })
} }
parseSerie(query){ /* - ParseSerie
Parse the HTML from the redditocall
and search for the h3 tag to be the
same of the title and resolve a object.
*/
parseSerie(title) {
return new Promise(async resolve => { return new Promise(async resolve => {
let data = this.$('p a'); let data = this.$('p a');
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
let serieElement = data[i].children[0].data let serieElement = data[i].children[0].data;
if (serieElement.split(" (")[0] === query) { if (serieElement.split(" (")[0] === title) {
let year = this.$('p a')[i].attribs.href.split('/r/AnimeThemes/wiki/')[1].split('#wiki')[0];
this.$ = await redditocall(this.$('p a')[i].attribs.href.split('/r/AnimeThemes/wiki/')[1].split('#wiki')[0]); this.$ = await redditocall(this.$('p a')[i].attribs.href.split('/r/AnimeThemes/wiki/')[1].split('#wiki')[0]);
for (let i = 0; i < this.$('h3').length; i++) { for (let i = 0; i < this.$('h3').length; i++) {
if (this.$('h3')[i].children[0].children[0].data === query) {
if (this.$('h3')[i].children[0].children[0].data === title) {
let parsed = this.parseAnime(this.$('h3')[i]); let parsed = this.parseAnime(this.$('h3')[i]);
parsed.year = year;
resolve(parsed); resolve(parsed);
} }
} }
@ -192,17 +202,18 @@ class ThemeParser {
} }
} }
}) });
} }
parseLinks() { parseLinks() {
return new Promise(async resolve => { return new Promise(async resolve => {
let years = this.$('h3 a'); let years = this.$('h3 a');
this.$('h3 a')[0].children[0].data
for (let i = 0; i < years.length; i++) { for (let i = 0; i < years.length; i++) {
let yearElement = years[i]; let yearElement = years[i];
await this.year(this.$(yearElement).attr('href').split('/')[4]) await this.year(this.$(yearElement).attr('href').split('/')[4])
.then(async animes => { .then(async animes => {
this.animes = this.animes.concat(animes); this.animes = this.animes.concat(animes);
@ -215,65 +226,80 @@ class ThemeParser {
}) })
} }
parseAnime(dat) { parseAnime(element) {
let el = this.$(dat).children('a'); let el = this.$(element).children('a');
let title = el.text(); let title = el.text();
let malId = el.attr('href').split('/')[4]; let mal_id = el.attr('href').split('/')[4];
let next = this.$(dat).next(); let next = this.$(element).next();
let theme = { let theme = {
id: malId, id: mal_id,
title title
} };
if (next.prop("tagName") === "TABLE") {
if (next.prop("tagName") === "P") {
theme.themes = this.parseTable(next.next());
} else if (next.prop("tagName") === "TABLE") {
theme.themes = this.parseTable(next); theme.themes = this.parseTable(next);
}
}else if (next.prop("tagName") === "P") {
theme.themes = this.parseTable(next.next());
}
return theme; return theme;
} }
parseTable(table) { /* - ParseTable
if (table.prop('tagName') !== "TABLE") { Parse the table tag from the HTML
return this.parseTable(table.next()); and returns a object with all the
information.
*/
parseTable(element) {
if (element.prop('tagName') !== "TABLE") {
return this.parseTable(element.next());
} }
let themes = []; let themes = [];
table.children('tbody').children('tr').each(function () {
const $ = cheerio.load(this); element.find('tbody').find('tr').each((i, elem) => {
const td = $('td'); // Theme row
let name = replaceAll(td.first().text(), "&quot;", "\"") let name = replaceAll(elem.children[1].children[0].data, "&quot;", "\"");
let linkEl = td.eq(1).children().first(); let link = elem.children[3].children[0].attribs.href;
let link = linkEl.attr('href'); let linkDesc = elem.children[3].children[0].children[0].data;
let linkDesc = linkEl.text(); let episodes = elem.children[5].children.length > 0 ? elem.children[5].children[0].data : "";
let episodes = td.eq(2).text(); let notes = elem.children[7].children.length > 0 ? elem.children[7].children[0].data : "";
let notes = td.eq(3).text();
themes.push({ themes.push({
name, name,
link, link,
desc: linkDesc, desc: linkDesc,
type: (name.startsWith('OP') ? 'opening' : 'ending'), type: name.startsWith('OP') ? 'Opening' : name.startsWith('ED') ? 'Ending' : 'OP/ED',
episodes, episodes,
notes notes
}) });
}) });
return themes; return themes;
} }
} }
async function redditocall(href) { async function redditocall(href) {
let resp = await homgot(REDDIT_ANIMETHEMES + href + ".json", { parse: true }) let resp = await homgot(REDDIT_ANIMETHEMES + href + ".json", { parse: true });
return cheerio.load(getHTML(resp.data.content_html)); return cheerio.load(getHTML(resp.data.content_html));
} }
function getHTML(str) { function getHTML(str) {
let html = replaceAll(str, "&lt;", "<") let html = replaceAll(str, "&lt;", "<");
html = replaceAll(html, "&gt;", ">") html = replaceAll(html, "&gt;", ">");
return html; return html;
} }
@ -281,4 +307,5 @@ function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace); return str.replace(new RegExp(find, 'g'), replace);
} }
module.exports = ThemeParser; module.exports = ThemeParser;

@ -22,91 +22,107 @@ global.btoa = btoa;
async function videoServersJK(id) { async function videoServersJK(id) {
const $ = await homgot(`${BASE_JKANIME}${id}`, { scrapy: true }); const $ = await homgot(`${BASE_JKANIME}${id}`, { scrapy: true });
let servers = {};
const scripts = $('script'); let script;
const episodes = $('div#reproductor-box li'); const serverNames = $('div#reproductor-box li').map((index, element) => {
const serverNames = []; return $(element).find('a').text();
let servers = []; }).get();
episodes.each((index, element) => serverNames.push($(element).find('a').text())) $('script').each((index, element) => {
if ($(element).html().includes('var video = [];')) {
for (let i = 0; i < scripts.length; i++) { script = $(element).html();
try { }
const contents = $(scripts[i]).html(); });
if ((contents || '').includes('var video = [];')) {
Array.from({ length: episodes.length }, (v, k) => { try {
let index = Number(k + 1); let videoUrls = script.match(/(?<=src=").*?(?=[\*"])/gi);
let videoPageURL = contents.split(`video[${index}] = \'<iframe class="player_conte" src="`)[1].split('"')[0];
servers.push({ iframe: videoPageURL }); for (let i = 0; i < serverNames.length; i++) {
}); servers[serverNames[i]] = videoUrls[i];
}
} catch (err) {
console.log(err)
return null;
} }
}
} catch (err) {
console.log(err);
return null;
}
let serverList = []; let serverList = [];
for (let server in servers) { for (let server in servers) {
serverList.push({ if (serverNames[serverNames.indexOf(server)].toLowerCase() === 'desu') {
id: serverNames[server].toLowerCase(), serverList.push({
url: await getVideoURL(servers[server].iframe), id: serverNames[serverNames.indexOf(server)].toLowerCase(),
direct: true url: await desuServerUrl(servers[server]) !== null ? await desuServerUrl(servers[server]) : servers[server],
}); direct: true
});
}else {
serverList.push({
id: serverNames[serverNames.indexOf(server)].toLowerCase(),
url: servers[server],
direct: true
});
}
} }
serverList = serverList.filter(x => x.id !== 'xtreme s' && x.id !== 'desuka'); serverList = serverList.filter(x => x.id !== 'xtreme s' && x.id !== 'desuka');
return await Promise.all(serverList); return serverList;
} }
async function getVideoURL(url) { async function desuServerUrl(url) {
const $ = await homgot(url, { scrapy: true }); const $ = await homgot(url, { scrapy: true});
let script;
const video = $('video'); $('script').each((index, element) => {
if (video.length) { if ($(element).html().includes('var parts = {')) {
const src = $(video).find('source').attr('src'); if ($(element).html()) {
return src || null; script = $(element).html();
} }else {
else { return null;
}
}
});
const scripts = $('script'); let result = script.match(/swarmId: '(https:\/\/\S+)'/gi)
const l = global; .toString()
const ll = String; .split('\'')[1];
const $script2 = $(scripts[1]).html();
eval($script2); return result;
return l.ss || null;
}
} }
const jkanimeInfo = async (id) => { const jkanimeInfo = async (id) => {
let $ = await homgot(`${BASE_JKANIME}${id}`, { scrapy: true }); let $ = await homgot(`${BASE_JKANIME}${id}`, { scrapy: true });
let nextEpisodeDate let nextEpisodeDate;
let rawNextEpisode = $('div[id="container"] div.left-container div[id="proxep"] p')[0] let rawNextEpisode = $('div[id="container"] div.left-container div[id="proxep"] p')[0];
if (rawNextEpisode === undefined) { if (rawNextEpisode === undefined) {
nextEpisodeDate = null nextEpisodeDate = null;
} else { } else {
if (rawNextEpisode.children[1].data === ' ') { if (rawNextEpisode.children[1].data === ' ') {
nextEpisodeDate = null nextEpisodeDate = null;
} else { } else {
nextEpisodeDate = rawNextEpisode.children[1].data.trim() nextEpisodeDate = rawNextEpisode.children[1].data.trim();
} }
} }
const eps_temp_list = []; const eps_temp_list = [];
let episodes_aired = ''; let episodes_aired = '';
$('div#container div.left-container div.navigation a').each(async (index, element) => { $('div#container div.left-container div.navigation a').each(async (index, element) => {
const $element = $(element); const $element = $(element);
const total_eps = $element.text(); const total_eps = $element.text();
eps_temp_list.push(total_eps); eps_temp_list.push(total_eps);
}) });
try { episodes_aired = eps_temp_list[0].split('-')[1].trim(); } catch (err) { } try { episodes_aired = eps_temp_list[0].split('-')[1].trim(); } catch (err) { }
const animeListEps = [{ nextEpisodeDate: nextEpisodeDate }]; const animeListEps = [{ nextEpisodeDate: nextEpisodeDate }];
for (let i = 1; i <= episodes_aired; i++) { for (let i = 1; i <= episodes_aired; i++) {
let episode = i; let episode = i;
let animeId = $('div[id="container"] div.content-box div[id="episodes-content"]')[0].children[1].children[3].attribs.src.split('/')[7].split('.jpg')[0]; let animeId = $('div[id="container"] div.content-box div[id="episodes-content"]')[0].children[1].children[3].attribs.src.split('/')[7].split('.jpg')[0];
@ -122,8 +138,52 @@ const jkanimeInfo = async (id) => {
}; };
function getPoster(id) {
let data = JSON.parse(JSON.stringify(require('../assets/directory.json')));
for (let anime of data) {
if (anime.id === id) {
return anime.poster;
}
}
return "";
};
async function getRelatedAnimes(id) {
const $ = await homgot(`${BASE_ANIMEFLV}/anime/${id}`, { scrapy: true });
let listRelated = {};
let relatedAnimes = [];
if ($('ul.ListAnmRel').length) {
$('ul.ListAnmRel li a').each((index, element) => {
listRelated[$(element).text()] = $(element).attr('href');
});
for (related in listRelated) {
let posterUrl = getPoster(listRelated[related].split('/')[2]);
relatedAnimes.push(
{
id: listRelated[related].split('/')[2],
title: related,
poster: posterUrl
}
);
}
return relatedAnimes;
}else {
return [];
}
};
const animeflvGenres = async (id) => { const animeflvGenres = async (id) => {
let $ = await homgot(`${BASE_ANIMEFLV}${id}`, { scrapy: true }); let $ = await homgot(`${BASE_ANIMEFLV}/${id}`, { scrapy: true });
$('main.Main section.WdgtCn nav.Nvgnrs a').each((index, element) => { $('main.Main section.WdgtCn nav.Nvgnrs a').each((index, element) => {
return $(element).attr('href').split('=')[1] || null; return $(element).attr('href').split('=')[1] || null;
}); });
@ -131,45 +191,51 @@ const animeflvGenres = async (id) => {
const animeflvInfo = async (id) => { const animeflvInfo = async (id) => {
let $ = await homgot(`${BASE_ANIMEFLV}anime/${id}`, { scrapy: true }); let $ = await homgot(`${BASE_ANIMEFLV}/anime/${id}`, { scrapy: true });
let scripts = $('script').toArray(); let scripts = $('script').toArray();
const anime_info_ids = []; const anime_info_ids = [];
const anime_eps_data = []; const anime_eps_data = [];
Array.from({ length: scripts.length }, (v, k) => { for (let script of scripts) {
const contents = $(scripts[k]).html(); const contents = $(script).html();
if ((contents || '').includes('var anime_info = [')) { if ((contents || '').includes('var anime_info = [')) {
let anime_info = contents.split('var anime_info = ')[1].split(';\n')[0]; let anime_info = contents.split('var anime_info = ')[1].split(';\n')[0];
let dat_anime_info = JSON.parse(anime_info); let dat_anime_info = JSON.parse(anime_info);
anime_info_ids.push(dat_anime_info); anime_info_ids.push(dat_anime_info);
} }
if ((contents || '').includes('var episodes = [')) { if ((contents || '').includes('var episodes = [')) {
let episodes = contents.split('var episodes = ')[1].split(';')[0]; let episodes = contents.split('var episodes = ')[1].split(';')[0];
let eps_data = JSON.parse(episodes) let eps_data = JSON.parse(episodes);
anime_eps_data.push(eps_data); anime_eps_data.push(eps_data);
} }
}); }
const animeId = id; const animeId = id;
let nextEpisodeDate let nextEpisodeDate;
if (anime_info_ids.length > 0) { if (anime_info_ids.length > 0) {
if (anime_info_ids[0].length === 4) { if (anime_info_ids[0].length === 4) {
nextEpisodeDate = anime_info_ids[0][3] nextEpisodeDate = anime_info_ids[0][3];
} else { } else {
nextEpisodeDate = null nextEpisodeDate = null;
} }
} }
const amimeTempList = []; const amimeTempList = [];
for (const [key] of Object.entries(anime_eps_data)) { for (const [key] of Object.entries(anime_eps_data)) {
let episode = anime_eps_data[key].map(x => x[0]); let episode = anime_eps_data[key].map(x => x[0]);
let episodeId = anime_eps_data[key].map(x => x[1]); let episodeId = anime_eps_data[key].map(x => x[1]);
amimeTempList.push(episode, episodeId); amimeTempList.push(episode, episodeId);
} }
const animeListEps = [{ nextEpisodeDate: nextEpisodeDate }]; const animeListEps = [{ nextEpisodeDate: nextEpisodeDate }];
Array.from({ length: amimeTempList[1].length }, (v, k) => {
let data = amimeTempList.map(x => x[k]); for (let i = 0; i < amimeTempList[1].length; i++) {
let data = amimeTempList.map(x => x[i]);
let episode = data[0]; let episode = data[0];
let id = data[1]; let id = data[1];
let link = `${id}/${animeId}-${episode}` let link = `${id}/${animeId}-${episode}`
@ -177,16 +243,16 @@ const animeflvInfo = async (id) => {
animeListEps.push({ animeListEps.push({
episode: episode, episode: episode,
id: link, id: link,
}) });
}) }
return animeListEps
return animeListEps;
}; };
const getAnimeCharacters = async(title) =>{ const getAnimeCharacters = async(title) =>{
const matchAnime = await getMALid(title) const matchAnime = await getMALid(title);
try { try {
if(matchAnime !== null) { if(matchAnime !== null) {
@ -199,18 +265,20 @@ const getAnimeCharacters = async(title) =>{
})); }));
} }
} catch (err) { } catch (err) {
console.log(err) console.log(err);
} }
}; };
const getAnimeVideoPromo = async(title) =>{ const getAnimeVideoPromo = async(title) =>{
const matchAnime = await getMALid(title) const matchAnime = await getMALid(title);
try { try {
if(matchAnime !== null) { if(matchAnime !== null) {
const data = await homgot(`${BASE_JIKAN}anime/${matchAnime.mal_id}/videos`, {parse: true})
const data = await homgot(`${BASE_JIKAN}anime/${matchAnime.mal_id}/videos`, {parse: true});
return data.promo.map(doc => ({ return data.promo.map(doc => ({
title: doc.title, title: doc.title,
previewImage: doc.image_url, previewImage: doc.image_url,
@ -218,22 +286,22 @@ const getAnimeVideoPromo = async(title) =>{
})); }));
} }
} catch (err) { } catch (err) {
console.log(err) console.log(err);
} }
}; };
const animeExtraInfo = async (title) => { const animeExtraInfo = async (title) => {
const matchAnime = await getMALid(title) const matchAnime = await getMALid(title);
try { try {
if(matchAnime !== null) { if(matchAnime !== null) {
const data = await homgot(`${BASE_JIKAN}anime/${matchAnime.mal_id}`, {parse: true}) const data = await homgot(`${BASE_JIKAN}anime/${matchAnime.mal_id}`, {parse: true});
const promises = []; const promises = [];
let broadcast = '' let broadcast = '';
Array(data).map(doc => { Array(data).map(doc => {
@ -260,7 +328,7 @@ const animeExtraInfo = async (title) => {
} else { } else {
broadcast = airDay[doc.broadcast.split('at')[0].replace(" ", "").toLowerCase()] broadcast = airDay[doc.broadcast.split('at')[0].replace(" ", "").toLowerCase()]
} }
promises.push({ promises.push({
titleJapanese: doc.title_japanese, titleJapanese: doc.title_japanese,
source: doc.source, source: doc.source,
@ -283,34 +351,30 @@ const animeExtraInfo = async (title) => {
} }
} catch (err) { } catch (err) {
console.log(err) console.log(err);
} }
}; };
const getMALid = async(title) =>{ const getMALid = async (title) =>{
if (title === undefined || title === null) { if (title === undefined || title === null) {
return 1;
return 1
} else { } else {
const res = await homgot(`${BASE_JIKAN}search/anime?q=${title}`,{ parse: true }) const res = await homgot(`${BASE_JIKAN}search/anime?q=${title}`,{ parse: true });
const matchAnime = res.results.find(x => x.title === title);
if(typeof matchAnime === 'undefined') {
return null;
} else {
return matchAnime;
}
const matchAnime = res.results.find(x => x.title === title);
if(typeof matchAnime === 'undefined') {
return null;
} else {
return matchAnime;
}
} }
}; };
const imageUrlToBase64 = async (url) => { const imageUrlToBase64 = async (url) => {
let img = await homgot(url) let img = await homgot(url)
return img.rawBody.toString('base64'); return img.rawBody.toString('base64');
@ -319,7 +383,7 @@ const imageUrlToBase64 = async (url) => {
const searchAnime = async (query) => { const searchAnime = async (query) => {
let data = JSON.parse(JSON.stringify(require('../assets/directory.json'))); let data = JSON.parse(JSON.stringify(require('../assets/directory.json')));
let queryLowerCase = query.toLowerCase() let queryLowerCase = query.toLowerCase();
const res = data.filter(x => x.title.toLowerCase().includes(queryLowerCase)); const res = data.filter(x => x.title.toLowerCase().includes(queryLowerCase));
return res.map(doc => ({ return res.map(doc => ({
@ -336,8 +400,8 @@ const transformUrlServer = async (urlReal) => {
for (const data of urlReal) { for (const data of urlReal) {
if (data.server === 'amus' || data.server === 'natsuki') { if (data.server === 'amus' || data.server === 'natsuki') {
let res = await homgot(data.code.replace("embed", "check"), { parse: true }); let res = await homgot(data.code.replace("embed", "check"), { parse: true });
data.code = res.file || null data.code = res.file || null;
data.direct = true data.direct = true;
} }
} }
@ -384,44 +448,63 @@ const obtainPreviewNews = (encoded) => {
return image; return image;
} }
const structureThemes = async (body, indv) => {
const promises = []
/* - StructureThemes
This function only parses the theme/themes
if indv is true, then only return a object, if it's false
then returns a array with the themes selected.
*/
const structureThemes = async (body, indv) => {
if (indv === true) { if (indv === true) {
promises.push({
return {
title: body.title, title: body.title,
year: body.year, year: body.year,
themes: await getThemesData(body.themes), themes: await getThemesData(body.themes)
}); };
} else { } else {
for (let i = 0; i <= body.length - 1; i++) { for (let i = 0; i <= body.length - 1; i++) {
promises.push({
const themes = [];
themes.push({
title: body[i].title, title: body[i].title,
year: body[i].year, year: body[i].year,
themes: await getThemesData(body[i].themes), themes: await getThemesData(body[i].themes),
}); });
} }
return themes;
} }
return promises;
}; };
/* - GetThemesData
Get the themes from the object and
format to a new array of items where
these items are formatted better.
*/
const getThemesData = async (themes) => { const getThemesData = async (themes) => {
let promises = [] let items = [];
for (let i = 0; i <= themes.length - 1; i++) { for (let i = 0; i <= themes.length - 1; i++) {
promises.push({ items.push({
title: themes[i].name.split('"')[1] || 'Remasterización', title: themes[i].name.split('"')[1] || 'Remasterización',
type: themes[i].name.split('"')[0] || 'OP/ED', type: themes[i].type,
episodes: themes[i].episodes || null, episodes: themes[i].episodes !== "" ? themes[i].episodes : null,
notes: themes[i].notes !== "" ? themes[i].notes : null,
video: themes[i].link video: themes[i].link
}); });
} }
return promises.filter(x => x.title !== 'Remasterización'); return items.filter(x => x.title !== 'Remasterización');
}; };
@ -441,13 +524,14 @@ module.exports = {
animeflvInfo, animeflvInfo,
getAnimeCharacters, getAnimeCharacters,
getAnimeVideoPromo, getAnimeVideoPromo,
getRelatedAnimes,
animeExtraInfo, animeExtraInfo,
getMALid,
imageUrlToBase64, imageUrlToBase64,
searchAnime, searchAnime,
transformUrlServer, transformUrlServer,
obtainPreviewNews, obtainPreviewNews,
structureThemes, structureThemes,
getThemes, getThemes,
getMALid,
videoServersJK videoServersJK
} }

Loading…
Cancel
Save