From 3366f73d63de70bf9d3c0e5f5e3e381434742128 Mon Sep 17 00:00:00 2001 From: MikeZeDev Date: Tue, 1 Aug 2023 18:15:57 +0000 Subject: [PATCH] Sen/RawSenManga : fixes manga list and stuff (#5912) * Fixes https://github.com/manga-download/hakuneko/issues/5909 * Fixes https://github.com/manga-download/hakuneko/issues/5908 Please not that SenManga api gives errors whatever i do for manga listing. Better tell the user to use clipboard. --- src/web/mjs/connectors/RawSenManga.mjs | 22 ++++---- src/web/mjs/connectors/SenManga.mjs | 69 ++++++++++++++++++++------ 2 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/web/mjs/connectors/RawSenManga.mjs b/src/web/mjs/connectors/RawSenManga.mjs index 38efa728a7f..25bb7294f00 100644 --- a/src/web/mjs/connectors/RawSenManga.mjs +++ b/src/web/mjs/connectors/RawSenManga.mjs @@ -1,4 +1,5 @@ import Connector from '../engine/Connector.mjs'; +import Manga from '../engine/Manga.mjs'; export default class RawSenManga extends Connector { @@ -14,6 +15,13 @@ export default class RawSenManga extends Connector { this.requestOptions.headers.set('x-cookie', 'viewer=1'); } + async _getMangaFromURI(uri) { + const request = new Request(uri, this.requestOptions); + const id = uri.pathname; + const title = (await this.fetchDOM(request, 'div.desc h1.series'))[0].textContent.trim(); + return new Manga(this, id, title); + } + async _getMangas() { let mangaList = []; let request = new Request(this.url + '/directory', this.requestOptions); @@ -28,10 +36,10 @@ export default class RawSenManga extends Connector { async _getMangasFromPage(page) { let request = new Request(this.url + '/directory?page=' + page, this.requestOptions); - let data = await this.fetchDOM(request, 'div.content div.upd div.item > a'); + let data = await this.fetchDOM(request, 'div.content div.mng'); return data.map(element => { return { - id: this.getRootRelativeOrAbsoluteLink(element, this.url), + id: this.getRootRelativeOrAbsoluteLink(element.querySelector('a'), this.url), title: element.querySelector('div.series-title').textContent.trim() }; }); @@ -50,12 +58,8 @@ export default class RawSenManga extends Connector { } async _getPages(chapter) { - let script = ` - new Promise(resolve => { - resolve(imglist.map(img => img.url)); - }); - `; - let request = new Request(this.url + chapter.id, this.requestOptions); - return Engine.Request.fetchUI(request, script); + const request = new Request(this.url + chapter.id, this.requestOptions); + const data = await this.fetchDOM(request, 'div.reader source.picture'); + return data.filter(picture => !picture.src.includes('histats') ).map(picture => this.getRootRelativeOrAbsoluteLink(picture, this.url)); } } \ No newline at end of file diff --git a/src/web/mjs/connectors/SenManga.mjs b/src/web/mjs/connectors/SenManga.mjs index 5d1c1fc34f2..b8ff02127d3 100644 --- a/src/web/mjs/connectors/SenManga.mjs +++ b/src/web/mjs/connectors/SenManga.mjs @@ -1,31 +1,72 @@ import Connector from '../engine/Connector.mjs'; +import Manga from '../engine/Manga.mjs'; -/** - * - */ export default class SenManga extends Connector { - /** - * - */ constructor() { super(); super.id = 'senmanga'; super.label = 'SenManga'; - this.tags = []; - this.url = 'http://www.senmanga.com'; + this.tags = [ 'manga', 'multi-lingual']; + this.url = 'https://www.senmanga.com'; this.links = { login: 'https://www.senmanga.com/login' }; + this.requestOptions.headers.set('x-referer', this.url); + this.requestOptions.headers.set('x-origin', this.url); + + } + + get icon() { + return '/img/connectors/rawsenmanga'; } - _getMangaList( callback ) { - callback( new Error( 'Please report this broken website on HakuNeko\'s GitHub project page.' ), undefined ); + async _getMangaFromURI(uri) { + const id = uri.href.split('/').pop(); + const url = new URL('/api/title/' + id, this.url).href; + const request = new Request(url, this.requestOptions); + const data = await this.fetchJSON(request); + return new Manga(this, data.data.id, data.data.title.trim()); } - _getChapterList( manga, callback ) { - callback( new Error( 'Please report this broken website on HakuNeko\'s GitHub project page.' ), undefined ); + + async _getMangas() { + const mangalist = []; + for (let offset = 0, run = true; run; offset+= 60) { + const mangas = await this._getMangasFromPage(offset); + mangas.length > 0 ? mangalist.push(...mangas) : run = false; + await this.wait(500); + } + return mangalist; } - _getPageList( manga, chapter, callback ) { - callback( new Error( 'Please report this broken website on HakuNeko\'s GitHub project page.' ), undefined ); + + async _getMangasFromPage(offset) { + //note : website API is very broken, i got error 500 while browsing directory on a naked firefox + //cant fix that :/ + const url = new URL('/api/search?limit=60&offset=' + offset, this.url); + const request = new Request(url, this.requestOptions); + const data = await this.fetchJSON(request); + return data.success ? data.data.map(element => new Manga(this, element.id, element.title.trim())) : []; } + + async _getChapters(manga) { + const url = new URL('/api/title/' + manga.id +'/chapters', this.url).href; + const request = new Request(url, this.requestOptions); + const data = await this.fetchJSON(request); + return !data.success ? [] : data.data + .filter(element => element.externalUrl == null) //i.e english chapters are on Mangaplus + .map(element => { + return { + id: '/read/' + element.id, + title : element.full_title.trim() + ' (' + element.language.code + ')', + language : element.language.code + }; + }); + } + + async _getPages(chapter) { + const request = new Request(this.url + chapter.id, this.requestOptions); + return Engine.Request.fetchUI(request, '__NEXT_DATA__.props.pageProps.chapter.pageList.url'); + + } + } \ No newline at end of file