eztv-crawler
Version:
A promised based node module to scrape TV shows, episodes and torrent info from EZTV.
192 lines • 7.65 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EztvCrawlerException = exports.getTorrentsByImdbId = exports.getTorrents = exports.search = exports.getShow = exports.getShows = void 0;
const bytes_1 = __importDefault(require("bytes"));
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const cheerio_1 = require("cheerio");
/**
* Crawl any given url
*
* @link https://www.npmjs.com/package/crawler
* @param url
* @returns `Crawler.CrawlerRequestResponse`
*/
function crawl(url) {
return __awaiter(this, void 0, void 0, function* () {
const body = yield (0, cross_fetch_1.default)(url).then((resp) => __awaiter(this, void 0, void 0, function* () { return resp.text(); }));
const $ = (0, cheerio_1.load)(body);
return { body, $ };
});
}
/**
* Get all shows listen on EZTV
*
* @returns `object`
*/
function getShows() {
return __awaiter(this, void 0, void 0, function* () {
const { $ } = yield crawl(`https://eztv.wf/showlist/`);
const shows = $('a[class="thread_link"]').toArray();
return shows.map(show => {
var _a;
const showIdRegex = (_a = $(show).attr('href')) === null || _a === void 0 ? void 0 : _a.match(/shows\/(\d+)\//);
return {
id: showIdRegex ? parseInt(showIdRegex[1]) : null,
title: $(show).text()
};
}).filter(show => show.id);
});
}
exports.getShows = getShows;
/**
* Get a show and its episodes
*
* Recommended to use an ID, if using a showname
* it must be an exact match except for uppercase
*
* @param showId - A show ID or a show name
* @returns `object`
*/
function getShow(show) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
/**
* If a string is passed find show based on title
*/
if (typeof show === 'string') {
const shows = yield getShows();
const findShow = shows.find(s => s.title.toLowerCase() === show.toLowerCase());
if (!findShow) {
throw new EztvCrawlerException(`Did not find a show with name ${show}`);
}
return getShow(findShow.id);
}
const { $ } = yield crawl(`https://eztv.wf/shows/${show}/`);
const episodes = $('[name="hover"]').toArray();
const imdbIdRegex = (_a = $('[itemprop="aggregateRating"] a').attr('href')) === null || _a === void 0 ? void 0 : _a.match(/tt\d+/);
const result = {
title: $('.section_post_header [itemprop="name"]').text(),
summary: $('[itemprop="description"] p').text(),
description: $('span[itemprop="description"] + br + br + hr + br + span').text(),
imdbId: imdbIdRegex ? imdbIdRegex[0] : null,
episodes: episodes.map(episode => {
return transformToEpisode($, episode);
})
};
if (!result || !result.title || result.title === '') {
throw new EztvCrawlerException(`Did not find a show with name ${show}`);
}
return result;
});
}
exports.getShow = getShow;
/**
* Search for a TV show episode
*
* @param query - string
* @returns `episodeObject`
*/
function search(query) {
return __awaiter(this, void 0, void 0, function* () {
const { $ } = yield crawl(`https://eztv.wf/search/${query}`);
const episodes = $('[name="hover"]').toArray();
return episodes.map(episode => {
return transformToEpisode($, episode);
});
});
}
exports.search = search;
/**
* Get a list of torrents
*
* @param limit
* @param page
* @param apiBaseUrl - If eztv domain changed or eztv is blocked in your country provide a proxy url here
* @returns `ApiResponseType`
*/
function getTorrents(limit = 10, page = 1, apiBaseUrl = 'https://eztv.wf/api/') {
return __awaiter(this, void 0, void 0, function* () {
return yield makeApiRequest('/get-torrents', { limit: limit.toString(), page: page.toString() }, apiBaseUrl);
});
}
exports.getTorrents = getTorrents;
/**
* Get a list of torrents based on IMDb ID
*
* NOTE:
* For TV Shows provide the IMDb id of the show itself, it does not work
* when you provide an IMDb for individual episodes
*
* @param imdbId - IMDb ID
* @param apiBaseUrl - If eztv domain changed or eztv is blocked in your country provide a proxy url here
* @returns `ApiResponseType`
*/
function getTorrentsByImdbId(imdbId, limit = 30, page = 1, apiBaseUrl = 'https://eztv.wf/api/') {
return __awaiter(this, void 0, void 0, function* () {
return yield makeApiRequest('/get-torrents', { imdb_id: imdbId, limit: limit.toString(), page: page.toString() }, apiBaseUrl);
});
}
exports.getTorrentsByImdbId = getTorrentsByImdbId;
/**
* Send a request to EZTV's API
*
* @param path
* @param params
* @param apiBaseUrl
* @returns `ApiResponseType`
*/
function makeApiRequest(path, params, apiBaseUrl = 'https://eztv.wf/api/') {
return __awaiter(this, void 0, void 0, function* () {
if (params.imdb_id) {
params.imdb_id = params.imdb_id.replace(/\D+/, '');
}
try {
const request = yield (0, cross_fetch_1.default)(`${apiBaseUrl}/${path}?${new URLSearchParams(params)}`);
const json = yield request.json();
return json;
}
catch (e) {
if (e instanceof Error) {
throw new EztvCrawlerException(e.message);
}
throw new EztvCrawlerException('Could not fullfill request.');
}
});
}
/**
* Transforms a <table> Element into a episode object
*
* Note: in torrents, don't parse the `.download_2` class, it contains spam and malware in some cases
*
* @param $ - cheerio.CheerioAPI
* @param episode - cheerio.Element
* @returns `episodeObject`
*/
function transformToEpisode($, episode) {
var _a, _b, _c;
return {
showLink: $(episode).find('td:nth-child(1) a').attr('href'),
title: (_a = $(episode).find('td:nth-child(2)').text()) === null || _a === void 0 ? void 0 : _a.replace(/\n/g, ''),
magnet: (_b = $(episode).find('td:nth-child(3) .magnet').attr('href')) === null || _b === void 0 ? void 0 : _b.replace(/\n/g, ''),
torrent: (_c = $(episode).find('td:nth-child(3) .download_1').attr('href')) === null || _c === void 0 ? void 0 : _c.replace(/\n/g, ''),
size: (0, bytes_1.default)($(episode).find('td:nth-child(4)').text()),
released: $(episode).find('td:nth-child(5)').text(),
seeds: parseInt($(episode).find('td:nth-child(6)').text()) || 0
};
}
class EztvCrawlerException extends Error {
}
exports.EztvCrawlerException = EztvCrawlerException;
//# sourceMappingURL=main.js.map