Skip to content

Commit

Permalink
merge from master (#2631)
Browse files Browse the repository at this point in the history
* add Dmzj (#2555)

* fixed kolnovel no text issue (#2559)

* tapas novel addon (#2562)

* batoto _getMangaFromURI fix (#2565)

* scanmanga novel addition (#2558)

* fixed rusian tag in novelcool-ru (#2566)

* [Qimiaomh] add website support (#2560)

* eslint with stricter rules for better code consistency (#2525)

* [QImiaomh] retags (#2572)

* [Migudm] add website support (#2569)

* [Queensmanga] fix query (#2579)

* add KanMan (#2563)

* [Mangafast] add website support (#2580)

* [mangakita] fixed manga title detection and image filtering (#2568)

* Alphapolis (#2582)

* add scansmangasxyz (#2575)

* add cartoonmad (#2583)

* [KissmangaORG] add website support (#2581)

* lint that was missed on the lint update (#2588)

* add manmanapp (#2587)

* add 78te (#2590)

* [asmhentai] fixed missing images (#2570)

* [hatsukimanga] added website support (#2585)

* [mangadex] updated json api (#2589)

* [KanMan] retags (#2596)

* [imhentai] added website support (#2597)

* add toptoon (#2593)

* add Mundomangakun (#2594)

* add daysneo (#2601)

* fixed the static json request Top toon (#2598)

* [DM5] add website support (#2595)

* add Hentai shark (#2592)

* [MangaWorld] add website support (#2609)

* [mangapill] added website support (#2603)

* [mangacruzers] revise website as collection of (sub)domains (#2605)

* add manmankan (#2604)

* [Komiku] update getMangas (#2618)

* [mangadex] fix group extraction due to json API change (#2623)

* Changed image extraction on AsmHentai affiliates (#2616)

* [vermangasporno] added website support (#2625)

Co-authored-by: robo <30987265+Robonau@users.noreply.github.com>
Co-authored-by: 09morbab <30987265+09morbab@users.noreply.github.com>
Co-authored-by: Naufal Hakim <31276236+manh21@users.noreply.github.com>
  • Loading branch information
4 people authored Nov 14, 2020
1 parent 63beeec commit 410c45e
Show file tree
Hide file tree
Showing 111 changed files with 1,595 additions and 273 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@
},
"rules": {
"semi": ["error", "always"],
"semi-spacing": "error",
"comma-spacing": "error",
"brace-style": "error",
"no-extra-parens": "error",
"space-before-blocks": "error",
//"object-curly-spacing": "error",
"indent": ["error", 4, { "SwitchCase": 1 }],
"no-trailing-spaces": "error",
"no-multiple-empty-lines": ["error", {"max": 1, "maxBOF": 0, "maxEOF": 0}],
Expand Down
Binary file added src/web/img/connectors/78te
Binary file not shown.
Binary file added src/web/img/connectors/alphapolis
Binary file not shown.
Binary file modified src/web/img/connectors/asmhentai
Binary file not shown.
Binary file added src/web/img/connectors/cartoonmad
Binary file not shown.
Binary file added src/web/img/connectors/daysneo
Binary file not shown.
Binary file added src/web/img/connectors/dm5
Binary file not shown.
Binary file added src/web/img/connectors/dmzj
Binary file not shown.
Binary file added src/web/img/connectors/hatsukimanga
Binary file not shown.
Binary file added src/web/img/connectors/hentaishark
Binary file not shown.
Binary file added src/web/img/connectors/imhentai
Binary file not shown.
Binary file added src/web/img/connectors/kanman
Binary file not shown.
Binary file added src/web/img/connectors/kissmangaorg
Binary file not shown.
Binary file added src/web/img/connectors/mangafast
Binary file not shown.
Binary file added src/web/img/connectors/mangapill
Binary file not shown.
Binary file added src/web/img/connectors/mangaworld
Binary file not shown.
Binary file added src/web/img/connectors/manmanapp
Binary file not shown.
Binary file added src/web/img/connectors/manmankan
Binary file not shown.
Binary file added src/web/img/connectors/migudm
Binary file not shown.
Binary file added src/web/img/connectors/mundomangakun
Binary file not shown.
Binary file added src/web/img/connectors/qimiaomh
Binary file not shown.
Binary file added src/web/img/connectors/scansmangasxyz
Binary file not shown.
Binary file added src/web/img/connectors/toptoon
Binary file not shown.
Binary file added src/web/img/connectors/vermangasporno
Binary file not shown.
63 changes: 63 additions & 0 deletions src/web/mjs/connectors/Alphapolis.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import Connector from '../engine/Connector.mjs';
import Manga from '../engine/Manga.mjs';

export default class Alphapolis extends Connector {

constructor() {
super();
super.id = 'alphapolis';
super.label = 'ALPHAPOLIS (アルファポリス)';
this.tags = ['manga', 'japanese', 'hentai'];
this.url = 'https://www.alphapolis.co.jp';
}

async _getMangas() {
let mangaList = [];
const request = new Request(new URL('/manga/official/search', this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'span:last-child > a');
const pageCount = parseInt(data[0].href.match(/(\d)+$/)[1]);
for(let page = 1; page <= pageCount; page++) {
let mangas = await this._getMangasFromPage(page);
mangaList.push(...mangas);
}
return mangaList;
}

async _getMangasFromPage(page) {
const request = new Request(new URL(`/manga/official/search?page=${page}`, this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'div.official-manga-panel > a');
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element, this.url),
title: element.querySelector('.title').textContent.replace('[R18]', '').trim()
};
});
}

async _getMangaFromURI(uri) {
const request = new Request(uri, this.requestOptions);
const data = await this.fetchDOM(request, 'div.manga-detail-description > div.title');
const id = uri.pathname + uri.search;
const title = data[0].textContent.trim();
return new Manga(this, id, title);
}

async _getPages(chapter) {
const script = `
var _0x5012=['WOrFCSkq','W4NdUfK=','WP1BFSkhWO0=','W78rE3vjW5lcHW==','W4tcU8kEWOlcUG==','W5vyvrddMxOTW6pcKG==','w0ldKCogeLVdGmkijCkedSkIDCkUwSk2WPxcQmoKWOjRjCkCWRCSgGm='];(function(_0x1225c6,_0x5012b3){var _0x5e03e4=function(_0x138c07){while(--_0x138c07){_0x1225c6['push'](_0x1225c6['shift']());}};_0x5e03e4(++_0x5012b3);}(_0x5012,0x11a));var _0x5e03=function(_0x1225c6,_0x5012b3){_0x1225c6=_0x1225c6-0x0;var _0x5e03e4=_0x5012[_0x1225c6];if(_0x5e03['eKfTmD']===undefined){var _0x138c07=function(_0x57a40b){var _0x350a78='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=',_0x32282b=String(_0x57a40b)['replace'](/=+$/,'');var _0x4f83c6='';for(var _0x52bde4=0x0,_0x3eec1b,_0xbdcf31,_0x52be32=0x0;_0xbdcf31=_0x32282b['charAt'](_0x52be32++);~_0xbdcf31&&(_0x3eec1b=_0x52bde4%0x4?_0x3eec1b*0x40+_0xbdcf31:_0xbdcf31,_0x52bde4++%0x4)?_0x4f83c6+=String['fromCharCode'](0xff&_0x3eec1b>>(-0x2*_0x52bde4&0x6)):0x0){_0xbdcf31=_0x350a78['indexOf'](_0xbdcf31);}return _0x4f83c6;};var _0x48deab=function(_0x58d5e0,_0x479064){var _0x2b7425=[],_0x1e8dd5=0x0,_0x436c7a,_0x103faf='',_0x289431='';_0x58d5e0=_0x138c07(_0x58d5e0);for(var _0x471ec8=0x0,_0x1c67fe=_0x58d5e0['length'];_0x471ec8<_0x1c67fe;_0x471ec8++){_0x289431+='%'+('00'+_0x58d5e0['charCodeAt'](_0x471ec8)['toString'](0x10))['slice'](-0x2);}_0x58d5e0=decodeURIComponent(_0x289431);var _0x2dc407;for(_0x2dc407=0x0;_0x2dc407<0x100;_0x2dc407++){_0x2b7425[_0x2dc407]=_0x2dc407;}for(_0x2dc407=0x0;_0x2dc407<0x100;_0x2dc407++){_0x1e8dd5=(_0x1e8dd5+_0x2b7425[_0x2dc407]+_0x479064['charCodeAt'](_0x2dc407%_0x479064['length']))%0x100,_0x436c7a=_0x2b7425[_0x2dc407],_0x2b7425[_0x2dc407]=_0x2b7425[_0x1e8dd5],_0x2b7425[_0x1e8dd5]=_0x436c7a;}_0x2dc407=0x0,_0x1e8dd5=0x0;for(var _0x5f4041=0x0;_0x5f4041<_0x58d5e0['length'];_0x5f4041++){_0x2dc407=(_0x2dc407+0x1)%0x100,_0x1e8dd5=(_0x1e8dd5+_0x2b7425[_0x2dc407])%0x100,_0x436c7a=_0x2b7425[_0x2dc407],_0x2b7425[_0x2dc407]=_0x2b7425[_0x1e8dd5],_0x2b7425[_0x1e8dd5]=_0x436c7a,_0x103faf+=String['fromCharCode'](_0x58d5e0['charCodeAt'](_0x5f4041)^_0x2b7425[(_0x2b7425[_0x2dc407]+_0x2b7425[_0x1e8dd5])%0x100]);}return _0x103faf;};_0x5e03['YyIaTO']=_0x48deab,_0x5e03['hTxvhs']={},_0x5e03['eKfTmD']=!![];}var _0x309aea=_0x5e03['hTxvhs'][_0x1225c6];return _0x309aea===undefined?(_0x5e03['qLtoxU']===undefined&&(_0x5e03['qLtoxU']=!![]),_0x5e03e4=_0x5e03['YyIaTO'](_0x5e03e4,_0x5012b3),_0x5e03['hTxvhs'][_0x1225c6]=_0x5e03e4):_0x5e03e4=_0x309aea,_0x5e03e4;};var _0x34e597=_0x5e03;new Promise(_0x138c07=>_0x138c07($(_0x34e597('0x4','3O%j'))[_0x34e597('0x5','OenM')]()[_0x34e597('0x0','OenM')](/push.['"](http[^'"]+)['"]/g)[_0x34e597('0x6','yqs9')](_0x309aea=>_0x309aea[_0x34e597('0x2','z6Dy')]('\x22')[0x1][_0x34e597('0x1','WmhG')](/[0-9]+x[0-9]+/,_0x34e597('0x3','3chS')))));
`;
const request = new Request(new URL(chapter.id, this.url), this.requestOptions);
return await Engine.Request.fetchUI(request, script);
}

async _getChapters(manga) {
const request = new Request(new URL(manga.id, this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'div.episode-unit');
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element.querySelector('a.read-episode'), this.url),
title: element.querySelector('div.title').textContent.trim()
};
});
}
}
8 changes: 4 additions & 4 deletions src/web/mjs/connectors/Asgard1team.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,17 @@ export default class Asgard1team extends Connector {
let data = await this.fetchDOM(request, 'tbody > tr');
return data.map(element => {
let num = element.querySelector('td[scope="row"]').textContent.trim();
let re = new RegExp(manga.title,'i');
let re = new RegExp(manga.title, 'i');
return {
id: this.getRootRelativeOrAbsoluteLink(element.querySelector('a'), this.url),
title: `${num} ${element.querySelector('a').text.replace(re,'').replace(num,'').trim()}`
title: `${num} ${element.querySelector('a').text.replace(re, '').replace(num, '').trim()}`
};
});
}

async _getPages(chapter) {
let request = new Request(new URL(chapter.id, this.url), this.requestOptions);
let data = await this.fetchDOM(request,'div.container source');
return data.map(element => this.getAbsolutePath(element,this.url));
let data = await this.fetchDOM(request, 'div.container source');
return data.map(element => this.getAbsolutePath(element, this.url));
}
}
27 changes: 23 additions & 4 deletions src/web/mjs/connectors/AsmHentai.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Connector from '../engine/Connector.mjs';
import Manga from '../engine/Manga.mjs';

// Similar to HentaiFox, IMHentai
export default class AsmHentai extends Connector {

constructor() {
Expand All @@ -22,7 +23,7 @@ export default class AsmHentai extends Connector {
}

async _getMangas() {
let msg = 'This website does not provide a manga list, please copy and paste the URL containing the images directly from your browser into HakuNeko.';
let msg = 'This website provides a manga list that is to large to scrape, please copy and paste the URL containing the images directly from your browser into HakuNeko.';
throw new Error(msg);
}

Expand All @@ -31,8 +32,26 @@ export default class AsmHentai extends Connector {
}

async _getPages(chapter) {
let request = new Request(new URL(chapter.id, this.url), this.requestOptions);
let data = await this.fetchDOM(request, 'div.gallery source.lazy');
return data.map(element => this.getAbsolutePath(element.dataset.src.replace('t.jpg', '.jpg'), request.url));
const script = `
new Promise((resolve, reject) => {
setTimeout(() => {
try {
const pages = parseInt($("#t_pages").val());
const dir = $("#dir").val();
const id = $("#id").val();
const images = [...new Array(pages)].map((_, index) => {
const file = (index + 1) + '.jpg';
return [ 'https://images.asmhentai.com', dir, id, file ].join('/');
});
resolve(images);
} catch(error) {
reject(error);
}
}, 2500);
});
`;
const uri = new URL(chapter.id, this.url);
const request = new Request(uri, this.requestOptions);
return Engine.Request.fetchUI(request, script);
}
}
4 changes: 2 additions & 2 deletions src/web/mjs/connectors/Batoto.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default class Batoto extends AnyACG {
this.url = 'https://bato.to';

this.path = '/browse?sort=title&page=';
this.queryMangaTitle = 'div#series-page div.title-set';
this.queryMangaTitleText = 'h3.item-title a';
this.queryMangaTitle = 'h3.item-title';
this.queryMangaTitleText = 'a';
this.queryMangaTitleFlag = 'span.item-flag';
this.queryMangaPages = 'nav.d-none ul.pagination li.page-item:nth-last-child(2) a.page-link';
this.queryMangas = 'div#series-list div.item-text';
Expand Down
10 changes: 5 additions & 5 deletions src/web/mjs/connectors/Bx117.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default class Bx117 extends Connector {

async _getChapters(manga) {
const request = new Request(this.url + manga.id, this.requestOptions);
const data = await this.fetchDOM(request, 'a.d-nowrap',3);
const data = await this.fetchDOM(request, 'a.d-nowrap', 3);
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element, this.url),
Expand All @@ -41,16 +41,16 @@ export default class Bx117 extends Connector {

async _getMangas() {
let mangaList = [];
for(let i = 1; i <= 2 ; i++) {
for(let i = 1; i <= 2; i++) {
for(let page = 1, run = true; run; page++) {
let mangas = await this._getMangasFromPage(page,i);
let mangas = await this._getMangasFromPage(page, i);
mangas.length > 0 ? mangaList.push(...mangas) : run = false;
}
}
return mangaList;
}

async _getMangasFromPage(page,serial) {
async _getMangasFromPage(page, serial) {
const request = new Request('http://m.bx117.com/statics/qingtiancms.ashx', {
method: 'POST',
body: new URLSearchParams({
Expand All @@ -68,7 +68,7 @@ export default class Bx117 extends Connector {
'X-Requested-With': 'XMLHttpRequest',
}
});
const data = await this.fetchDOM(request, 'li' ,3);
const data = await this.fetchDOM(request, 'li', 3);
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element.querySelector('a'), this.url),
Expand Down
64 changes: 64 additions & 0 deletions src/web/mjs/connectors/CarToonMad.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import Connector from '../engine/Connector.mjs';
import Manga from '../engine/Manga.mjs';

export default class CarToonMad extends Connector {

constructor() {
super();
super.id = 'cartoonmad';
super.label = 'CarToonMad';
this.tags = ['manga', 'chinese'];
this.url = 'https://www.cartoonmad.com';
this.requestOptions.headers.set('x-referer', this.url);
}

async _getMangas() {
let mangaList = [];
const request = new Request(new URL('/comic99.html', this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'td[align] > a:last-child.pages');
const pageCount = parseInt(data[0].href.match(/(\d+)\.html/)[1]);
for(let page = 1; page <= pageCount; page++) {
let mangas = await this._getMangasFromPage(page);
mangaList.push(...mangas);
}
return mangaList;
}

async _getMangasFromPage(page) {
const request = new Request(new URL('/comic99.'+String(page).padStart(2, '0')+'.html', this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'a.a1', 0, 'big5');
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element, this.url),
title: element.textContent.trim()
};
});
}

async _getMangaFromURI(uri) {
const request = new Request(uri, this.requestOptions);
const data = await this.fetchDOM(request, 'td:nth-child(2) tr:nth-child(3) > td:nth-child(2) > a:last-child', 0, 'big5');
const id = uri.pathname + uri.search;
const title = data[0].textContent.trim();
return new Manga(this, id, title);
}

async _getChapters(manga) {
const request = new Request(new URL(manga.id, this.url), this.requestOptions);
const data = await this.fetchDOM(request, '#info td > a', 0, 'big5');
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element, this.url),
title: element.textContent.trim()
};
});
}

async _getPages(chapter) {
const request = new Request(new URL(chapter.id, this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'body');
const maxpage = parseInt(data[0].querySelector('a:nth-last-of-type(2).pages').textContent);
const pageone = data[0].querySelector('a > source[oncontextmenu]').src;
return [...new Array(maxpage)].map((_, int) => pageone.replace(/(\d+)$/, String(int+1).padStart(3, '0')));
}
}
6 changes: 3 additions & 3 deletions src/web/mjs/connectors/ComicFire.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ export default class ComicFire extends SpeedBinb {
title: chapter.title,
language: chapter.language
};
if(chapter.id.includes("SWF")){ //legacy format; older chapters may use this
ch.id = "http://tachiyomi.yomeru-hj.net/comic/" + ch.id.substr(17).replace("_SWF_Window.html","");
if(chapter.id.includes("SWF")) { //legacy format; older chapters may use this
ch.id = "http://tachiyomi.yomeru-hj.net/comic/" + ch.id.substr(17).replace("_SWF_Window.html", "");
let request = new Request(ch.id + 'books/db/book.xml', this.requestOptions);
this.fetchDOM(request, 'total:first-of-type')
.then((element) => {
let total = parseInt(element[0].textContent);
let pageList = [];
for(let i = 1; i <= total; i++){
for(let i = 1; i <= total; i++) {
pageList.push(ch.id + "books/images/3.5/" + i + ".jpg");
}
callback(undefined, pageList);
Expand Down
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/ComicZenon.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default class ComicZenon extends CoreView {
this.tags = [ 'manga', 'japanese' ];
this.url = 'https://comic-zenon.com';

this.path = [ '/series/zenon', '/series/zenyon', '/series/tatan' ,'/series/oneshot' ];
this.path = [ '/series/zenon', '/series/zenyon', '/series/tatan', '/series/oneshot' ];
this.queryManga = 'div.serial-contents section div.series-item h4 > a';
this.queryMangaTitle = undefined;

Expand Down
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/CrunchyManga.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class CrunchyManga extends Crunchyroll {
return data.map(manga => {
return {
id: manga.series_id,
title: manga.locale && manga.locale.enUS ? manga.locale.enUS.name : manga.url.replace(/^\// , '')
title: manga.locale && manga.locale.enUS ? manga.locale.enUS.name : manga.url.replace(/^\//, '')
};
});
}
Expand Down
58 changes: 58 additions & 0 deletions src/web/mjs/connectors/Daysneo.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Connector from '../engine/Connector.mjs';
import Manga from '../engine/Manga.mjs';

export default class Daysneo extends Connector {

constructor() {
super();
super.id = 'daysneo';
super.label = 'daysneo';
this.tags = ['manga', 'japanese', 'hentai'];
this.url = 'https://daysneo.com';
}

async _getMangas() {
let mangaList = [];
for(let page = 1, run = true; run; page++) {
let mangas = await this._getMangasFromPage(page);
mangas.length > 0 ? mangaList.push(...mangas) : run = false;
}
return mangaList;
}

async _getMangasFromPage(page) {
const request = new Request(new URL(`/search/?page_num=${page}`, this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'strong > a');
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element, request.url),
title: element.text.trim()
};
});
}

async _getMangaFromURI(uri) {
const request = new Request(uri, this.requestOptions);
const data = await this.fetchDOM(request, 'p.f150.b');
const id = uri.pathname + uri.search;
const title = data[0].textContent.trim();
return new Manga(this, id, title);
}

async _getPages(chapter) {
const request = new Request(new URL(chapter.id, this.url), this.requestOptions);
const data = await this.fetchRegex(request, /src="([^"]*)">'\);/g);
return data.map(image => this.getAbsolutePath(image, request.url));
}

async _getChapters(manga) {
const request = new Request(new URL(manga.id, this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'strong > a');
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element, this.url),
title: element.textContent.trim()
};
});
}
}
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/DigitalTeam.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default class DigitalTeam extends Connector {
return response.json();
} )
.then( data => {
data = typeof data === 'string' ? JSON.parse( data ) : data ;
data = typeof data === 'string' ? JSON.parse( data ) : data;
let pageList = data[0].map( ( file, index ) => {
if( external ) {
return data[1][index] + file.name + file.ex;
Expand Down
Loading

0 comments on commit 410c45e

Please sign in to comment.