mirror of
https://github.com/kodjodevf/mangayomi-extensions.git
synced 2026-02-14 02:41:39 +00:00
425 lines
16 KiB
JavaScript
425 lines
16 KiB
JavaScript
const mangayomiSources = [
|
|
{
|
|
"name": "Comick",
|
|
"langs": ["all", "en", "pt-br", "ru", "fr", "es-419", "pl", "tr", "it", "es", "id", "hu", "vi", "zh-hk", "ar", "de", "zh", "ca", "bg", "th", "fa", "uk", "mn", "ro", "he", "ms", "tl", "ja", "hi", "my", "ko", "cs", "pt", "nl", "sv", "bn", "no", "lt", "el", "sr", "da"],
|
|
"ids": {
|
|
"all": 370890607,
|
|
"en": 955190069,
|
|
"pt-br": 494197461,
|
|
"ru": 1050814052,
|
|
"fr": 380505196,
|
|
"es-419": 296390197,
|
|
"pl": 242913014,
|
|
"tr": 507059585,
|
|
"it": 851891714,
|
|
"es": 115169439,
|
|
"id": 719269008,
|
|
"hu": 719759654,
|
|
"vi": 301477894,
|
|
"zh-hk": 113594984,
|
|
"ar": 602472856,
|
|
"de": 401493183,
|
|
"zh": 752155292,
|
|
"ca": 1069764002,
|
|
"bg": 678531099,
|
|
"th": 311480598,
|
|
"fa": 141560456,
|
|
"uk": 8261465,
|
|
"mn": 565474938,
|
|
"ro": 533803532,
|
|
"he": 459976450,
|
|
"ms": 375702775,
|
|
"tl": 737984097,
|
|
"ja": 796489006,
|
|
"hi": 683471552,
|
|
"my": 778623467,
|
|
"ko": 1065236294,
|
|
"cs": 422767524,
|
|
"pt": 678647945,
|
|
"nl": 698202010,
|
|
"sv": 359879447,
|
|
"bn": 532878423,
|
|
"no": 481504622,
|
|
"lt": 112887841,
|
|
"el": 824905526,
|
|
"sr": 373675453,
|
|
"da": 574420905
|
|
},
|
|
"baseUrl": "https://comick.io",
|
|
"apiUrl": "https://api.comick.fun",
|
|
"iconUrl": "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.comick.png",
|
|
"typeSource": "single",
|
|
"itemType": 0,
|
|
"version": "0.0.85",
|
|
"pkgPath": "manga/src/all/comick.js"
|
|
}];
|
|
|
|
class DefaultExtension extends MProvider {
|
|
constructor() {
|
|
super();
|
|
this.client = new Client();
|
|
}
|
|
getHeaders(url) {
|
|
return {
|
|
"Referer": `${this.source.baseUrl}/`,
|
|
'User-Agent':
|
|
"Tachiyomi Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0"
|
|
};
|
|
}
|
|
|
|
async getPopular(page) {
|
|
const url = `${this.source.apiUrl}/v1.0/search?sort=follow&page=${page}&tachiyomi=true`;
|
|
const res = await this.client.get(url, this.getHeaders());
|
|
return this.mangaRes(res.body);
|
|
}
|
|
|
|
async getLatestUpdates(page) {
|
|
const url = `${this.source.apiUrl}/v1.0/search?sort=uploaded&page=${page}&tachiyomi=true`;
|
|
const res = await this.client.get(url, this.getHeaders());
|
|
return this.mangaRes(res.body);
|
|
}
|
|
async search(query, page, filterList) {
|
|
let url = `${this.source.apiUrl}/v1.0/search`;
|
|
|
|
if (query) {
|
|
url += `?q=${encodeURIComponent(query)}&tachiyomi=true`;
|
|
} else {
|
|
filterList.forEach(filter => {
|
|
if (filter.type === "CompletedFilter" && filter.state) {
|
|
url += `${this.ll(url)}completed=true`;
|
|
} else if (filter.type === "GenreFilter") {
|
|
const included = filter.state.filter(e => e.state === 1);
|
|
const excluded = filter.state.filter(e => e.state === 2);
|
|
included.forEach(val => url += `${this.ll(url)}genres=${val.value}`);
|
|
excluded.forEach(val => url += `${this.ll(url)}excludes=${val.value}`);
|
|
} else if (filter.type === "DemographicFilter") {
|
|
const included = filter.state.filter(e => e.state === 1);
|
|
included.forEach(val => url += `${this.ll(url)}demographic=${val.value}`);
|
|
} else if (filter.type === "TypeFilter") {
|
|
const country = filter.state.filter(e => e.state);
|
|
country.forEach(coun => url += `${this.ll(url)}country=${coun.value}`);
|
|
} else if (filter.type === "SortFilter") {
|
|
url += `${this.ll(url)}sort=${filter.values[filter.state].value}`;
|
|
} else if (filter.type === "StatusFilter") {
|
|
url += `${this.ll(url)}status=${filter.values[filter.state].value}`;
|
|
} else if (filter.type === "CreatedAtFilter" && filter.state > 0) {
|
|
url += `${this.ll(url)}time=${filter.values[filter.state].value}`;
|
|
} else if (filter.type === "MinimumFilter" && filter.state) {
|
|
url += `${this.ll(url)}minimum=${filter.state}`;
|
|
} else if (filter.type === "FromYearFilter" && filter.state) {
|
|
url += `${this.ll(url)}from=${filter.state}`;
|
|
} else if (filter.type === "ToYearFilter" && filter.state) {
|
|
url += `${this.ll(url)}to=${filter.state}`;
|
|
} else if (filter.type === "TagFilter" && filter.state) {
|
|
const tags = filter.state.split(",");
|
|
tags.forEach(tag => url += `${this.ll(url)}tags=${tag}`);
|
|
}
|
|
});
|
|
url += `&page=${page}&tachiyomi=true`;
|
|
}
|
|
const res = await this.client.get(url, this.getHeaders());
|
|
return this.mangaRes(res.body);
|
|
}
|
|
|
|
async getDetail(url) {
|
|
const apiUrl = `${this.source.apiUrl}${url.replace("#", "")}?tachiyomi=true`;
|
|
const res = await this.client.get(apiUrl, this.getHeaders());
|
|
const data = JSON.parse(res.body);
|
|
const lang = this.source.lang != "all" ? `&lang=${this.source.lang}` : "";
|
|
const chapUrlReq =
|
|
`${this.source.apiUrl}${url.replaceAll("#", '')}chapters?${lang}&tachiyomi=true&page=1`;
|
|
const total = JSON.parse((await this.client.get(chapUrlReq, this.getHeaders())).body).total;
|
|
const newChapUrlReq =
|
|
`${this.source.apiUrl}${url.replaceAll("#", '')}chapters?limit=${parseInt(total, 10)}${lang}&tachiyomi=true&page=1`;
|
|
const newRes = await this.client.get(newChapUrlReq, this.getHeaders());
|
|
const chapters = JSON.parse(newRes.body).chapters.map(chapter => {
|
|
let title = "";
|
|
let scanlator = "";
|
|
|
|
if (chapter.chap !== "null" && chapter.vol !== "null") {
|
|
title = this.beautifyChapterName(
|
|
chapter.vol,
|
|
chapter.chap,
|
|
chapter.title
|
|
);
|
|
} else {
|
|
title = chapter.title;
|
|
}
|
|
|
|
if (chapter.group_name !== "null") {
|
|
scanlator = chapter.group_name
|
|
.toString()
|
|
.replace(/]/g, "")
|
|
.replace(/\[/g, "");
|
|
}
|
|
|
|
return {
|
|
name: title,
|
|
url: chapter.hid,
|
|
scanlator: scanlator ?? "",
|
|
dateUpload: new Date(chapter.created_at).valueOf().toString(),
|
|
};
|
|
});
|
|
|
|
return {
|
|
author: data.authors?.map(author => author.name).join(', '),
|
|
description: data.comic.desc,
|
|
genres: Array.from(data.comic.md_comic_md_genres.map(g => g.md_genres.name)),
|
|
status: { "1": 0, "2": 1, "3": 3, "4": 2 }[data.comic.status],
|
|
chapters
|
|
};
|
|
}
|
|
|
|
async getPageList(url) {
|
|
const apiUrl = `${this.source.apiUrl}/chapter/${url}?tachiyomi=true`;
|
|
const res = await this.client.get(apiUrl, this.getHeaders());
|
|
const data = JSON.parse(res.body);
|
|
return data.chapter.images.map(image => ({
|
|
url: image.url
|
|
}));
|
|
}
|
|
getFilterList() {
|
|
return [
|
|
{
|
|
type_name: "HeaderFilter",
|
|
name: "The filter is ignored when using text search.",
|
|
},
|
|
{
|
|
type_name: "GroupFilter",
|
|
type: "GenreFilter",
|
|
name: "Genre",
|
|
state: [
|
|
["4-Koma", "4-koma"],
|
|
["Action", "action"],
|
|
["Adaptation", "adaptation"],
|
|
["Adult", "adult"],
|
|
["Adventure", "adventure"],
|
|
["Aliens", "aliens"],
|
|
["Animals", "animals"],
|
|
["Anthology", "anthology"],
|
|
["Award Winning", "award-winning"],
|
|
["Comedy", "comedy"],
|
|
["Cooking", "cooking"],
|
|
["Crime", "crime"],
|
|
["Crossdressing", "crossdressing"],
|
|
["Delinquents", "delinquents"],
|
|
["Demons", "demons"],
|
|
["Doujinshi", "doujinshi"],
|
|
["Drama", "drama"],
|
|
["Ecchi", "ecchi"],
|
|
["Fan Colored", "fan-colored"],
|
|
["Fantasy", "fantasy"],
|
|
["Full Color", "full-color"],
|
|
["Gender Bender", "gender-bender"],
|
|
["Genderswap", "genderswap"],
|
|
["Ghosts", "ghosts"],
|
|
["Gore", "gore"],
|
|
["Gyaru", "gyaru"],
|
|
["Harem", "harem"],
|
|
["Historical", "historical"],
|
|
["Horror", "horror"],
|
|
["Incest", "incest"],
|
|
["Isekai", "isekai"],
|
|
["Loli", "loli"],
|
|
["Long Strip", "long-strip"],
|
|
["Mafia", "mafia"],
|
|
["Magic", "magic"],
|
|
["Magical Girls", "magical-girls"],
|
|
["Martial Arts", "martial-arts"],
|
|
["Mature", "mature"],
|
|
["Mecha", "mecha"],
|
|
["Medical", "medical"],
|
|
["Military", "military"],
|
|
["Monster Girls", "monster-girls"],
|
|
["Monsters", "monsters"],
|
|
["Music", "music"],
|
|
["Mystery", "mystery"],
|
|
["Ninja", "ninja"],
|
|
["Office Workers", "office-workers"],
|
|
["Official Colored", "official-colored"],
|
|
["Oneshot", "oneshot"],
|
|
["Philosophical", "philosophical"],
|
|
["Police", "police"],
|
|
["Post-Apocalyptic", "post-apocalyptic"],
|
|
["Psychological", "psychological"],
|
|
["Reincarnation", "reincarnation"],
|
|
["Reverse Harem", "reverse-harem"],
|
|
["Romance", "romance"],
|
|
["Samurai", "samurai"],
|
|
["School Life", "school-life"],
|
|
["Sci-Fi", "sci-fi"],
|
|
["Sexual Violence", "sexual-violence"],
|
|
["Shota", "shota"],
|
|
["Shoujo Ai", "shoujo-ai"],
|
|
["Shounen Ai", "shounen-ai"],
|
|
["Slice of Life", "slice-of-life"],
|
|
["Smut", "smut"],
|
|
["Sports", "sports"],
|
|
["Superhero", "superhero"],
|
|
["Supernatural", "supernatural"],
|
|
["Survival", "survival"],
|
|
["Thriller", "thriller"],
|
|
["Time Travel", "time-travel"],
|
|
["Traditional Games", "traditional-games"],
|
|
["Tragedy", "tragedy"],
|
|
["User Created", "user-created"],
|
|
["Vampires", "vampires"],
|
|
["Video Games", "video-games"],
|
|
["Villainess", "villainess"],
|
|
["Virtual Reality", "virtual-reality"],
|
|
["Web Comic", "web-comic"],
|
|
["Wuxia", "wuxia"],
|
|
["Yaoi", "yaoi"],
|
|
["Yuri", "yuri"],
|
|
["Zombies", "zombies"]
|
|
].map(x => ({ type_name: 'TriState', name: x[0], value: x[1] }))
|
|
},
|
|
{
|
|
type_name: "GroupFilter",
|
|
type: "DemographicFilter",
|
|
name: "Demographic",
|
|
state: [
|
|
["Shounen", "1"],
|
|
["Shoujo", "2"],
|
|
["Seinen", "3"],
|
|
["Josei", "4"]
|
|
].map(x => ({ type_name: 'TriState', name: x[0], value: x[1] }))
|
|
},
|
|
{
|
|
type_name: "GroupFilter",
|
|
type: "TypeFilter",
|
|
name: "Type",
|
|
state: [
|
|
["Manga", "jp"],
|
|
["Manhwa", "kr"],
|
|
["Manhua", "cn"]
|
|
].map(x => ({ type_name: 'CheckBox', name: x[0], value: x[1] }))
|
|
},
|
|
{
|
|
type_name: "SelectFilter",
|
|
type: "SortFilter",
|
|
name: "Sort",
|
|
state: 0,
|
|
values: [
|
|
["Most popular", "follow"],
|
|
["Most follows", "user_follow_count"],
|
|
["Most views", "view"],
|
|
["High rating", "rating"],
|
|
["Last updated", "uploaded"],
|
|
["Newest", "created_at"]
|
|
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
|
},
|
|
{
|
|
type_name: "SelectFilter",
|
|
type: "StatusFilter",
|
|
name: "Status",
|
|
state: 0,
|
|
values: [
|
|
["All", "0"],
|
|
["Ongoing", "1"],
|
|
["Completed", "2"],
|
|
["Cancelled", "3"],
|
|
["Hiatus", "4"]
|
|
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
|
},
|
|
{
|
|
type_name: 'CheckBox',
|
|
type: "CompletedFilter",
|
|
name: "Completely Scanlated?",
|
|
value: ""
|
|
},
|
|
{
|
|
type_name: "SelectFilter",
|
|
type: "CreatedAtFilter",
|
|
name: "Created at",
|
|
state: 0,
|
|
values: [
|
|
["", ""],
|
|
["3 days", "3"],
|
|
["7 days", "7"],
|
|
["30 days", "30"],
|
|
["3 months", "90"],
|
|
["6 months", "180"],
|
|
["1 year", "365"]
|
|
].map(x => ({ type_name: 'SelectOption', name: x[0], value: x[1] }))
|
|
},
|
|
{
|
|
type_name: "TextFilter",
|
|
type: "MinimumFilter",
|
|
name: "Minimum Chapters",
|
|
},
|
|
{
|
|
type_name: "HeaderFilter",
|
|
name: "From Year, ex: 2010",
|
|
},
|
|
{
|
|
type_name: "TextFilter",
|
|
type: "FromYearFilter",
|
|
name: "From",
|
|
},
|
|
{
|
|
type_name: "HeaderFilter",
|
|
name: "To Year, ex: 2021",
|
|
},
|
|
{
|
|
type_name: "TextFilter",
|
|
type: "ToYearFilter",
|
|
name: "To",
|
|
},
|
|
{
|
|
type_name: "HeaderFilter",
|
|
name: "Separate tags with commas",
|
|
},
|
|
{
|
|
type_name: "TextFilter",
|
|
type: "TagFilter",
|
|
name: "Tags",
|
|
},
|
|
];
|
|
}
|
|
mangaRes(body) {
|
|
body = JSON.parse(body);
|
|
return {
|
|
list: body.map(manga => ({
|
|
name: manga.title,
|
|
imageUrl: manga.cover_url,
|
|
link: `/comic/${manga.hid}/#`
|
|
})),
|
|
hasNextPage: body.hasNextPage || false
|
|
};
|
|
}
|
|
beautifyChapterName(vol, chap, title) {
|
|
let result = "";
|
|
|
|
if (vol && vol.trim() !== "") {
|
|
if (chap && chap.trim() === "") {
|
|
result += `Volume ${vol} `;
|
|
} else {
|
|
result += `Vol. ${vol} `;
|
|
}
|
|
}
|
|
|
|
if (chap && chap.trim() !== "") {
|
|
if (vol && vol.trim() === "") {
|
|
result += `Chapter ${chap}`;
|
|
} else {
|
|
result += `Ch. ${chap} `;
|
|
}
|
|
}
|
|
|
|
if (title && title.trim() !== "") {
|
|
if (chap && chap.trim() === "") {
|
|
result += title;
|
|
} else {
|
|
result += ` : ${title}`;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
ll(url) {
|
|
return url.includes("?") ? "&" : "?";
|
|
}
|
|
}
|