Merge pull request #204 from uwu-wuw/main

fix
This commit is contained in:
Moustapha Kodjo Amadou
2025-04-01 09:47:38 +02:00
committed by GitHub
7 changed files with 94 additions and 178 deletions

View File

@@ -1,5 +1,6 @@
import 'package:mangayomi/bridge_lib.dart'; import 'package:mangayomi/bridge_lib.dart';
class MangaBox extends MProvider { class MangaBox extends MProvider {
MangaBox({required this.source}); MangaBox({required this.source});
@@ -12,6 +13,7 @@ class MangaBox extends MProvider {
final res = final res =
(await client.get( (await client.get(
Uri.parse("${source.baseUrl}/${popularUrlPath(source.name, page)}"), Uri.parse("${source.baseUrl}/${popularUrlPath(source.name, page)}"),
headers: getHeader(source.baseUrl),
)).body; )).body;
return mangaRes(res); return mangaRes(res);
} }
@@ -21,6 +23,7 @@ class MangaBox extends MProvider {
final res = final res =
(await client.get( (await client.get(
Uri.parse("${source.baseUrl}/${latestUrlPath(source.name, page)}"), Uri.parse("${source.baseUrl}/${latestUrlPath(source.name, page)}"),
headers: getHeader(source.baseUrl),
)).body; )).body;
return mangaRes(res); return mangaRes(res);
} }
@@ -30,66 +33,30 @@ class MangaBox extends MProvider {
final filters = filterList.filters; final filters = filterList.filters;
String url = ""; String url = "";
if (query.isNotEmpty && if (query.isNotEmpty) {
(source.name != "Manganato" && source.name != "Mangabat")) {
url = "${source.baseUrl}/${simpleQueryPath(source.name, page, query)}"; url = "${source.baseUrl}/${simpleQueryPath(source.name, page, query)}";
} else { } else {
url = source.baseUrl;
if (source.name == "Manganato" || source.name == "Mangabat") { String genre = "all";
url += String sort = "latest";
"/advanced_search?page=$page&keyw=${normalizeSearchQuery(query)}"; String status = "all";
String genreInclude = "";
String genreExclude = "";
for (var filter in filters) { for (var filter in filters) {
if (filter.type == "KeywordFilter") { if (filter.type == "GenreListFilter") {
final key = filter.values[filter.state].value; genre = filter.values[filter.state].value;
url += "${ll(url)}keyt=$key";
} else if (filter.type == "SortFilter") { } else if (filter.type == "SortFilter") {
final sort = filter.values[filter.state].value; sort = filter.values[filter.state].value;
url += "${ll(url)}orby=$sort";
} else if (filter.type == "StatusFilter") { } else if (filter.type == "StatusFilter") {
final status = filter.values[filter.state].value; status = filter.values[filter.state].value;
url += "${ll(url)}sts=$status";
} else if (filter.type == "GenreListFilter") {
final included =
(filter.state as List)
.where((e) => e.state == 1 ? true : false)
.toList();
final excluded =
(filter.state as List)
.where((e) => e.state == 2 ? true : false)
.toList();
if (included.isNotEmpty) {
for (var val in included) {
genreInclude += "_${val.value}";
}
}
if (excluded.isNotEmpty) {
for (var val in excluded) {
genreExclude += "_${val.value}";
}
}
}
}
url += "${ll(url)}g_i=$genreInclude";
url += "${ll(url)}g_e=$genreExclude";
} else {
for (var filter in filters) {
if (filter.type == "SortFilter") {
final sort = filter.values[filter.state].value;
url += "${ll(url)}type=$sort";
} else if (filter.type == "StatusFilter") {
final status = filter.values[filter.state].value;
url += "${ll(url)}state=$status";
} else if (filter.type == "GenreListFilter") {
final genre = filter.values[filter.state].value;
url += "${ll(url)}category=$genre";
}
} }
} }
url = "${source.baseUrl}/genre/$genre?type=$sort&state=$status&page=$page";
} }
final res = (await client.get(Uri.parse(url))).body; final res = (await client.get(Uri.parse(url), headers: getHeader(source.baseUrl),)).body;
List<MManga> mangaList = []; List<MManga> mangaList = [];
List<String> urls = []; List<String> urls = [];
@@ -143,7 +110,10 @@ class MangaBox extends MProvider {
{"Ongoing": 0, "Completed": 1}, {"Ongoing": 0, "Completed": 1},
]; ];
MManga manga = MManga(); MManga manga = MManga();
final res = (await client.get(Uri.parse(url))).body; final res = (await client.get(
Uri.parse(url),
headers: getHeader(source.baseUrl),
)).body;
final document = parseHtml(res); final document = parseHtml(res);
manga.author = manga.author =
document.xpathFirst( document.xpathFirst(
@@ -159,7 +129,7 @@ class MangaBox extends MProvider {
final description = final description =
document.xpathFirst( document.xpathFirst(
'//*[@id="panel-story-info-description" ]/text() | //*[@id="story_discription" ]/text() | //div[@id="noidungm"]/text()', '//*[@id="contentBox" ]/text() | //*[@id="story_discription" ]/text() | //div[@id="noidungm"]/text()',
) ?? ) ??
""; "";
@@ -219,7 +189,7 @@ class MangaBox extends MProvider {
@override @override
Future<List<String>> getPageList(String url) async { Future<List<String>> getPageList(String url) async {
final res = (await client.get(Uri.parse(url))).body; final res = (await client.get(Uri.parse(url), headers: getHeader(source.baseUrl),)).body;
List<String> pageUrls = []; List<String> pageUrls = [];
final urls = xpath( final urls = xpath(
res, res,
@@ -270,39 +240,27 @@ class MangaBox extends MProvider {
} }
String popularUrlPath(String sourceName, int page) { String popularUrlPath(String sourceName, int page) {
if (sourceName == "Manganato") { if (sourceName != "Mangairo") {
return "genre-all/$page?type=topview"; return "manga-list/hot-manga?page=$page";
} else if (sourceName == "Mangabat") { } else {
return "manga-list-all/$page?type=topview";
} else if (sourceName == "Mangairo") {
return "manga-list/type-topview/ctg-all/state-all/page-$page"; return "manga-list/type-topview/ctg-all/state-all/page-$page";
} }
return "manga_list?type=topview&category=all&state=all&page=$page";
} }
String latestUrlPath(String sourceName, int page) { String latestUrlPath(String sourceName, int page) {
if (sourceName == "Manganato") { if (sourceName != "Mangairo") {
return "genre-all/$page"; return "manga-list/latest-manga?page=$page";
} else if (sourceName == "Mangabat") { } else {
return "manga-list-all/$page";
} else if (sourceName == "Mangairo") {
return "manga-list/type-latest/ctg-all/state-all/page-$page"; return "manga-list/type-latest/ctg-all/state-all/page-$page";
} }
return "manga_list?type=latest&category=all&state=all&page=$page";
} }
String simpleQueryPath(String sourceName, int page, String query) { String simpleQueryPath(String sourceName, int page, String query) {
if (sourceName == "Mangakakalot") { if (sourceName == "Mangairo") {
return "search/story/${normalizeSearchQuery(query)}?page=$page";
} else if (sourceName == "Mangairo") {
return "list/search/${normalizeSearchQuery(query)}?page=$page"; return "list/search/${normalizeSearchQuery(query)}?page=$page";
} else if (sourceName == "Mangabat") { } else {
return "search/manga/${normalizeSearchQuery(query)}?page=$page";
} else if (sourceName == "Manganato") {
return "search/story/${normalizeSearchQuery(query)}?page=$page"; return "search/story/${normalizeSearchQuery(query)}?page=$page";
} }
return "search/${normalizeSearchQuery(query)}?page=$page";
} }
String normalizeSearchQuery(String query) { String normalizeSearchQuery(String query) {
@@ -331,12 +289,7 @@ class MangaBox extends MProvider {
return []; return [];
} }
return [ return [
SelectFilter("KeywordFilter", "Keyword search:", 0, [ HeaderFilter("NOTE: The filter is ignored when using text search."),
SelectFilterOption("Everything", ""),
SelectFilterOption("Title", "title"),
SelectFilterOption("Alt title", "alternative"),
SelectFilterOption("Author", "author"),
]),
SelectFilter("SortFilter", "Order by:", 0, [ SelectFilter("SortFilter", "Order by:", 0, [
SelectFilterOption("Latest", "latest"), SelectFilterOption("Latest", "latest"),
SelectFilterOption("Newest", "newest"), SelectFilterOption("Newest", "newest"),
@@ -348,92 +301,52 @@ class MangaBox extends MProvider {
SelectFilterOption("Ongoing", "ongoing"), SelectFilterOption("Ongoing", "ongoing"),
SelectFilterOption("Dropped", "drop"), SelectFilterOption("Dropped", "drop"),
]), ]),
if (source.name == "Manganato" || source.name == "Mangabat")
GroupFilter("GenreListFilter", "Category:", [
TriStateFilter("Action", "2"),
TriStateFilter("Adult", "3"),
TriStateFilter("Adventure", "4"),
TriStateFilter("Comedy", "6"),
TriStateFilter("Cooking", "7"),
TriStateFilter("Doujinshi", "9"),
TriStateFilter("Drama", "10"),
TriStateFilter("Ecchi", "11"),
TriStateFilter("Fantasy", "12"),
TriStateFilter("Gender bender", "13"),
TriStateFilter("Harem", "14"),
TriStateFilter("Historical", "15"),
TriStateFilter("Horror", "16"),
TriStateFilter("Isekai", "45"),
TriStateFilter("Josei", "17"),
TriStateFilter("Manhua", "44"),
TriStateFilter("Manhwa", "43"),
TriStateFilter("Martial arts", "19"),
TriStateFilter("Mature", "20"),
TriStateFilter("Mecha", "21"),
TriStateFilter("Medical", "22"),
TriStateFilter("Mystery", "24"),
TriStateFilter("One shot", "25"),
TriStateFilter("Psychological", "26"),
TriStateFilter("Romance", "27"),
TriStateFilter("School life", "28"),
TriStateFilter("Sci fi", "29"),
TriStateFilter("Seinen", "30"),
TriStateFilter("Shoujo", "31"),
TriStateFilter("Shoujo ai", "32"),
TriStateFilter("Shounen", "33"),
TriStateFilter("Shounen ai", "34"),
TriStateFilter("Slice of life", "35"),
TriStateFilter("Smut", "36"),
TriStateFilter("Sports", "37"),
TriStateFilter("Supernatural", "38"),
TriStateFilter("Tragedy", "39"),
TriStateFilter("Webtoons", "40"),
TriStateFilter("Yaoi", "41"),
TriStateFilter("Yuri", "42"),
]),
if (source.name != "Manganato" && source.name != "Mangabat")
SelectFilter("GenreListFilter", "Category:", 0, [ SelectFilter("GenreListFilter", "Category:", 0, [
SelectFilterOption("ALL", "all"), SelectFilterOption("ALL", "all"),
SelectFilterOption("Action", "2"), SelectFilterOption("Action", "action"),
SelectFilterOption("Adult", "3"), SelectFilterOption("Adult", "adult"),
SelectFilterOption("Adventure", "4"), SelectFilterOption("Adventure", "adventure"),
SelectFilterOption("Comedy", "6"), SelectFilterOption("Comedy", "comedy"),
SelectFilterOption("Cooking", "7"), SelectFilterOption("Cooking", "cooking"),
SelectFilterOption("Doujinshi", "9"), SelectFilterOption("Doujinshi", "doujinshi"),
SelectFilterOption("Drama", "10"), SelectFilterOption("Drama", "drama"),
SelectFilterOption("Ecchi", "11"), SelectFilterOption("Ecchi", "ecchi"),
SelectFilterOption("Fantasy", "12"), SelectFilterOption("Fantasy", "fantasy"),
SelectFilterOption("Gender bender", "13"), SelectFilterOption("Gender Bender", "gender-bender"),
SelectFilterOption("Harem", "14"), SelectFilterOption("Harem", "harem"),
SelectFilterOption("Historical", "15"), SelectFilterOption("Historical", "historical"),
SelectFilterOption("Horror", "16"), SelectFilterOption("Horror", "horror"),
SelectFilterOption("Isekai", "45"), SelectFilterOption("Isekai", "isekai"),
SelectFilterOption("Josei", "17"), SelectFilterOption("Josei", "josei"),
SelectFilterOption("Manhua", "44"), SelectFilterOption("Manhua", "manhua"),
SelectFilterOption("Manhwa", "43"), SelectFilterOption("Manhwa", "manhwa"),
SelectFilterOption("Martial arts", "19"), SelectFilterOption("Martial arts", "martial-arts"),
SelectFilterOption("Mature", "20"), SelectFilterOption("Mature", "mature"),
SelectFilterOption("Mecha", "21"), SelectFilterOption("Mecha", "mecha"),
SelectFilterOption("Medical", "22"), SelectFilterOption("Medical", "medical"),
SelectFilterOption("Mystery", "24"), SelectFilterOption("Mystery", "mystery"),
SelectFilterOption("One shot", "25"), SelectFilterOption("One shot", "one-shot"),
SelectFilterOption("Psychological", "26"), SelectFilterOption("Psychological", "psychological"),
SelectFilterOption("Romance", "27"), SelectFilterOption("Reincarnation", "reincarnation"),
SelectFilterOption("School life", "28"), SelectFilterOption("Romance", "romance"),
SelectFilterOption("Sci fi", "29"), SelectFilterOption("School life", "school-life"),
SelectFilterOption("Seinen", "30"), SelectFilterOption("Sci fi", "sci-fi"),
SelectFilterOption("Shoujo", "31"), SelectFilterOption("Seinen", "seinen"),
SelectFilterOption("Shoujo ai", "32"), SelectFilterOption("Shoujo", "shoujo"),
SelectFilterOption("Shounen", "33"), SelectFilterOption("Shoujo ai", "shoujo-ai"),
SelectFilterOption("Shounen ai", "34"), SelectFilterOption("Shounen", "shounen"),
SelectFilterOption("Slice of life", "35"), SelectFilterOption("Shounen ai", "shounen-ai"),
SelectFilterOption("Smut", "36"), SelectFilterOption("Slice of life", "slice-of-life"),
SelectFilterOption("Sports", "37"), SelectFilterOption("Smut", "smut"),
SelectFilterOption("Supernatural", "38"), SelectFilterOption("Sports", "sports"),
SelectFilterOption("Tragedy", "39"), SelectFilterOption("Supernatural", "supernatural"),
SelectFilterOption("Webtoons", "40"), SelectFilterOption("Survival", "survival"),
SelectFilterOption("Yaoi", "41"), SelectFilterOption("System", "system"),
SelectFilterOption("Yuri", "42"), SelectFilterOption("Thriller", "thriller"),
SelectFilterOption("Tragedy", "tragedy"),
SelectFilterOption("Webtoons", "webtoons"),
SelectFilterOption("Yaoi", "yaoi"),
SelectFilterOption("Yuri", "yuri"),
]), ]),
]; ];
} }
@@ -447,7 +360,10 @@ class MangaBox extends MProvider {
} }
Map<String, String> getHeader(String url) { Map<String, String> getHeader(String url) {
final headers = {'referer': '$url/'}; final Map<String, String> headers = {
"Referer": "$url/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
};
return headers; return headers;
} }

View File

@@ -4,7 +4,7 @@ import 'src/mangairo/mangaeiro.dart';
import 'src/mangakakalot/mangakakalot.dart'; import 'src/mangakakalot/mangakakalot.dart';
import 'src/manganato/manganato.dart'; import 'src/manganato/manganato.dart';
const mangaboxVersion = "0.0.6"; const mangaboxVersion = "0.0.65";
const mangaboxSourceCodeUrl = const mangaboxSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/mangabox/mangabox.dart"; "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/mangabox/mangabox.dart";

View File

@@ -4,7 +4,7 @@ Source get mangabatSource => _mangabatSource;
Source _mangabatSource = Source( Source _mangabatSource = Source(
name: "Mangabat", name: "Mangabat",
baseUrl: "https://m.mangabat.com", baseUrl: "https://www.mangabats.com",
lang: "en", lang: "en",
typeSource: "mangabox", typeSource: "mangabox",
iconUrl: iconUrl:

View File

@@ -4,7 +4,7 @@ Source get mangakakalotSource => _mangakakalotSource;
Source _mangakakalotSource = Source( Source _mangakakalotSource = Source(
name: "Mangakakalot", name: "Mangakakalot",
baseUrl: "https://mangakakalot.com", baseUrl: "https://www.mangakakalot.gg",
lang: "en", lang: "en",
typeSource: "mangabox", typeSource: "mangabox",
iconUrl: iconUrl:

View File

@@ -4,7 +4,7 @@ Source get manganatoSource => _manganatoSource;
Source _manganatoSource = Source( Source _manganatoSource = Source(
name: "Manganato", name: "Manganato",
baseUrl: "https://manganato.com", baseUrl: "https://www.natomanga.com",
lang: "en", lang: "en",
typeSource: "mangabox", typeSource: "mangabox",
iconUrl: iconUrl:

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@ const mangayomiSources = [{
"typeSource": "single", "typeSource": "single",
"isManga": true, "isManga": true,
"isNsfw": false, "isNsfw": false,
"version": "0.0.3", "version": "0.0.35",
"dateFormat": "", "dateFormat": "",
"dateFormatLocale": "", "dateFormatLocale": "",
"pkgPath": "manga/src/all/webtoons.js" "pkgPath": "manga/src/all/webtoons.js"
@@ -137,7 +137,7 @@ class DefaultExtension extends MProvider {
const res = await new Client().get(url); const res = await new Client().get(url);
const doc = new Document(res.body); const doc = new Document(res.body);
const info = doc.selectFirst("div.cont_box"); const info = doc.selectFirst("div.cont_box");
const cover = info.selectFirst("div.detail_body")?.attr("style")?.substringAfter("url(")?.substringBeforeLast(")") ?? info.selectFirst("span.thmb img").attr('src'); const cover = info.selectFirst("div.detail_body")?.attr("style")?.match(/url\(['"]?(.*?)['"]?\)/)?.[1] ?? info.selectFirst("span.thmb img")?.attr("src");
const title = info.selectFirst("h1.subj, h3.subj").text.trim(); const title = info.selectFirst("h1.subj, h3.subj").text.trim();
const genre = Array.from(info.select("p.genre")).map(el => el.text) != '' ? Array.from(info.select("p.genre")).map(el => el.text) : [info.selectFirst("div.info h2").text]; const genre = Array.from(info.select("p.genre")).map(el => el.text) != '' ? Array.from(info.select("p.genre")).map(el => el.text) : [info.selectFirst("div.info h2").text];
const author = info.selectFirst("div.author_area").text.replace(/\s+/g, ' ').replace(/author info/g, '').trim() ?? info.selectFirst("a.author").text; const author = info.selectFirst("div.author_area").text.replace(/\s+/g, ' ').replace(/author info/g, '').trim() ?? info.selectFirst("a.author").text;