mirror of
https://github.com/knightcrawler-stremio/knightcrawler.git
synced 2024-12-20 03:29:51 +00:00
94 lines
3.0 KiB
JavaScript
94 lines
3.0 KiB
JavaScript
const axios = require('axios');
|
|
const cheerio = require("cheerio");
|
|
const decode = require("magnet-uri");
|
|
const Promises = require("../../lib/promises");
|
|
const { getRandomUserAgent } = require("../../lib/requestHelper");
|
|
|
|
const defaultTimeout = 10000;
|
|
|
|
const baseUrl = 'https://www.erai-raws.info';
|
|
|
|
const Categories = {
|
|
ANIMES: 'anime',
|
|
EPISODES: 'episodes'
|
|
};
|
|
|
|
function browse(config = {}, retries = 2) {
|
|
if (retries === 0) {
|
|
return Promise.reject(new Error(`Failed browse request`));
|
|
}
|
|
const page = config.page || 1;
|
|
const category = config.category;
|
|
|
|
return singleRequest(`${baseUrl}/${category}/page/${page}/`, config)
|
|
.then((body) => parseTableBody(body)
|
|
.then(animes => Promises.sequence(animes.map(anime => () => singleRequest(anime.animeLink))))
|
|
.then(animeBodies => Promise.all(animeBodies.map(animeBody => parseTorrentPage(animeBody))))
|
|
.then(animeInfos => animeInfos.reduce((a, b) => a.concat(b), [])))
|
|
.catch((err) => browse(config, retries - 1));
|
|
}
|
|
|
|
function singleRequest(requestUrl, config = {}) {
|
|
const timeout = config.timeout || defaultTimeout;
|
|
const options = { headers: { 'User-Agent': getRandomUserAgent() }, timeout: timeout, };
|
|
|
|
return axios.get(requestUrl, options).then((response) => {
|
|
const body = response.data;
|
|
if (!body || (Buffer.isBuffer(body) && !body.size)) {
|
|
throw new Error(`No body: ${requestUrl}`);
|
|
} else if (
|
|
body.includes("502: Bad gateway") ||
|
|
body.includes("403 Forbidden")
|
|
) {
|
|
throw new Error(`Invalid body contents: ${requestUrl}`);
|
|
}
|
|
return body;
|
|
});
|
|
}
|
|
|
|
function parseTableBody(body) {
|
|
return new Promise((resolve, reject) => {
|
|
const $ = cheerio.load(body);
|
|
|
|
if (!$) {
|
|
reject(new Error("Failed loading body"));
|
|
}
|
|
|
|
const links = $('[itemprop=\'headline\'] a, .content-area a.aa_ss_ops_new')
|
|
.map((i, element) => ({
|
|
name: $(element).text(),
|
|
animeLink: $(element).attr("href"),
|
|
})).get();
|
|
resolve(links);
|
|
});
|
|
}
|
|
|
|
function parseTorrentPage(body) {
|
|
return new Promise(async (resolve, reject) => {
|
|
const $ = cheerio.load(body);
|
|
|
|
if (!$) {
|
|
reject(new Error("Failed loading body"));
|
|
}
|
|
const entries = $('.tab-content table, .content-area table')
|
|
.map((i, entry) => {
|
|
const languages = $(entry).find('.tooltip3').map((_, l) => $(l).attr('data-title')).get().join('/');
|
|
const magnets = $(entry).find('a[href^="magnet"]').map((_, m) => $(m).attr('href')).get();
|
|
return { languages, magnets }
|
|
}).get();
|
|
const torrents = entries
|
|
.map(entry => entry.magnets
|
|
.map(magnet => decode(magnet))
|
|
.map(decodedMagnet => ({
|
|
title: decodedMagnet.name,
|
|
infoHash: decodedMagnet.infoHash,
|
|
trackers: decodedMagnet.tr,
|
|
languages: entry.languages
|
|
})))
|
|
.reduce((a, b) => a.concat(b), []);
|
|
resolve(torrents);
|
|
});
|
|
}
|
|
|
|
module.exports = { browse, Categories };
|