diff --git a/src/web/img/connectors/mangascanws b/src/web/img/connectors/mangascanws new file mode 100644 index 0000000000..4d9b144f02 Binary files /dev/null and b/src/web/img/connectors/mangascanws differ diff --git a/src/web/img/connectors/beautymanga b/src/web/img/connectors/mangatigre similarity index 100% rename from src/web/img/connectors/beautymanga rename to src/web/img/connectors/mangatigre diff --git a/src/web/img/connectors/manhuadb b/src/web/img/connectors/manhuadb new file mode 100644 index 0000000000..72bb76c508 Binary files /dev/null and b/src/web/img/connectors/manhuadb differ diff --git a/src/web/img/connectors/manhwamanga b/src/web/img/connectors/manhwamanga new file mode 100644 index 0000000000..2c1e65b51c Binary files /dev/null and b/src/web/img/connectors/manhwamanga differ diff --git a/src/web/img/connectors/niceoppai b/src/web/img/connectors/niceoppai new file mode 100644 index 0000000000..10a29b8368 Binary files /dev/null and b/src/web/img/connectors/niceoppai differ diff --git a/src/web/img/connectors/novelmania b/src/web/img/connectors/novelmania new file mode 100644 index 0000000000..cf01e20504 Binary files /dev/null and b/src/web/img/connectors/novelmania differ diff --git a/src/web/img/connectors/projectsuki b/src/web/img/connectors/projectsuki new file mode 100644 index 0000000000..72bb76c508 Binary files /dev/null and b/src/web/img/connectors/projectsuki differ diff --git a/src/web/img/connectors/truyenvn b/src/web/img/connectors/truyenvn new file mode 100644 index 0000000000..5c2505defb Binary files /dev/null and b/src/web/img/connectors/truyenvn differ diff --git a/src/web/mjs/connectors/BeautyManga.mjs b/src/web/mjs/connectors/BeautyManga.mjs deleted file mode 100644 index 1f1c97ba55..0000000000 --- a/src/web/mjs/connectors/BeautyManga.mjs +++ /dev/null @@ -1,53 +0,0 @@ -import WordPressMadara from './templates/WordPressMadara.mjs'; -export default class BeautyManga extends WordPressMadara { - constructor() { - super(); - super.id = 'beautymanga'; - super.label = 'BeautyManga'; - this.tags = [ 'manga', 'webtoon', 'english' ]; - this.url = 'https://mangadex.today'; - this.path = '/popular-manga'; - this.queryMangas = 'div.item-thumb.hover-details.c-image-hover a'; - this.queryMangasPageCount = 'ul.pagination li:nth-last-of-type(2) a'; - this.pathMangas = '?page=%PAGE%'; - this.queryPages = 'p#arraydata'; - this.mangaTitleFilter = ''; - } - async _getMangasFromPage(page) { - let uri = new URL(this.path + this.pathMangas.replace('%PAGE%', page), this.url); - uri.pathname = uri.pathname.replace(/\/+/g, '/'); - let request = new Request(uri, this.requestOptions); - let data = await this.fetchDOM(request, this.queryMangas); - return data.map(element => { - return { - id: new URL(element.href, request.url).pathname, - title: element.title.replace(this.mangaTitleFilter, '').trim() - }; - }); - } - async _getChaptersAjaxOld(mangaID) { - const uri = new URL('/ajax-list-chapter?mangaID='+mangaID, this.url); - const request = new Request(uri, { - method: 'GET' - }); - const data = await this.fetchDOM(request, this.queryChapters); - if (data.length) { - return data; - } else { - throw new Error('No chapters found (new ajax endpoint)!'); - } - } - async _getPages(chapter) { - let uri = new URL(chapter.id, this.url); - let request = new Request(uri, this.requestOptions); - let data = await this.fetchDOM(request, this.queryPages); - let el = data[0].innerText.split(','); - return el.map(element => { - const uri = new URL(this.getAbsolutePath(element, request.url)); - return this.createConnectorURI({ - url: uri.href, - referer: uri.origin - }); - }); - } -} \ No newline at end of file diff --git a/src/web/mjs/connectors/MangaFull.mjs b/src/web/mjs/connectors/MangaFull.mjs index 73e3dcac81..d860d4d1d9 100644 --- a/src/web/mjs/connectors/MangaFull.mjs +++ b/src/web/mjs/connectors/MangaFull.mjs @@ -96,4 +96,4 @@ export default class MangaFull extends Connector { callback( error, undefined ); } ); } -} \ No newline at end of file +} diff --git a/src/web/mjs/connectors/MangaScanWS.mjs b/src/web/mjs/connectors/MangaScanWS.mjs new file mode 100644 index 0000000000..4cf5077986 --- /dev/null +++ b/src/web/mjs/connectors/MangaScanWS.mjs @@ -0,0 +1,25 @@ +import MangaReaderCMS from './templates/MangaReaderCMS.mjs'; + +export default class MangaScanWS extends MangaReaderCMS { + + constructor() { + super(); + super.id = 'mangascanws'; + super.label = 'MangaScanWS'; + this.tags = [ 'manga', 'webtoon', 'french' ]; + this.url = 'https://mangascan.ws'; + } + async _getPages(chapter) { + const data = await super._getPages(chapter); + return data.map(element => this.createConnectorURI(element)); + } + async _handleConnectorURI(payload) { + let request = new Request(payload, this.requestOptions); + request.headers.set('x-referer', this.url); + let response = await fetch(request); + let data = await response.blob(); + data = await this._blobToBuffer(data); + this._applyRealMime(data); + return data; + } +} diff --git a/src/web/mjs/connectors/MangaTigre.mjs b/src/web/mjs/connectors/MangaTigre.mjs new file mode 100644 index 0000000000..cbb243959e --- /dev/null +++ b/src/web/mjs/connectors/MangaTigre.mjs @@ -0,0 +1,104 @@ +import Connector from '../engine/Connector.mjs'; +import Manga from '../engine/Manga.mjs'; + +export default class MangaTigre extends Connector { + constructor() { + super(); + super.id = 'mangatigre'; + super.label = 'MangaTigre'; + this.tags = [ 'manga', 'webtoon', 'spanish' ]; + this.url = 'https://www.mangatigre.net'; + this.token = undefined; + this.requestOptions.headers.set('x-origin', this.url); + this.booktype = { + 1: "manga", + 2: "manhwa", + 3: "manhua", + }; + } + + async _getMangas() { + const uri = new URL('/mangas', this.url); + await this.getToken(uri); + let mangaList = []; + for (let page = 1, run = true; run; page++) { + const mangas = await this._getMangasFromPage(page); + mangas.length > 0 ? mangaList.push(...mangas) : run = false; + } + return mangaList; + } + + async _getMangasFromPage(page) { + const uri = new URL('/mangas', this.url); + const request = new Request(uri, { + method: 'POST', + body: JSON.stringify({_token : this.token, page : page}), + headers: { + 'content-type': 'application/json', + 'x-referer': uri.href + } + }); + const response = await fetch(request); + const data = await response.json(); + return data.data.map(element => { + let btype = this.booktype[element.type]; + return { + id: '/'+btype+'/'+element.slug, + title: element.name.trim() + }; + }); + } + + async _getChapters(manga) { + const slug = manga.id.split('/')[2]; + const uri = new URL(manga.id, this.url); + await this.getToken(uri); + const request = new Request(uri, { + method: 'POST', + body: JSON.stringify({_token : this.token}), + headers: { + 'content-type': 'application/json', + 'x-referer': uri.href + } + }); + const data = await this.fetchDOM(request, 'a'); + return data.map(element => { + return { + id: element.pathname, + title: element.text.trim() + }; + }); + } + + async _getPages(chapter) { + const uri = new URL(chapter.id, this.url); + const script = ` + new Promise(resolve => { + resolve({ + chap : window.chapter, cdn : window.cdn + }); + }); + `; + const request = new Request(uri); + const response = await Engine.Request.fetchUI(request, script); + const chap = JSON.parse(response.chap); + const CDN = response.cdn; + let keyz = Object.keys(chap.images).sort(); + let pagelist = []; + for (let i = 0; i < keyz.length; i++ ) { + let key = keyz[i]; + let image = chap.images[key]; + let link = '//'.concat(CDN, '/chapters/').concat(chap.manga.slug, '/').concat(chap.number, '/').concat(image.name, '.').concat(image.format); + pagelist.push(this.getAbsolutePath(link, request.url)); + } + return pagelist; + } + async getToken(url) { + try{ + let request = new Request(url, this.requestOptions); + let data = await this.fetchDOM(request, 'button[data-token]', 3); + this.token = data[0].getAttribute('data-token'); + } catch(e) { + } + } +} \ No newline at end of file diff --git a/src/web/mjs/connectors/ManhuaDB.mjs b/src/web/mjs/connectors/ManhuaDB.mjs new file mode 100644 index 0000000000..84fb57b780 --- /dev/null +++ b/src/web/mjs/connectors/ManhuaDB.mjs @@ -0,0 +1,72 @@ +import Connector from '../engine/Connector.mjs'; +import Manga from '../engine/Manga.mjs'; +export default class ManhuaDB extends Connector { + constructor() { + super(); + super.id = 'manhuadb'; + super.label = 'ManhuaDB'; + this.tags = [ 'manga', 'webtoon', 'chinese' ]; + this.url = 'https://www.manhuadb.com'; + this.path = '/manhua/list.html'; + this.queryMangas = 'div.media.comic-book-unit div.media-body h2 > a'; + this.queryMangasPagesArray = 'select#page-selector option'; + this.queryChapters = 'ol.links-of-books li a'; + this.queryPages = 'div.content-text source[loading="lazy"]'; + this.queryMangaTitleURI = 'div.comic-main-section div.comic-info h1.comic-title'; + } + async _getMangaFromURI(uri) { + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangaTitleURI); + return new Manga(this, uri.pathname, data[0].textContent.trim()); + } + async _getMangas() { + let mangaList = []; + const uri = new URL(this.path, this.url); + const request = new Request(uri, this.requestOptions); + const pagesArray = await this.fetchDOM(request, this.queryMangasPagesArray); + for(let i = 0; i < pagesArray.length; i++) { + const page = new URL(pagesArray[i].value, this.url); + const mangas = await this._getMangasFromPage(page); + mangaList.push(...mangas); + } + return mangaList; + } + async _getMangasFromPage(uri) { + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangas); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.text.trim() + }; + }); + } + async _getChapters(manga) { + const uri = new URL(manga.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryChapters); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.title.trim() + }; + }).reverse(); + } + async _getPages(chapter) { + const uri = new URL(chapter.id, this.url); + const script = ` + new Promise(resolve => { + resolve({ + img_pre : window.img_pre, img_data_arr : window.img_data_arr , img_host : window.img_host + }); + }); + `; + const request = new Request(uri); + const response = await Engine.Request.fetchUI(request, script); + let pagelist = []; + response.img_data_arr.forEach(image =>{ + pagelist.push(response.img_host+response.img_pre +image.img); + }); + return pagelist; + } +} \ No newline at end of file diff --git a/src/web/mjs/connectors/ManhwaManga.mjs b/src/web/mjs/connectors/ManhwaManga.mjs new file mode 100644 index 0000000000..9f11dca42c --- /dev/null +++ b/src/web/mjs/connectors/ManhwaManga.mjs @@ -0,0 +1,62 @@ +import Connector from '../engine/Connector.mjs'; +import Manga from '../engine/Manga.mjs'; +export default class ManhwaManga extends Connector { + constructor() { + super(); + super.id = 'manhwamanga'; + super.label = 'ManhwaManga'; + this.tags = [ 'manga', 'webtoon', 'english', 'hentai' ]; + this.url = 'https://manhwamanga.net'; + this.path = '/latest-updates'; + this.queryMangas = 'a.item-cover'; + this.queryMangasPagesCount = 'ul.pagination li:last-of-type a'; + this.queryChapters = 'div.episode-list div.main a'; + this.queryPages = 'div#viewer source[data-src]'; + this.queryMangaTitleURI = 'h1.item-title span'; + } + async _getMangaFromURI(uri) { + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangaTitleURI); + return new Manga(this, uri.pathname, data[0].textContent.trim()); + } + async _getMangas() { + let mangaList = []; + const uri = new URL(this.path, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangasPagesCount); + const pageCount = parseInt(data[0].getAttribute('data-page')); + for(let page = 1; page <= pageCount; page++) { + const mangas = await this._getMangasFromPage(page); + mangaList.push(...mangas); + } + return mangaList; + } + async _getMangasFromPage(page) { + const uri = new URL(this.path + '/page/'+ page, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangas); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.title.trim() + }; + }); + } + async _getChapters(manga) { + const uri = new URL(manga.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryChapters); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.querySelector('b').textContent.trim() + }; + }); + } + async _getPages(chapter) { + const uri = new URL(chapter.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryPages); + return data.map(image => this.getAbsolutePath(image.getAttribute('data-src'), request.url)); + } +} \ No newline at end of file diff --git a/src/web/mjs/connectors/NiceOppai.mjs b/src/web/mjs/connectors/NiceOppai.mjs new file mode 100644 index 0000000000..43a7b78953 --- /dev/null +++ b/src/web/mjs/connectors/NiceOppai.mjs @@ -0,0 +1,35 @@ +import WordPressLightPro from './templates/WordPressLightPro.mjs'; + +export default class NiceOppai extends WordPressLightPro { + + constructor() { + super(); + super.id = 'niceoppai'; + super.label ='NiceOppai'; + this.tags = ['manga', 'thai']; + this.url = 'https://www.niceoppai.net'; + this.path = '/manga_list/all/any/name-az/'; + this.queryMangas = 'div.mng_lst div.nde div.det a'; + this.queryChapters = 'div.mng_det ul.lst li a.lst'; + this.queryPages = 'div#image-container source'; + } + + async _getChaptersFromPage(manga, page) { + const request = new Request (new URL(this.url + manga.id+ 'chapter-list/' + page), this.requestOptions); + const data = await this.fetchDOM(request, this.queryChapters); + return data.map(element => { + return { + id: this.getRelativeLink( element ), + title: element.innerText.replace( manga.title, '' ).trim(), + language: this.language + }; + }); + } + + async _getPages(chapter) { + const uri = new URL(chapter.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryPages); + return data.map(image => this.getAbsolutePath(image, request.url)); + } +} \ No newline at end of file diff --git a/src/web/mjs/connectors/NovelMania.mjs b/src/web/mjs/connectors/NovelMania.mjs new file mode 100644 index 0000000000..4d20e9e317 --- /dev/null +++ b/src/web/mjs/connectors/NovelMania.mjs @@ -0,0 +1,102 @@ +import Connector from '../engine/Connector.mjs'; +import Manga from '../engine/Manga.mjs'; + +export default class NovelMania extends Connector { + + constructor() { + super(); + super.id = 'novelmania'; + super.label = 'NovelMania'; + this.tags = [ 'novel', 'portuguese' ]; + this.url = 'https://novelmania.com.br'; + this.novelFormat = 'image/png'; + this.novelWidth = '56em'; + // parseInt(1200 / window.devicePixelRatio) + 'px'; + this.novelPadding = '1.5em'; + } + + async _getMangaFromURI(uri) { + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, 'meta[property="og:title"]'); + return new Manga(this, uri.pathname, data[0].content.trim()); + } + + async _getMangas() { + let mangaList = []; + const uri = new URL('/novels', this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, 'ul.pagination li:nth-last-of-type(2) a'); + const pageCount = parseInt(data[0].text); + for(let page = 1; page <= pageCount; page++) { + const mangas = await this._getMangasFromPage(page); + mangaList.push(...mangas); + } + return mangaList; + } + + async _getMangasFromPage(page) { + const uri = new URL('/novels/?page=' + page, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, 'div.row.mb-2 a.novel.novel-title'); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.querySelector('h5').textContent.trim() + }; + }); + } + + async _getChapters(manga) { + const uri = new URL(manga.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, 'ol.list-inline li a'); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.querySelector('span').textContent.trim()+ ':'+element.querySelector('strong').textContent.trim() + }; + }).reverse(); + } + + async _getPages(chapter) { + const uri = new URL(chapter.id, this.url); + const request = new Request(uri, this.requestOptions); + let darkmode = Engine.Settings.NovelColorProfile(); + let script = ` + new Promise((resolve, reject) => { + document.body.style.width = '${this.novelWidth}'; + let container = document.querySelector('div.container'); + container.style.maxWidth = '${this.novelWidth}'; + container.style.padding = '0'; + container.style.margin = '0'; + let novel = document.querySelector('div#chapter-content'); + novel.style.padding = '${this.novelPadding}'; + [...novel.querySelectorAll(":not(:empty)")].forEach(ele => { + ele.style.backgroundColor = '${darkmode.background}' + ele.style.color = '${darkmode.text}' + }) + novel.style.backgroundColor = '${darkmode.background}'; + novel.style.color = '${darkmode.text}'; + let script = document.createElement('script'); + script.onerror = error => reject(error); + script.onload = async function() { + try { + let canvas = await html2canvas(novel); + let textimg = canvas.toDataURL('${this.novelFormat}'); + const picnodes = document.querySelectorAll('div#chapter-content img'); + let final = []; + final.push(textimg); + picnodes.forEach(element => final.push(element.src)); + resolve( final); + } catch (error){ + reject(error) + } + } + script.src = 'https://html2canvas.hertzen.com/dist/html2canvas.min.js'; + document.body.appendChild(script); + }); + `; + const response = await Engine.Request.fetchUI(request, script, 30000, true); + return response; + } +} \ No newline at end of file diff --git a/src/web/mjs/connectors/ProjectSuki.mjs b/src/web/mjs/connectors/ProjectSuki.mjs new file mode 100644 index 0000000000..c892598123 --- /dev/null +++ b/src/web/mjs/connectors/ProjectSuki.mjs @@ -0,0 +1,92 @@ +import Connector from '../engine/Connector.mjs'; +import Manga from '../engine/Manga.mjs'; + +export default class ProjectSuki extends Connector { + + constructor() { + super(); + super.id = 'projectsuki'; + super.label = 'ProjectSuki'; + this.tags = [ 'manga', 'webtoon', 'english' ]; + this.url = 'https://projectsuki.com'; + } + + async _getMangaFromURI(uri) { + const request = new Request(uri, this.requestOptions); + const id = uri.pathname + uri.search; + const title = (await this.fetchDOM(request, 'h2[itemprop="title"'))[0].textContent.trim(); + return new Manga(this, id, title); + } + + async _getMangas() { + let mangaList = []; + for (let page = 0, run = true; run; page++) { + const mangas = await this._getMangasFromPage(page); + mangas.length > 0 ? mangaList.push(...mangas) : run = false; + } + return mangaList; + } + + async _getMangasFromPage(page) { + const uri = new URL('/browse/' + page, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, 'a.inherit-color.p-1[aria-label]'); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.getAttribute('aria-label').trim() + }; + }); + } + + async _getChapters(manga) { + const uri = new URL(manga.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, 'td.col-5.col-sm-4.col-md-4.text-truncate > a'); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.textContent.trim(), + }; + }); + } + + async _getPages(chapter) { + const script = ` + new Promise((resolve, reject) => { + const xrequesto = function (element, url, data, method) + { + let xhr = new XMLHttpRequest(); + xhr.onload = function () { + if (xhr.status >= 200 && xhr.status < 300) + { + datar = JSON.parse(xhr.response); + element.insertAdjacentHTML('beforeend', datar['src']); + let images = [...document.querySelectorAll( 'img.img-fluid.center-block' )]; + resolve(images.map(image => image.src)); + } + else + { + throw Error('Cant get images :/ !'); + } + } + xhr.open(method, url); + xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); + xhr.send(data); + } + const xelement = document.querySelector('.strip-reader'); + const xbookid = window.location.href.split('/') [4]; + let xchapterid = window.location.href.split('/') [5]; + xrequesto(xelement, '/callpage', JSON.stringify({ + bookid: xbookid, + chapterid: xchapterid, + first: true + }) + , 'POST'); + }); + `; + const uri = new URL(chapter.id, this.url); + let request = new Request(uri, this.requestOptions); + return await Engine.Request.fetchUI(request, script); + } +} \ No newline at end of file diff --git a/src/web/mjs/connectors/TruyenVN.mjs b/src/web/mjs/connectors/TruyenVN.mjs new file mode 100644 index 0000000000..68dff64af8 --- /dev/null +++ b/src/web/mjs/connectors/TruyenVN.mjs @@ -0,0 +1,71 @@ +import Connector from '../engine/Connector.mjs'; +import Manga from '../engine/Manga.mjs'; +export default class TruyenVN extends Connector { + constructor() { + super(); + super.id = 'truyenvn'; + super.label = 'TruyenVN'; + this.tags = [ 'manga', 'webtoon', 'vietnamese', 'hentai' ]; + this.url = 'https://truyenvnpro.com'; + this.path = '/danh-sach-truyen'; + this.queryMangas = 'div.form-row div.entry > a'; + this.queryMangasPagesCount = 'div.z-pagination a:nth-last-child(2)'; + this.queryChapters = 'section#chapterList a'; + this.queryPages = 'div.content-text source[loading="lazy"]'; + this.queryMangaTitleURI = 'div.row h1.name'; + } + async _getMangaFromURI(uri) { + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangaTitleURI); + return new Manga(this, uri.pathname, data[0].textContent.trim()); + } + async _getMangas() { + let mangaList = []; + const uri = new URL(this.path, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangasPagesCount); + const pageCount = parseInt(data[0].text); + for(let page = 1; page <= pageCount; page++) { + const mangas = await this._getMangasFromPage(page); + mangaList.push(...mangas); + } + return mangaList; + } + async _getMangasFromPage(page) { + const uri = new URL(this.path + '/page/'+ page, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangas); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.title.trim() + }; + }); + } + async _getChapters(manga) { + const uri = new URL(manga.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryChapters); + return data.map(element => { + return { + id: this.getRootRelativeOrAbsoluteLink(element, this.url), + title: element.querySelector('span').textContent.trim() + }; + }); + } + async _getPages(chapter) { + const uri = new URL(chapter.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryPages); + return data.map(image => this.createConnectorURI(this.getAbsolutePath(image.src, request.url))); + } + async _handleConnectorURI(payload) { + let request = new Request(payload, this.requestOptions); + request.headers.set('x-referer', this.url); + let response = await fetch(request); + let data = await response.blob(); + data = await this._blobToBuffer(data); + this._applyRealMime(data); + return data; + } +} \ No newline at end of file diff --git a/src/web/mjs/connectors/templates/WordPressLightPro.mjs b/src/web/mjs/connectors/templates/WordPressLightPro.mjs index 3620de8aef..8669507f75 100644 --- a/src/web/mjs/connectors/templates/WordPressLightPro.mjs +++ b/src/web/mjs/connectors/templates/WordPressLightPro.mjs @@ -19,115 +19,61 @@ export default class WordPressLightPro extends Connector { this.language = ''; } - /** - * - */ - _getMangaListFromPages( mangaPageLinks, index ) { - index = index || 0; - return this.fetchDOM( mangaPageLinks[ index ], this.queryMangas, 5 ) - .then( data => { - let mangaList = data.map( element => { - return { - id: this.getRelativeLink( element ), - title: element.title.trim() || element.text.trim() - }; - } ); - if( index < mangaPageLinks.length - 1 ) { - return this._getMangaListFromPages( mangaPageLinks, index + 1 ) - .then( mangas => mangaList.concat( mangas ) ); - } else { - return Promise.resolve( mangaList ); - } - } ); + async _getMangas() { + const request = new Request (new URL(this.url + this.path), this.requestOptions); + const dom = await this.fetchDOM(request, 'body' ); + let pageCount = parseInt( dom[0].querySelector(this.queryMangasPageCount).href.match( /(\d+)\/$/ )[1] ); + let pagesList = []; + for (let i = 1; i <= pageCount; i++){ + pagesList.push(...await this._getMangasFromPage(i)); + } + return pagesList; } - /** - * - */ - _getMangaList( callback ) { - this.fetchDOM( this.url + this.path, this.queryMangasPageCount ) - .then( data => { - let pageCount = parseInt( data[0].href.match( /(\d+)\/$/ )[1] ); - let pageLinks = [... new Array( pageCount ).keys()].map( page => this.url + this.path + ( page + 1 ) + '/' ); - return this._getMangaListFromPages( pageLinks ); - } ) - .then( data => { - callback( null, data ); - } ) - .catch( error => { - console.error( error, this ); - callback( error, undefined ); - } ); + async _getMangasFromPage(page) { + const request = new Request (new URL(this.url + this.path + page), this.requestOptions); + const data = await this.fetchDOM(request, this.queryMangas); + return data.map(element => { + return { + id: this.getRelativeLink(element, this.url), + title: element.title.trim() || element.text.trim() + }; + }); } - /** - * - */ - _getChapterListFromPages( manga, chapterPageLinks, index ) { - index = index || 0; - return this.fetchDOM( chapterPageLinks[ index ], this.queryChapters, 5 ) - .then( data => { - let chapterList = data.map( element => { - let anchor = element.nodeName.toLowerCase() === 'a' ? element : element.closest( 'a' ); - return { - id: this.getRelativeLink( anchor ), - title: element.innerText.replace( manga.title, '' ).trim(), - language: this.language - }; - } ); - if( index < chapterPageLinks.length - 1 ) { - return this._getChapterListFromPages( manga, chapterPageLinks, index + 1 ) - .then( chapters => chapterList.concat( chapters ) ); - } else { - return Promise.resolve( chapterList ); - } - } ); - } + async _getChapters(manga) { + const uri = new URL(manga.id, this.url); + const request = new Request(uri, this.requestOptions); + let data = await this.fetchDOM(request, this.queryChaptersPageCount); + const pageCount = data.length === 0 ? 1 : parseInt( data[0].href.match( /(\d+)\/$/ )[1] ); + let pagesList = []; + for (let i = 1; i <= pageCount; i++){ + pagesList.push(...await this._getChaptersFromPage(manga, i)); + } + return pagesList; + } - /** - * - */ - _getChapterList( manga, callback ) { - this.fetchDOM( this.url + manga.id, this.queryChaptersPageCount ) - .then( data => { - let pageCount = data.length === 0 ? 1 : parseInt( data[0].href.match( /(\d+)\/$/ )[1] ); - let pageLinks = [... new Array( pageCount ).keys()].map( page => this.url + manga.id + 'chapters-list/' + ( page + 1 ) + '/' ); - pageLinks[0] = this.url + manga.id; - return this._getChapterListFromPages( manga, pageLinks ); - } ) - .then( data => { - callback( null, data ); - } ) - .catch( error => { - console.error( error, manga ); - callback( error, undefined ); - } ); + async _getChaptersFromPage(manga, page){ + const request = new Request (new URL(this.url + manga.id+ 'chapter-list/' + page), this.requestOptions); + const data = await this.fetchDOM(request, this.queryChapters); + return data.map(element => { + return { + id: this.getRelativeLink( element ), + title: element.innerText.replace( manga.title, '' ).trim(), + language: this.language + }; + }); } - /** - * - */ - _getPageList( manga, chapter, callback ) { - this.fetchDOM( this.url + chapter.id, this.queryPageLinks ) - .then( data => { - let pageList = data.map( element => this.createConnectorURI( this.url + chapter.id + element.value + '/' ) ); - callback( null, pageList ); - } ) - .catch( error => { - console.error( error, chapter ); - callback( error, undefined ); - } ); + async _getPages(chapter) { + const uri = new URL(chapter.id, this.url); + const request = new Request(uri, this.requestOptions); + const data = await this.fetchDOM(request, this.queryPageLinks ); + return data.map(element => this.createConnectorURI(this.url + chapter.id + element.value + '/')); } - /** - * - */ - _handleConnectorURI( payload ) { + async _handleConnectorURI( payload ) { let request = new Request( payload, this.requestOptions ); - /* - * TODO: only perform requests when from download manager - * or when from browser for preview and selected chapter matches - */ return this.fetchDOM( request, this.queryPages ) .then( data => { let span = document.createElement( 'span' ); @@ -137,4 +83,4 @@ export default class WordPressLightPro extends Connector { .then( response => response.blob() ) .then( data => this._blobToBuffer( data ) ); } -} \ No newline at end of file +}