manga-parser
Version:
A parser for manga online sources
308 lines (250 loc) • 7.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _moment = require('moment');
var _moment2 = _interopRequireDefault(_moment);
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _utils = require('../utils');
var _abstractCatalog = require('../abstract-catalog');
var _abstractCatalog2 = _interopRequireDefault(_abstractCatalog);
var _models = require('../models');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class Mangafox extends _abstractCatalog2.default {
constructor() {
super();
this.name = 'Mangafox';
this.catalogName = 'mangafox';
this.baseUrl = 'http://fanfox.net/';
this.lang = _abstractCatalog.LANGUAGE_EN;
this.hasVolumeInfos = true;
}
/**
* @param {number} page
* @returns {string}
*/
popularMangaRequest(page) {
let pageStr = page !== 1 ? `${(0, _utils.toString)(page)}.html` : '';
return `${this.baseUrl}/directory/${pageStr}`;
}
/**
* @param $
* @returns {Array.<Manga>}
*/
popularMangaList($) {
let mangas = [];
let provider = this;
$('div#mangalist > ul.list > li').each((i, elem) => {
let manga = this.extractMangaSummary($, elem, provider.getNextIndex());
mangas.push(manga);
});
return mangas;
}
/**
* @param $
* @returns {{hasNext: boolean, nextUrl: string, nextPage: ?number}}
*/
popularMangaPaginator($) {
let pagination = $('a:has(span.next)');
let nextPage = null;
if (pagination.length) {
nextPage = pagination.attr('href').match(/(\d+)\.htm/);
if (nextPage && nextPage.length) {
nextPage = parseInt(nextPage[1]);
}
}
return {
hasNext: Boolean(pagination.length),
nextUrl: pagination.attr('href'),
nextPage: nextPage
};
}
/**
* @param {number} page
* @returns {string}
*/
latestUpdatesRequest(page) {
let pageStr = page !== 1 ? `${(0, _utils.toString)(page)}.html` : '';
return `${this.baseUrl}/directory/${pageStr}?latest`;
}
/**
* @param $
* @returns {Array.<Manga>}
*/
latestUpdatesList($) {
let mangas = [];
$('div#mangalist > ul.list > li').each((i, elem) => {
let manga = this.extractMangaSummary($, elem, Infinity);
mangas.push(manga);
});
return mangas;
}
/**
* @param $
* @returns {{hasNext: boolean, nextUrl: string, nextPage: ?number}}
*/
latestUpdatesPaginator($) {
return this.popularMangaPaginator($);
}
/**
* @param $
* @param manga
* @returns {Manga}
*/
mangaDetail($, manga) {
let container = $('div#title').first();
let detailsContainer = container.find('table > tbody > tr').eq(1).first();
let sideContainer = $('#series_info').first();
manga.author = (0, _utils.trimSpaces)(detailsContainer.find('td').eq(1).text());
manga.artist = (0, _utils.trimSpaces)(detailsContainer.find('td').eq(2).text());
manga.genre = (0, _utils.trimSpaces)(detailsContainer.find('td').eq(3).text());
manga.description = (0, _utils.trimSpaces)(container.find('p.summary').first().text());
manga.status = this.parseStatus((0, _utils.trimSpaces)(sideContainer.find('.data').first().text()));
manga.setThumbnailUrl(sideContainer.find('div.cover > img').first().attr('src'));
manga.detailsFetched = true;
return manga;
}
/**
* @private
* @param {string} status
* @returns {string}
*/
parseStatus(status) {
if (status.indexOf('Ongoing') > -1) {
return _models.STATUS_ONGOING;
} else if (status.indexOf('Completed') > -1) {
return _models.STATUS_COMPLETED;
}
return _models.STATUS_UNKNOWN;
}
/**
* @param $
* @returns {Array}
*/
chapterList($) {
let chapters = [];
$('h3.volume').each((i, elem) => {
let volumeNumber = $(elem).text().match(/Volume ([\d|TBD]+)/)[1];
if (!isNaN(parseInt(volumeNumber))) {
volumeNumber = parseInt(volumeNumber);
}
$(elem).parent().next('ul.chlist').find('li div').each((i, elem) => {
let chapter = new _models.Chapter();
let url = $(elem).find('a.tips').first();
chapter.setUrl(url.attr('href'));
chapter.title = (0, _utils.trimSpaces)(url.text());
chapter.publishedAt = (0, _utils.resetDateTime)(this.parseChapterDate((0, _utils.trimSpaces)($(elem).find('span.date').first().text())));
chapter.volume = volumeNumber;
chapter.generateId();
chapters.push(chapter);
});
});
return chapters;
}
/**
* @param $
* @returns {{}}
*/
chapterListByVolume($) {
let chapters = this.chapterList($);
return _lodash2.default.groupBy(chapters, 'volume');
}
/**
* @private
* @param date
* @returns {Date}
*/
parseChapterDate(date) {
if (date.indexOf('Today') > -1 || date.indexOf(' ago') > -1) {
return new Date();
} else if (date.indexOf('Yesterday') > -1) {
return (0, _moment2.default)().subtract(1, 'days').toDate();
}
let momentDate = (0, _moment2.default)(date, 'MMM D, YYYY');
if (momentDate.isValid()) {
return momentDate.toDate();
}
return new Date(1970, 0, 1);
}
/**
* @param $
* @returns {Array}
*/
pageList($) {
let pages = [];
let url = $('a#comments').attr('href');
let options = $('select.m').first().find('option:not([value=0])');
options.each((i, elem) => {
let page = $(elem).attr('value');
pages.push((0, _utils.sanitizeUrlProtocol)(`${url}${page}.html`));
});
return pages;
}
/**
* @param $
* @returns {string}
*/
imageUrl($) {
return $('#image').first().attr('src');
}
/**
* @param query
* @param page
* @returns {{url: string, headers: any, method: string, form: any}}
*/
searchOptions(query, page) {
// prettier-ignore
return `${this.baseUrl}/search.php?name_method=cw&author_method=cw&artist_method=cw&advopts=1&name=${query}&page=${(0, _utils.toString)(page)}`;
}
/**
* @param $
* @returns {Array}
*/
search($) {
let mangas = [];
$('div#mangalist > ul.list > li').each((i, elem) => {
let manga = this.extractMangaSummary($, elem, Infinity);
mangas.push(manga);
});
return mangas;
}
/**
* @param $
* @returns {{ hasNext: boolean, nextUrl: ?string, nextPage: ?number }}
*/
searchPaginator($) {
let pagination = $('a:has(span.next)');
let nextPage = null;
if (pagination.length) {
nextPage = pagination.attr('href').match(/page=(\d+)/);
if (nextPage && nextPage.length) {
nextPage = parseInt(nextPage[1]);
}
}
return {
hasNext: Boolean(pagination.length),
nextUrl: pagination.length ? pagination.attr('href') : null,
nextPage: nextPage
};
}
/**
* @private
* @param $
* @param elem
* @param catalogId
* @returns {Manga}
*/
extractMangaSummary($, elem, catalogId) {
let manga = new _models.Manga();
let link = $(elem).find('a.title');
manga.setUrl(link.attr('href'));
manga.title = (0, _utils.trimSpaces)(link.text());
manga.setThumbnailUrl($(elem).find('img').attr('src'));
manga.catalogId = catalogId;
manga.catalog = this.catalogName;
manga.generateId();
return manga;
}
}
exports.default = new Mangafox();