Skip to content

Commit

Permalink
MyAnimeList (manga) fixes (#5467)
Browse files Browse the repository at this point in the history
* MyAnimeList (manga)  fixes

* Fixes #5464
* Get Mangas from store
* Handle preview and download of free and paid volumes (paid was tested)
* Does not support light novels. They use a modified Publus with path an sizes thats all i can say. Attempts to add it ended up in successful unscrambling but many errors 500 (junk pages? )

* Update MyAnimeListManga.mjs

* Update MyAnimeListManga.mjs
  • Loading branch information
MikeZeDev authored and Sheepux committed Mar 26, 2023
1 parent c185a61 commit 01eedba
Showing 1 changed file with 71 additions and 23 deletions.
94 changes: 71 additions & 23 deletions src/web/mjs/connectors/MyAnimeListManga.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ export default class MyAnimeListManga extends Connector {
super.label = 'MyAnimeList (Manga)';
this.tags = [ 'manga', 'high-quality', 'english' ];
this.url = 'https://myanimelist.net';
this.links = {
login: 'https://myanimelist.net/login.php'
};
this.config = {
throttle: {
label: 'Throttle Requests [ms]',
description: 'Enter the timespan in [ms] to delay consecuitive HTTP requests.\nThe website may reject to many consecuitive requests',
input: 'numeric',
min: 0,
max: 5000,
value: 500
}
};
}

async _getMangaFromURI(uri) {
Expand All @@ -20,30 +33,49 @@ export default class MyAnimeListManga extends Connector {
}

async _getMangas() {
let request = new Request(new URL('/read/manga', this.url), this.requestOptions);
let data = await this.fetchDOM(request, 'tr.ranking-list td.title div.detail > a:first-of-type');
return data.map(element => {
return {
id: element.href.split('/').pop(),
title: element.text.trim()
};
});
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 _getChapters(manga) {
let request = new Request(new URL('/read/manga/detail/' + manga.id, this.url), this.requestOptions);
let data = await this.fetchDOM(request, 'table.top-ranking-table tr td div.detail a:first-of-type');
async _getMangasFromPage(page) {
const uri = new URL('/store/search?p=' + page, this.url);
const request = new Request(uri, this.requestOptions);
const data = await this.fetchDOM(request, 'div.items a.item');
return data.map(element => {
return {
id: this.getRootRelativeOrAbsoluteLink(element, this.url),
title: element.text.trim(),
language: ''
title: element.querySelector('span.title').textContent.trim()
};
});
}

async _getChapters(manga) {
let request = new Request(new URL(manga.id, this.url), this.requestOptions);
const data = await this.fetchDOM(request, 'div.v-manga-store-purchase-bulk-button');
const jObject= JSON.parse(data[0].dataset['items']);
return jObject.filter(element => element.is_previewable || element.is_free || element.is_possessed)
.filter(element => !element.viewer_url.includes('novel_viewer'))
.map(element => {
const isPossessed = !element.is_possessed ? false : element.is_possessed; //value can be null instead of false
const isFull = element.is_free || isPossessed;
let title = element.numbering_text.trim();
title += isFull ? '' : ' [Preview]';
return {
id: this.getRootRelativeOrAbsoluteLink(isFull ? element.viewer_url : element.preview_url, this.url),
title: title,
language: ''
};
});
}

async _getPages(chapter) {
let request = new Request(new URL(chapter.id, this.url), this.requestOptions);
//TODO : add support for light novels : its modified Publus reader
const url = new URL(chapter.id, this.url);
let request = new Request(url, this.requestOptions);
let data = await this.fetchDOM(request, 'div.v-manga-store-viewer');
if(data.length === 0) {
throw new Error('You must first login to see this page!');
Expand All @@ -52,18 +84,34 @@ export default class MyAnimeListManga extends Connector {
return data.manuscript.filenames.map(file => {
let uri = new URL(data.manuscript.image_base_url + '/' + file);
uri.search = data.manuscript.query_params_part;
return this.createConnectorURI(uri.href);
return this.createConnectorURI({imageUrl : uri.href, referer : url, mode : 'xor'});
});
}

async _handleConnectorURI(payload) {
let request = new Request(payload, this.requestOptions);
let response = await fetch(request);
let data = await response.arrayBuffer();
return {
mimeType: response.headers.get('content-type'),
data: this._decryptImage(data)
};
await this.wait(this.config.throttle.value);
//handling modes already in case of future addition of light novels support
switch(payload.mode) {
case 'xor': {
const Xreferal = new URL(payload.referer);
let request = new Request(payload.imageUrl, this.requestOptions);
request.headers.set('Accept', 'application/json, text/plain, */*');
request.headers.set('X-Requested-With', 'XMLHttpRequest');
request.headers.set('X-Referral-Path', Xreferal.pathname );
request.headers.set('x-origin', this.url);
request.headers.set('x-referer', payload.referer);
let response = await fetch(request);
let data = await response.arrayBuffer();
return {
mimeType: response.headers.get('content-type'),
data: this._decryptImage(data)
};
}

case 'puzzle' : {
//
}
}
}

_decryptImage(encrypted) {
Expand All @@ -78,4 +126,4 @@ export default class MyAnimeListManga extends Connector {
}
return decrypted;
}
}
}

0 comments on commit 01eedba

Please sign in to comment.