UNPKG

manga-parser

Version:
352 lines (282 loc) 9.11 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _bluebird = require('bluebird'); var _bluebird2 = _interopRequireDefault(_bluebird); var _cheerio = require('cheerio'); var _cheerio2 = _interopRequireDefault(_cheerio); var _sites = require('./sites'); var catalogs = _interopRequireWildcard(_sites); var _chapterRecognition = require('./chapter-recognition'); var _chapterRecognition2 = _interopRequireDefault(_chapterRecognition); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } let request = require('request'); request = request.defaults({ timeout: 20000, gzip: true }); class Parser { constructor() { let sources = {}; _lodash2.default.forEach(catalogs, catalog => { sources[catalog.catalogName] = catalog; }); this.catalogs = sources; } /** * Fetch the popular mangas on the catalog * @param {string} catalogName * @param {number} page Page to fetch * @returns {Promise<{mangas: Array<Manga>, hasNext: boolean, nextUrl: string, nextPage: number}>} */ getPopularMangaList(catalogName, page = null) { const catalog = this.getCatalog(catalogName); let options = catalog.popularMangaRequest(page); return new _bluebird2.default(function (resolve, reject) { request(options, function (error, response, page) { if (error) { return reject(error); } let $ = _cheerio2.default.load(page); let mangas; let paginator; try { mangas = catalog.popularMangaList($); } catch (error) { return reject(error); } try { paginator = catalog.popularMangaPaginator($); } catch (error) { return reject(error); } return resolve(_extends({ mangas }, paginator)); }); }); } /** * Fetch the latest updated manga on the catalog * @param {string} catalogName * @param {number} page Page to fetch * @returns {Promise<{mangas: Array<Manga>, hasNext: boolean, nextUrl: string, nextPage: number}>} */ getLatestUpdatesList(catalogName, page = null) { const catalog = this.getCatalog(catalogName); let options = catalog.latestUpdatesRequest(page); return new _bluebird2.default(function (resolve, reject) { request(options, function (error, response, page) { if (error) { return reject(error); } let $ = _cheerio2.default.load(page); let mangas; let paginator; try { mangas = catalog.latestUpdatesList($); } catch (error) { return reject(error); } try { paginator = catalog.latestUpdatesPaginator($); } catch (error) { return reject(error); } return resolve(_extends({ mangas }, paginator)); }); }); } /** * Search for Manga from a catalog * @param {string} catalogName * @param {string} query * @param {?number} page * @returns {Promise<{ mangas: Array<Manga>, hasNext: boolean, nextUrl: ?string, nextPage: ?number }>} */ searchManga(catalogName, query, page = null) { const catalog = this.getCatalog(catalogName); const options = catalog.searchOptions(query, page); return new _bluebird2.default(function (resolve, reject) { request(options, function (error, response, page) { if (error) { return reject(error); } let $ = _cheerio2.default.load(page); let mangas; let paginator; try { mangas = catalog.search($); } catch (error) { return reject(error); } try { paginator = catalog.searchPaginator($); } catch (error) { return reject(error); } return resolve(_extends({ mangas }, paginator)); }); }); } /** * Fetch every information for a Manga * @param {string} catalogName * @param {Manga} manga * @returns {Promise<Manga>} */ getMangaDetail(catalogName, manga) { const catalog = this.getCatalog(catalogName); return new _bluebird2.default(function (resolve, reject) { request(manga.url, function (error, response, page) { if (error) { return reject(error); } let $ = _cheerio2.default.load(page); try { manga = catalog.mangaDetail($, manga); } catch (error) { return reject(error); } resolve(manga); }); }); } /** * Fetch the list of chapters for Manga * @param {string} catalogName * @param {Manga} manga * @returns {Promise<Array<Chapter>>} */ getChapterList(catalogName, manga) { const catalog = this.getCatalog(catalogName); return new _bluebird2.default(function (resolve, reject) { request(manga.url, function (error, response, page) { if (error) { return reject(error); } let $ = _cheerio2.default.load(page); let chapters; try { chapters = catalog.chapterList($); } catch (error) { return reject(error); } _lodash2.default.forEach(chapters, (chapter, index) => { chapters[index] = _chapterRecognition2.default.parseChapterNumber(chapter, manga); }); chapters = _lodash2.default.orderBy(chapters, ['number', 'publishedAt'], ['asc', 'asc']); resolve(chapters); }); }); } /** * Fetch the list of chapters for a Manga sorted by volumes * @param {string} catalogName * @param {Manga} manga * @returns {Promise<{}>} */ getChapterListByVolumes(catalogName, manga) { const catalog = this.getCatalog(catalogName); if (!catalog.hasVolumeInfos) { return _bluebird2.default.reject(`${catalogName} does not have volume infos`); } return new _bluebird2.default(function (resolve, reject) { request(manga.url, function (error, response, page) { if (error) { return reject(error); } let $ = _cheerio2.default.load(page); let volumes; try { volumes = catalog.chapterListByVolume($); } catch (error) { return reject(error); } _lodash2.default.forEach(volumes, (chapters, volume) => { _lodash2.default.forEach(chapters, (chapter, index) => { chapters[index] = _chapterRecognition2.default.parseChapterNumber(chapter, manga); }); volumes[volume] = _lodash2.default.orderBy(chapters, ['number', 'publishedAt'], ['asc', 'asc']); }); resolve(volumes); }); }); } /** * Fetch every pages URL for a manga * @param {string} catalogName * @param {Chapter} chapter * @returns {Promise<Array<string>>} */ getPageList(catalogName, chapter) { const catalog = this.getCatalog(catalogName); return new _bluebird2.default((resolve, reject) => { request(chapter.url, (error, response, page) => { if (error) { return reject(error); } let $ = _cheerio2.default.load(page); let pages; try { pages = catalog.pageList($); } catch (error) { return reject(error); } return resolve(pages); }); }); } /** * Fetch the image URL from a page URL * @param {string} catalogName * @param {string} pageURL * @returns {Promise<string>} */ getImageURL(catalogName, pageURL) { const catalog = this.getCatalog(catalogName); return new _bluebird2.default((resolve, reject) => { request(pageURL, (error, response, page) => { if (error) { return reject(error); } let $ = _cheerio2.default.load(page); let imageURL; try { imageURL = catalog.imageUrl($); } catch (error) { return reject(error); } return resolve(imageURL); }); }); } /** * Return the list of catalogs * @returns {{name:AbstractCatalog}} */ getCatalogs() { return this.catalogs; } /** * Return a catalog * @param {string} catalogName * @returns {AbstractCatalog} */ getCatalog(catalogName) { if (!(catalogName in this.catalogs)) { throw new Error('Catalog does not exist'); } return this.catalogs[catalogName]; } } exports.default = new Parser();