Merge pull request #28 from aruppi/master

Merge changes into develop
pull/29/head
Guillermo Rivas 4 years ago committed by GitHub
commit c4e8f84cf2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,10 @@
github: jeluchu
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: jeluchu
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ["https://www.paypal.me/jeluchu"]

@ -1,4 +1,4 @@
# **Aruppi API** (v3.4.2) # **Aruppi API** (v3.4.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
> >

@ -1,6 +1,6 @@
{ {
"name": "aruppi", "name": "aruppi",
"version": "3.4.2", "version": "3.4.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": {

@ -3,7 +3,7 @@ module.exports = {
BASE_ANIMEFLV: 'https://animeflv.net/', BASE_ANIMEFLV: 'https://animeflv.net/',
BASE_JKANIME: 'https://jkanime.net/', BASE_JKANIME: 'https://jkanime.net/',
BASE_ANIMEFLV_JELU: 'https://aruppi.jeluchu.xyz/apis/animeflv/v1/', BASE_ANIMEFLV_JELU: 'https://aruppi.jeluchu.xyz/apis/animeflv/v1/',
BASE_YOUTUBE: 'https://aruppi.jeluchu.xyz/apis/youtube/v3/search?channelId=', BASE_YOUTUBE: 'https://aruppi.jeluchu.xyz/api/Youtube/?channelId=',
BASE_JIKAN: 'https://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/',

@ -7,8 +7,6 @@ const version = require('./../package.json').version;
const middlewares = require('./middlewares/index').middleware; const middlewares = require('./middlewares/index').middleware;
const api = require('./api'); const api = require('./api');
const api_legacy = require('./v2/api');
const app = express(); const app = express();
app.use(helmet()); app.use(helmet());
@ -41,7 +39,17 @@ app.get('/api/v1', (req, res) => {
}); });
}); });
app.use('/api/v2', api_legacy); app.get('/api/v2/*', (req, res) => {
res.redirect('/api/v2')
});
app.get('/api/v2', (req, res) => {
res.json({
message: 'Sorry, version v2 is not avaiable, if you want to see content go to v3'
});
});
app.use('/api/v3', api); app.use('/api/v3', api);
app.use(middlewares); app.use(middlewares);

@ -46546,7 +46546,7 @@
] ]
}, },
{ {
"id": "animedb.pl?show=anime&aid=8624", "id": "8624",
"title": "Gensou Mangekyou: The Memories of Phantasm", "title": "Gensou Mangekyou: The Memories of Phantasm",
"year": "2011", "year": "2011",
"themes": [ "themes": [

@ -56,13 +56,13 @@ async function videoServersJK(id) {
serverList.push({ serverList.push({
id: serverNames[serverNames.indexOf(server)].toLowerCase(), id: serverNames[serverNames.indexOf(server)].toLowerCase(),
url: await desuServerUrl(servers[server]) !== null ? await desuServerUrl(servers[server]) : servers[server], url: await desuServerUrl(servers[server]) !== null ? await desuServerUrl(servers[server]) : servers[server],
direct: true direct: false
}); });
}else { }else {
serverList.push({ serverList.push({
id: serverNames[serverNames.indexOf(server)].toLowerCase(), id: serverNames[serverNames.indexOf(server)].toLowerCase(),
url: servers[server], url: servers[server],
direct: true direct: false
}); });
} }

@ -1,469 +0,0 @@
const rss = require('rss-to-json');
const {
homgot
} = require('./apiCall');
const {
jkanimeInfo,
animeflvGenres,
animeflvInfo,
imageUrlToBase64,
getAnimeCharacters,
getAnimeVideoPromo,
animeExtraInfo,
searchAnime,
transformUrlServer,
obtainPreviewNews,
structureThemes,
videoServersJK,
getAnimes,
getDirectory,
getThemes,
directoryAnimes,
radioStations,
animeGenres,
animeThemes
} = require('../utils');
const ThemeParser = require('../utils/animetheme');
const parserThemes = new ThemeParser();
const {
BASE_ANIMEFLV_JELU, BASE_JIKAN, BASE_IVOOX, BASE_QWANT, BASE_YOUTUBE, GENRES_URL, BASE_THEMEMOE
} = require('./urls');
const schedule = async (day) =>{
let options = { parse: true }
const data = await homgot(`${BASE_JIKAN}schedule/${day.current}`, options);
const body = data[day.current];
const promises = []
body.map(doc =>{
promises.push({
title: doc.title,
malid: doc.mal_id,
image: doc.image_url
});
});
return promises;
};
const top = async (type, subtype, page) =>{
let options = { parse: true }
const data = await homgot(`${BASE_JIKAN}top/${type}/${page}/${subtype}`, options);
return data.top;
};
const getAllAnimes = async () =>{
let data = await getAnimes();
return data.map(item => ({
index: item[0],
animeId: item[3],
title: item[1],
id: item[2],
type: item[4]
}));
};
const getAllDirectory = async (genres) =>{ return await getDirectory(genres); };
const getAnitakume = async () =>{
const promises = [];
await rss.load(BASE_IVOOX).then(rss => {
const body = JSON.parse(JSON.stringify(rss, null, 3)).items
body.map(doc =>{
let time = new Date(doc.created)
const monthNames = ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"];
let day = time.getDate()
let month = monthNames[time.getMonth()]
let year = time.getFullYear()
let date
if(month < 10){
date = `${day} de 0${month} de ${year}`
}else{
date = `${day} de ${month} de ${year}`
}
promises.push({
title: doc.title,
duration: doc.itunes_duration,
created: date,
mp3: doc.enclosures.map(x => x.url)
});
});
});
return promises;
};
const getNews = async (pageRss) =>{
const promises = [];
for(let i = 0; i <= pageRss.length -1; i++) {
await rss.load(pageRss[i].url).then(rss => {
const body = JSON.parse(JSON.stringify(rss, null, 3)).items;
body.map(doc => {
promises.push({
title: doc.title,
url: doc.link,
author: pageRss[i].author,
thumbnail: obtainPreviewNews(doc[pageRss[i].content]),
content: doc[pageRss[i].content]
});
});
});
}
return promises;
};
const season = async (year, type) =>{
let options = { parse: true }
const data = await homgot(`${BASE_JIKAN}season/${year}/${type}`, options);
let body = data.anime;
const promises = []
body.map(doc =>{
promises.push({
title: doc.title,
malid: doc.mal_id,
image: doc.image_url,
genres: doc.genres.map(x => x.name)
});
});
return promises;
};
const allSeasons = async () =>{
let options = { parse: true }
const data = await homgot(`${BASE_JIKAN}season/archive`, options);
let body = data.archive;
const promises = []
body.map(doc =>{
promises.push({
year: doc.year,
seasons: doc.seasons,
});
});
return promises;
};
const laterSeasons = async () =>{
let options = { parse: true }
const data = await homgot(`${BASE_JIKAN}season/later`, options);
let body = data.anime;
const promises = []
body.map(doc =>{
promises.push({
malid: doc.mal_id,
title: doc.title,
image: doc.image_url
});
});
return promises;
};
const getLastEpisodes = async () =>{
const data = await homgot(`${BASE_ANIMEFLV_JELU}LatestEpisodesAdded`, { parse: true });
return await Promise.all(data.episodes.map(async (item) => ({
id: item.id,
title: item.title,
image: item.poster,
episode: item.episode,
servers: await transformUrlServer(JSON.parse(JSON.stringify(item.servers)))
})));
};
const getSpecials = async (type, subType, page) =>{
let options = { parse: true }
const data = await homgot(`${BASE_ANIMEFLV_JELU}${type.url}/${subType}/${page}`, options);
let body = data[type.prop];
const promises = []
body.map(doc =>{
promises.push({
id: doc.id,
title: doc.title,
type: doc.type,
banner: doc.banner,
image: doc.poster,
synopsis: doc.synopsis,
status: doc.debut,
rate: doc.rating,
genres: doc.genres.map(x => x),
episodes: doc.episodes.map(x => x)
});
});
return promises;
};
const getMoreInfo = async (title) =>{
try {
const promises = [];
const res = directoryAnimes.filter(x => {
if (x.title === title) {
return x;
} else {
return x.title === `${title} (TV)` ? x : undefined;
}
})[0];
if (!res.jkanime) {
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 animeflvInfo(res.id).then(episodes => episodes || null),
moreInfo: await animeExtraInfo(res.mal_id).then(info => info || null),
promo: await getAnimeVideoPromo(res.mal_id).then(promo => promo || null),
characters: await getAnimeCharacters(res.mal_id).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_id).then(info => info || null),
promo: await getAnimeVideoPromo(res.mal_id).then(promo => promo || null),
characters: await getAnimeCharacters(res.mal_id).then(characters => characters || null)
});
}
return promises;
} catch (e) {
console.log(e)
}
};
const getAnimeServers = async (id) => {
if (isNaN(id.split('/')[0])) {
return await videoServersJK(id)
} else {
const data = await homgot(`${BASE_ANIMEFLV_JELU}GetAnimeServers/${id}`, { parse: true });
return await transformUrlServer(data.servers);
}
};
const search = async (title) =>{ return await searchAnime(title); };
const getImages = async (query) => {
let options = { parse: true }
const data = await homgot(`${BASE_QWANT}count=${query.count}&q=${query.title}&t=${query.type}&safesearch=${query.safesearch}&locale=${query.country}&uiv=4`, options);
const body = data.data.result.items;
const promises = [];
body.map(doc =>{
promises.push({
type: doc.thumb_type,
thumbnail: `https:${doc.thumbnail}`,
fullsize: `https:${doc.media_fullsize}`
});
});
return promises;
};
const getYoutubeVideos = async (channelId) => {
let options = { parse: true }
const data = await homgot(`${BASE_YOUTUBE}${channelId.id}&part=${channelId.part}&order=${channelId.order}&maxResults=${channelId.maxResults}`, options);
const body = data[channelId.prop];
const promises = [];
body.map(doc =>{
promises.push({
title: doc.snippet.title,
videoId: doc.id.videoId,
thumbDefault: doc.snippet.thumbnails.default.url,
thumbMedium: doc.snippet.thumbnails.medium.url,
thumbHigh: doc.snippet.thumbnails.high.url
});
});
return promises;
};
const getRadioStations = async () => {
return radioStations;
}
const getOpAndEd = async (title) => {
let data = await parserThemes.serie(title);
return await structureThemes(data, true);
};
const getThemesYear = async (year) => {
let data = [];
if (year === undefined) {
return await parserThemes.allYears();
} else {
data = await parserThemes.year(year)
return await structureThemes(data, false)
}
};
const getRandomTheme = async () => {
let promise = [];
let options = { parse: true }
const data = await homgot(`${BASE_THEMEMOE}roulette`, options);
let themes = await getThemes(data.themes)
promise.push({
name: data.name,
title: themes[0].name,
link: themes[0].video
});
return promise;
};
const getArtist = async (id) => {
let data;
if (id === undefined) {
return await parserThemes.artists();
} else {
data = await parserThemes.artist(id)
return await structureThemes(data, false)
}
};
const getAnimeGenres = async(genre, order, page) => {
let $
let promises = []
let options = { scrapy: true }
if (page !== undefined) {
$ = await homgot(`${GENRES_URL}genre%5B%5D=${genre}&order=${order}&page=${page}`,options)
} else {
$ = await homgot(`${GENRES_URL}genre%5B%5D=${genre}&order=${order}`,options)
}
$('div.Container ul.ListAnimes li article').each((index , element) =>{
const $element = $(element);
const id = $element.find('div.Description a.Button').attr('href').slice(1);
const title = $element.find('a h3').text();
const poster = $element.find('a div.Image figure img').attr('src');
const banner = poster.replace('covers' , 'banners').trim();
const type = $element.find('div.Description p span.Type').text();
const synopsis = $element.find('div.Description p').eq(1).text().trim();
const rating = $element.find('div.Description p span.Vts').text();
promises.push(animeflvGenres(id).then(async genres => ({
id: id || null,
title: title || null,
poster: await imageUrlToBase64(poster) || null,
banner: banner || null,
synopsis: synopsis || null,
type: type || null,
rating: rating || null,
genres: genres || null
})))
})
return Promise.all(promises);
};
const getAllThemes = async () => animeThemes;
module.exports = {
schedule,
top,
getAllAnimes,
getAllDirectory,
getAnitakume,
getNews,
season,
allSeasons,
laterSeasons,
getLastEpisodes,
getSpecials,
getMoreInfo,
getAnimeServers,
search,
getImages,
getYoutubeVideos,
getRadioStations,
getOpAndEd,
getThemesYear,
getRandomTheme,
getArtist,
getAnimeGenres,
getAllThemes
};

@ -1,27 +0,0 @@
const got = require('got');
const cheerio = require('cheerio');
const { CookieJar} = require('tough-cookie');
const cookieJar = new CookieJar();
let response
let data
const homgot = async (url, options) => {
if (options !== undefined) {
if (options.scrapy) {
response = await got(url, { cookieJar })
data = await cheerio.load(response.body)
}
if (options.parse) {
data = await got(url, { cookieJar }).json()
}
} else {
data = await got.get(url, { cookieJar });
}
return data
}
module.exports = {homgot}

@ -1,49 +0,0 @@
const express = require('express');
const routes = require('./routes/index');
const router = express.Router();
router.get('/', (req, res) => {
res.set('Cache-Control', 'no-store');
res.json({
message: 'Aruppi API - 🎏',
author: 'Jéluchu',
version: '2.6.9',
credits: 'The bitch loves APIs that offers data to Aruppi App',
deprecated: 'This version will be available until users migrate to Aruppi App v1.5.0',
entries: [
{
'Schedule': '/api/v2/schedule/:day',
'Top': '/api/v2/top/:type/:subtype/:page',
'AllAnimes': '/api/v2/allAnimes',
'Anitakume': '/api/v2/anitakume',
'News': '/api/v2/news',
'Season': '/api/v2/season/:year/:type',
'All Seasons': '/api/v2/allSeasons',
'All Directory': '/api/v2/allDirectory',
'Genres': '/api/v2/getByGenres/:genre/:order/:page?',
'Futures Seasons': '/api/v2/laterSeasons',
'LastEpisodes': '/api/v2/lastEpisodes',
'Movies': '/api/v2/movies/:type/:page',
'Ovas': '/api/v2/ovas/:type/:page',
'Specials': '/api/v2/specials/:type/:page',
'Tv': '/api/v2/tv/:type/:page',
'MoreInfo': '/api/v2/moreInfo/:title',
'GetAnimeServers': '/api/v2/getAnimeServers/:id',
'Search': '/api/v2/search/:title',
'Images': '/api/v2/images/:query',
'Videos': '/api/v2/videos/:channelId',
'Radios': '/api/v2/radio',
'All Themes': '/api/v2/allThemes',
'Themes': '/api/v2/themes/:title',
'Year Themes': '/api/v2/themesYear/:year?',
'Random Theme': '/api/v2/randomTheme',
'Artists Theme': '/api/v2/artists/:id?'
}
]
});
});
router.use('/', routes);
module.exports = router;

@ -1,503 +0,0 @@
const express = require('express');
const router = express.Router();
const api = require('../api');
const { BASE_KUDASAI, BASE_PALOMITRON, BASE_RAMENPARADOS, BASE_CRUNCHYROLL } = require('../urls');
router.get('/schedule/:day' , (req, res) =>{
let day = {current: req.params.day}
api.schedule(day)
.then(day =>{
if (day.length > 0) {
res.status(200).json({
day
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/top/:type/:subtype/:page' , (req, res) =>{
let type = req.params.type;
let subtype = req.params.subtype;
let page = req.params.page;
api.top(type, subtype, page)
.then(top =>{
if (top.length > 0) {
res.status(200).json({
top
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/allAnimes' , (req, res) =>{
api.getAllAnimes()
.then(animes =>{
if (animes.length > 0) {
res.status(200).json({
animes
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/allDirectory/:genres?' , (req, res) =>{
let genres = req.params.genres;
api.getAllDirectory(genres)
.then(directory =>{
if (directory.length > 0) {
res.status(200).json({
directory
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/anitakume' , (req, res) =>{
api.getAnitakume()
.then(podcast =>{
if (podcast.length > 0) {
res.status(200).json({
podcast
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/news' , (req, res) =>{
let pagesRss = [
{ url: BASE_KUDASAI, author: 'Kudasai', content: 'content_encoded' },
{ url: BASE_PALOMITRON, author: 'Palomitron', content: 'description' },
{ url: BASE_RAMENPARADOS, author: 'Ramen para dos', content: 'content' },
{ url: BASE_CRUNCHYROLL, author: 'Crunchyroll', content: 'content_encoded' }
];
api.getNews(pagesRss)
.then(news =>{
if (news.length > 0) {
res.status(200).json({
news
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/season/:year/:type' , (req, res) =>{
let year = req.params.year;
let type = req.params.type;
api.season(year, type)
.then(season =>{
if (season.length > 0) {
res.status(200).json({
season
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/allSeasons' , (req, res) =>{
api.allSeasons()
.then(archive =>{
if (archive.length > 0) {
res.status(200).json({
archive
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/laterSeasons' , (req, res) =>{
api.laterSeasons()
.then(future =>{
if (future.length > 0) {
res.status(200).json({
future
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/lastEpisodes' , (req, res) =>{
api.getLastEpisodes()
.then(episodes =>{
if (episodes.length > 0) {
res.status(200).json({
episodes
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/movies/:type/:page' , (req, res) =>{
let type = {url: 'Movies', prop: 'movies'}
let subType = req.params.type;
let page = req.params.page;
api.getSpecials(type, subType, page)
.then(movies =>{
if (movies.length > 0) {
res.status(200).json({
movies
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/ovas/:type/:page' , (req, res) =>{
let type = {url: 'Ova', prop: 'ova'}
let subType = req.params.type;
let page = req.params.page;
api.getSpecials(type, subType, page)
.then(ovas =>{
if (ovas.length > 0) {
res.status(200).json({
ovas
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/specials/:type/:page' , (req, res) =>{
let type = {url: 'Special', prop: 'special'}
let subType = req.params.type;
let page = req.params.page;
api.getSpecials(type, subType, page)
.then(specials =>{
if (specials.length > 0) {
res.status(200).json({
specials
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/tv/:type/:page' , (req, res) =>{
let type = {url: 'Tv', prop: 'tv'}
let subType = req.params.type;
let page = req.params.page;
api.getSpecials(type, subType, page)
.then(tv =>{
if (tv.length > 0) {
res.status(200).json({
tv
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/moreInfo/:title' , (req, res) =>{
let title = req.params.title;
api.getMoreInfo(title)
.then(info =>{
if (info.length > 0) {
res.status(200).json({
info
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/getAnimeServers/:id([^/]+/[^/]+)' , (req, res) =>{
let id = req.params.id;
api.getAnimeServers(id)
.then(servers =>{
if (servers.length > 0) {
res.status(200).json({
servers
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/search/:title' , (req, res) =>{
let title = req.params.title;
api.search(title)
.then(search =>{
if (search.length > 0) {
res.status(200).json({
search
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/images/:query' , (req, res) =>{
let query = { title: req.params.query, count: '51', type: 'images', safesearch: '1', country: 'es_ES', uiv: '4' };
api.getImages(query)
.then(images =>{
if (images.length > 0) {
res.status(200).json({
images
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/videos/:channelId' , (req, res) =>{
let channelId = { id: req.params.channelId, part: 'snippet,id', order: 'date', maxResults: '50', prop: 'items' };
api.getYoutubeVideos(channelId)
.then(videos =>{
if (videos.length > 0) {
res.status(200).json({
videos
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/radio' , (req, res) =>{
api.getRadioStations()
.then(stations =>{
if (stations.length > 0) {
res.status(200).json({
stations
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/allThemes', (req, res) =>{
api.getAllThemes()
.then(themes =>{
if (themes.length > 0) {
res.status(200).json({
themes
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/themes/:title' , (req, res) =>{
let title = req.params.title;
api.getOpAndEd(title)
.then(themes =>{
if (themes.length > 0) {
res.status(200).json({
themes
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/themesYear/:year?', (req, res) =>{
let year = req.params.year;
let season = req.params.season
api.getThemesYear(year, season)
.then(themes =>{
if (themes.length > 0) {
res.status(200).json({
themes
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/randomTheme', (req, res) =>{
api.getRandomTheme()
.then(random =>{
if (random.length > 0) {
res.set('Cache-Control', 'no-store');
res.status(200).json({
random
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/artists/:id?', (req, res) =>{
let id = req.params.id;
api.getArtist(id)
.then(artists =>{
if (artists.length > 0) {
res.status(200).json({
artists
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
router.get('/getByGenres/:genre/:order/:page?' , (req , res) =>{
let genre = req.params.genre;
let order = req.params.order;
let page = req.params.page;
api.getAnimeGenres(genre, order , page)
.then(animes =>{
if (animes.length > 0) {
res.status(200).json({
animes
});
} else (
res.status(500).json({ message: 'Aruppi lost in the shell'})
)
}).catch((err) =>{
console.error(err);
});
});
module.exports = router;

@ -1,20 +0,0 @@
module.exports = {
BASE_ARUPPI: 'https://aruppi.jeluchu.xyz/',
BASE_ANIMEFLV: 'https://animeflv.net/',
BASE_JKANIME: 'https://jkanime.net/',
BASE_ANIMEFLV_JELU: 'https://aruppi.jeluchu.xyz/apis/animeflv/v1/',
BASE_YOUTUBE: 'https://aruppi.jeluchu.xyz/apis/youtube/v3/search?channelId=',
BASE_JIKAN: 'https://aruppi.jeluchu.xyz/apis/jikan/v3/',
BASE_IVOOX: 'https://www.ivoox.com/podcast-anitakume_fg_f1660716_filtro_1.xml',
BASE_KUDASAI: 'https://somoskudasai.com/feed/',
BASE_PALOMITRON: 'https://elpalomitron.com/category/animemanga/feed/',
BASE_RAMENPARADOS: 'https://ramenparados.com/category/noticias/anime/feed/',
BASE_CRUNCHYROLL: 'https://www.crunchyroll.com/newsrss?lang=esES',
ANIMEFLV_SEARCH: 'https://animeflv.net/browse?',
GENRES_URL: 'https://animeflv.net/browse?',
SEARCH_DIRECTORY: 'https://animeflv.net/browse?order=title&page=',
BASE_EPISODE_IMG_URL: 'https://cdn.animeflv.net/screenshots/',
BASE_QWANT: 'https://api.qwant.com/search/images?',
REDDIT_ANIMETHEMES: 'https://reddit.com/r/AnimeThemes/wiki/',
BASE_THEMEMOE: 'https://themes.moe/api/'
};

@ -1,306 +0,0 @@
[
{
"name": "Ghost Anime Radio",
"url": "http://animeradio.su:8000/"
},
{
"name": "Vocaloid Radio",
"url": "http://curiosity.shoutca.st:8019/stream"
},
{
"name": "NyanServer (J-Trance)",
"url": "http://radio.nyan.pw/station/stream"
},
{
"name": "Listen Radio (J-Pop)",
"url": "https://listen.moe/stream"
},
{
"name": "Listen Radio (K-Pop)",
"url": "https://listen.moe/kpop/stream"
},
{
"name": "Anison FM",
"url": "http://pool.anison.fm:9000/AniSonFM(128)"
},
{
"name": "Radio Nami",
"url": "https://radionami.com/play_radio.m3u"
},
{
"name": "R/a/dio",
"url": "http://relay0.r-a-d.io/main.mp3"
},
{
"name": "Chiru.no",
"url": "http://chiru.no:8000/stream.mp3"
},
{
"name": "Vocaloid Radio VRX",
"url": "http://vrx.piro.moe:8000/stream-192"
},
{
"name": "Asian Wave Japan",
"url": "https://listen1.myradio24.com/7934"
},
{
"name": "Radio Vocaloid",
"url": "http://142.4.217.133:9848/stream"
},
{
"name": "Final Fantasy Radio",
"url": "http://finalfantasystation.com:8000/stream"
},
{
"name": "Shinsen Radio",
"url": "http://shinsen-radio.org:8000/shinsen-radio.128.mp3"
},
{
"name": "Anime Nexus",
"url": "http://radio.animenexus.mx:8000/animenexus"
},
{
"name": "Yggdrasil Radio",
"url": "http://shirayuki.org:9100/"
},
{
"name": "Eden Radio",
"url": "http://edenofthewest.com:8080/eden.mp3"
},
{
"name": "Gensokyo Radio",
"url": "http://stream.gensokyoradio.net:8000/"
},
{
"name": "Radio J-Hero",
"url": "http://stm1.radiojhero.com:8008/;"
},
{
"name": "Phate Radio",
"url": "http://stream.phate.io/phatecc"
},
{
"name": "91.8 The fan",
"url": "http://198.27.80.154:8800/live"
},
{
"name": "Radio AOI",
"url": "http://radioaoi.pl/stream.m3u"
},
{
"name": "Radio Touhou",
"url": "http://www.touhouradio.com/touhouradio.m3u"
},
{
"name": "Radio MultiAnime",
"url": "http://67.20.61.70:8301"
},
{
"name": "Radio Fan World Anime",
"url": "http://stream.miradio.in:2199/tunein/fanworld.pls"
},
{
"name": "Radio Japan-A",
"url": "http://www.japanaradio.com/free/48kaacp.pls"
},
{
"name": "Radio JPopsuki",
"url": "http://jpopsuki.fm:2199/tunein/jpopsuki-stream.pls"
},
{
"name": "Radio Hot Mix",
"url": "http://hotmixradio-japan.ice.infomaniak.ch/hotmixradio-japan-128.mp3"
},
{
"name": "Dada more Radio",
"url": "http://dadamore2.ddo.jp:8000/listen.pls"
},
{
"name": "Initial D World",
"url": "http://69.163.186.124:9001/listen.aac"
},
{
"name": "Radio Blast",
"url": "http://192.99.150.31:8315/"
},
{
"name": "Kibo FM",
"url": "http://listen.kibo.fm:8000/kibofm"
},
{
"name": "Power 945",
"url": "http://38.96.148.28:8754/stream"
},
{
"name": "Japan Fans",
"url": "http://159.253.37.137:9984/listen.pls"
},
{
"name": "Radio Aniterasu",
"url": "http://aniterasu.com:8000/;?1442956789440.mp3"
},
{
"name": "Big B Radio's J-Pop",
"url": "http://64.71.79.181:6059/stream"
},
{
"name": "Radio Blue Heron",
"url": "http://cp3.digistream.info:8170"
},
{
"name": "Friends Forever",
"url": "http://23.29.71.154:8066/"
},
{
"name": "Radio Greek Otaku",
"url": "http://192.99.4.210:3684/stream"
},
{
"name": "Radio UR",
"url": "http://listen.ur-radio.de/anime.mp3"
},
{
"name": "Radio Anime",
"url": "http://stream.animeradio.de/animeradio.mp3"
},
{
"name": "PowerPlay J-Pop",
"url": "http://agnes.torontocast.com:8102"
},
{
"name": "Radio Asia Dream",
"url": "http://bluford.torontocast.com:8526"
},
{
"name": "J-Pop Kawaii",
"url": "http://bb31.sonixcast.com:20002/stream/1/"
},
{
"name": "J-Club HipHop",
"url": "http://agnes.torontocast.com:8051"
},
{
"name": "J-Rock",
"url": "http://cristina.torontocast.com:8057"
},
{
"name": "J-Pop Sakura",
"url": "http://bb31.sonixcast.com:20278/stream/1/"
},
{
"name": "J-Pop Haru Sakura",
"url": "http://184.75.223.178:8087/"
},
{
"name": "Radio Ronin",
"url": "https://s3.radio.co/sff133d65b/listen"
},
{
"name": "Radio Shinka",
"url": "http://5.9.65.9:8171/live"
},
{
"name": "Radio Naihatsu",
"url": "http://108.163.223.242:8305/"
},
{
"name": "J-Pop Project",
"url": "http://agnes.torontocast.com:8083/"
},
{
"name": "J-idols Project",
"url": "http://agnes.torontocast.com:8011/"
},
{
"name": "Radio J1",
"url": "https://jenny.torontocast.com:2000/stream/J1HITS"
},
{
"name": "J1 XTRA",
"url": "https://jenny.torontocast.com:2000/stream/J1XTRA"
},
{
"name": "J1 GOLD",
"url": "https://jenny.torontocast.com:2000/stream/J1GOLD"
},
{
"name": "Animu FM",
"url": "http://cast.animu.com.br:9021/stream"
},
{
"name": "Radio Wave Anime",
"url": "http://s04.radio-tochka.com:5470/mount"
},
{
"name": "Radio Anime Stream",
"url": "https://radioanime.radioca.st/stream"
},
{
"name": "Radio Baka",
"url": "http://144.217.203.184:8398/;"
},
{
"name": "Radio Animecol",
"url": "http://node-15.zeno.fm/6bfysacxc6quv"
},
{
"name": "JMusic Anime",
"url": "http://ample-zeno-24.radiojar.com/ddetxwuhkpeuv"
},
{
"name": "Radio Japanese Music",
"url": "http://live.japanesemusicid.com:8000/japanesemusic"
},
{
"name": "Radio Japannext",
"url": "https://perseus.shoutca.st/tunein/japannex.pls"
},
{
"name": "Radio Akari",
"url": "http://ample-zeno-22.radiojar.com/0t952vqukfeuv"
},
{
"name": "Anime Universe",
"url": "http://176.31.241.17:8147/;"
},
{
"name": "Geek Radio Music",
"url": "http://stream.zenolive.com/8d0xskxsxxquv"
},
{
"name": "Radio Aniterasu",
"url": "http://aniterasuradio.com:8000/;"
},
{
"name": "Radio Akiba",
"url": "http://stm24.srvstm.com:9526/;"
},
{
"name": "Radio Caprice",
"url": "http://79.111.119.111:8002/anime"
},
{
"name": "Radio Caprice J-Rock",
"url": "http://79.111.119.111:8002/jpop"
},
{
"name": "Nihonara!",
"url": "http://79.111.119.111:8002/jrock"
},
{
"name": "Radio Opening",
"url": "http://5.39.86.120:8000/nihonara_128.mp3"
},
{
"name": "Radio Aewen K-J-Pop",
"url": "http://stream.zeno.fm/tza2ayy47qruv"
},
{
"name": "Radio Wkend",
"url": "http://209.58.145.135:8031/stream"
},
{
"name": "Nihongo FM",
"url": "http://199.180.72.2:9004/stream"
}
]

@ -1,288 +0,0 @@
const cheerio = require('cheerio');
const {
homgot
} = require('../api/apiCall');
const {
REDDIT_ANIMETHEMES
} = require('../api/urls');
class ThemeParser {
constructor() {}
async all() {
try {
this.animes = [];
this.$ = await redditocall('year_index');
return await this.parseLinks();
}
catch(err) {
throw err;
}
}
async allYears() {
try {
this.animes = [];
this.$ = await redditocall('year_index');
return await this.parseYears();
}
catch(err) {
throw err;
}
}
async serie(query) {
try {
this.animes = [];
this.$ = await redditocall('anime_index');
return await this.parseSerie(query);
}
catch(err) {
throw err;
}
}
async artists() {
try {
this.animes = [];
this.$ = await redditocall('artist');
return await this.parseArtists();
}
catch(err) {
throw err;
}
}
async artist(id) {
try {
this.animes = [];
this.$ = await redditocall(`artist/${id}`);
return await this.parseArtist();
}
catch(err) {
throw err;
}
}
async random(query) {
try {
this.animes = [];
this.$ = await redditocall('anime_index');
return await this.parseRandom(query);
}
catch(err) {
throw err;
}
}
async year(date) {
let animes = [];
this.$ = await redditocall(date)
this.$('h3').each((i, el) => {
let parsed = this.parseAnime(el);
parsed.year = date;
animes.push(parsed);
})
return animes;
}
parseRandom() {
return new Promise(async resolve => {
let data = this.$('p a');
const origin = '1'
let randomize = Math.round(Math.random()*((data.length-1)-origin)+parseInt(origin));
this.$ = await redditocall(this.$('p a')[randomize].attribs.href.split('/r/AnimeThemes/wiki/')[1].split('#wiki')[0]);
let rand = Math.round(Math.random()*this.$('h3').length - 1);
let parsed = this.parseAnime(this.$('h3')[rand]);
resolve(parsed);
})
}
parseYears(){
return new Promise(async resolve => {
let promises = []
let data = this.$('h3 a');
for (let i = 0; i < data.length; i++) {
promises.push({
id: data[i].children[0].parent.attribs.href.split('/')[4],
name: data[i].children[0].data
})
if (i === data.length - 1) {
resolve(promises)
}
}
})
}
parseArtists(){
return new Promise(async resolve => {
let promises = []
let data = this.$('p a').filter(x => x > 0);
for (let i = 0; i < data.length; i++) {
promises.push({
id: data[i].children[0].parent.attribs.href.split('/')[5],
name: data[i].children[0].data
})
if (i === data.length - 1) {
resolve(promises)
}
}
})
}
parseArtist(){
return new Promise(async resolve => {
let promises = []
let data = this.$('h3');
for (let i = 0; i < data.length; i++) {
let parsed = await this.parseAnime(data[i])
promises.push(parsed)
if (i === data.length - 1) {
resolve(promises)
}
}
})
}
parseSerie(query){
return new Promise(async resolve => {
let data = this.$('p a');
for (let i = 0; i < data.length; i++) {
let serieElement = data[i].children[0].data
if (serieElement.split(" (")[0] === query) {
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++) {
if (this.$('h3')[i].children[0].children[0].data === query) {
let parsed = this.parseAnime(this.$('h3')[i]);
resolve(parsed);
}
}
}
}
})
}
parseLinks() {
return new Promise(async resolve => {
let years = this.$('h3 a');
this.$('h3 a')[0].children[0].data
for (let i = 0; i < years.length; i++) {
let yearElement = years[i];
await this.year(this.$(yearElement).attr('href').split('/')[4])
.then(async animes => {
this.animes = this.animes.concat(animes);
if(i === years.length - 1) {
resolve(this.animes);
}
})
}
})
}
parseAnime(dat) {
let el = this.$(dat).children('a');
let title = el.text();
let malId = el.attr('href').split('/')[4];
let next = this.$(dat).next();
let theme = {
id: malId,
title
}
if (next.prop("tagName") === "P") {
theme.themes = this.parseTable(next.next());
} else if (next.prop("tagName") === "TABLE") {
theme.themes = this.parseTable(next);
}
return theme;
}
parseTable(table) {
if (table.prop('tagName') !== "TABLE") {
return this.parseTable(table.next());
}
let themes = [];
table.children('tbody').children('tr').each(function () {
const $ = cheerio.load(this);
const td = $('td'); // Theme row
let name = replaceAll(td.first().text(), "&quot;", "\"")
let linkEl = td.eq(1).children().first();
let link = linkEl.attr('href');
let linkDesc = linkEl.text();
let episodes = td.eq(2).text();
let notes = td.eq(3).text();
themes.push({
name,
link,
desc: linkDesc,
type: (name.startsWith('OP') ? 'opening' : 'ending'),
episodes,
notes
})
})
return themes;
}
}
async function redditocall(href) {
let options = { parse: true }
let resp = await homgot(REDDIT_ANIMETHEMES + href + ".json", options)
return cheerio.load(getHTML(resp.data.content_html));
}
function getHTML(str) {
let html = replaceAll(str, "&lt;", "<")
html = replaceAll(html, "&gt;", ">")
return html;
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
module.exports = ThemeParser;

@ -1,528 +0,0 @@
const {
BASE_ANIMEFLV, BASE_JIKAN, BASE_EPISODE_IMG_URL, BASE_ARUPPI, ANIMEFLV_SEARCH, BASE_JKANIME
} = require('../api/urls.js');
const {
homgot
} = require('../api/apiCall.js');
const directoryAnimes = JSON.parse(JSON.stringify(require('../../assets/directory.json')));
const radioStations = require('../../assets/radiostations.json');
const animeGenres = require('../../assets/genres.json');
const animeThemes = require('../../assets/themes.json');
function btoa(str) {
let buffer;
if (str instanceof Buffer) {
buffer = str;
}
else {
buffer = Buffer.from(str.toString(), 'binary');
}
return buffer.toString('base64');
}
global.btoa = btoa;
async function videoServersJK(id) {
const $ = await homgot(`${BASE_JKANIME}${id}`, { scrapy: true });
const scripts = $('script');
const episodes = $('div#reproductor-box li');
const serverNames = [];
let servers = [];
episodes.each((index, element) => serverNames.push($(element).find('a').text()))
for (let i = 0; i < scripts.length; i++) {
try {
const contents = $(scripts[i]).html();
if ((contents || '').includes('var video = [];')) {
Array.from({ length: episodes.length }, (v, k) => {
let index = Number(k + 1);
let videoPageURL = contents.split(`video[${index}] = \'<iframe class="player_conte" src="`)[1].split('"')[0];
servers.push({ iframe: videoPageURL });
});
}
} catch (err) {
console.log(err)
return null;
}
}
let serverList = [];
for (let server in servers) {
serverList.push({
id: serverNames[server].toLowerCase(),
url: servers[server].iframe,
direct: false
});
}
serverList = serverList.filter(x => x.id !== 'xtreme s' && x.id !== 'desuka');
return await Promise.all(serverList);
}
async function getVideoURL(url) {
const $ = await homgot(url, { scrapy: true });
const video = $('video');
if (video.length) {
const src = $(video).find('source').attr('src');
return src || null;
}
else {
const scripts = $('script');
const l = global;
const ll = String;
const $script2 = $(scripts[1]).html();
eval($script2);
return l.ss || null;
}
}
const jkanimeInfo = async (id) => {
let $ = await homgot(`${BASE_JKANIME}${id}`, { scrapy: true });
let nextEpisodeDate
let rawNextEpisode = $('div[id="container"] div.left-container div[id="proxep"] p')[0]
if (rawNextEpisode === undefined) {
nextEpisodeDate = null
} else {
if (rawNextEpisode.children[1].data === ' ') {
nextEpisodeDate = null
} else {
nextEpisodeDate = rawNextEpisode.children[1].data.trim()
}
}
const eps_temp_list = [];
let episodes_aired = '';
$('div#container div.left-container div.navigation a').each(async (index, element) => {
const $element = $(element);
const total_eps = $element.text();
eps_temp_list.push(total_eps);
})
try { episodes_aired = eps_temp_list[0].split('-')[1].trim(); } catch (err) { }
const animeListEps = [{ nextEpisodeDate: nextEpisodeDate }];
for (let i = 1; i <= episodes_aired; 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 link = `${animeId}/${episode}`
animeListEps.push({
episode: episode,
id: link
})
}
return animeListEps;
};
const animeflvGenres = async (id) => {
const promises = [];
let options = { scrapy: true }
let $ = await homgot(`${BASE_ANIMEFLV}${id}`, options);
$('main.Main section.WdgtCn nav.Nvgnrs a').each((index, element) => {
const $element = $(element);
const genre = $element.attr('href').split('=')[1] || null;
promises.push(genre);
});
return promises;
}
const animeflvInfo = async (id) => {
let $ = await homgot(`${BASE_ANIMEFLV}anime/${id}`, { scrapy: true });
let scripts = $('script').toArray();
const anime_info_ids = [];
const anime_eps_data = [];
Array.from({ length: scripts.length }, (v, k) => {
const contents = $(scripts[k]).html();
if ((contents || '').includes('var anime_info = [')) {
let anime_info = contents.split('var anime_info = ')[1].split(';\n')[0];
let dat_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 animeId = id;
let nextEpisodeDate
if (anime_info_ids.length > 0) {
if (anime_info_ids[0].length === 4) {
nextEpisodeDate = anime_info_ids[0][3]
} else {
nextEpisodeDate = null
}
}
const amimeTempList = [];
for (const [key] 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 link = `${id}/${animeId}-${episode}`
animeListEps.push({
episode: episode,
id: link,
})
})
return animeListEps
};
const getAnimeCharacters = async(mal_id) =>{
let data;
try {
data = await homgot(`${BASE_JIKAN}anime/${mal_id}/characters_staff`, { parse: true });
}catch(error) {
console.log(error);
}
if(data !== null) {
return data.characters.map(doc => ({
id: doc.mal_id,
name: doc.name,
image: doc.image_url,
role: doc.role
}));
}
};
const getAnimeVideoPromo = async(mal_id) =>{
let data;
try {
data = await homgot(`${BASE_JIKAN}anime/${mal_id}/videos`, {parse: true});
}catch(error) {
console.log(error);
}
if(data !== null) {
return data.promo.map(doc => ({
title: doc.title,
previewImage: doc.image_url,
videoURL: doc.video_url
}));
}
};
const animeExtraInfo = async (mal_id) => {
const data = await homgot(`${BASE_JIKAN}anime/${mal_id}`, {parse: true});
try {
if(data !== null) {
const promises = [];
let broadcast = ''
Array(data).map(doc => {
let airDay = {
'mondays': 'Lunes',
'monday': 'Lunes',
'tuesdays': 'Martes',
'tuesday': 'Martes',
'wednesdays': 'Miércoles',
'wednesday': 'Miércoles',
'thursdays': 'Jueves',
'thursday': 'Jueves',
'fridays': 'Viernes',
'friday': 'Viernes',
'saturdays': 'Sábados',
'saturday': 'Sábados',
'sundays': 'Domingos',
'sunday': 'Domingos',
'default': 'Sin emisión'
};
if (doc.broadcast === null) {
broadcast = null
} else {
broadcast = airDay[doc.broadcast.split('at')[0].replace(" ", "").toLowerCase()]
}
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],
rank: doc.rank,
broadcast: broadcast,
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);
}
} catch (err) {
console.log(err)
}
};
const imageUrlToBase64 = async (url) => {
let img = await homgot(url)
return img.rawBody.toString('base64');
};
const searchAnime = async (query) => {
let $ = await homgot(`${ANIMEFLV_SEARCH}q=${query}`, { scrapy: true });
return Promise.all(await obtainAnimeSeries($));
};
const obtainAnimeSeries = async ($) => {
let promises = [];
await asyncForEach($('div.Container ul.ListAnimes li article'), async (element) => {
const $element = $(element);
const id = $element.find('div.Description a.Button').attr('href').slice(1);
const title = $element.find('a h3').text();
let poster =$element.find('a div.Image figure img').attr('src') || $element.find('a div.Image figure img').attr('data-cfsrc');
const type = $element.find('div.Description p span.Type').text();
promises.push({
id: id || null,
title: title || null,
type: type || null,
image: await imageUrlToBase64(poster) || null
});
})
return promises;
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
const transformUrlServer = async (urlReal) => {
let res
const promises = []
for (const index in urlReal) {
if (urlReal[index].server === 'amus' || urlReal[index].server === 'natsuki') {
let options = { parse: true }
res = await homgot(urlReal[index].code.replace("embed", "check"), options);
urlReal[index].code = res.file || null
urlReal[index].direct = true
}
}
urlReal.map(doc => {
promises.push({
id: doc.title.toLowerCase(),
url: doc.code,
direct: doc.direct || false
});
});
return promises;
}
const obtainPreviewNews = (encoded) => {
let image;
if (encoded.includes('src="https://img1.ak.crunchyroll.com/')) {
if (encoded.split('https://img1.ak.crunchyroll.com/')[1].includes('.jpg')) {
image = `https://img1.ak.crunchyroll.com/${encoded.split('https://img1.ak.crunchyroll.com/')[1].split('.jpg')[0]}.jpg`
} else {
image = `https://img1.ak.crunchyroll.com/${encoded.split('https://img1.ak.crunchyroll.com/')[1].split('.png')[0]}.png`
}
} else if (encoded.includes('<img title=')) {
image = encoded.substring(encoded.indexOf("<img title=\""), encoded.indexOf("\" alt")).split('src=\"')[1]
} else if (encoded.includes('<img src=')) {
image = encoded
.substring(encoded.indexOf("<img src=\""), encoded.indexOf("\" alt"))
.substring(10).replace("http", "https")
.replace("httpss", "https")
} else if (encoded.includes('<img')) {
image = encoded.split("src=")[1].split(" class=")[0].replace("\"", '').replace('\"', '')
} else if (encoded.includes('https://www.youtube.com/embed/')) {
let getSecondThumb = encoded.split('https://www.youtube.com/embed/')[1].split('?feature')[0]
image = `https://img.youtube.com/vi/${getSecondThumb}/0.jpg`
} else if (encoded.includes('https://www.dailymotion.com/')) {
let getDailymotionThumb = encoded
.substring(encoded.indexOf("\" src=\""), encoded.indexOf("\" a"))
.substring(47)
image = `https://www.dailymotion.com/thumbnail/video/${getDailymotionThumb}`
} else {
let number = Math.floor(Math.random() * 30);
image = `${BASE_ARUPPI}news/${number}.png`
}
return image;
}
const structureThemes = async (body, indv) => {
const promises = []
let themes
if (indv === true) {
themes = await getThemesData(body.themes)
promises.push({
title: body.title,
year: body.year,
themes: themes,
});
} else {
for (let i = 0; i <= body.length - 1; i++) {
themes = await getThemesData(body[i].themes)
promises.push({
title: body[i].title,
year: body[i].year,
themes: themes,
});
}
}
return promises;
};
const getThemesData = async (themes) => {
let promises = []
for (let i = 0; i <= themes.length - 1; i++) {
promises.push({
title: themes[i].name.split('"')[1] || 'Remasterización',
type: themes[i].name.split('"')[0] || 'OP/ED',
video: themes[i].link
});
}
return promises;
};
const getThemes = async (themes) => {
let promises = []
themes.map(doc => {
promises.push({
name: doc.themeName,
type: doc.themeType,
video: doc.mirror.mirrorURL
});
});
return promises;
};
const getAnimes = async () => await homgot(`${BASE_ANIMEFLV}api/animes/list`, { parse: true });
const getDirectory = async (genres) => {
if (genres === 'sfw') {
return directoryAnimes.filter(function (doc) {
if (!doc.genres.includes('Ecchi') && !doc.genres.includes('ecchi')) {
return {
id: doc.id,
title: doc.title,
mal_id: doc.mal_id,
poster: doc.poster,
type: doc.type,
genres: doc.genres,
state: doc.state,
score: doc.score,
jkanime: false,
description: doc.description
};
}
});
}
return directoryAnimes.map(doc => ({
id: doc.id,
title: doc.title,
mal_id: doc.mal_id,
poster: doc.poster,
type: doc.type,
genres: doc.genres,
state: doc.state,
score: doc.score,
jkanime: false,
description: doc.description
}));
};
module.exports = {
jkanimeInfo,
animeflvGenres,
animeflvInfo,
getAnimeCharacters,
getAnimeVideoPromo,
animeExtraInfo,
imageUrlToBase64,
searchAnime,
transformUrlServer,
obtainPreviewNews,
structureThemes,
getThemes,
getAnimes,
getDirectory,
videoServersJK,
directoryAnimes,
radioStations,
animeGenres,
animeThemes
}
Loading…
Cancel
Save