Files
kodjodevf-mangayomi-extensions/javascript/manga/src/it/mangaworld.js
RndDev123 4a9f16c5ae New Source: MangaWorld (IT) + Fixes
New Source:
- Manga World

JKAnime, TioAnime, ,AnimeFenix and AnimeWorld:
- Add await before this.parseAnimeList for readability
2024-11-28 07:04:26 +01:00

281 lines
11 KiB
JavaScript

const mangayomiSources = [{
"name": "MangaWorld",
"lang": "it",
"baseUrl": "https://www.mangaworld.ac",
"apiUrl": "",
"iconUrl": "https://www.mangaworld.ac/public/assets/images/MangaWorldSquareLogo.png",
"typeSource": "single",
"isManga": true,
"version": "0.0.1",
"dateFormat": "",
"dateFormatLocale": "",
"pkgPath": "manga/src/it/mangaworld.js"
}];
class DefaultExtension extends MProvider {
constructor () {
super();
this.client = new Client();
this.getPageCount = /totalPages["']:\s*(\d+).*?page["']:\s*(\d+)/i; // totalPages:\s*(\d+).*?page:\s*(\d+)
this.getMangas = /['"]mangas['"]:([\s\S]+?])\s*\}/i; // mangas:([\s\S]+?])\s*\}
this.getManga = /manga['"]:\s*(\{[\S\s]*?\}),\s*['"]image/i; // manga:\s*(\{[\S\s]*?\}),\s*image
this.getPages = /pages['"]:\s*(\{[\S\s]*?\})\s*\}/ // pages: ({[\S\s]*?})\s*}
this.getChapter = /chapter['"]:\s*(\{[\S\s]*?\}),\s*['"]image/i; // chapter:\s*(\{[\S\s]*?\}),\s*image
this.getCdn = /cdn_url["']:\s*["'](.+?)["']/i;
}
parseStatus(status) {
return {
'In corso': 0,
'Finito': 1,
'In pausa': 2,
'Droppato': 3,
'Cancellato': 3
}[status] ?? 5;
}
async parseMangaList(url) {
const res = await this.client.get(url);
const json = this.getMangas.exec(res.body)[1];
let mangas = JSON.parse(json).map(manga => ({
name: manga.title,
imageUrl: manga.imageT,
author: manga.author.join(', '),
artist: manga.artist.join(', '),
status: this.parseStatus(manga.statusT),
description: manga.trama,
genre: manga.genres.map(g => g.name),
link: `${this.source.baseUrl}/manga/${manga.linkId}/${manga.slug}`,
}));
const pageNums = this.getPageCount.exec(res.body);
return { "list": mangas, "hasNextPage": pageNums[1] > pageNums[2] };
}
async getPopular(page) {
return await this.parseMangaList(this.source.baseUrl + `/archive?sort=most_read&page=${page}`);
}
async getLatestUpdates(page) {
return await this.parseMangaList(this.source.baseUrl + `/archive?sort=newest&page=${page}`);
}
async search(query, page, filters) {
let url = `${this.source.baseUrl}/archive?keyword=${query}`
// Search sometimes failed because filters were empty. I experienced this mostly on android...
if (!filters || filters.length == 0) {
return await this.parseMangaList(url + `&page=${page}`);
}
// type
for (const filter of filters[0].state) {
if (filter.state == true)
url += `&type=${filter.value}`;
}
// genre
for (const filter of filters[1].state) {
if (filter.state == true)
url += `&genre=${filter.value}`;
}
// status
for (const filter of filters[2].state) {
if (filter.state == true)
url += `&status=${filter.value}`;
}
// year
for (const filter of filters[3].state) {
if (filter.state == true)
url += `&year=${filter.value}`;
}
// sort
url += `&sort=${filters[4].values[filters[4].state].value}`;
return await this.parseMangaList(url + `&page=${page}`);
}
async getDetail(url) {
const res = await this.client.get(url);
const chapters = [];
const manga = JSON.parse(this.getManga.exec(res.body)[1]);
const pages = JSON.parse(this.getPages.exec(res.body)[1]);
const baseUrl = `${this.source.baseUrl}/manga/${manga.linkId}/${manga.slug}/read/`;
for (const v of pages.volumes) {
for (const c of v.chapters) {
chapters.push({
name: c.name,
url: baseUrl + c.id,
dateUpload: new Date(c.createdAt).valueOf().toString(),
});
}
}
for (const c of pages.singleChapters) {
chapters.push({
name: c.name,
url: baseUrl + c.id,
dateUpload: new Date(c.createdAt).valueOf().toString(),
});
}
return {
name: manga.title,
imageUrl: manga.imageT,
author: manga.author.join(', '),
artist: manga.artist.join(', '),
status: this.parseStatus(manga.statusT),
description: manga.trama,
genre: manga.genres.map(g => g.name),
chapters: chapters
};
}
// For manga chapter pages
async getPageList(url) {
const res = await new Client().get(url);
const cdn = this.getCdn.exec(res.body)[1];
const chapter = JSON.parse(this.getChapter.exec(res.body)[1]);
const manga = chapter.manga;
const volume = chapter.volume;
const baseUrl = volume ?
`${cdn}/chapters/${manga.slugFolder}-${manga.id}/${volume.slugFolder}-${volume.id}/${chapter.slugFolder}-${chapter.id}/` :
`${cdn}/chapters/${manga.slugFolder}-${manga.id}/${chapter.slugFolder}-${chapter.id}/`;
return chapter.pages.map(img => ({url: baseUrl + img}));
}
getFilterList() {
return [
{
type_name: "GroupFilter",
name: "Tipo",
state: [
['Manga', 'manga'],
['Manhua', 'manhua'],
['Manhwa', 'manhwa'],
['Oneshot', 'oneshot']
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
},
{
type_name: "GroupFilter",
name: "Generi",
state: [
['Adulti', 'adulti'],
['Arti Marziali', 'arti-marziali'],
['Avventura', 'avventura'],
['Azione', 'azione'],
['Commedia', 'commedia'],
['Doujinshi', 'doujinshi'],
['Drammatico', 'drammatico'],
['Ecchi', 'ecchi'],
['Fantasy', 'fantasy'],
['Gender Bender', 'gender-bender'],
['Harem', 'harem'],
['Hentai', 'hentai'],
['Horror', 'horror'],
['Josei', 'josei'],
['Lolicon', 'lolicon'],
['Maturo', 'maturo'],
['Mecha', 'mecha'],
['Mistero', 'mistero'],
['Psicologico', 'psicologico'],
['Romantico', 'romantico'],
['Sci-fi', 'sci-fi'],
['Scolastico', 'scolastico'],
['Seinen', 'seinen'],
['Shotacon', 'shotacon'],
['Shoujo', 'shoujo'],
['Shoujo Ai', 'shoujo-ai'],
['Shounen', 'shounen'],
['Shounen Ai', 'shounen-ai'],
['Slice of Life', 'slice-of-life'],
['Smut', 'smut'],
['Soprannaturale', 'soprannaturale'],
['Sport', 'sport'],
['Storico', 'storico'],
['Tragico', 'tragico'],
['Yaoi', 'yaoi'],
['Yuri', 'yuri']
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
},
{
type_name: "GroupFilter",
name: "Stato",
state: [
['In corso', 'ongoing'],
['Finito', 'completed'],
['Droppato', 'dropped'],
['In pausa', 'paused'],
['Cancellato', 'canceled']
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
},
{
type_name: "GroupFilter",
name: "Anno",
state: [
['Sconosciuto', 'Sconosciuto'],
['1968', '1968'],
['1970', '1970'],
['1972', '1972'],
['1973', '1973'],
['1974', '1974'],
['1975', '1975'],
['1976', '1976'],
['1977', '1977'],
['1979', '1979'],
['1980', '1980'],
['1981', '1981'],
['1982', '1982'],
['1983', '1983'],
['1984', '1984'],
['1985', '1985'],
['1986', '1986'],
['1987', '1987'],
['1988', '1988'],
['1989', '1989'],
['1990', '1990'],
['1991', '1991'],
['1992', '1992'],
['1993', '1993'],
['1994', '1994'],
['1995', '1995'],
['1996', '1996'],
['1997', '1997'],
['1998', '1998'],
['1999', '1999'],
['2000', '2000'],
['2001', '2001'],
['2002', '2002'],
['2003', '2003'],
['2004', '2004'],
['2005', '2005'],
['2006', '2006'],
['2007', '2007'],
['2008', '2008'],
['2009', '2009'],
['2010', '2010'],
['2011', '2011'],
['2012', '2012'],
['2013', '2013'],
['2014', '2014'],
['2015', '2015'],
['2016', '2016'],
['2017', '2017'],
['2018', '2018'],
['2019', '2019'],
['2020', '2020'],
['2021', '2021'],
['2022', '2022'],
['2023', '2023'],
['2024', '2024']
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
},
{
type_name: "SelectFilter",
type: "sort",
name: "Ordina per",
state: 4,
values: [
['Più letti', 'most_read'],
['Meno letti', 'less_read'],
['Più recenti', 'newest'],
['Meno recenti', 'oldest'],
['A-Z', 'a-z'],
['Z-A', 'z-a']
].map(x => ({type_name: 'SelectOption', name: x[0], value: x[1] }))
}
];
}
getSourcePreferences() {
throw new Error("getSourcePreferences not implemented");
}
}