Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge nightly stable #7742

Merged
merged 54 commits into from
Feb 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f080517
Siyahmelek: change domain (#7294)
MikeZeDev Jul 30, 2024
94ed443
Fix lint on Siyahmelek.mjs (#7296)
MikeZeDev Jul 31, 2024
ae81ff3
PixivComics: change endpoint & update hash algo (#7298)
MikeZeDev Jul 31, 2024
458ca1a
add connector mikoroku (#7219)
akn19 Jul 31, 2024
f4731ad
CuuTruyen (#7307)
beer-psi Aug 6, 2024
0233a42
Ngomik: change domain (#7308)
MikeZeDev Aug 8, 2024
c57d57a
FIx GourmetScans: fix getting pages (#7324)
MikeZeDev Aug 12, 2024
b94c858
RuyaManga : cahnge domain (#7323)
MikeZeDev Aug 12, 2024
6e87e11
MoreNovel : change domain (#7315)
MikeZeDev Aug 12, 2024
8276c1b
Domains updates (#7328)
MikeZeDev Aug 15, 2024
ea13f3e
TempestScans: change domain (#7333)
MikeZeDev Aug 28, 2024
e4ff2d6
feat(RadiantScans): add connector (#7384)
TristanWasTaken Sep 4, 2024
6c5495d
Desu : use referrer to download images (#7352)
MikeZeDev Sep 7, 2024
9449d2e
IrisScanlator: change Domain (#7347)
MikeZeDev Sep 7, 2024
f605bd0
GriMelek change domain (#7370)
MikeZeDev Sep 7, 2024
fb4b2ea
Welovemanga.one : fix getting image (#7373)
MikeZeDev Sep 7, 2024
f131c6e
Update SushiScans.mjs (#7388)
aboudiom59 Sep 10, 2024
ffa9ad8
PixivComics : change salt (#7394)
MikeZeDev Sep 15, 2024
1dff65e
TruyenQQ : change domain (#7392)
MikeZeDev Sep 15, 2024
56cd39f
PixivComics: change salt again (#7397)
MikeZeDev Sep 17, 2024
02ad257
MangaTale : change domain (#7399)
MikeZeDev Sep 21, 2024
96fad7a
PixivComics : get salt from chapter JSON (#7402)
MikeZeDev Sep 24, 2024
df53a2c
KomikIndo: change domain (#7420)
MikeZeDev Sep 24, 2024
aecdff5
TenshiID: change domain (#7432)
MikeZeDev Sep 27, 2024
c411654
Rackus (PMScans) : change domain (#7436)
MikeZeDev Oct 5, 2024
b28af44
SamuraiScan: domain change (#7459)
MikeZeDev Oct 6, 2024
2ac9298
feat(Iken, VortexScans, MangaGalaxy): add Iken template (#7462)
TristanWasTaken Oct 9, 2024
b59d3f5
TukangKomik: update domain (#7486)
MikeZeDev Oct 17, 2024
9c5dd11
MangaSwat: change domain (#7500)
MikeZeDev Oct 19, 2024
84a6f23
fix lints (#7505)
noname2noname Oct 19, 2024
278e6ba
fix title fetch and image fetch in hitomi (#7504)
noname2noname Oct 19, 2024
83ea5c3
AllHentai: change domain (#7502)
MikeZeDev Oct 19, 2024
cf0e314
AresManga: change domain (#7501)
MikeZeDev Oct 19, 2024
fd02dd9
OlympusScanlation: change domain (#7506)
MikeZeDev Oct 20, 2024
234e970
update domains (#7507)
MikeZeDev Oct 20, 2024
18fdb27
Miauscan: change domain (#7520)
MikeZeDev Oct 26, 2024
ca08fa4
TenshiID: update domain (#7529)
MikeZeDev Oct 30, 2024
6553ec1
Add imperiodabritannia Connector (#7551)
Lapot300 Nov 15, 2024
c3d9330
LikeManga : change domain (#7556)
MikeZeDev Nov 20, 2024
f5452a9
WebtoonHatti : change domain (#7572)
MikeZeDev Nov 30, 2024
277b991
TCBScans: domain change (#7576)
MikeZeDev Dec 4, 2024
3a5b802
BacaKomik: change domain (#7628)
MikeZeDev Dec 27, 2024
82415b4
ComicBoost: fix getting pages (#7655)
MikeZeDev Jan 8, 2025
501fd6e
WebtoonHatti: change domain (#7634)
MikeZeDev Jan 8, 2025
174a5bc
Desu : update domain (#7665)
MikeZeDev Jan 14, 2025
f80cc06
Komiku: fix getting pages (#7667)
MikeZeDev Jan 18, 2025
2e63532
Update Issue Templates (#7717)
manga-download-owner Feb 2, 2025
c1af026
Manhuaga : Madara to MangaStream (#7701)
MikeZeDev Feb 2, 2025
39aa13c
Grimelel : change domain (#7689)
MikeZeDev Feb 2, 2025
a43172b
Add Weeb Central connector/website (#7720)
kiseki999 Feb 3, 2025
4c15671
Yurineko: update domain (#7725)
MikeZeDev Feb 5, 2025
f3d35df
MeioNovel: change domain (#7721)
MikeZeDev Feb 5, 2025
1d1df00
Adding TernoScans and ErosScan (#7658)
Bazket571 Feb 8, 2025
8d14ce6
Hivetoon: Change template (#7731)
MikeZeDev Feb 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/ISSUE_TEMPLATE/1-connector-website-not-working.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ description: Notify that a connector is not working
title: "[<NameOfConnector>] Connector not working"
labels: ["Website Change"]
body:
- type: markdown
attributes:
value: |
> [!CAUTION]
> Do **NOT** report that **MangaLife** or **MangaSee** moved to **WeebCentral**, it will not be fixed!
> See: [#7407](https://github.com/manga-download/hakuneko/issues/7407) for info.
- type: checkboxes
attributes:
label: Is there an existing issue for this connector?
Expand Down
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/2-suggest-a-new-connector-website.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: ✍ Suggest a new Connector/Website
about: Want a new website to be added in hakuneko ?
title: "[Site Request] thewebsitename"
labels: Website Suggestion
assignees: ''

---

> [!CAUTION]
> Do **NOT** request **WeebCentral**, it will not be added!
> See: [#7407](https://github.com/manga-download/hakuneko/issues/7407) for info.

**Name of the website**
thewebsitename

**Website urls (examples below)**
- Site: https://thewebsiteurl/
- Manga List: https://thewebsiteurl/mangalist.html
- Manga example: https://thewebsiteurl/manga/themanganame.html
- Chapter online viewer example: https://thewebsiteurl/manga/0012/view.html

**Languages**
List of languages supported by the website

**Website relationship*
If applicable describe the relation with any other website (eg : "alternative domain, copy of ...").

**Additional details**
Add any other context details that you may have found (like template to reuse)
Binary file added src/web/img/connectors/cuutruyen
Binary file not shown.
Binary file added src/web/img/connectors/erosscans
Binary file not shown.
Binary file added src/web/img/connectors/imperiodabritannia
Binary file not shown.
Binary file added src/web/img/connectors/mangagalaxy
Binary file not shown.
Binary file added src/web/img/connectors/mikoroku
Binary file not shown.
Binary file modified src/web/img/connectors/tecnoscan
Binary file not shown.
Binary file modified src/web/img/connectors/vortexscans
Binary file not shown.
Binary file added src/web/img/connectors/weebcentral
Binary file not shown.
4 changes: 2 additions & 2 deletions src/web/mjs/connectors/AllHentai.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export default class AllHentai extends Connector {
super.id = 'allhentai';
super.label = 'AllHentai';
this.tags = ['hentai', 'russian'];
this.url = 'https://20.allhen.online';
this.url = 'https://z.ahen.me';
this.links = {
login: 'https://20.allhen.online/internal/auth'
login: 'https://z.ahen.me/internal/auth'
};
this.config = {
throttle: {
Expand Down
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/AresManga.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default class AresManga extends WordPressMangastream {
super.id = 'aresmanga';
super.label = 'Ares Manga';
this.tags = ['webtoon', 'arabic'];
this.url = 'https://aresnov.org';
this.url = 'https://fl-ares.com';
this.path = '/series/list-mode/';
}
}
8 changes: 4 additions & 4 deletions src/web/mjs/connectors/BacaKomik.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export default class BacaKomik extends WordPressMangastream {
super.id = 'bacakomik';
super.label = 'BacaKomik';
this.tags = [ 'manga', 'indonesian' ];
this.url = 'https://bacakomik.co';
this.path = '/daftar-manga/?list';
this.url = 'https://bacakomik.one';
this.path = '/daftar-komik/?list';

this.queryMangas = 'div.cpp div.daftarkartun div.jdlbar ul li a.tip';
this.queryChapters = 'div.eps_lst ul li span.lchx a';
this.queryChaptersTitle = undefined;
this.queryPages = 'div.chapter-area div.chapter-content div.chapter-image img';
this.queryPages = 'div#anjay_ini_id_kh img';
}
}
}
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/BacaMangaOrg.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default class BacaMangaOrg extends WordPressMangastream {
super.id = 'bacamangaorg';
super.label = 'MangaTale';
this.tags = ['manga', 'webtoon', 'indonesian'];
this.url = 'https://mangatale.co';
this.url = 'https://mangatale.id';
this.path = '/manga/list-mode/';
}
}
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/ComicBoost.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export default class ComicBoost extends Connector {
if (fileinfos.BlockHeight) //if we have a block size for the page, its a puzzle !
{
mode = 'puzzle';
blocks = window.NFBR.a6G.a5x.prototype.g8w(fPage, fPage.width, fPage.height)
blocks = window.NFBR.a6G.a5x.prototype.C5X(fPage, fPage.width, fPage.height)
}

return {
Expand Down
135 changes: 135 additions & 0 deletions src/web/mjs/connectors/CuuTruyen.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import Connector from '../engine/Connector.mjs';
import Manga from '../engine/Manga.mjs';

export default class CuuTruyen extends Connector {
constructor() {
super();
super.id = 'cuutruyen';
super.label = 'Cứu Truyện';
this.tags = ['manga', 'vietnamese'];
this.url = 'https://cuutruyen.net';
}

async _getMangaFromURI(uri) {
const mangaid = uri.href.match(/\/mangas\/([0-9]+)/)[1];
const req = new URL(`/api/v2/mangas/${mangaid}`, this.url);
const request = new Request(req, this.requestOptions);
const { data: { name } } = await this.fetchJSON(request);
return new Manga(this, mangaid, name.trim());
}

async _getMangas() {
const uri = new URL('/api/v2/mangas/recently_updated?page=1&per_page=30', this.url);
const request = new Request(uri, this.requestOptions);
const data = await this.fetchJSON(request);
const pages = data._metadata.total_pages;

const mangaList = this._getMangasFromPage(data);

for (let page = 2; page <= pages; page++) {
const uri = new URL(`/api/v2/mangas/recently_updated?page=${page}&per_page=30`, this.url);
const request = new Request(uri, this.requestOptions);
const data = await this.fetchJSON(request);
const mangas = this._getMangasFromPage(data);
mangaList.push(...mangas);
}
return mangaList;
}

_getMangasFromPage(data) {
return data.data.map((c) => ({
id: c.id,
title: c.name.trim(),
}));
}

async _getChapters(manga) {
const uri = new URL(`/api/v2/mangas/${manga.id}/chapters`, this.url);
const request = new Request(uri, this.requestOptions);
const { data } = await this.fetchJSON(request);
return data
.filter((chapter) => chapter.status === 'processed')
.map((chapter) => {
let title = `Chapter ${chapter.number}`;

if (chapter.name) {
title += `: ${chapter.name}`;
}

return { id: chapter.id, title };
});
}

async _getPages(chapter) {
const uri = new URL('/api/v2/chapters/' + chapter.id, this.url);
const request = new Request(uri, this.requestOptions);
const { data: { pages } } = await this.fetchJSON(request);

if (pages.some((image) => image.status !== 'processed')) {
throw new Error('This chapter is still processing, please try again later.');
}

return pages.map((image) => {
return this.createConnectorURI({
url: image.image_url,
drmData: image.drm_data,
});
});
}

async _handleConnectorURI(payload) {
const response = await fetch(payload.url, {
cache: 'no-cache',
referrer: `${this.url}/`,
headers: {
'accept': 'image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5',
},
});

if (!payload.drmData) {
return this._blobToBuffer(await response.blob());
}

const decryptedDrmData = this.decodeXorCipher(atob(payload.drmData), '3141592653589793');

if (!decryptedDrmData.startsWith('#v4|')) {
throw new Error(`Invalid DRM data (does not start with magic bytes): ${decryptedDrmData}`);
}

const image = await createImageBitmap(await response.blob());
const canvas = document.createElement('canvas');

canvas.width = image.width;
canvas.height = image.height;

const ctx = canvas.getContext('2d');
let sy = 0;

for (const t of decryptedDrmData.split('|').slice(1)) {
const [dy, height] = t.split('-', 2).map(Number);

ctx.drawImage(image, 0, sy, image.width, height, 0, dy, image.width, height);
sy += height;
}

return this._blobToBuffer(await this._canvasToBlob(canvas));
}

_canvasToBlob(canvas) {
return new Promise(resolve => {
canvas.toBlob(data => {
resolve(data);
}, Engine.Settings.recompressionFormat.value, parseFloat(Engine.Settings.recompressionQuality.value) / 100);
});
}

decodeXorCipher(data, key) {
let output = "";

for (let i = 0; i < data.length; i++) {
output += String.fromCharCode(data.charCodeAt(i) ^ key.charCodeAt(i % key.length));
}

return output;
}
}
14 changes: 12 additions & 2 deletions src/web/mjs/connectors/Desu.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class Desu extends Connector {
super.id = 'desu';
super.label = 'Desu';
this.tags = ['manga', 'webtoon', 'russian'];
this.url = 'https://desu.me';
this.url = 'https://x.desu.win';
}

async _getMangaFromURI(uri) {
Expand Down Expand Up @@ -69,6 +69,16 @@ export default class Desu extends Connector {
const uri = new URL(chapter.id, this.url);
const request = new Request(uri, this.requestOptions);
const pages = await Engine.Request.fetchUI(request, script);
return pages.map(element => this.getAbsolutePath(element.url, this.url));
return pages.map(element => this.createConnectorURI(this.getAbsolutePath(element.url, this.url)));
}

async _handleConnectorURI(payload) {
const request = new Request(payload, this.requestOptions);
request.headers.set('x-referer', this.url);
const response = await fetch(request);
let data = await response.blob();
data = await this._blobToBuffer(data);
this._applyRealMime(data);
return data;
}
}
31 changes: 31 additions & 0 deletions src/web/mjs/connectors/ErosScans.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import WordPressMangastream from './templates/WordPressMangastream.mjs';

export default class ErosScan extends WordPressMangastream {

constructor() {
super();
super.id = 'erosscans';
super.label = 'Eros Scan';
this.tags = ['webtoon', 'english'];
this.path = '/manga/list-mode/';
this.config = {
url: {
label: 'URL',
description: 'This website changes their URL regularly.\nThis is the last known URL which can also be manually set by the user.',
input: 'text',
value: 'https://doomcomic.xyz'
}
};
}

get url() {
return this.config.url.value;
}

set url(value) {
if (this.config && value) {
this.config.url.value = value;
Engine.Settings.save();
}
}
}
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/Fbsquads.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export default class Fbsquads extends WordPressMadara {
super.id = 'fbsquads';
super.label = 'Fleur Blanche Squads';
this.tags = [ 'webtoon', 'spanish', 'scanlation', 'yaoi' ];
this.url = 'https://fbsscan.com';
this.url = 'https://fbsquadx.com';
}
}
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/FirstKiss.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class FirstKiss extends Connector {
super.id = 'firstkiss';
super.label = 'LikeManga.io';
this.tags = ['webtoon', 'english'];
this.url = 'https://likemanga.io';
this.url = 'https://likemanga.ink';
this.requestOptions.headers.set('x-referer', this.url);
this.requestOptions.headers.set('x-origin', this.url);
}
Expand Down
35 changes: 23 additions & 12 deletions src/web/mjs/connectors/GourmetScans.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,29 @@ export default class GourmetScans extends WordPressMadara {
const url = new URL(chapter.id, this.url);
const request = new Request(url, this.requestOptions);
const script = `
new Promise((resolve, reject) => {
try {
let rocketscript = new RocketLazyLoadScripts;
rocketscript._loadEverythingNow();
} catch (error) {}

setTimeout(() => {
var imgdata = JSON.parse(CryptoJS.AES.decrypt(chapter_data, wpmangaprotectornonce, {
format: CryptoJSAesJson
}).toString(CryptoJS.enc.Utf8));
resolve(JSON.parse(imgdata));
}, 2500);
new Promise( (resolve, reject) => {
const start = Date.now();
const interval = setInterval(function () {
try {
if (CryptoJS) {
clearInterval(interval);
let imgdata = JSON.parse(CryptoJS.AES.decrypt(chapter_data, wpmangaprotectornonce, {
format: CryptoJSAesJson
}).toString(CryptoJS.enc.Utf8));
resolve(JSON.parse(imgdata));
}
} catch (error) {
clearInterval(interval);
reject(error);
} finally {
if(Date.now() - start > 10_000) {
clearInterval(interval);
reject(new Error('Unable to get pictures after more than 10 seconds !'));
}
}
}, 1000);
window.dispatchEvent(new KeyboardEvent('keydown'));

});
`;
const data = await Engine.Request.fetchUI(request, script);
Expand Down
22 changes: 16 additions & 6 deletions src/web/mjs/connectors/Hitomi.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,21 @@ export default class Hitomi extends Connector {
}

async _getMangaFromURI(uri) {
let request = new Request(uri, this.requestOptions);
let data = await this.fetchDOM(request, 'div.gallery h1 a', 3);
let id = uri.pathname.match(/(\d+)\.html$/)[1];
let title = data[0].text.trim();
return new Manga(this, id, title);
const request = new Request(uri, this.requestOptions);
const script = `
new Promise((resolve, reject) => {
setTimeout(() => {
try {
resolve(galleryinfo.title);
} catch(error) {
reject(error);
}
}, 1000);
});
`;
const title = await Engine.Request.fetchUI(request, script);
const id = uri.pathname.match(/(\d+)\.html$/)[1];
return new Manga(this, id, title.trim());
}

async _getMangas() {
Expand All @@ -38,7 +48,7 @@ export default class Hitomi extends Connector {
new Promise((resolve, reject) => {
setTimeout(() => {
try {
let images = galleryinfo.files.map(info => url_from_url_from_hash(galleryinfo.id, info));
let images = galleryinfo.files.map(image => url_from_url_from_hash(galleryinfo.id, image, 'webp', undefined, 'a'));
resolve(images);
} catch(error) {
reject(error);
Expand Down
2 changes: 1 addition & 1 deletion src/web/mjs/connectors/HunterScan.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ export default class HunterScan extends WordPressMadara {
super.id = 'hunterscan';
super.label = 'Hunters Scan';
this.tags = [ 'manga', 'webtoon', 'portuguese' ];
this.url = 'https://huntersscan.xyz/';
this.url = 'https://htoons.online';
}
}
Loading
Loading