Added MoreInfo

pull/1/head
Jéluchu 5 years ago
parent 9ec11e5165
commit 14b42ec6a0

86
package-lock.json generated

@ -4,6 +4,14 @@
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@babel/runtime": {
"version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.1.tgz",
"integrity": "sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"@types/debug": { "@types/debug": {
"version": "0.0.31", "version": "0.0.31",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.31.tgz", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.31.tgz",
@ -34,6 +42,16 @@
"uri-js": "^4.2.2" "uri-js": "^4.2.2"
} }
}, },
"animeflv-scrapper": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/animeflv-scrapper/-/animeflv-scrapper-0.2.12.tgz",
"integrity": "sha512-EvASm0nj9tCtopOZ6L9JF5jX0c0Nmv1ROYEg4/wKcGlX2rINvtXNoW6jqM7SGWG4POrh4RI1AjkpbiaP/cMibA==",
"requires": {
"@babel/runtime": "^7.8.7",
"cloudscraper": "^4.6.0",
"node-html-parser": "^1.2.12"
}
},
"array-flatten": { "array-flatten": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
@ -75,21 +93,6 @@
"follow-redirects": "1.5.10" "follow-redirects": "1.5.10"
} }
}, },
"basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"requires": {
"safe-buffer": "5.1.2"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
},
"bcrypt-pbkdf": { "bcrypt-pbkdf": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@ -582,6 +585,11 @@
"har-schema": "^2.0.0" "har-schema": "^2.0.0"
} }
}, },
"he": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
},
"helmet": { "helmet": {
"version": "3.22.0", "version": "3.22.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-3.22.0.tgz", "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.22.0.tgz",
@ -843,33 +851,6 @@
"mime-db": "1.43.0" "mime-db": "1.43.0"
} }
}, },
"morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
"integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
"requires": {
"basic-auth": "~2.0.1",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-finished": "~2.3.0",
"on-headers": "~1.0.2"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
}
}
},
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@ -899,10 +880,13 @@
"nan": "^2.13.2" "nan": "^2.13.2"
} }
}, },
"node-fetch": { "node-html-parser": {
"version": "2.6.0", "version": "1.2.18",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.2.18.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" "integrity": "sha512-DypklUSTuY9JDfYWz/NZYZA8mvgKmjRmHZe7at0H6O4KoXcs8QSpnH5mFk888gLsqXXRMVNmJGk/FdqaO9T1UQ==",
"requires": {
"he": "1.1.1"
}
}, },
"npm": { "npm": {
"version": "6.14.5", "version": "6.14.5",
@ -4036,11 +4020,6 @@
"ee-first": "1.1.1" "ee-first": "1.1.1"
} }
}, },
"on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
},
"parse5": { "parse5": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
@ -4119,6 +4098,11 @@
"resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
"integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA=="
}, },
"regenerator-runtime": {
"version": "0.13.5",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
"integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
},
"request": { "request": {
"version": "2.88.2", "version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",

@ -41,6 +41,7 @@
"url": "https://github.com/aruppi/aruppi-api.git" "url": "https://github.com/aruppi/aruppi-api.git"
}, },
"dependencies": { "dependencies": {
"animeflv-scrapper": "^0.2.12",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"cheerio": "^1.0.0-rc.3", "cheerio": "^1.0.0-rc.3",
"cheerio-tableparser": "^1.0.1", "cheerio-tableparser": "^1.0.1",
@ -50,8 +51,6 @@
"express": "^4.16.4", "express": "^4.16.4",
"helmet": "^3.22.0", "helmet": "^3.22.0",
"image-to-base64": "^2.1.0", "image-to-base64": "^2.1.0",
"morgan": "^1.10.0",
"node-fetch": "^2.6.0",
"npm": "^6.14.5", "npm": "^6.14.5",
"request": "^2.88.0", "request": "^2.88.0",
"rss-to-json": "^1.1.1" "rss-to-json": "^1.1.1"

@ -1,5 +1,15 @@
const rss = require('rss-to-json'); const rss = require('rss-to-json');
const cloudscraper = require('cloudscraper'); const cloudscraper = require('cloudscraper');
const animeflv = require("animeflv-scrapper");
const {
animeflvInfo,
imageUrlToBase64,
getAnimeCharacters,
getAnimeVideoPromo,
animeExtraInfo
} = require('../utils/index');
const { const {
BASE_ANIMEFLV, BASE_ANIMEFLV_JELU, BASE_JIKAN, BASE_IVOOX, BASE_KUDASAI, BASE_PALOMITRON BASE_ANIMEFLV, BASE_ANIMEFLV_JELU, BASE_JIKAN, BASE_IVOOX, BASE_KUDASAI, BASE_PALOMITRON
} = require('./urls'); } = require('./urls');
@ -233,7 +243,6 @@ const getOvas = async (type, page) =>{
}; };
const getSpecials = async (type, page) =>{ const getSpecials = async (type, page) =>{
const data = await cloudscraper.get(`${BASE_ANIMEFLV_JELU}Special/${type}/${page}`); const data = await cloudscraper.get(`${BASE_ANIMEFLV_JELU}Special/${type}/${page}`);
@ -284,6 +293,50 @@ const getTv = async (type, page) =>{
}; };
const getMoreInfo = async (title) =>{
const promises = []
let animeTitle =""
let animeId = ""
await animeflv.searchAnime(title).then(data => {
data.forEach(function (anime) {
if (anime.label === title) {
animeTitle = anime.label
animeId = anime.animeId
}
}
)
});
try{
promises.push(await animeflvInfo(animeId).then(async extra => ({
title: animeTitle || null,
poster: await imageUrlToBase64(extra.animeExtraInfo[0].poster) || null,
synopsis: extra.animeExtraInfo[0].synopsis || null,
status: extra.animeExtraInfo[0].debut || null,
type: extra.animeExtraInfo[0].type || null,
rating: extra.animeExtraInfo[0].rating || null,
genres: extra.genres || null,
episodes: extra.listByEps || null,
moreInfo: await animeExtraInfo(title).then(info =>{
return info || null
}),
promo: await getAnimeVideoPromo(title).then(promo =>{
return promo || null
}),
characters: await getAnimeCharacters(animeTitle).then(characters =>{
return characters || null
})
})));
}catch(err){
console.log(err)
}
return Promise.all(promises);
};
module.exports = { module.exports = {
schedule, schedule,
top, top,
@ -295,5 +348,6 @@ module.exports = {
getMovies, getMovies,
getOvas, getOvas,
getSpecials, getSpecials,
getTv getTv,
getMoreInfo
}; };

@ -18,10 +18,11 @@ router.get('/', (req, res) => {
'News': '/api/v2/news', 'News': '/api/v2/news',
'Season': '/api/v2/season/:year/:type', 'Season': '/api/v2/season/:year/:type',
'LastEpisodes': '/api/v2/lastEpisodes', 'LastEpisodes': '/api/v2/lastEpisodes',
'Movies': '/api/v2/movies', 'Movies': '/api/v2/movies/:type/:page',
'Ovas': '/api/v2/ovas', 'Ovas': '/api/v2/ovas/:type/:page',
'Specials': '/api/v2/specials', 'Specials': '/api/v2/specials/:type/:page',
'Tv': '/api/v2/tv' 'Tv': '/api/v2/tv/:type/:page',
'MoreInfo': '/api/v2/moreInfo/:title'
} }
] ]
}); });

@ -166,4 +166,19 @@ router.get('/tv/:type/:page' , (req, res) =>{
}); });
router.get('/moreInfo/:title' , (req, res) =>{
let title = req.params.title;
api.getMoreInfo(title)
.then(info =>{
res.status(200).json({
info
});
}).catch((err) =>{
console.error(err);
});
});
module.exports = router; module.exports = router;

@ -1,14 +1,10 @@
module.exports = { module.exports = {
BASE_ANIMEFLV: 'https://animeflv.net/', BASE_ANIMEFLV: 'https://animeflv.net/',
BASE_ANIMEFLV_JELU: 'https://dev.aruppi.jeluchu.xyz/apis/animeflv/v1/', BASE_ANIMEFLV_JELU: 'https://aruppi.jeluchu.xyz/apis/animeflv/v1/',
BASE_JIKAN: 'https://dev.aruppi.jeluchu.xyz/apis/jikan/v3/', BASE_JIKAN: 'https://aruppi.jeluchu.xyz/apis/jikan/v3/',
BASE_IVOOX: 'https://www.ivoox.com/podcast-anitakume_fg_f1660716_filtro_1.xml', BASE_IVOOX: 'https://www.ivoox.com/podcast-anitakume_fg_f1660716_filtro_1.xml',
BASE_KUDASAI: 'https://somoskudasai.com/feed/', BASE_KUDASAI: 'https://somoskudasai.com/feed/',
BASE_PALOMITRON: 'https://elpalomitron.com/category/animemanga/feed/', BASE_PALOMITRON: 'https://elpalomitron.com/category/animemanga/feed/',
BROWSE_URL: 'https://animeflv.net/browse?',
SEARCH_URL: 'https://animeflv.net/browse?q=', SEARCH_URL: 'https://animeflv.net/browse?q=',
ANIME_VIDEO_URL: 'https://animeflv.net/ver/', BASE_EPISODE_IMG_URL: 'https://cdn.animeflv.net/screenshots/'
BASE_EPISODE_IMG_URL: 'https://cdn.animeflv.net/screenshots/',
BASE_JIKA_URL: 'http://devel.jeluchu.xyz/apis/jikan/v3/search/anime?q=',
BASE_MYANIME_LIST_URL : 'https://myanimelist.net/character/'
}; };

@ -1,5 +1,4 @@
const express = require('express'); const express = require('express');
const morgan = require('morgan');
const helmet = require('helmet'); const helmet = require('helmet');
const cors = require('cors'); const cors = require('cors');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
@ -9,7 +8,6 @@ const api = require('./api');
const app = express(); const app = express();
app.use(morgan('dev'));
app.use(helmet()); app.use(helmet());
app.use(cors()); app.use(cors());
app.use(bodyParser.json()); app.use(bodyParser.json());

@ -1,5 +1,250 @@
const cloudscraper = require('cloudscraper') const cloudscraper = require('cloudscraper')
const imageToBase64 = require("image-to-base64"); const imageToBase64 = require("image-to-base64");
const cheerio = require('cheerio');
const {
BASE_ANIMEFLV, BASE_JIKAN, BASE_EPISODE_IMG_URL
} = require('../api/urls');
const animeflvInfo = async(id) =>{
try{
const res = await cloudscraper(`${BASE_ANIMEFLV}anime/${id}`);
const body = await res;
const $ = cheerio.load(body);
const scripts = $('script');
const anime_info_ids = [];
const anime_eps_data = [];
const animeExtraInfo = [];
const genres = [];
let listByEps;
let animeTitle = $('body div.Wrapper div.Body div div.Ficha.fchlt div.Container h2.Title').text();
let poster = `${BASE_ANIMEFLV}` + $('body div div div div div aside div.AnimeCover div.Image figure img').attr('src')
const banner = poster.replace('covers' , 'banners').trim();
let synopsis = $('body div div div div div main section div.Description p').text().trim();
let rating = $('body div div div.Ficha.fchlt div.Container div.vtshr div.Votes span#votes_prmd').text();
const debut = $('body div.Wrapper div.Body div div.Container div.BX.Row.BFluid.Sp20 aside.SidebarA.BFixed p.AnmStts').text();
const type = $('body div.Wrapper div.Body div div.Ficha.fchlt div.Container span.Type').text()
animeExtraInfo.push({
title: animeTitle,
poster: poster,
banner: banner,
synopsis: synopsis,
rating: rating,
debut: debut,
type: type,
})
$('main.Main section.WdgtCn nav.Nvgnrs a').each((index , element) =>{
const $element = $(element);
const genre = $element.attr('href').split('=')[1] || null;
genres.push(genre);
});
Array.from({length: scripts.length} , (v , k) =>{
const $script = $(scripts[k]);
const contents = $script.html();
if((contents || '').includes('var anime_info = [')) {
let anime_info = contents.split('var anime_info = ')[1].split(';')[0];
let dat_anime_info = JSON.parse(JSON.stringify(anime_info));//JSON.parse(anime_info);
anime_info_ids.push(dat_anime_info);
}
if((contents || '').includes('var episodes = [')) {
let episodes = contents.split('var episodes = ')[1].split(';')[0];
let eps_data = JSON.parse(episodes)
anime_eps_data.push(eps_data);
}
});
const AnimeThumbnailsId = anime_info_ids[0].split(',')[0].split('"')[1];
const animeId = id;
let nextEpisodeDate = anime_info_ids[0][3] || null
const amimeTempList = [];
for(const [key , value] of Object.entries(anime_eps_data)){
let episode = anime_eps_data[key].map(x => x[0]);
let episodeId = anime_eps_data[key].map(x => x[1]);
amimeTempList.push(episode , episodeId);
}
const animeListEps = [{nextEpisodeDate: nextEpisodeDate}];
Array.from({length: amimeTempList[1].length} , (v , k) =>{
let data = amimeTempList.map(x => x[k]);
let episode = data[0];
let id = data[1];
let imagePreview = `${BASE_EPISODE_IMG_URL}${AnimeThumbnailsId}/${episode}/th_3.jpg`
let link = `${id}/${animeId}-${episode}`
// @ts-ignore
animeListEps.push({
episode: episode,
id: link,
imagePreview: imagePreview
})
})
listByEps = animeListEps;
return {listByEps , genres , animeExtraInfo};
}catch(err){
console.error(err)
}
};
const getAnimeCharacters = async(title) =>{
const res = await cloudscraper(`${BASE_JIKAN}search/anime?q=${title}`);
const matchAnime = JSON.parse(res).results.filter(x => x.title === title);
const malId = matchAnime[0].mal_id;
if(typeof matchAnime[0].mal_id === 'undefined') return null;
const jikanCharactersURL = `${BASE_JIKAN}anime/${malId}/characters_staff`;
const data = await cloudscraper.get(jikanCharactersURL);
let body = JSON.parse(data).characters;
if(typeof body === 'undefined') return null;
const charactersId = body.map(doc =>{
return doc.mal_id
})
const charactersNames = body.map(doc => {
return doc.name;
});
const charactersImages = body.map(doc =>{
return doc.image_url
});
let characters = [];
Array.from({length: charactersNames.length} , (v , k) =>{
const id = charactersId[k];
let name = charactersNames[k];
let characterImg = charactersImages[k];
characters.push({
character:{
id: id,
name: name,
image: characterImg
}
});
});
return Promise.all(characters);
};
const getAnimeVideoPromo = async(title) =>{
const res = await cloudscraper(`${BASE_JIKAN}search/anime?q=${title}`);
const matchAnime = JSON.parse(res).results.filter(x => x.title === title);
const malId = matchAnime[0].mal_id;
if(typeof matchAnime[0].mal_id === 'undefined') return null;
const jikanCharactersURL = `${BASE_JIKAN}anime/${malId}/videos`;
const data = await cloudscraper.get(jikanCharactersURL);
const body = JSON.parse(data).promo;
const promises = [];
body.map(doc =>{
promises.push({
title: doc.title,
previewImage: doc.image_url,
videoURL: doc.video_url
});
});
return Promise.all(promises);
};
const animeExtraInfo = async(title) =>{
const res = await cloudscraper(`${BASE_JIKAN}search/anime?q=${title}`);
const matchAnime = JSON.parse(res).results.filter(x => x.title === title);
const malId = matchAnime[0].mal_id;
if(typeof matchAnime[0].mal_id === 'undefined') return null;
const animeDetails = `${BASE_JIKAN}anime/${malId}`;
const data = await cloudscraper.get(animeDetails);
const body = Array(JSON.parse(data));
const promises = [];
body.map(doc =>{
let airDay
switch (doc.broadcast.split('at')[0].replace(" ", "").toLowerCase()) {
case "mondays":
airDay = "Lunes";
break;
case "monday":
airDay = "Lunes";
break;
case "tuesdays":
airDay = "Martes";
break;
case "tuesday":
airDay = "Martes";
break;
case "wednesdays":
airDay = "Miércoles";
break;
case "wednesday":
airDay = "Miércoles";
break;
case "thursdays":
airDay = "Jueves";
break;
case "thursday":
airDay = "Jueves";
break;
case "fridays":
airDay = "Viernes";
break;
case "friday":
airDay = "Viernes";
break;
case "saturdays":
airDay = "Sábados";
break;
case "saturday":
airDay = "Sábados";
break;
case "sundays":
airDay = "Domingos";
break;
case "sunday":
airDay = "Domingos";
break;
default:
airDay = "Sin emisión";
}
promises.push({
titleJapanese: doc.title_japanese,
source: doc.source,
totalEpisodes: doc.episodes,
aired:{
from: doc.aired.from,
to: doc.aired.to
},
duration: doc.duration.split('per')[0].replace(" ", ""),
rank: doc.rank,
broadcast: airDay,
producers: doc.producers.map(x => x.name) || null,
licensors: doc.licensors.map(x => x.name) || null,
studios: doc.studios.map(x => x.name) || null,
openingThemes: doc.opening_themes || null,
endingThemes: doc.ending_themes || null
});
});
return Promise.all(promises);
};
const imageUrlToBase64 = async(url) => {
let base64image = ""
await imageToBase64(url).then((response) => {base64image = response})
return base64image.toString("base64");
};
const MergeRecursive = (obj1 , obj2) => { const MergeRecursive = (obj1 , obj2) => {
for(var p in obj2) { for(var p in obj2) {
@ -18,16 +263,6 @@ const MergeRecursive = (obj1 , obj2) => {
return obj1; return obj1;
} }
const imageUrlToBase64 = async(url) => {
let res = await cloudscraper({
url,
method: "GET",
encoding: null
});
return Buffer.from(res).toString("base64");
};
const urlify = async(text) =>{ const urlify = async(text) =>{
const urls = []; const urls = [];
const urlRegex = /(https?:\/\/[^\s]+)/g; const urlRegex = /(https?:\/\/[^\s]+)/g;
@ -39,8 +274,11 @@ const urlify = async(text) =>{
module.exports = { module.exports = {
MergeRecursive, animeflvInfo,
millisecondsToDate, getAnimeCharacters,
getAnimeVideoPromo,
animeExtraInfo,
imageUrlToBase64, imageUrlToBase64,
MergeRecursive,
urlify urlify
} }
Loading…
Cancel
Save