|
|
|
|
@@ -1,5 +1,6 @@
|
|
|
|
|
import 'package:mangayomi/bridge_lib.dart';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MangaBox extends MProvider {
|
|
|
|
|
MangaBox({required this.source});
|
|
|
|
|
|
|
|
|
|
@@ -12,6 +13,7 @@ class MangaBox extends MProvider {
|
|
|
|
|
final res =
|
|
|
|
|
(await client.get(
|
|
|
|
|
Uri.parse("${source.baseUrl}/${popularUrlPath(source.name, page)}"),
|
|
|
|
|
headers: getHeader(source.baseUrl),
|
|
|
|
|
)).body;
|
|
|
|
|
return mangaRes(res);
|
|
|
|
|
}
|
|
|
|
|
@@ -21,6 +23,7 @@ class MangaBox extends MProvider {
|
|
|
|
|
final res =
|
|
|
|
|
(await client.get(
|
|
|
|
|
Uri.parse("${source.baseUrl}/${latestUrlPath(source.name, page)}"),
|
|
|
|
|
headers: getHeader(source.baseUrl),
|
|
|
|
|
)).body;
|
|
|
|
|
return mangaRes(res);
|
|
|
|
|
}
|
|
|
|
|
@@ -30,66 +33,30 @@ class MangaBox extends MProvider {
|
|
|
|
|
final filters = filterList.filters;
|
|
|
|
|
|
|
|
|
|
String url = "";
|
|
|
|
|
if (query.isNotEmpty &&
|
|
|
|
|
(source.name != "Manganato" && source.name != "Mangabat")) {
|
|
|
|
|
if (query.isNotEmpty) {
|
|
|
|
|
|
|
|
|
|
url = "${source.baseUrl}/${simpleQueryPath(source.name, page, query)}";
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
url = source.baseUrl;
|
|
|
|
|
if (source.name == "Manganato" || source.name == "Mangabat") {
|
|
|
|
|
url +=
|
|
|
|
|
"/advanced_search?page=$page&keyw=${normalizeSearchQuery(query)}";
|
|
|
|
|
String genreInclude = "";
|
|
|
|
|
String genreExclude = "";
|
|
|
|
|
for (var filter in filters) {
|
|
|
|
|
if (filter.type == "KeywordFilter") {
|
|
|
|
|
final key = filter.values[filter.state].value;
|
|
|
|
|
url += "${ll(url)}keyt=$key";
|
|
|
|
|
} else if (filter.type == "SortFilter") {
|
|
|
|
|
final sort = filter.values[filter.state].value;
|
|
|
|
|
url += "${ll(url)}orby=$sort";
|
|
|
|
|
} else if (filter.type == "StatusFilter") {
|
|
|
|
|
final 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";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String genre = "all";
|
|
|
|
|
String sort = "latest";
|
|
|
|
|
String status = "all";
|
|
|
|
|
|
|
|
|
|
for (var filter in filters) {
|
|
|
|
|
if (filter.type == "GenreListFilter") {
|
|
|
|
|
genre = filter.values[filter.state].value;
|
|
|
|
|
} else if (filter.type == "SortFilter") {
|
|
|
|
|
sort = filter.values[filter.state].value;
|
|
|
|
|
} else if (filter.type == "StatusFilter") {
|
|
|
|
|
status = filter.values[filter.state].value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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<String> urls = [];
|
|
|
|
|
@@ -143,7 +110,10 @@ class MangaBox extends MProvider {
|
|
|
|
|
{"Ongoing": 0, "Completed": 1},
|
|
|
|
|
];
|
|
|
|
|
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);
|
|
|
|
|
manga.author =
|
|
|
|
|
document.xpathFirst(
|
|
|
|
|
@@ -159,7 +129,7 @@ class MangaBox extends MProvider {
|
|
|
|
|
|
|
|
|
|
final description =
|
|
|
|
|
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
|
|
|
|
|
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 = [];
|
|
|
|
|
final urls = xpath(
|
|
|
|
|
res,
|
|
|
|
|
@@ -270,39 +240,27 @@ class MangaBox extends MProvider {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String popularUrlPath(String sourceName, int page) {
|
|
|
|
|
if (sourceName == "Manganato") {
|
|
|
|
|
return "genre-all/$page?type=topview";
|
|
|
|
|
} else if (sourceName == "Mangabat") {
|
|
|
|
|
return "manga-list-all/$page?type=topview";
|
|
|
|
|
} else if (sourceName == "Mangairo") {
|
|
|
|
|
if (sourceName != "Mangairo") {
|
|
|
|
|
return "manga-list/hot-manga?page=$page";
|
|
|
|
|
} else {
|
|
|
|
|
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) {
|
|
|
|
|
if (sourceName == "Manganato") {
|
|
|
|
|
return "genre-all/$page";
|
|
|
|
|
} else if (sourceName == "Mangabat") {
|
|
|
|
|
return "manga-list-all/$page";
|
|
|
|
|
} else if (sourceName == "Mangairo") {
|
|
|
|
|
if (sourceName != "Mangairo") {
|
|
|
|
|
return "manga-list/latest-manga?page=$page";
|
|
|
|
|
} else {
|
|
|
|
|
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) {
|
|
|
|
|
if (sourceName == "Mangakakalot") {
|
|
|
|
|
return "search/story/${normalizeSearchQuery(query)}?page=$page";
|
|
|
|
|
} else if (sourceName == "Mangairo") {
|
|
|
|
|
if (sourceName == "Mangairo") {
|
|
|
|
|
return "list/search/${normalizeSearchQuery(query)}?page=$page";
|
|
|
|
|
} else if (sourceName == "Mangabat") {
|
|
|
|
|
return "search/manga/${normalizeSearchQuery(query)}?page=$page";
|
|
|
|
|
} else if (sourceName == "Manganato") {
|
|
|
|
|
} else {
|
|
|
|
|
return "search/story/${normalizeSearchQuery(query)}?page=$page";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "search/${normalizeSearchQuery(query)}?page=$page";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String normalizeSearchQuery(String query) {
|
|
|
|
|
@@ -331,12 +289,7 @@ class MangaBox extends MProvider {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
return [
|
|
|
|
|
SelectFilter("KeywordFilter", "Keyword search:", 0, [
|
|
|
|
|
SelectFilterOption("Everything", ""),
|
|
|
|
|
SelectFilterOption("Title", "title"),
|
|
|
|
|
SelectFilterOption("Alt title", "alternative"),
|
|
|
|
|
SelectFilterOption("Author", "author"),
|
|
|
|
|
]),
|
|
|
|
|
HeaderFilter("NOTE: The filter is ignored when using text search."),
|
|
|
|
|
SelectFilter("SortFilter", "Order by:", 0, [
|
|
|
|
|
SelectFilterOption("Latest", "latest"),
|
|
|
|
|
SelectFilterOption("Newest", "newest"),
|
|
|
|
|
@@ -348,93 +301,53 @@ class MangaBox extends MProvider {
|
|
|
|
|
SelectFilterOption("Ongoing", "ongoing"),
|
|
|
|
|
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, [
|
|
|
|
|
SelectFilterOption("ALL", "all"),
|
|
|
|
|
SelectFilterOption("Action", "2"),
|
|
|
|
|
SelectFilterOption("Adult", "3"),
|
|
|
|
|
SelectFilterOption("Adventure", "4"),
|
|
|
|
|
SelectFilterOption("Comedy", "6"),
|
|
|
|
|
SelectFilterOption("Cooking", "7"),
|
|
|
|
|
SelectFilterOption("Doujinshi", "9"),
|
|
|
|
|
SelectFilterOption("Drama", "10"),
|
|
|
|
|
SelectFilterOption("Ecchi", "11"),
|
|
|
|
|
SelectFilterOption("Fantasy", "12"),
|
|
|
|
|
SelectFilterOption("Gender bender", "13"),
|
|
|
|
|
SelectFilterOption("Harem", "14"),
|
|
|
|
|
SelectFilterOption("Historical", "15"),
|
|
|
|
|
SelectFilterOption("Horror", "16"),
|
|
|
|
|
SelectFilterOption("Isekai", "45"),
|
|
|
|
|
SelectFilterOption("Josei", "17"),
|
|
|
|
|
SelectFilterOption("Manhua", "44"),
|
|
|
|
|
SelectFilterOption("Manhwa", "43"),
|
|
|
|
|
SelectFilterOption("Martial arts", "19"),
|
|
|
|
|
SelectFilterOption("Mature", "20"),
|
|
|
|
|
SelectFilterOption("Mecha", "21"),
|
|
|
|
|
SelectFilterOption("Medical", "22"),
|
|
|
|
|
SelectFilterOption("Mystery", "24"),
|
|
|
|
|
SelectFilterOption("One shot", "25"),
|
|
|
|
|
SelectFilterOption("Psychological", "26"),
|
|
|
|
|
SelectFilterOption("Romance", "27"),
|
|
|
|
|
SelectFilterOption("School life", "28"),
|
|
|
|
|
SelectFilterOption("Sci fi", "29"),
|
|
|
|
|
SelectFilterOption("Seinen", "30"),
|
|
|
|
|
SelectFilterOption("Shoujo", "31"),
|
|
|
|
|
SelectFilterOption("Shoujo ai", "32"),
|
|
|
|
|
SelectFilterOption("Shounen", "33"),
|
|
|
|
|
SelectFilterOption("Shounen ai", "34"),
|
|
|
|
|
SelectFilterOption("Slice of life", "35"),
|
|
|
|
|
SelectFilterOption("Smut", "36"),
|
|
|
|
|
SelectFilterOption("Sports", "37"),
|
|
|
|
|
SelectFilterOption("Supernatural", "38"),
|
|
|
|
|
SelectFilterOption("Tragedy", "39"),
|
|
|
|
|
SelectFilterOption("Webtoons", "40"),
|
|
|
|
|
SelectFilterOption("Yaoi", "41"),
|
|
|
|
|
SelectFilterOption("Yuri", "42"),
|
|
|
|
|
]),
|
|
|
|
|
SelectFilter("GenreListFilter", "Category:", 0, [
|
|
|
|
|
SelectFilterOption("ALL", "all"),
|
|
|
|
|
SelectFilterOption("Action", "action"),
|
|
|
|
|
SelectFilterOption("Adult", "adult"),
|
|
|
|
|
SelectFilterOption("Adventure", "adventure"),
|
|
|
|
|
SelectFilterOption("Comedy", "comedy"),
|
|
|
|
|
SelectFilterOption("Cooking", "cooking"),
|
|
|
|
|
SelectFilterOption("Doujinshi", "doujinshi"),
|
|
|
|
|
SelectFilterOption("Drama", "drama"),
|
|
|
|
|
SelectFilterOption("Ecchi", "ecchi"),
|
|
|
|
|
SelectFilterOption("Fantasy", "fantasy"),
|
|
|
|
|
SelectFilterOption("Gender Bender", "gender-bender"),
|
|
|
|
|
SelectFilterOption("Harem", "harem"),
|
|
|
|
|
SelectFilterOption("Historical", "historical"),
|
|
|
|
|
SelectFilterOption("Horror", "horror"),
|
|
|
|
|
SelectFilterOption("Isekai", "isekai"),
|
|
|
|
|
SelectFilterOption("Josei", "josei"),
|
|
|
|
|
SelectFilterOption("Manhua", "manhua"),
|
|
|
|
|
SelectFilterOption("Manhwa", "manhwa"),
|
|
|
|
|
SelectFilterOption("Martial arts", "martial-arts"),
|
|
|
|
|
SelectFilterOption("Mature", "mature"),
|
|
|
|
|
SelectFilterOption("Mecha", "mecha"),
|
|
|
|
|
SelectFilterOption("Medical", "medical"),
|
|
|
|
|
SelectFilterOption("Mystery", "mystery"),
|
|
|
|
|
SelectFilterOption("One shot", "one-shot"),
|
|
|
|
|
SelectFilterOption("Psychological", "psychological"),
|
|
|
|
|
SelectFilterOption("Reincarnation", "reincarnation"),
|
|
|
|
|
SelectFilterOption("Romance", "romance"),
|
|
|
|
|
SelectFilterOption("School life", "school-life"),
|
|
|
|
|
SelectFilterOption("Sci fi", "sci-fi"),
|
|
|
|
|
SelectFilterOption("Seinen", "seinen"),
|
|
|
|
|
SelectFilterOption("Shoujo", "shoujo"),
|
|
|
|
|
SelectFilterOption("Shoujo ai", "shoujo-ai"),
|
|
|
|
|
SelectFilterOption("Shounen", "shounen"),
|
|
|
|
|
SelectFilterOption("Shounen ai", "shounen-ai"),
|
|
|
|
|
SelectFilterOption("Slice of life", "slice-of-life"),
|
|
|
|
|
SelectFilterOption("Smut", "smut"),
|
|
|
|
|
SelectFilterOption("Sports", "sports"),
|
|
|
|
|
SelectFilterOption("Supernatural", "supernatural"),
|
|
|
|
|
SelectFilterOption("Survival", "survival"),
|
|
|
|
|
SelectFilterOption("System", "system"),
|
|
|
|
|
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) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|