mirror of
https://github.com/kodjodevf/mangayomi-extensions.git
synced 2026-02-14 02:41:39 +00:00
dart format
This commit is contained in:
@@ -50,5 +50,5 @@ List<Source> dartAnimesourceList = [
|
||||
animesvision,
|
||||
diziwatchSource,
|
||||
aniZoneSource,
|
||||
animeonlineninjaSource
|
||||
animeonlineninjaSource,
|
||||
];
|
||||
|
||||
@@ -6,8 +6,10 @@ class DataLifeEngine extends MProvider {
|
||||
|
||||
MSource source;
|
||||
|
||||
final Client client =
|
||||
Client(source, json.encode({"useDartHttpClient": true}));
|
||||
final Client client = Client(
|
||||
source,
|
||||
json.encode({"useDartHttpClient": true}),
|
||||
);
|
||||
|
||||
@override
|
||||
bool get supportsLatest => false;
|
||||
@@ -18,8 +20,9 @@ class DataLifeEngine extends MProvider {
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res =
|
||||
(await client.get(Uri.parse("$baseUrl${getPath(source)}page/$page")))
|
||||
.body;
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl${getPath(source)}page/$page"),
|
||||
)).body;
|
||||
return animeFromElement(res);
|
||||
}
|
||||
|
||||
@@ -38,21 +41,25 @@ class DataLifeEngine extends MProvider {
|
||||
final headers = {
|
||||
"Host": Uri.parse(baseUrl).host,
|
||||
"Origin": baseUrl,
|
||||
"Referer": "$baseUrl/"
|
||||
"Referer": "$baseUrl/",
|
||||
};
|
||||
final cleanQuery = query.replaceAll(" ", "+");
|
||||
if (page == 1) {
|
||||
res = (await client.post(
|
||||
res =
|
||||
(await client.post(
|
||||
Uri.parse(
|
||||
"$baseUrl?do=search&subaction=search&story=$cleanQuery"),
|
||||
headers: headers))
|
||||
.body;
|
||||
"$baseUrl?do=search&subaction=search&story=$cleanQuery",
|
||||
),
|
||||
headers: headers,
|
||||
)).body;
|
||||
} else {
|
||||
res = (await client.post(
|
||||
res =
|
||||
(await client.post(
|
||||
Uri.parse(
|
||||
"$baseUrl?do=search&subaction=search&search_start=$page&full_search=0&result_from=11&story=$cleanQuery"),
|
||||
headers: headers))
|
||||
.body;
|
||||
"$baseUrl?do=search&subaction=search&search_start=$page&full_search=0&result_from=11&story=$cleanQuery",
|
||||
),
|
||||
headers: headers,
|
||||
)).body;
|
||||
}
|
||||
} else {
|
||||
String url = "";
|
||||
@@ -76,8 +83,9 @@ class DataLifeEngine extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
String res =
|
||||
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
|
||||
.body;
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl${getUrlWithoutDomain(url)}"),
|
||||
)).body;
|
||||
MManga anime = MManga();
|
||||
final description = xpath(res, '//span[@itemprop="description"]/text()');
|
||||
anime.description = description.isNotEmpty ? description.first : "";
|
||||
@@ -96,9 +104,12 @@ class DataLifeEngine extends MProvider {
|
||||
}
|
||||
} else {
|
||||
final doc = parseHtml(res);
|
||||
final elements = doc
|
||||
final elements =
|
||||
doc
|
||||
.select(".hostsblock div:has(a)")
|
||||
.where((MElement e) => e.outerHtml.contains("loadVideo('https://"))
|
||||
.where(
|
||||
(MElement e) => e.outerHtml.contains("loadVideo('https://"),
|
||||
)
|
||||
.toList();
|
||||
if (elements.isNotEmpty) {
|
||||
for (var element in elements) {
|
||||
@@ -110,8 +121,12 @@ class DataLifeEngine extends MProvider {
|
||||
.replaceAll("vf", " VF");
|
||||
ep.url = element
|
||||
.select("a")
|
||||
.map((MElement e) => substringBefore(
|
||||
substringAfter(e.attr('onclick'), "loadVideo('"), "')"))
|
||||
.map(
|
||||
(MElement e) => substringBefore(
|
||||
substringAfter(e.attr('onclick'), "loadVideo('"),
|
||||
"')",
|
||||
),
|
||||
)
|
||||
.toList()
|
||||
.join(",")
|
||||
.replaceAll("/vd.php?u=", "");
|
||||
@@ -124,8 +139,12 @@ class DataLifeEngine extends MProvider {
|
||||
ep.url = doc
|
||||
.select("a")
|
||||
.where((MElement e) => e.outerHtml.contains("loadVideo('https://"))
|
||||
.map((MElement e) => substringBefore(
|
||||
substringAfter(e.attr('onclick'), "loadVideo('"), "')"))
|
||||
.map(
|
||||
(MElement e) => substringBefore(
|
||||
substringAfter(e.attr('onclick'), "loadVideo('"),
|
||||
"')",
|
||||
),
|
||||
)
|
||||
.toList()
|
||||
.join(",")
|
||||
.replaceAll("/vd.php?u=", "");
|
||||
@@ -145,8 +164,12 @@ class DataLifeEngine extends MProvider {
|
||||
List<MVideo> a = [];
|
||||
if (sUrl.contains("dood") || sUrl.contains("d000")) {
|
||||
a = await doodExtractor(sUrl, "DoodStream");
|
||||
} else if (["streamhide", "guccihide", "streamvid", "dhtpre"]
|
||||
.any((a) => sUrl.contains(a))) {
|
||||
} else if ([
|
||||
"streamhide",
|
||||
"guccihide",
|
||||
"streamvid",
|
||||
"dhtpre",
|
||||
].any((a) => sUrl.contains(a))) {
|
||||
a = await streamHideExtractor(sUrl);
|
||||
} else if (sUrl.contains("uqload")) {
|
||||
a = await uqloadExtractor(sUrl);
|
||||
@@ -192,14 +215,17 @@ class DataLifeEngine extends MProvider {
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final masterUrl = substringBefore(
|
||||
substringAfter(
|
||||
substringAfter(
|
||||
substringAfter(unpackJs(res), "sources:"), "file:\""),
|
||||
"src:\""),
|
||||
'"');
|
||||
substringAfter(substringAfter(unpackJs(res), "sources:"), "file:\""),
|
||||
"src:\"",
|
||||
),
|
||||
'"',
|
||||
);
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
List<MVideo> videos = [];
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -226,12 +252,16 @@ class DataLifeEngine extends MProvider {
|
||||
if (js.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
final masterUrl =
|
||||
substringBefore(substringAfter(unpackJs(js.first), "{file:\""), "\"}");
|
||||
final masterUrl = substringBefore(
|
||||
substringAfter(unpackJs(js.first), "{file:\""),
|
||||
"\"}",
|
||||
);
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
List<MVideo> videos = [];
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -259,8 +289,10 @@ class DataLifeEngine extends MProvider {
|
||||
return [];
|
||||
}
|
||||
|
||||
final videoUrl =
|
||||
substringBefore(substringAfter(js.first, "sources: [\""), '"');
|
||||
final videoUrl = substringBefore(
|
||||
substringAfter(js.first, "sources: [\""),
|
||||
'"',
|
||||
);
|
||||
MVideo video = MVideo();
|
||||
video
|
||||
..url = videoUrl
|
||||
@@ -271,22 +303,23 @@ class DataLifeEngine extends MProvider {
|
||||
}
|
||||
|
||||
Future<List<MVideo>> vidmolyExtractor(String url) async {
|
||||
final headers = {
|
||||
'Referer': 'https://vidmoly.to',
|
||||
};
|
||||
final headers = {'Referer': 'https://vidmoly.to'};
|
||||
List<MVideo> videos = [];
|
||||
final playListUrlResponse = (await client.get(Uri.parse(url))).body;
|
||||
final playlistUrl =
|
||||
RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ??
|
||||
"";
|
||||
if (playlistUrl.isEmpty) return [];
|
||||
final masterPlaylistRes =
|
||||
await client.get(Uri.parse(playlistUrl), headers: headers);
|
||||
final masterPlaylistRes = await client.get(
|
||||
Uri.parse(playlistUrl),
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (masterPlaylistRes.statusCode == 200) {
|
||||
for (var it
|
||||
in substringAfter(masterPlaylistRes.body, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes.body,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -321,7 +354,8 @@ class DataLifeEngine extends MProvider {
|
||||
value: "https://wiflix-hd.vip",
|
||||
dialogTitle: "Changer l'url de base",
|
||||
dialogMessage: "",
|
||||
text: "https://wiflix-hd.vip"),
|
||||
text: "https://wiflix-hd.vip",
|
||||
),
|
||||
if (source.name == "French Anime")
|
||||
EditTextPreference(
|
||||
key: "overrideBaseUrl",
|
||||
@@ -330,7 +364,8 @@ class DataLifeEngine extends MProvider {
|
||||
value: "https://french-anime.com",
|
||||
dialogTitle: "Changer l'url de base",
|
||||
dialogMessage: "",
|
||||
text: "https://french-anime.com"),
|
||||
text: "https://french-anime.com",
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -360,20 +395,20 @@ class DataLifeEngine extends MProvider {
|
||||
SelectFilterOption("Seinen", "/genre/seinen/"),
|
||||
SelectFilterOption("Horreur", "/genre/horreur/"),
|
||||
SelectFilterOption("Tranche de vie", "/genre/tranchedevie/"),
|
||||
SelectFilterOption("Psychologique", "/genre/psychologique/")
|
||||
SelectFilterOption("Psychologique", "/genre/psychologique/"),
|
||||
]),
|
||||
if (source.name == "French Anime")
|
||||
SelectFilter("GenresFilter", "Genres", 0, [
|
||||
SelectFilterOption("<Sélectionner>", ""),
|
||||
SelectFilterOption("Animes VF", "/animes-vf/"),
|
||||
SelectFilterOption("Animes VOSTFR", "/animes-vostfr/"),
|
||||
SelectFilterOption("Films VF et VOSTFR", "/films-vf-vostfr/")
|
||||
SelectFilterOption("Films VF et VOSTFR", "/films-vf-vostfr/"),
|
||||
]),
|
||||
if (source.name == "Wiflix")
|
||||
SelectFilter("CategoriesFilter", "Catégories", 0, [
|
||||
SelectFilterOption("<Sélectionner>", ""),
|
||||
SelectFilterOption("Séries", "/serie-en-streaming/"),
|
||||
SelectFilterOption("Films", "/film-en-streaming/")
|
||||
SelectFilterOption("Films", "/film-en-streaming/"),
|
||||
]),
|
||||
if (source.name == "Wiflix")
|
||||
SelectFilter("GenresFilter", "Genres", 0, [
|
||||
@@ -381,17 +416,25 @@ class DataLifeEngine extends MProvider {
|
||||
SelectFilterOption("Action", "/film-en-streaming/action/"),
|
||||
SelectFilterOption("Animation", "/film-en-streaming/animation/"),
|
||||
SelectFilterOption(
|
||||
"Arts Martiaux", "/film-en-streaming/arts-martiaux/"),
|
||||
"Arts Martiaux",
|
||||
"/film-en-streaming/arts-martiaux/",
|
||||
),
|
||||
SelectFilterOption("Aventure", "/film-en-streaming/aventure/"),
|
||||
SelectFilterOption("Biopic", "/film-en-streaming/biopic/"),
|
||||
SelectFilterOption("Comédie", "/film-en-streaming/comedie/"),
|
||||
SelectFilterOption(
|
||||
"Comédie Dramatique", "/film-en-streaming/comedie-dramatique/"),
|
||||
"Comédie Dramatique",
|
||||
"/film-en-streaming/comedie-dramatique/",
|
||||
),
|
||||
SelectFilterOption(
|
||||
"Épouvante Horreur", "/film-en-streaming/horreur/"),
|
||||
"Épouvante Horreur",
|
||||
"/film-en-streaming/horreur/",
|
||||
),
|
||||
SelectFilterOption("Drame", "/film-en-streaming/drame/"),
|
||||
SelectFilterOption(
|
||||
"Documentaire", "/film-en-streaming/documentaire/"),
|
||||
"Documentaire",
|
||||
"/film-en-streaming/documentaire/",
|
||||
),
|
||||
SelectFilterOption("Espionnage", "/film-en-streaming/espionnage/"),
|
||||
SelectFilterOption("Famille", "/film-en-streaming/famille/"),
|
||||
SelectFilterOption("Fantastique", "/film-en-streaming/fantastique/"),
|
||||
@@ -401,7 +444,9 @@ class DataLifeEngine extends MProvider {
|
||||
SelectFilterOption("Policier", "/film-en-streaming/policier/"),
|
||||
SelectFilterOption("Romance", "/film-en-streaming/romance/"),
|
||||
SelectFilterOption(
|
||||
"Science-Fiction", "/film-en-streaming/science-fiction/"),
|
||||
"Science-Fiction",
|
||||
"/film-en-streaming/science-fiction/",
|
||||
),
|
||||
SelectFilterOption("Spectacles", "/film-en-streaming/spectacles/"),
|
||||
SelectFilterOption("Thriller", "/film-en-streaming/thriller/"),
|
||||
SelectFilterOption("Western", "/film-en-streaming/western/"),
|
||||
|
||||
@@ -7,13 +7,17 @@ const _datalifeengineSourceCodeUrl =
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/datalifeengine/datalifeengine.dart";
|
||||
|
||||
List<Source> get datalifeengineSourcesList => _datalifeengineSourcesList;
|
||||
List<Source> _datalifeengineSourcesList = [
|
||||
List<Source> _datalifeengineSourcesList =
|
||||
[
|
||||
//French Anime (FR)
|
||||
frenchanimeSource,
|
||||
//Wiflix (FR)
|
||||
wiflixSource,
|
||||
]
|
||||
.map((e) => e
|
||||
.map(
|
||||
(e) =>
|
||||
e
|
||||
..sourceCodeUrl = _datalifeengineSourceCodeUrl
|
||||
..version = _datalifeengineVersion)
|
||||
..version = _datalifeengineVersion,
|
||||
)
|
||||
.toList();
|
||||
|
||||
@@ -13,9 +13,12 @@ class DopeFlix extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client.get(Uri.parse(
|
||||
"$baseUrl/${getPreferenceValue(source.id, "preferred_popular_page")}?page=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"$baseUrl/${getPreferenceValue(source.id, "preferred_popular_page")}?page=$page",
|
||||
),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@@ -109,25 +112,32 @@ class DopeFlix extends MProvider {
|
||||
final resS =
|
||||
(await client.get(Uri.parse("$baseUrl/ajax/v2/tv/seasons/$id"))).body;
|
||||
|
||||
final seasonIds =
|
||||
xpath(resS, '//a[@class="dropdown-item ss-item"]/@data-id');
|
||||
final seasonNames =
|
||||
xpath(resS, '//a[@class="dropdown-item ss-item"]/text()');
|
||||
final seasonIds = xpath(
|
||||
resS,
|
||||
'//a[@class="dropdown-item ss-item"]/@data-id',
|
||||
);
|
||||
final seasonNames = xpath(
|
||||
resS,
|
||||
'//a[@class="dropdown-item ss-item"]/text()',
|
||||
);
|
||||
for (int i = 0; i < seasonIds.length; i++) {
|
||||
final seasonId = seasonIds[i];
|
||||
final seasonName = seasonNames[i];
|
||||
|
||||
final html = (await client
|
||||
.get(Uri.parse("$baseUrl/ajax/v2/season/episodes/$seasonId")))
|
||||
.body;
|
||||
final html =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/ajax/v2/season/episodes/$seasonId"),
|
||||
)).body;
|
||||
|
||||
final epsHtmls = parseHtml(html).select("div.eps-item");
|
||||
|
||||
for (var epH in epsHtmls) {
|
||||
final epHtml = epH.outerHtml;
|
||||
final episodeId =
|
||||
xpath(epHtml, '//div[contains(@class,"eps-item")]/@data-id')
|
||||
.first;
|
||||
xpath(
|
||||
epHtml,
|
||||
'//div[contains(@class,"eps-item")]/@data-id',
|
||||
).first;
|
||||
final epNum =
|
||||
xpath(epHtml, '//div[@class="episode-number"]/text()').first;
|
||||
final epName = xpath(epHtml, '//h3[@class="film-name"]/text()').first;
|
||||
@@ -157,8 +167,10 @@ class DopeFlix extends MProvider {
|
||||
final resSource =
|
||||
(await client.get(Uri.parse("$baseUrl/ajax/sources/$id"))).body;
|
||||
|
||||
final vidUrl =
|
||||
substringBefore(substringAfter(resSource, "\"link\":\""), "\"");
|
||||
final vidUrl = substringBefore(
|
||||
substringAfter(resSource, "\"link\":\""),
|
||||
"\"",
|
||||
);
|
||||
List<MVideo> a = [];
|
||||
String masterUrl = "";
|
||||
String type = "";
|
||||
@@ -168,10 +180,11 @@ class DopeFlix extends MProvider {
|
||||
final id = substringBefore(substringAfter(vidUrl, "/embed-4/"), "?");
|
||||
final serverUrl = substringBefore(vidUrl, "/embed");
|
||||
|
||||
final resServer = (await client.get(
|
||||
final resServer =
|
||||
(await client.get(
|
||||
Uri.parse("$serverUrl/ajax/embed-4/getSources?id=$id"),
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"}))
|
||||
.body;
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"},
|
||||
)).body;
|
||||
final encrypted = getMapValue(resServer, "encrypted");
|
||||
|
||||
String videoResJson = "";
|
||||
@@ -192,10 +205,12 @@ class DopeFlix extends MProvider {
|
||||
index += item.last;
|
||||
}
|
||||
videoResJson = decryptAESCryptoJS(ciphertext, password);
|
||||
masterUrl = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
masterUrl =
|
||||
((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
.first)['file'];
|
||||
|
||||
type = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
type =
|
||||
((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
.first)['type'];
|
||||
} else {
|
||||
masterUrl =
|
||||
@@ -207,7 +222,8 @@ class DopeFlix extends MProvider {
|
||||
.first)['type'];
|
||||
}
|
||||
|
||||
final tracks = (json.decode(resServer)['tracks'] as List)
|
||||
final tracks =
|
||||
(json.decode(resServer)['tracks'] as List)
|
||||
.where((e) => e['kind'] == 'captions' ? true : false)
|
||||
.toList();
|
||||
List<MTrack> subtitles = [];
|
||||
@@ -227,8 +243,10 @@ class DopeFlix extends MProvider {
|
||||
final masterPlaylistRes =
|
||||
(await client.get(Uri.parse(masterUrl))).body;
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -264,13 +282,15 @@ class DopeFlix extends MProvider {
|
||||
}
|
||||
|
||||
Future<List<List<int>>> generateIndexPairs() async {
|
||||
final res = (await client.get(Uri.parse(
|
||||
"https://rabbitstream.net/js/player/prod/e4-player.min.js")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("https://rabbitstream.net/js/player/prod/e4-player.min.js"),
|
||||
)).body;
|
||||
|
||||
String script = substringBefore(substringAfter(res, "const "), "()");
|
||||
script = script.substring(0, script.lastIndexOf(','));
|
||||
final list = script
|
||||
final list =
|
||||
script
|
||||
.split(",")
|
||||
.map((String e) {
|
||||
String value = substringAfter(e, "=");
|
||||
@@ -283,9 +303,10 @@ class DopeFlix extends MProvider {
|
||||
.toList()
|
||||
.skip(1)
|
||||
.toList();
|
||||
return chunked(list, 2)
|
||||
.map((List<int> list) => list.reversed.toList())
|
||||
.toList();
|
||||
return chunked(
|
||||
list,
|
||||
2,
|
||||
).map((List<int> list) => list.reversed.toList()).toList();
|
||||
}
|
||||
|
||||
List<List<int>> chunked(List<int> list, int size) {
|
||||
@@ -316,7 +337,9 @@ class DopeFlix extends MProvider {
|
||||
animeList.add(anime);
|
||||
}
|
||||
final pages = xpath(
|
||||
res, '//ul[contains(@class,"pagination")]/li/a[@title="Next"]/@title');
|
||||
res,
|
||||
'//ul[contains(@class,"pagination")]/li/a[@title="Next"]/@title',
|
||||
);
|
||||
return MPages(animeList, pages.isNotEmpty);
|
||||
}
|
||||
|
||||
@@ -326,13 +349,13 @@ class DopeFlix extends MProvider {
|
||||
SelectFilter("TypeFilter", "Type", 0, [
|
||||
SelectFilterOption("All", "all"),
|
||||
SelectFilterOption("Movies", "movies"),
|
||||
SelectFilterOption("TV Shows", "tv")
|
||||
SelectFilterOption("TV Shows", "tv"),
|
||||
]),
|
||||
SelectFilter("QualityFilter", "Quality", 0, [
|
||||
SelectFilterOption("All", "all"),
|
||||
SelectFilterOption("HD", "HD"),
|
||||
SelectFilterOption("SD", "SD"),
|
||||
SelectFilterOption("CAM", "CAM")
|
||||
SelectFilterOption("CAM", "CAM"),
|
||||
]),
|
||||
SelectFilter("ReleaseYearFilter", "Released at", 0, [
|
||||
SelectFilterOption("All", "all"),
|
||||
@@ -343,7 +366,7 @@ class DopeFlix extends MProvider {
|
||||
SelectFilterOption("2020", "2020"),
|
||||
SelectFilterOption("2019", "2019"),
|
||||
SelectFilterOption("2018", "2018"),
|
||||
SelectFilterOption("Older", "older-2018")
|
||||
SelectFilterOption("Older", "older-2018"),
|
||||
]),
|
||||
SeparatorFilter(),
|
||||
GroupFilter("GenresFilter", "Genre", [
|
||||
@@ -374,7 +397,7 @@ class DopeFlix extends MProvider {
|
||||
CheckBoxFilter("TV Movie", "8"),
|
||||
CheckBoxFilter("War", "17"),
|
||||
CheckBoxFilter("War & Politics", "28"),
|
||||
CheckBoxFilter("Western", "6")
|
||||
CheckBoxFilter("Western", "6"),
|
||||
]),
|
||||
GroupFilter("CountriesFilter", "Countries", [
|
||||
CheckBoxFilter("Argentina", "11"),
|
||||
@@ -412,7 +435,7 @@ class DopeFlix extends MProvider {
|
||||
CheckBoxFilter("Taiwan", "119"),
|
||||
CheckBoxFilter("Thailand", "57"),
|
||||
CheckBoxFilter("United Kingdom", "180"),
|
||||
CheckBoxFilter("United States of America", "129")
|
||||
CheckBoxFilter("United States of America", "129"),
|
||||
]),
|
||||
];
|
||||
}
|
||||
@@ -427,7 +450,8 @@ class DopeFlix extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["dopebox.to", "dopebox.se"],
|
||||
entryValues: ["https://dopebox.to", "https://dopebox.se"]),
|
||||
entryValues: ["https://dopebox.to", "https://dopebox.se"],
|
||||
),
|
||||
if (source.name == "SFlix")
|
||||
ListPreference(
|
||||
key: "preferred_domain",
|
||||
@@ -435,14 +459,16 @@ class DopeFlix extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["sflix.to", "sflix.se"],
|
||||
entryValues: ["https://sflix.to", "https://sflix.se"]),
|
||||
entryValues: ["https://sflix.to", "https://sflix.se"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_quality",
|
||||
title: "Preferred Quality",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080p", "720p", "480p", "360p"]),
|
||||
entryValues: ["1080p", "720p", "480p", "360p"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_subLang",
|
||||
title: "Preferred sub language",
|
||||
@@ -459,7 +485,7 @@ class DopeFlix extends MProvider {
|
||||
"Portuguese",
|
||||
"Romanian",
|
||||
"Russian",
|
||||
"Spanish"
|
||||
"Spanish",
|
||||
],
|
||||
entryValues: [
|
||||
"Arabic",
|
||||
@@ -472,22 +498,25 @@ class DopeFlix extends MProvider {
|
||||
"Portuguese",
|
||||
"Romanian",
|
||||
"Russian",
|
||||
"Spanish"
|
||||
]),
|
||||
"Spanish",
|
||||
],
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_latest_page",
|
||||
title: "Preferred latest page",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Movies", "TV Shows"],
|
||||
entryValues: ["Latest Movies", "Latest TV Shows"]),
|
||||
entryValues: ["Latest Movies", "Latest TV Shows"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_popular_page",
|
||||
title: "Preferred popular page",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Movies", "TV Shows"],
|
||||
entryValues: ["movie", "tv-show"]),
|
||||
entryValues: ["movie", "tv-show"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,17 @@ const _dopeflixSourceCodeUrl =
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/dopeflix/dopeflix.dart";
|
||||
|
||||
List<Source> get dopeflixSourcesList => _dopeflixSourcesList;
|
||||
List<Source> _dopeflixSourcesList = [
|
||||
List<Source> _dopeflixSourcesList =
|
||||
[
|
||||
//DopeBox (EN)
|
||||
dopeboxSource,
|
||||
//SFlix (EN)
|
||||
sflixSource,
|
||||
]
|
||||
.map((e) => e
|
||||
.map(
|
||||
(e) =>
|
||||
e
|
||||
..sourceCodeUrl = _dopeflixSourceCodeUrl
|
||||
..version = _dopeflixVersion)
|
||||
..version = _dopeflixVersion,
|
||||
)
|
||||
.toList();
|
||||
|
||||
@@ -7,13 +7,17 @@ const _zorothemeSourceCodeUrl =
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/multisrc/zorotheme/zorotheme.dart";
|
||||
|
||||
List<Source> get zorothemeSourcesList => _zorothemeSourcesList;
|
||||
List<Source> _zorothemeSourcesList = [
|
||||
List<Source> _zorothemeSourcesList =
|
||||
[
|
||||
//AniWatch.to (EN)
|
||||
aniwatchSource,
|
||||
//Kaido.to (EN)
|
||||
kaidoSource,
|
||||
]
|
||||
.map((e) => e
|
||||
.map(
|
||||
(e) =>
|
||||
e
|
||||
..sourceCodeUrl = _zorothemeSourceCodeUrl
|
||||
..version = _zorothemeVersion)
|
||||
..version = _zorothemeVersion,
|
||||
)
|
||||
.toList();
|
||||
|
||||
@@ -10,18 +10,20 @@ class ZoroTheme extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client
|
||||
.get(Uri.parse("${source.baseUrl}/most-popular?page=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/most-popular?page=$page"),
|
||||
)).body;
|
||||
|
||||
return animeElementM(res);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client
|
||||
.get(Uri.parse("${source.baseUrl}/recently-updated?page=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/recently-updated?page=$page"),
|
||||
)).body;
|
||||
|
||||
return animeElementM(res);
|
||||
}
|
||||
@@ -122,28 +124,36 @@ class ZoroTheme extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"Currently Airing": 0, "Finished Airing": 1}
|
||||
{"Currently Airing": 0, "Finished Airing": 1},
|
||||
];
|
||||
final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body;
|
||||
MManga anime = MManga();
|
||||
final status = xpath(res,
|
||||
'//*[@class="anisc-info"]/div[contains(text(),"Status:")]/span[2]/text()');
|
||||
final status = xpath(
|
||||
res,
|
||||
'//*[@class="anisc-info"]/div[contains(text(),"Status:")]/span[2]/text()',
|
||||
);
|
||||
if (status.isNotEmpty) {
|
||||
anime.status = parseStatus(status.first, statusList);
|
||||
}
|
||||
|
||||
final author = xpath(res,
|
||||
'//*[@class="anisc-info"]/div[contains(text(),"Studios:")]/span/text()');
|
||||
final author = xpath(
|
||||
res,
|
||||
'//*[@class="anisc-info"]/div[contains(text(),"Studios:")]/span/text()',
|
||||
);
|
||||
if (author.isNotEmpty) {
|
||||
anime.author = author.first.replaceAll("Studios:", "");
|
||||
}
|
||||
final description = xpath(res,
|
||||
'//*[@class="anisc-info"]/div[contains(text(),"Overview:")]/text()');
|
||||
final description = xpath(
|
||||
res,
|
||||
'//*[@class="anisc-info"]/div[contains(text(),"Overview:")]/text()',
|
||||
);
|
||||
if (description.isNotEmpty) {
|
||||
anime.description = description.first.replaceAll("Overview:", "");
|
||||
}
|
||||
final genre = xpath(res,
|
||||
'//*[@class="anisc-info"]/div[contains(text(),"Genres:")]/a/text()');
|
||||
final genre = xpath(
|
||||
res,
|
||||
'//*[@class="anisc-info"]/div[contains(text(),"Genres:")]/a/text()',
|
||||
);
|
||||
|
||||
anime.genre = genre;
|
||||
final id = substringAfterLast(url, '-');
|
||||
@@ -177,11 +187,13 @@ class ZoroTheme extends MProvider {
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
final id = substringAfterLast(url, '?ep=');
|
||||
|
||||
final res = (await client.get(
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/servers?episodeId=$id"),
|
||||
headers: {"referer": "${source.baseUrl}/$url"}))
|
||||
.body;
|
||||
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/servers?episodeId=$id",
|
||||
),
|
||||
headers: {"referer": "${source.baseUrl}/$url"},
|
||||
)).body;
|
||||
final html = json.decode(res)["html"];
|
||||
|
||||
final serverElements = parseHtml(html).select("div.server-item");
|
||||
@@ -194,11 +206,13 @@ class ZoroTheme extends MProvider {
|
||||
final id = serverElement.attr("data-id");
|
||||
final subDub = serverElement.attr("data-type");
|
||||
|
||||
final resE = (await client.get(
|
||||
final resE =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/sources?id=$id"),
|
||||
headers: {"referer": "${source.baseUrl}/$url"}))
|
||||
.body;
|
||||
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/sources?id=$id",
|
||||
),
|
||||
headers: {"referer": "${source.baseUrl}/$url"},
|
||||
)).body;
|
||||
String epUrl = substringBefore(substringAfter(resE, "\"link\":\""), "\"");
|
||||
List<MVideo> a = [];
|
||||
if (hosterSelection.contains(name) && typeSelection.contains(subDub)) {
|
||||
@@ -222,30 +236,36 @@ class ZoroTheme extends MProvider {
|
||||
Future<List<MVideo>> rapidCloudExtractor(String url, String name) async {
|
||||
final serverUrl = ['https://megacloud.tv', 'https://rapid-cloud.co'];
|
||||
|
||||
final serverType = url.startsWith('https://megacloud.tv') || url.startsWith('https://megacloud.club') ? 0 : 1;
|
||||
final serverType =
|
||||
url.startsWith('https://megacloud.tv') ||
|
||||
url.startsWith('https://megacloud.club')
|
||||
? 0
|
||||
: 1;
|
||||
final sourceUrl = [
|
||||
'/embed-2/ajax/e-1/getSources?id=',
|
||||
'/ajax/embed-6-v2/getSources?id='
|
||||
'/ajax/embed-6-v2/getSources?id=',
|
||||
];
|
||||
final sourceSpliter = ['/e-1/', '/embed-6-v2/'];
|
||||
final id = url.split(sourceSpliter[serverType]).last.split('?').first;
|
||||
|
||||
String resServer = "";
|
||||
if (serverType == 0) {
|
||||
resServer =
|
||||
await evaluateJavascriptViaWebview("https://megacloud.tv/about", {
|
||||
"X-Requested-With": "org.lineageos.jelly"
|
||||
}, [
|
||||
resServer = await evaluateJavascriptViaWebview(
|
||||
"https://megacloud.tv/about",
|
||||
{"X-Requested-With": "org.lineageos.jelly"},
|
||||
[
|
||||
cryptoStr,
|
||||
decodePng,
|
||||
getSrcStr,
|
||||
"getSources('$id').then(s => window.flutter_inappwebview.callHandler('setResponse', JSON.stringify(s)))"
|
||||
]);
|
||||
"getSources('$id').then(s => window.flutter_inappwebview.callHandler('setResponse', JSON.stringify(s)))",
|
||||
],
|
||||
);
|
||||
} else {
|
||||
resServer = (await client.get(
|
||||
resServer =
|
||||
(await client.get(
|
||||
Uri.parse('${serverUrl[serverType]}${sourceUrl[serverType]}$id'),
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"}))
|
||||
.body;
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"},
|
||||
)).body;
|
||||
}
|
||||
|
||||
final encrypted = getMapValue(resServer, "encrypted");
|
||||
@@ -268,16 +288,19 @@ class ZoroTheme extends MProvider {
|
||||
videoResJson = decryptAESCryptoJS(ciphertext, password);
|
||||
} else {
|
||||
videoResJson = json.encode(
|
||||
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>));
|
||||
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>),
|
||||
);
|
||||
}
|
||||
|
||||
String masterUrl =
|
||||
((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
.first)['file'];
|
||||
String type = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
String type =
|
||||
((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
.first)['type'];
|
||||
|
||||
final tracks = (json.decode(resServer)['tracks'] as List)
|
||||
final tracks =
|
||||
(json.decode(resServer)['tracks'] as List)
|
||||
.where((e) => e['kind'] == 'captions' ? true : false)
|
||||
.toList();
|
||||
List<MTrack> subtitles = [];
|
||||
@@ -295,8 +318,10 @@ class ZoroTheme extends MProvider {
|
||||
if (type == "hls") {
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -330,19 +355,22 @@ class ZoroTheme extends MProvider {
|
||||
Future<List<List<int>>> generateIndexPairs(int serverType) async {
|
||||
final jsPlayerUrl = [
|
||||
"https://megacloud.tv/js/player/a/prod/e1-player.min.js",
|
||||
"https://rapid-cloud.co/js/player/prod/e6-player-v2.min.js"
|
||||
"https://rapid-cloud.co/js/player/prod/e6-player-v2.min.js",
|
||||
];
|
||||
final scriptText =
|
||||
(await client.get(Uri.parse(jsPlayerUrl[serverType]))).body;
|
||||
|
||||
final switchCode = scriptText.substring(
|
||||
scriptText.lastIndexOf('switch'), scriptText.indexOf('=partKey'));
|
||||
scriptText.lastIndexOf('switch'),
|
||||
scriptText.indexOf('=partKey'),
|
||||
);
|
||||
|
||||
List<int> indexes = [];
|
||||
for (var variableMatch
|
||||
in RegExp(r'=(\w+)').allMatches(switchCode).toList()) {
|
||||
final regex = RegExp(
|
||||
',${(variableMatch as RegExpMatch).group(1)}=((?:0x)?([0-9a-fA-F]+))');
|
||||
',${(variableMatch as RegExpMatch).group(1)}=((?:0x)?([0-9a-fA-F]+))',
|
||||
);
|
||||
Match? match = regex.firstMatch(scriptText);
|
||||
|
||||
if (match != null) {
|
||||
@@ -374,13 +402,19 @@ class ZoroTheme extends MProvider {
|
||||
List<MManga> animeList = [];
|
||||
|
||||
final urls = xpath(
|
||||
res, '//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@href');
|
||||
res,
|
||||
'//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@href',
|
||||
);
|
||||
|
||||
final names = xpath(res,
|
||||
'//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@data-jname');
|
||||
final names = xpath(
|
||||
res,
|
||||
'//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@data-jname',
|
||||
);
|
||||
|
||||
final images = xpath(
|
||||
res, '//*[@class^="flw-item"]/div[@class="film-poster"]/img/@data-src');
|
||||
res,
|
||||
'//*[@class^="flw-item"]/div[@class="film-poster"]/img/@data-src',
|
||||
);
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
anime.name = names[i];
|
||||
@@ -388,8 +422,11 @@ class ZoroTheme extends MProvider {
|
||||
anime.link = urls[i];
|
||||
animeList.add(anime);
|
||||
}
|
||||
final nextPage =
|
||||
xpath(res, '//li[@class="page-item"]/a[@title="Next"]/@href', "");
|
||||
final nextPage = xpath(
|
||||
res,
|
||||
'//li[@class="page-item"]/a[@title="Next"]/@href',
|
||||
"",
|
||||
);
|
||||
return MPages(animeList, !nextPage.isEmpty);
|
||||
}
|
||||
|
||||
@@ -403,7 +440,7 @@ class ZoroTheme extends MProvider {
|
||||
List<SelectFilterOption> yearList = [
|
||||
for (var i = 1917; i < 2024; i++)
|
||||
SelectFilterOption(i.toString(), i.toString()),
|
||||
SelectFilterOption("All", "")
|
||||
SelectFilterOption("All", ""),
|
||||
];
|
||||
|
||||
@override
|
||||
@@ -416,13 +453,13 @@ class ZoroTheme extends MProvider {
|
||||
SelectFilterOption("OVA", "3"),
|
||||
SelectFilterOption("ONA", "4"),
|
||||
SelectFilterOption("Special", "5"),
|
||||
SelectFilterOption("Music", "6")
|
||||
SelectFilterOption("Music", "6"),
|
||||
]),
|
||||
SelectFilter("StatusFilter", "Status", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
SelectFilterOption("Finished Airing", "1"),
|
||||
SelectFilterOption("Currently Airing", "2"),
|
||||
SelectFilterOption("Not yet aired", "3")
|
||||
SelectFilterOption("Not yet aired", "3"),
|
||||
]),
|
||||
SelectFilter("RatedFilter", "Rated", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
@@ -431,7 +468,7 @@ class ZoroTheme extends MProvider {
|
||||
SelectFilterOption("PG-13", "3"),
|
||||
SelectFilterOption("R", "4"),
|
||||
SelectFilterOption("R+", "5"),
|
||||
SelectFilterOption("Rx", "6")
|
||||
SelectFilterOption("Rx", "6"),
|
||||
]),
|
||||
SelectFilter("ScoreFilter", "Score", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
@@ -444,20 +481,20 @@ class ZoroTheme extends MProvider {
|
||||
SelectFilterOption("(7) Good", "7"),
|
||||
SelectFilterOption("(8) Very Good", "8"),
|
||||
SelectFilterOption("(9) Great", "9"),
|
||||
SelectFilterOption("(10) Masterpiece", "10")
|
||||
SelectFilterOption("(10) Masterpiece", "10"),
|
||||
]),
|
||||
SelectFilter("SeasonFilter", "Season", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
SelectFilterOption("Spring", "1"),
|
||||
SelectFilterOption("Summer", "2"),
|
||||
SelectFilterOption("Fall", "3"),
|
||||
SelectFilterOption("Winter", "4")
|
||||
SelectFilterOption("Winter", "4"),
|
||||
]),
|
||||
SelectFilter("LanguageFilter", "Language", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
SelectFilterOption("SUB", "1"),
|
||||
SelectFilterOption("DUB", "2"),
|
||||
SelectFilterOption("SUB & DUB", "3")
|
||||
SelectFilterOption("SUB & DUB", "3"),
|
||||
]),
|
||||
SelectFilter("SortFilter", "Sort by", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
@@ -467,14 +504,18 @@ class ZoroTheme extends MProvider {
|
||||
SelectFilterOption("Score", "score"),
|
||||
SelectFilterOption("Name A-Z", "name_az"),
|
||||
SelectFilterOption("Released Date", "released_date"),
|
||||
SelectFilterOption("Most Watched", "most_watched")
|
||||
SelectFilterOption("Most Watched", "most_watched"),
|
||||
]),
|
||||
SelectFilter(
|
||||
"StartYearFilter", "Start year", 0, yearList.reversed.toList()),
|
||||
"StartYearFilter",
|
||||
"Start year",
|
||||
0,
|
||||
yearList.reversed.toList(),
|
||||
),
|
||||
SelectFilter("StartMonthFilter", "Start month", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
for (var i = 1; i < 13; i++)
|
||||
SelectFilterOption(i.toString(), i.toString())
|
||||
SelectFilterOption(i.toString(), i.toString()),
|
||||
]),
|
||||
SelectFilter("StartDayFilter", "Start day", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
@@ -485,12 +526,12 @@ class ZoroTheme extends MProvider {
|
||||
SelectFilter("EndmonthFilter", "End month", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
for (var i = 1; i < 32; i++)
|
||||
SelectFilterOption(i.toString(), i.toString())
|
||||
SelectFilterOption(i.toString(), i.toString()),
|
||||
]),
|
||||
SelectFilter("EndDayFilter", "End day", 0, [
|
||||
SelectFilterOption("All", ""),
|
||||
for (var i = 1; i < 32; i++)
|
||||
SelectFilterOption(i.toString(), i.toString())
|
||||
SelectFilterOption(i.toString(), i.toString()),
|
||||
]),
|
||||
GroupFilter("GenreFilter", "Genre", [
|
||||
CheckBoxFilter("Action", "1"),
|
||||
@@ -535,7 +576,7 @@ class ZoroTheme extends MProvider {
|
||||
CheckBoxFilter("Thriller", "41"),
|
||||
CheckBoxFilter("Vampire", "32"),
|
||||
CheckBoxFilter("Yaoi", "33"),
|
||||
CheckBoxFilter("Yuri", "34")
|
||||
CheckBoxFilter("Yuri", "34"),
|
||||
]),
|
||||
];
|
||||
}
|
||||
@@ -549,7 +590,8 @@ class ZoroTheme extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 1,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080", "720", "480", "360"]),
|
||||
entryValues: ["1080", "720", "480", "360"],
|
||||
),
|
||||
if (source.name == "HiAnime")
|
||||
ListPreference(
|
||||
key: "preferred_server1",
|
||||
@@ -557,7 +599,8 @@ class ZoroTheme extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["HD-1", "HD-2", "StreamTape"],
|
||||
entryValues: ["HD-1", "HD-2", "StreamTape"]),
|
||||
entryValues: ["HD-1", "HD-2", "StreamTape"],
|
||||
),
|
||||
if (source.name != "HiAnime")
|
||||
ListPreference(
|
||||
key: "preferred_server1",
|
||||
@@ -565,14 +608,16 @@ class ZoroTheme extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
|
||||
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"]),
|
||||
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_type1",
|
||||
title: "Preferred Type",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Sub", "Dub"],
|
||||
entryValues: ["sub", "dub"]),
|
||||
entryValues: ["sub", "dub"],
|
||||
),
|
||||
if (source.name != "HiAnime")
|
||||
MultiSelectListPreference(
|
||||
key: "hoster_selection1",
|
||||
@@ -580,7 +625,8 @@ class ZoroTheme extends MProvider {
|
||||
summary: "",
|
||||
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
|
||||
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"],
|
||||
values: ["Vidstreaming", "VidCloud", "StreamTape"]),
|
||||
values: ["Vidstreaming", "VidCloud", "StreamTape"],
|
||||
),
|
||||
if (source.name == "HiAnime")
|
||||
MultiSelectListPreference(
|
||||
key: "hoster_selection1",
|
||||
@@ -588,14 +634,16 @@ class ZoroTheme extends MProvider {
|
||||
summary: "",
|
||||
entries: ["HD-1", "HD-2", "StreamTape"],
|
||||
entryValues: ["HD-1", "HD-2", "StreamTape"],
|
||||
values: ["HD-1", "HD-2", "StreamTape"]),
|
||||
values: ["HD-1", "HD-2", "StreamTape"],
|
||||
),
|
||||
MultiSelectListPreference(
|
||||
key: "type_selection_new",
|
||||
title: "Enable/Disable Types",
|
||||
summary: "",
|
||||
entries: ["Sub", "Dub", "Raw"],
|
||||
entryValues: ["sub", "dub"],
|
||||
values: ["sub", "dub", "raw"]),
|
||||
values: ["sub", "dub", "raw"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -10,18 +10,24 @@ class AnimeWorldIndia extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/advanced-search/page/$page/?s_lang=${source.lang}&s_orderby=viewed")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/advanced-search/page/$page/?s_lang=${source.lang}&s_orderby=viewed",
|
||||
),
|
||||
)).body;
|
||||
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/advanced-search/page/$page/?s_lang=${source.lang}&s_orderby=update")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/advanced-search/page/$page/?s_lang=${source.lang}&s_orderby=update",
|
||||
),
|
||||
)).body;
|
||||
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
@@ -80,7 +86,9 @@ class AnimeWorldIndia extends MProvider {
|
||||
anime.status = MStatus.completed;
|
||||
} else {
|
||||
final eps = xpath(
|
||||
res, '//ul/li/a[contains(@href,"${source.baseUrl}/watch")]/text()');
|
||||
res,
|
||||
'//ul/li/a[contains(@href,"${source.baseUrl}/watch")]/text()',
|
||||
);
|
||||
if (eps.isNotEmpty) {
|
||||
final epParts = eps.first
|
||||
.substring(3)
|
||||
@@ -101,19 +109,26 @@ class AnimeWorldIndia extends MProvider {
|
||||
.xpath('//li[contains(text(),"Producers:")]/span/a/text()')
|
||||
.join(', ');
|
||||
anime.genre = document.xpath(
|
||||
'//span[@class="leading-6"]/a[contains(@class,"border-opacity-30")]/text()');
|
||||
final seasonsJson = json.decode(substringBeforeLast(
|
||||
'//span[@class="leading-6"]/a[contains(@class,"border-opacity-30")]/text()',
|
||||
);
|
||||
final seasonsJson =
|
||||
json.decode(
|
||||
substringBeforeLast(
|
||||
substringBefore(
|
||||
substringAfter(res, "var season_list = "), "var season_label ="),
|
||||
";")) as List<Map<String, dynamic>>;
|
||||
substringAfter(res, "var season_list = "),
|
||||
"var season_label =",
|
||||
),
|
||||
";",
|
||||
),
|
||||
)
|
||||
as List<Map<String, dynamic>>;
|
||||
bool isSingleSeason = seasonsJson.length == 1;
|
||||
List<MChapter>? episodesList = [];
|
||||
for (var i = 0; i < seasonsJson.length; i++) {
|
||||
final seasonJson = seasonsJson[i];
|
||||
final seasonName = isSingleSeason ? "" : "Season ${i + 1}";
|
||||
final episodesJson =
|
||||
(seasonJson["episodes"]["all"] as List<Map<String, dynamic>>)
|
||||
.reversed
|
||||
(seasonJson["episodes"]["all"] as List<Map<String, dynamic>>).reversed
|
||||
.toList();
|
||||
for (var j = 0; j < episodesJson.length; j++) {
|
||||
final episodeJson = episodesJson[j];
|
||||
@@ -148,16 +163,24 @@ class AnimeWorldIndia extends MProvider {
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body;
|
||||
var resJson = substringBefore(
|
||||
substringAfterLast(res, "\"players\":"), ",\"noplayer\":");
|
||||
var streams = (json.decode(resJson) as List<Map<String, dynamic>>)
|
||||
.where((e) =>
|
||||
substringAfterLast(res, "\"players\":"),
|
||||
",\"noplayer\":",
|
||||
);
|
||||
var streams =
|
||||
(json.decode(resJson) as List<Map<String, dynamic>>)
|
||||
.where(
|
||||
(e) =>
|
||||
(e["type"] == "stream" ? true : false) &&
|
||||
(e["url"] as String).isNotEmpty)
|
||||
(e["url"] as String).isNotEmpty,
|
||||
)
|
||||
.toList()
|
||||
.where((e) => language(source.lang).isEmpty ||
|
||||
.where(
|
||||
(e) =>
|
||||
language(source.lang).isEmpty ||
|
||||
language(source.lang) == e["language"]
|
||||
? true
|
||||
: false)
|
||||
: false,
|
||||
)
|
||||
.toList();
|
||||
List<MVideo> videos = [];
|
||||
for (var stream in streams) {
|
||||
@@ -183,9 +206,11 @@ class AnimeWorldIndia extends MProvider {
|
||||
"${source.baseUrl}${getUrlWithoutDomain(element.selectFirst("img").getSrc)}";
|
||||
animeList.add(anime);
|
||||
}
|
||||
final hasNextPage = xpath(res,
|
||||
'//li/span[@class="page-numbers current"]/parent::li//following-sibling::li/a/@href')
|
||||
.isNotEmpty;
|
||||
final hasNextPage =
|
||||
xpath(
|
||||
res,
|
||||
'//li/span[@class="page-numbers current"]/parent::li//following-sibling::li/a/@href',
|
||||
).isNotEmpty;
|
||||
return MPages(animeList, hasNextPage);
|
||||
}
|
||||
|
||||
@@ -199,7 +224,7 @@ class AnimeWorldIndia extends MProvider {
|
||||
"ml": "malayalam",
|
||||
"mr": "marathi",
|
||||
"ta": "tamil",
|
||||
"te": "telugu"
|
||||
"te": "telugu",
|
||||
};
|
||||
return languages[lang] ?? "";
|
||||
}
|
||||
@@ -208,17 +233,23 @@ class AnimeWorldIndia extends MProvider {
|
||||
List<MVideo> videos = [];
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final streamCode = substringBefore(
|
||||
substringAfter(substringAfter(res, "sniff("), ", \""), '"');
|
||||
substringAfter(substringAfter(res, "sniff("), ", \""),
|
||||
'"',
|
||||
);
|
||||
|
||||
final streamUrl =
|
||||
"${substringBefore(url, "/watch")}/m3u8/$streamCode/master.txt?s=1&cache=1";
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(streamUrl))).body;
|
||||
|
||||
List<MTrack> audios = [];
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-MEDIA:TYPE=AUDIO")
|
||||
.split("#EXT-X-MEDIA:TYPE=AUDIO")) {
|
||||
final line =
|
||||
substringBefore(substringAfter(it, "#EXT-X-MEDIA:TYPE=AUDIO"), "\n");
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO",
|
||||
).split("#EXT-X-MEDIA:TYPE=AUDIO")) {
|
||||
final line = substringBefore(
|
||||
substringAfter(it, "#EXT-X-MEDIA:TYPE=AUDIO"),
|
||||
"\n",
|
||||
);
|
||||
final audioUrl = substringBefore(substringAfter(line, "URI=\""), "\"");
|
||||
MTrack audio = MTrack();
|
||||
audio
|
||||
@@ -227,8 +258,10 @@ class AnimeWorldIndia extends MProvider {
|
||||
audios.add(audio);
|
||||
}
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -299,7 +332,7 @@ class AnimeWorldIndia extends MProvider {
|
||||
SelectFilterOption("1993", "1993"),
|
||||
SelectFilterOption("1992", "1992"),
|
||||
SelectFilterOption("1991", "1991"),
|
||||
SelectFilterOption("1990", "1990")
|
||||
SelectFilterOption("1990", "1990"),
|
||||
]),
|
||||
SelectFilter("SortFilter", "Sort", 0, [
|
||||
SelectFilterOption("Default", "default"),
|
||||
@@ -353,7 +386,8 @@ class AnimeWorldIndia extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["1080p", "720p", "480p", "360p", "240p"],
|
||||
entryValues: ["1080", "720", "480", "360", "240"]),
|
||||
entryValues: ["1080", "720", "480", "360", "240"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,10 @@ List<String> _languages = [
|
||||
];
|
||||
|
||||
List<Source> get animeworldindiaSourcesList => _animeworldindiaSourcesList;
|
||||
List<Source> _animeworldindiaSourcesList = _languages
|
||||
.map((e) => Source(
|
||||
List<Source> _animeworldindiaSourcesList =
|
||||
_languages
|
||||
.map(
|
||||
(e) => Source(
|
||||
name: 'AnimeWorld India',
|
||||
baseUrl: "https://anime-world.in",
|
||||
lang: e,
|
||||
@@ -29,5 +31,7 @@ List<Source> _animeworldindiaSourcesList = _languages
|
||||
iconUrl: _iconUrl,
|
||||
version: _animeworldindiaVersion,
|
||||
itemType: ItemType.anime,
|
||||
sourceCodeUrl: _animeworldindiaSourceCodeUrl))
|
||||
sourceCodeUrl: _animeworldindiaSourceCodeUrl,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
@@ -9,17 +9,23 @@ class Nyaa extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=&s=downloads&o=desc&p=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=&s=downloads&o=desc&p=$page",
|
||||
),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=$page",
|
||||
),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@@ -78,8 +84,8 @@ class Nyaa extends MProvider {
|
||||
SelectFilterOption("Date", "id"),
|
||||
SelectFilterOption("Seeders", "seeders"),
|
||||
SelectFilterOption("Leechers", "leechers"),
|
||||
SelectFilterOption("Download", "downloads")
|
||||
])
|
||||
SelectFilterOption("Download", "downloads"),
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -92,7 +98,8 @@ class Nyaa extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Anime", "Live Action"],
|
||||
entryValues: ["1_0", "4_0"]),
|
||||
entryValues: ["1_0", "4_0"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -100,17 +107,21 @@ class Nyaa extends MProvider {
|
||||
List<MManga> animeList = [];
|
||||
final document = parseHtml(res);
|
||||
|
||||
final values = document
|
||||
.select("body > div > div.table-responsive > table > tbody > tr");
|
||||
final values = document.select(
|
||||
"body > div > div.table-responsive > table > tbody > tr",
|
||||
);
|
||||
for (var value in values) {
|
||||
MManga anime = MManga();
|
||||
anime.imageUrl =
|
||||
"${source.baseUrl}${getUrlWithoutDomain(value.selectFirst("td:nth-child(1) > a > img").getSrc)}";
|
||||
MElement firstElement = value
|
||||
MElement firstElement =
|
||||
value
|
||||
.select("td > a")
|
||||
.where((MElement e) =>
|
||||
.where(
|
||||
(MElement e) =>
|
||||
e.outerHtml.contains("/view/") &&
|
||||
!e.outerHtml.contains("#comments"))
|
||||
!e.outerHtml.contains("#comments"),
|
||||
)
|
||||
.toList()
|
||||
.first;
|
||||
anime.link =
|
||||
@@ -120,8 +131,10 @@ class Nyaa extends MProvider {
|
||||
}
|
||||
|
||||
final hasNextPage =
|
||||
xpath(res, '//ul[@class="pagination"]/li[contains(text(),"»")]/a/@href')
|
||||
.isNotEmpty;
|
||||
xpath(
|
||||
res,
|
||||
'//ul[@class="pagination"]/li[contains(text(),"»")]/a/@href',
|
||||
).isNotEmpty;
|
||||
return MPages(animeList, hasNextPage);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,4 +16,5 @@ Source _nyaaSource = Source(
|
||||
iconUrl: _iconUrl,
|
||||
version: _nyaaVersion,
|
||||
itemType: ItemType.anime,
|
||||
sourceCodeUrl: _nyaaSourceCodeUrl);
|
||||
sourceCodeUrl: _nyaaSourceCodeUrl,
|
||||
);
|
||||
|
||||
@@ -30,9 +30,10 @@ class OkAnime extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client
|
||||
.get(Uri.parse("${source.baseUrl}/espisode-list?page=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/espisode-list?page=$page"),
|
||||
)).body;
|
||||
List<MManga> animeList = [];
|
||||
String path = '//*[contains(@class,"anime-card")]';
|
||||
final urls = xpath(res, '$path/div[@class="anime-title")]/h4/a/@href');
|
||||
@@ -46,8 +47,10 @@ class OkAnime extends MProvider {
|
||||
anime.link = urls[i];
|
||||
animeList.add(anime);
|
||||
}
|
||||
final nextPage =
|
||||
xpath(res, '//li[@class="page-item"]/a[@rel="next"]/@href');
|
||||
final nextPage = xpath(
|
||||
res,
|
||||
'//li[@class="page-item"]/a[@rel="next"]/@href',
|
||||
);
|
||||
return MPages(animeList, nextPage.isNotEmpty);
|
||||
}
|
||||
|
||||
@@ -73,34 +76,40 @@ class OkAnime extends MProvider {
|
||||
anime.link = urls[i];
|
||||
animeList.add(anime);
|
||||
}
|
||||
final nextPage =
|
||||
xpath(res, '//li[@class="page-item"]/a[@rel="next"]/@href');
|
||||
final nextPage = xpath(
|
||||
res,
|
||||
'//li[@class="page-item"]/a[@rel="next"]/@href',
|
||||
);
|
||||
return MPages(animeList, nextPage.isNotEmpty);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"يعرض الان": 0, "مكتمل": 1}
|
||||
{"يعرض الان": 0, "مكتمل": 1},
|
||||
];
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
MManga anime = MManga();
|
||||
final status = xpath(res,
|
||||
'//*[@class="full-list-info" and contains(text(),"حالة الأنمي")]/small/a/text()');
|
||||
final status = xpath(
|
||||
res,
|
||||
'//*[@class="full-list-info" and contains(text(),"حالة الأنمي")]/small/a/text()',
|
||||
);
|
||||
if (status.isNotEmpty) {
|
||||
anime.status = parseStatus(status.first, statusList);
|
||||
}
|
||||
anime.description = xpath(res, '//*[@class="review-content"]/text()').first;
|
||||
|
||||
anime.genre = xpath(res, '//*[@class="review-author-info"]/a/text()');
|
||||
final epUrls = xpath(res,
|
||||
'//*[contains(@class,"anime-card")]/div[@class="anime-title")]/h5/a/@href')
|
||||
.reversed
|
||||
.toList();
|
||||
final names = xpath(res,
|
||||
'//*[contains(@class,"anime-card")]/div[@class="anime-title")]/h5/a/text()')
|
||||
.reversed
|
||||
.toList();
|
||||
final epUrls =
|
||||
xpath(
|
||||
res,
|
||||
'//*[contains(@class,"anime-card")]/div[@class="anime-title")]/h5/a/@href',
|
||||
).reversed.toList();
|
||||
final names =
|
||||
xpath(
|
||||
res,
|
||||
'//*[contains(@class,"anime-card")]/div[@class="anime-title")]/h5/a/text()',
|
||||
).reversed.toList();
|
||||
|
||||
List<MChapter>? episodesList = [];
|
||||
for (var i = 0; i < epUrls.length; i++) {
|
||||
@@ -152,14 +161,16 @@ class OkAnime extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 1,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080", "720", "480", "360"]),
|
||||
entryValues: ["1080", "720", "480", "360"],
|
||||
),
|
||||
MultiSelectListPreference(
|
||||
key: "hoster_selection",
|
||||
title: "Enable/Disable Hosts",
|
||||
summary: "",
|
||||
entries: ["Dood", "Voe", "Mp4upload", "VidBom", "Okru"],
|
||||
entryValues: ["Dood", "Voe", "Mp4upload", "VidBom", "Okru"],
|
||||
values: ["Dood", "Voe", "Mp4upload", "VidBom", "Okru"]),
|
||||
values: ["Dood", "Voe", "Mp4upload", "VidBom", "Okru"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _okanimeSource = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/ar/okanime/icon.png",
|
||||
sourceCodeUrl: _okanimeSourceCodeUrl,
|
||||
version: _okanimeVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -23,9 +23,11 @@ class AnimeToast extends MProvider {
|
||||
MManga anime = MManga();
|
||||
anime.name = element.selectFirst("div.item-thumbnail a").attr("title");
|
||||
anime.link = getUrlWithoutDomain(
|
||||
element.selectFirst("div.item-thumbnail a").attr("href"));
|
||||
anime.imageUrl =
|
||||
element.selectFirst("div.item-thumbnail a img").attr("src");
|
||||
element.selectFirst("div.item-thumbnail a").attr("href"),
|
||||
);
|
||||
anime.imageUrl = element
|
||||
.selectFirst("div.item-thumbnail a img")
|
||||
.attr("src");
|
||||
animeList.add(anime);
|
||||
}
|
||||
return MPages(animeList, false);
|
||||
@@ -46,7 +48,9 @@ class AnimeToast extends MProvider {
|
||||
animeList.add(anime);
|
||||
}
|
||||
return MPages(
|
||||
animeList, document.selectFirst("li.next a")?.attr("href") != null);
|
||||
animeList,
|
||||
document.selectFirst("li.next a")?.attr("href") != null,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -106,7 +110,8 @@ class AnimeToast extends MProvider {
|
||||
MChapter ep = MChapter();
|
||||
ep.name = document.selectFirst("h1.light-title")?.text ?? "Film";
|
||||
ep.url = getUrlWithoutDomain(
|
||||
document.selectFirst("link[rel=canonical]").attr("href"));
|
||||
document.selectFirst("link[rel=canonical]").attr("href"),
|
||||
);
|
||||
episodesList.add(ep);
|
||||
}
|
||||
anime.chapters = episodesList.reversed.toList();
|
||||
@@ -134,16 +139,24 @@ class AnimeToast extends MProvider {
|
||||
final doc = parseHtml((await client.get(Uri.parse(sUrl))).body);
|
||||
final nUrl = doc.selectFirst("#player-embed a").attr("href");
|
||||
final nDoc = parseHtml((await client.get(Uri.parse(nUrl))).body);
|
||||
epcu = int.tryParse(substringAfter(
|
||||
epcu =
|
||||
int.tryParse(
|
||||
substringAfter(
|
||||
document.selectFirst("div.tab-pane a.current-link")?.text ?? "",
|
||||
"Ep.")) ??
|
||||
"Ep.",
|
||||
),
|
||||
) ??
|
||||
100;
|
||||
ep = nDoc.select("div.tab-pane a");
|
||||
}
|
||||
} else {
|
||||
epcu = int.tryParse(substringAfter(
|
||||
epcu =
|
||||
int.tryParse(
|
||||
substringAfter(
|
||||
document.selectFirst("div.tab-pane a.current-link")?.text ?? "",
|
||||
"Ep.")) ??
|
||||
"Ep.",
|
||||
),
|
||||
) ??
|
||||
100;
|
||||
ep = document.select("div.tab-pane a");
|
||||
}
|
||||
@@ -218,14 +231,16 @@ class AnimeToast extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Voe", "DoodStream", "Filemoon", "Mp4upload"],
|
||||
entryValues: ["voe", "doodStream", "filemoon", "mp4upload"]),
|
||||
entryValues: ["voe", "doodStream", "filemoon", "mp4upload"],
|
||||
),
|
||||
MultiSelectListPreference(
|
||||
key: "hoster_selection",
|
||||
title: "Hoster auswählen",
|
||||
summary: "",
|
||||
entries: ["Voe", "DoodStream", "Filemoon", "Mp4upload"],
|
||||
entryValues: ["voe", "dood", "filemoon", "mp4upload"],
|
||||
values: ["voe", "dood", "filemoon", "mp4upload"]),
|
||||
values: ["voe", "dood", "filemoon", "mp4upload"],
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _animetoast = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/animetoast/icon.png",
|
||||
sourceCodeUrl: _animetoastCodeUrl,
|
||||
version: _animetoastVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -22,9 +22,11 @@ class AnimePahe extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client.get(Uri.parse("$baseUrl/api?m=airing&page=$page"),
|
||||
headers: headers))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/api?m=airing&page=$page"),
|
||||
headers: headers,
|
||||
)).body;
|
||||
final jsonResult = json.decode(res);
|
||||
final hasNextPage = jsonResult["current_page"] < jsonResult["last_page"];
|
||||
List<MManga> animeList = [];
|
||||
@@ -41,10 +43,11 @@ class AnimePahe extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
final res = (await client.get(
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/api?m=search&l=8&q=$query"),
|
||||
headers: headers))
|
||||
.body;
|
||||
headers: headers,
|
||||
)).body;
|
||||
final jsonResult = json.decode(res);
|
||||
List<MManga> animeList = [];
|
||||
for (var item in jsonResult["data"]) {
|
||||
@@ -60,16 +63,17 @@ class AnimePahe extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"Currently Airing": 0, "Finished Airing": 1}
|
||||
{"Currently Airing": 0, "Finished Airing": 1},
|
||||
];
|
||||
MManga anime = MManga();
|
||||
final id = substringBefore(substringAfterLast(url, "?anime_id="), "&name=");
|
||||
final name = substringAfterLast(url, "&name=");
|
||||
final session = await getSession(name, id);
|
||||
final res = (await client.get(
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/anime/$session?anime_id=$id"),
|
||||
headers: headers))
|
||||
.body;
|
||||
headers: headers,
|
||||
)).body;
|
||||
final document = parseHtml(res);
|
||||
final status =
|
||||
(document.xpathFirst('//div/p[contains(text(),"Status:")]/text()') ??
|
||||
@@ -85,8 +89,10 @@ class AnimePahe extends MProvider {
|
||||
.replaceAll("Studio:\n", "")
|
||||
.trim();
|
||||
anime.imageUrl = document.selectFirst("div.anime-poster a").attr("href");
|
||||
anime.genre =
|
||||
xpath(res, '//*[contains(@class,"anime-genre")]/ul/li/text()');
|
||||
anime.genre = xpath(
|
||||
res,
|
||||
'//*[contains(@class,"anime-genre")]/ul/li/text()',
|
||||
);
|
||||
final synonyms =
|
||||
(document.xpathFirst('//div/p[contains(text(),"Synonyms:")]/text()') ??
|
||||
"")
|
||||
@@ -105,7 +111,10 @@ class AnimePahe extends MProvider {
|
||||
}
|
||||
|
||||
Future<List<MChapter>> recursivePages(
|
||||
String url, String res, String session) async {
|
||||
String url,
|
||||
String res,
|
||||
String session,
|
||||
) async {
|
||||
final jsonResult = json.decode(res);
|
||||
final page = jsonResult["current_page"];
|
||||
final hasNextPage = page < jsonResult["last_page"];
|
||||
@@ -128,13 +137,15 @@ class AnimePahe extends MProvider {
|
||||
}
|
||||
|
||||
Future<String> getSession(String title, String animeId) async {
|
||||
final res = (await client.get(Uri.parse("$baseUrl/api?m=search&q=$title"),
|
||||
headers: headers))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/api?m=search&q=$title"),
|
||||
headers: headers,
|
||||
)).body;
|
||||
return substringBefore(
|
||||
substringAfter(
|
||||
substringAfter(res, "\"id\":$animeId"), "\"session\":\""),
|
||||
"\"");
|
||||
substringAfter(substringAfter(res, "\"id\":$animeId"), "\"session\":\""),
|
||||
"\"",
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -150,24 +161,35 @@ class AnimePahe extends MProvider {
|
||||
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
final btn = buttons[i];
|
||||
final audio = btn.attr("data-audio"); // Get audio type (jpn/eng). Japanese or Dubbed.
|
||||
final audio = btn.attr(
|
||||
"data-audio",
|
||||
); // Get audio type (jpn/eng). Japanese or Dubbed.
|
||||
final kwikLink = btn.attr("data-src");
|
||||
final quality = btn.text;
|
||||
final paheWinLink = downloadLinks[i].attr("href");
|
||||
|
||||
if (getPreferenceValue(source.id, "preffered_link_type")) {
|
||||
final noRedirectClient = Client(source,
|
||||
json.encode({"followRedirects": false, "useDartHttpClient": true}));
|
||||
final noRedirectClient = Client(
|
||||
source,
|
||||
json.encode({"followRedirects": false, "useDartHttpClient": true}),
|
||||
);
|
||||
final kwikHeaders =
|
||||
(await noRedirectClient.get(Uri.parse("${paheWinLink}/i"))).headers;
|
||||
final kwikUrl =
|
||||
"https://${substringAfterLast(getMapValue(json.encode(kwikHeaders), "location"), "https://")}";
|
||||
final reskwik = (await client
|
||||
.get(Uri.parse(kwikUrl), headers: {"Referer": "https://kwik.cx/"}));
|
||||
final matches = RegExp(r'\("(\S+)",\d+,"(\S+)",(\d+),(\d+)')
|
||||
.firstMatch(reskwik.body);
|
||||
final token = decrypt(matches!.group(1)!, matches.group(2)!,
|
||||
matches.group(3)!, int.parse(matches.group(4)!));
|
||||
final reskwik = (await client.get(
|
||||
Uri.parse(kwikUrl),
|
||||
headers: {"Referer": "https://kwik.cx/"},
|
||||
));
|
||||
final matches = RegExp(
|
||||
r'\("(\S+)",\d+,"(\S+)",(\d+),(\d+)',
|
||||
).firstMatch(reskwik.body);
|
||||
final token = decrypt(
|
||||
matches!.group(1)!,
|
||||
matches.group(2)!,
|
||||
matches.group(3)!,
|
||||
int.parse(matches.group(4)!),
|
||||
);
|
||||
final url = RegExp(r'action="([^"]+)"').firstMatch(token)!.group(1)!;
|
||||
final tok = RegExp(r'value="([^"]+)"').firstMatch(token)!.group(1)!;
|
||||
var code = 419;
|
||||
@@ -175,22 +197,27 @@ class AnimePahe extends MProvider {
|
||||
String location = "";
|
||||
|
||||
while (code != 302 && tries < 20) {
|
||||
String cookie =
|
||||
getMapValue(json.encode(res.request.headers), "cookie");
|
||||
String cookie = getMapValue(
|
||||
json.encode(res.request.headers),
|
||||
"cookie",
|
||||
);
|
||||
cookie +=
|
||||
"; ${getMapValue(json.encode(reskwik.headers), "set-cookie").replaceAll("path=/;", "")}";
|
||||
final resNo = await Client(
|
||||
source,
|
||||
json.encode(
|
||||
{"followRedirects": false, "useDartHttpClient": true}))
|
||||
.post(Uri.parse(url), headers: {
|
||||
json.encode({"followRedirects": false, "useDartHttpClient": true}),
|
||||
).post(
|
||||
Uri.parse(url),
|
||||
headers: {
|
||||
"referer": reskwik.request.url.toString(),
|
||||
"cookie": cookie,
|
||||
"user-agent":
|
||||
getMapValue(json.encode(res.request.headers), "user-agent")
|
||||
}, body: {
|
||||
"_token": tok
|
||||
});
|
||||
"user-agent": getMapValue(
|
||||
json.encode(res.request.headers),
|
||||
"user-agent",
|
||||
),
|
||||
},
|
||||
body: {"_token": tok},
|
||||
);
|
||||
code = resNo.statusCode;
|
||||
tries++;
|
||||
location = getMapValue(json.encode(resNo.headers), "location");
|
||||
@@ -205,17 +232,24 @@ class AnimePahe extends MProvider {
|
||||
..quality = quality;
|
||||
videos.add(video);
|
||||
} else {
|
||||
final ress = (await client.get(Uri.parse(kwikLink),
|
||||
headers: {"Referer": "https://animepahe.com"}));
|
||||
final ress = (await client.get(
|
||||
Uri.parse(kwikLink),
|
||||
headers: {"Referer": "https://animepahe.com"},
|
||||
));
|
||||
final script = substringAfterLast(
|
||||
xpath(ress.body,
|
||||
'//script[contains(text(),"eval(function")]/text()')
|
||||
.first,
|
||||
"eval(function(");
|
||||
xpath(
|
||||
ress.body,
|
||||
'//script[contains(text(),"eval(function")]/text()',
|
||||
).first,
|
||||
"eval(function(",
|
||||
);
|
||||
final videoUrl = substringBefore(
|
||||
substringAfter(unpackJsAndCombine("eval(function($script"),
|
||||
"const source=\\'"),
|
||||
"\\';");
|
||||
substringAfter(
|
||||
unpackJsAndCombine("eval(function($script"),
|
||||
"const source=\\'",
|
||||
),
|
||||
"\\';",
|
||||
);
|
||||
MVideo video = MVideo();
|
||||
video
|
||||
..url = videoUrl
|
||||
@@ -235,7 +269,8 @@ class AnimePahe extends MProvider {
|
||||
final n = cm.substring(0, b);
|
||||
double mx = 0;
|
||||
for (var index = 0; index < ctn.length; index++) {
|
||||
mx += (int.tryParse(ctn[ctn.length - index - 1], radix: 10) ?? 0.0)
|
||||
mx +=
|
||||
(int.tryParse(ctn[ctn.length - index - 1], radix: 10) ?? 0.0)
|
||||
.toInt() *
|
||||
(pow(sep, index));
|
||||
}
|
||||
@@ -269,8 +304,10 @@ class AnimePahe extends MProvider {
|
||||
|
||||
List<MVideo> sortVideos(List<MVideo> videos) {
|
||||
String quality = getPreferenceValue(source.id, "preferred_quality");
|
||||
String preferredAudio = getPreferenceValue(source.id, "preferred_audio"); // get user's audio preference
|
||||
|
||||
String preferredAudio = getPreferenceValue(
|
||||
source.id,
|
||||
"preferred_audio",
|
||||
); // get user's audio preference
|
||||
|
||||
videos.sort((MVideo a, MVideo b) {
|
||||
// Prioritize audio first.
|
||||
@@ -314,28 +351,27 @@ class AnimePahe extends MProvider {
|
||||
title: "Preferred domain",
|
||||
summary: "",
|
||||
valueIndex: 1,
|
||||
entries: [
|
||||
"animepahe.com",
|
||||
"animepahe.ru",
|
||||
"animepahe.org"
|
||||
],
|
||||
entries: ["animepahe.com", "animepahe.ru", "animepahe.org"],
|
||||
entryValues: [
|
||||
"https://animepahe.com",
|
||||
"https://animepahe.ru",
|
||||
"https://animepahe.org"
|
||||
]),
|
||||
"https://animepahe.org",
|
||||
],
|
||||
),
|
||||
SwitchPreferenceCompat(
|
||||
key: "preffered_link_type",
|
||||
title: "Use HLS links",
|
||||
summary: "Enable this if you are having Cloudflare issues.",
|
||||
value: false),
|
||||
value: false,
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_quality",
|
||||
title: "Preferred Quality",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["1080p", "720p", "360p"],
|
||||
entryValues: ["1080", "720", "360"]),
|
||||
entryValues: ["1080", "720", "360"],
|
||||
),
|
||||
|
||||
ListPreference(
|
||||
key: "preferred_audio", // Add new preference for audio
|
||||
@@ -343,7 +379,8 @@ class AnimePahe extends MProvider {
|
||||
summary: "Select your preferred audio language (Japanese or English).",
|
||||
valueIndex: 0, // Default to Japanese (or whichever you prefer)
|
||||
entries: ["Japanese", "English"],
|
||||
entryValues: ["jpn", "eng"]),
|
||||
entryValues: ["jpn", "eng"],
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _animepaheSource = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/animepahe/icon.png",
|
||||
sourceCodeUrl: _animepaheSourceCodeUrl,
|
||||
version: _animepaheVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,4 +13,5 @@ Source _gogoanimeSource = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/gogoanime/icon.png",
|
||||
sourceCodeUrl: _gogoanimeSourceCodeUrl,
|
||||
version: _gogoanimeVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -10,17 +10,21 @@ class NineAnimeTv extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client
|
||||
.get(Uri.parse("${source.baseUrl}/filter?sort=all&page=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/filter?sort=all&page=$page"),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/filter?sort=recently_updated&page=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/filter?sort=recently_updated&page=$page",
|
||||
),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@@ -116,30 +120,36 @@ class NineAnimeTv extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"Currently Airing": 0, "Finished Airing": 1}
|
||||
{"Currently Airing": 0, "Finished Airing": 1},
|
||||
];
|
||||
|
||||
final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body;
|
||||
MManga anime = MManga();
|
||||
final document = parseHtml(res);
|
||||
final infoElement = document.selectFirst("div.film-infor");
|
||||
final status = infoElement.xpathFirst(
|
||||
'//div[contains(text(),"Status:")]/following-sibling::div/span/text()') ??
|
||||
final status =
|
||||
infoElement.xpathFirst(
|
||||
'//div[contains(text(),"Status:")]/following-sibling::div/span/text()',
|
||||
) ??
|
||||
"";
|
||||
anime.status = parseStatus(status, statusList);
|
||||
anime.description =
|
||||
infoElement.selectFirst("div.film-description > p")?.text ?? "";
|
||||
anime.author = infoElement.xpathFirst(
|
||||
'//div[contains(text(),"Studios:")]/following-sibling::div/a/text()') ??
|
||||
anime.author =
|
||||
infoElement.xpathFirst(
|
||||
'//div[contains(text(),"Studios:")]/following-sibling::div/a/text()',
|
||||
) ??
|
||||
"";
|
||||
|
||||
anime.genre = infoElement.xpath(
|
||||
'//div[contains(text(),"Genre:")]/following-sibling::div/a/text()');
|
||||
'//div[contains(text(),"Genre:")]/following-sibling::div/a/text()',
|
||||
);
|
||||
final id = parseHtml(res).selectFirst("div[data-id]").attr("data-id");
|
||||
|
||||
final resEp =
|
||||
(await client.get(Uri.parse("${source.baseUrl}/ajax/episode/list/$id")))
|
||||
.body;
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/ajax/episode/list/$id"),
|
||||
)).body;
|
||||
final html = json.decode(resEp)["html"];
|
||||
|
||||
List<MChapter>? episodesList = [];
|
||||
@@ -163,9 +173,10 @@ class NineAnimeTv extends MProvider {
|
||||
|
||||
@override
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
final res = (await client.get(
|
||||
Uri.parse("${source.baseUrl}/ajax/episode/servers?episodeId=$url")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/ajax/episode/servers?episodeId=$url"),
|
||||
)).body;
|
||||
|
||||
final html = json.decode(res)["html"];
|
||||
|
||||
@@ -178,9 +189,10 @@ class NineAnimeTv extends MProvider {
|
||||
final name = serverElement.text;
|
||||
final id = serverElement.attr("data-id");
|
||||
final subDub = serverElement.attr("data-type");
|
||||
final res = (await client
|
||||
.get(Uri.parse("${source.baseUrl}/ajax/episode/sources?id=$id")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/ajax/episode/sources?id=$id"),
|
||||
)).body;
|
||||
final epUrl = json.decode(res)["link"];
|
||||
List<MVideo> a = [];
|
||||
|
||||
@@ -214,17 +226,22 @@ class NineAnimeTv extends MProvider {
|
||||
Future<List<MVideo>> rapidCloudExtractor(String url, String name) async {
|
||||
final serverUrl = ['https://megacloud.tv', 'https://rapid-cloud.co'];
|
||||
|
||||
final serverType = url.startsWith('https://megacloud.tv') || url.startsWith('https://megacloud.club') ? 0 : 1;
|
||||
final serverType =
|
||||
url.startsWith('https://megacloud.tv') ||
|
||||
url.startsWith('https://megacloud.club')
|
||||
? 0
|
||||
: 1;
|
||||
final sourceUrl = [
|
||||
'/embed-2/ajax/e-1/getSources?id=',
|
||||
'/ajax/embed-6-v2/getSources?id='
|
||||
'/ajax/embed-6-v2/getSources?id=',
|
||||
];
|
||||
final sourceSpliter = ['/e-1/', '/embed-6-v2/'];
|
||||
final id = url.split(sourceSpliter[serverType]).last.split('?').first;
|
||||
final resServer = (await client.get(
|
||||
final resServer =
|
||||
(await client.get(
|
||||
Uri.parse('${serverUrl[serverType]}${sourceUrl[serverType]}$id'),
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"}))
|
||||
.body;
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"},
|
||||
)).body;
|
||||
final encrypted = getMapValue(resServer, "encrypted");
|
||||
String videoResJson = "";
|
||||
List<MVideo> videos = [];
|
||||
@@ -245,16 +262,19 @@ class NineAnimeTv extends MProvider {
|
||||
videoResJson = decryptAESCryptoJS(ciphertext, password);
|
||||
} else {
|
||||
videoResJson = json.encode(
|
||||
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>));
|
||||
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>),
|
||||
);
|
||||
}
|
||||
|
||||
String masterUrl =
|
||||
((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
.first)['file'];
|
||||
String type = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
String type =
|
||||
((json.decode(videoResJson) as List<Map<String, dynamic>>)
|
||||
.first)['type'];
|
||||
|
||||
final tracks = (json.decode(resServer)['tracks'] as List)
|
||||
final tracks =
|
||||
(json.decode(resServer)['tracks'] as List)
|
||||
.where((e) => e['kind'] == 'captions' ? true : false)
|
||||
.toList();
|
||||
List<MTrack> subtitles = [];
|
||||
@@ -272,8 +292,10 @@ class NineAnimeTv extends MProvider {
|
||||
if (type == "hls") {
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -307,19 +329,22 @@ class NineAnimeTv extends MProvider {
|
||||
Future<List<List<int>>> generateIndexPairs(int serverType) async {
|
||||
final jsPlayerUrl = [
|
||||
"https://megacloud.tv/js/player/a/prod/e1-player.min.js",
|
||||
"https://rapid-cloud.co/js/player/prod/e6-player-v2.min.js"
|
||||
"https://rapid-cloud.co/js/player/prod/e6-player-v2.min.js",
|
||||
];
|
||||
final scriptText =
|
||||
(await client.get(Uri.parse(jsPlayerUrl[serverType]))).body;
|
||||
|
||||
final switchCode = scriptText.substring(
|
||||
scriptText.lastIndexOf('switch'), scriptText.indexOf('=partKey'));
|
||||
scriptText.lastIndexOf('switch'),
|
||||
scriptText.indexOf('=partKey'),
|
||||
);
|
||||
|
||||
List<int> indexes = [];
|
||||
for (var variableMatch
|
||||
in RegExp(r'=(\w+)').allMatches(switchCode).toList()) {
|
||||
final regex = RegExp(
|
||||
',${(variableMatch as RegExpMatch).group(1)}=((?:0x)?([0-9a-fA-F]+))');
|
||||
',${(variableMatch as RegExpMatch).group(1)}=((?:0x)?([0-9a-fA-F]+))',
|
||||
);
|
||||
Match? match = regex.firstMatch(scriptText);
|
||||
|
||||
if (match != null) {
|
||||
@@ -391,13 +416,13 @@ class NineAnimeTv extends MProvider {
|
||||
CheckBoxFilter("Super Power", "31"),
|
||||
CheckBoxFilter("Supernatural", "37"),
|
||||
CheckBoxFilter("Thriller", "41"),
|
||||
CheckBoxFilter("Vampire", "32")
|
||||
CheckBoxFilter("Vampire", "32"),
|
||||
]),
|
||||
GroupFilter("SeasonFilter", "Season", [
|
||||
CheckBoxFilter("Fall", "3"),
|
||||
CheckBoxFilter("Summer", "2"),
|
||||
CheckBoxFilter("Spring", "1"),
|
||||
CheckBoxFilter("Winter", "4")
|
||||
CheckBoxFilter("Winter", "4"),
|
||||
]),
|
||||
GroupFilter("YearFilter", "Year", [
|
||||
CheckBoxFilter("2024", "2024"),
|
||||
@@ -423,7 +448,7 @@ class NineAnimeTv extends MProvider {
|
||||
CheckBoxFilter("2004", "2004"),
|
||||
CheckBoxFilter("2003", "2003"),
|
||||
CheckBoxFilter("2002", "2002"),
|
||||
CheckBoxFilter("2001", "2001")
|
||||
CheckBoxFilter("2001", "2001"),
|
||||
]),
|
||||
SelectFilter("SortFilter", "Sort by", 0, [
|
||||
SelectFilterOption("All", "all"),
|
||||
@@ -433,7 +458,7 @@ class NineAnimeTv extends MProvider {
|
||||
SelectFilterOption("Score", "score"),
|
||||
SelectFilterOption("Name A-Z", "name_az"),
|
||||
SelectFilterOption("Released Date", "released_date"),
|
||||
SelectFilterOption("Most Watched", "most_watched")
|
||||
SelectFilterOption("Most Watched", "most_watched"),
|
||||
]),
|
||||
GroupFilter("TypeFilter", "Type", [
|
||||
CheckBoxFilter("Movie", "1"),
|
||||
@@ -441,16 +466,18 @@ class NineAnimeTv extends MProvider {
|
||||
CheckBoxFilter("OVA", "3"),
|
||||
CheckBoxFilter("ONA", "4"),
|
||||
CheckBoxFilter("Special", "5"),
|
||||
CheckBoxFilter("Music", "6")
|
||||
CheckBoxFilter("Music", "6"),
|
||||
]),
|
||||
SelectFilter("StatusFilter", "Status", 0, [
|
||||
SelectFilterOption("All", "all"),
|
||||
SelectFilterOption("Finished Airing", "1"),
|
||||
SelectFilterOption("Currently Airing", "2"),
|
||||
SelectFilterOption("Not yet aired", "3")
|
||||
SelectFilterOption("Not yet aired", "3"),
|
||||
]),
|
||||
GroupFilter("LanguageFilter", "Language", [
|
||||
CheckBoxFilter("Sub", "sub"),
|
||||
CheckBoxFilter("Dub", "dub"),
|
||||
]),
|
||||
GroupFilter("LanguageFilter", "Language",
|
||||
[CheckBoxFilter("Sub", "sub"), CheckBoxFilter("Dub", "dub")]),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -463,35 +490,40 @@ class NineAnimeTv extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 1,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080", "720", "480", "360"]),
|
||||
entryValues: ["1080", "720", "480", "360"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_server",
|
||||
title: "Preferred server",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Vidstreaming", "VidCloud"],
|
||||
entryValues: ["Vidstreaming", "VidCloud"]),
|
||||
entryValues: ["Vidstreaming", "VidCloud"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_type",
|
||||
title: "Preferred Type",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Sub", "Dub"],
|
||||
entryValues: ["sub", "dub"]),
|
||||
entryValues: ["sub", "dub"],
|
||||
),
|
||||
MultiSelectListPreference(
|
||||
key: "hoster_selection",
|
||||
title: "Enable/Disable Hosts",
|
||||
summary: "",
|
||||
entries: ["Vidstreaming", "VidCloud"],
|
||||
entryValues: ["Vidstreaming", "Vidcloud"],
|
||||
values: ["Vidstreaming", "Vidcloud"]),
|
||||
values: ["Vidstreaming", "Vidcloud"],
|
||||
),
|
||||
MultiSelectListPreference(
|
||||
key: "type_selection",
|
||||
title: "Enable/Disable Types",
|
||||
summary: "",
|
||||
entries: ["Sub", "Dub"],
|
||||
entryValues: ["sub", "dub"],
|
||||
values: ["sub", "dub"]),
|
||||
values: ["sub", "dub"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _nineanimetv = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/nineanimetv/icon.png",
|
||||
sourceCodeUrl: _nineanimetvCodeUrl,
|
||||
version: _nineanimetvVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _uhdmoviesSource = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/uhdmovies/icon.png",
|
||||
sourceCodeUrl: _uhdmoviesSourceCodeUrl,
|
||||
version: _uhdmoviesVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -27,9 +27,10 @@ class UHDMovies extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
final res = (await client.get(
|
||||
Uri.parse("$baseUrl/page/$page/?s=${query.replaceAll(" ", "+")}")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/page/$page/?s=${query.replaceAll(" ", "+")}"),
|
||||
)).body;
|
||||
return animeFromElement(res);
|
||||
}
|
||||
|
||||
@@ -43,10 +44,14 @@ class UHDMovies extends MProvider {
|
||||
anime.description = description.first;
|
||||
}
|
||||
anime.status = MStatus.ongoing;
|
||||
final episodesTitles = xpath(res,
|
||||
'//*[contains(@style, "center") or contains(@class, "maxbutton")]/a[contains(@class, "maxbutton") or contains(@href, "?sid=")]/text()');
|
||||
final episodesUrls = xpath(res,
|
||||
'//*[contains(@style, "center") or contains(@class, "maxbutton")]/a[contains(@class, "maxbutton") or contains(@href, "?sid=")]/@href');
|
||||
final episodesTitles = xpath(
|
||||
res,
|
||||
'//*[contains(@style, "center") or contains(@class, "maxbutton")]/a[contains(@class, "maxbutton") or contains(@href, "?sid=")]/text()',
|
||||
);
|
||||
final episodesUrls = xpath(
|
||||
res,
|
||||
'//*[contains(@style, "center") or contains(@class, "maxbutton")]/a[contains(@class, "maxbutton") or contains(@href, "?sid=")]/@href',
|
||||
);
|
||||
bool isSeries = false;
|
||||
if (episodesTitles.first.contains("Episode") ||
|
||||
episodesTitles.first.contains("Zip") ||
|
||||
@@ -56,8 +61,10 @@ class UHDMovies extends MProvider {
|
||||
List<MChapter>? episodesList = [];
|
||||
if (!isSeries) {
|
||||
List<String> moviesTitles = [];
|
||||
moviesTitles = xpath(res,
|
||||
'//*[contains(@style, "center") or contains(@class, "maxbutton")]/parent::p//preceding-sibling::p[contains(@style, "center")]/text()');
|
||||
moviesTitles = xpath(
|
||||
res,
|
||||
'//*[contains(@style, "center") or contains(@class, "maxbutton")]/parent::p//preceding-sibling::p[contains(@style, "center")]/text()',
|
||||
);
|
||||
List<String> titles = [];
|
||||
if (moviesTitles.isEmpty) {
|
||||
moviesTitles = xpath(res, '//p[contains(@style, "center")]/text()');
|
||||
@@ -82,8 +89,10 @@ class UHDMovies extends MProvider {
|
||||
}
|
||||
} else {
|
||||
List<String> seasonTitles = [];
|
||||
final episodeTitles = xpath(res,
|
||||
'//*[contains(@style, "center") or contains(@class, "maxbutton")]/parent::p//preceding-sibling::p[contains(@style, "center") and not(text()^="Episode")]/text()');
|
||||
final episodeTitles = xpath(
|
||||
res,
|
||||
'//*[contains(@style, "center") or contains(@class, "maxbutton")]/parent::p//preceding-sibling::p[contains(@style, "center") and not(text()^="Episode")]/text()',
|
||||
);
|
||||
List<String> titles = [];
|
||||
for (var title in episodeTitles) {
|
||||
if (title.isNotEmpty) {
|
||||
@@ -132,7 +141,8 @@ class UHDMovies extends MProvider {
|
||||
value: "https://uhdmovies.fans",
|
||||
dialogTitle: "Currently used domain",
|
||||
dialogMessage: "",
|
||||
text: "https://uhdmovies.fans"),
|
||||
text: "https://uhdmovies.fans",
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -146,8 +156,9 @@ class UHDMovies extends MProvider {
|
||||
final link = links[i];
|
||||
String decodedLink = link;
|
||||
if (!link.contains("workers.dev")) {
|
||||
decodedLink = utf8
|
||||
.decode(base64Url.decode(substringAfter(link, "download?url=")));
|
||||
decodedLink = utf8.decode(
|
||||
base64Url.decode(substringAfter(link, "download?url=")),
|
||||
);
|
||||
}
|
||||
MVideo video = MVideo();
|
||||
video
|
||||
@@ -184,18 +195,25 @@ class UHDMovies extends MProvider {
|
||||
final js = xpath(lastDoc, '//script[contains(text(), "/?go=")]/text()');
|
||||
if (js.isEmpty) return "";
|
||||
String script = js.first;
|
||||
String nextUrl =
|
||||
substringBefore(substringAfter(script, "\"href\",\""), '"');
|
||||
String nextUrl = substringBefore(
|
||||
substringAfter(script, "\"href\",\""),
|
||||
'"',
|
||||
);
|
||||
if (!nextUrl.contains("http")) return "";
|
||||
String cookieName = substringAfter(nextUrl, "go=");
|
||||
String cookieValue =
|
||||
substringBefore(substringAfter(script, "'$cookieName', '"), "'");
|
||||
final response = (await client.get(Uri.parse(nextUrl),
|
||||
headers: {"referer": url, "Cookie": "$cookieName=$cookieValue"}))
|
||||
.body;
|
||||
String cookieValue = substringBefore(
|
||||
substringAfter(script, "'$cookieName', '"),
|
||||
"'",
|
||||
);
|
||||
final response =
|
||||
(await client.get(
|
||||
Uri.parse(nextUrl),
|
||||
headers: {"referer": url, "Cookie": "$cookieName=$cookieValue"},
|
||||
)).body;
|
||||
|
||||
final lastRes =
|
||||
parseHtml(response).selectFirst("meta[http-equiv]").attr("content");
|
||||
final lastRes = parseHtml(
|
||||
response,
|
||||
).selectFirst("meta[http-equiv]").attr("content");
|
||||
return substringAfter(lastRes, "url=");
|
||||
}
|
||||
|
||||
@@ -222,9 +240,12 @@ class UHDMovies extends MProvider {
|
||||
final name = xpath(html, '//input/@name').first;
|
||||
final value = xpath(html, '//input/@value').first;
|
||||
final body = {"$name": value};
|
||||
final response = (await client.post(Uri.parse(urlR.first),
|
||||
headers: {"referer": url}, body: body))
|
||||
.body;
|
||||
final response =
|
||||
(await client.post(
|
||||
Uri.parse(urlR.first),
|
||||
headers: {"referer": url},
|
||||
body: body,
|
||||
)).body;
|
||||
return recursiveDoc(url, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,16 +21,23 @@ class AnimeOnlineNinja extends MProvider {
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
String pageStr = page == 1 ? "" : "page/$page/";
|
||||
final res = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/$pageStr?s=${query.replaceAll(" ", "+")}")))
|
||||
.body;
|
||||
return parseAnimeList(res,
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/$pageStr?s=${query.replaceAll(" ", "+")}",
|
||||
),
|
||||
)).body;
|
||||
return parseAnimeList(
|
||||
res,
|
||||
selector: "div.result-item div.image a",
|
||||
hasNextPage: parseHtml(res)
|
||||
hasNextPage:
|
||||
parseHtml(res)
|
||||
.selectFirst(
|
||||
"div.pagination > *:last-child:not(span):not(.current)")
|
||||
"div.pagination > *:last-child:not(span):not(.current)",
|
||||
)
|
||||
?.text !=
|
||||
null);
|
||||
null,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -39,7 +46,8 @@ class AnimeOnlineNinja extends MProvider {
|
||||
MManga anime = MManga();
|
||||
final document = parseHtml(res);
|
||||
anime.description = document.selectFirst("div#info").text;
|
||||
anime.genre = document
|
||||
anime.genre =
|
||||
document
|
||||
.selectFirst("div.sheader")
|
||||
.select("div.data > div.sgeneros > a")
|
||||
.map((e) => e.text)
|
||||
@@ -82,12 +90,16 @@ class AnimeOnlineNinja extends MProvider {
|
||||
final type = player.attr("data-type");
|
||||
final id = player.attr("data-post");
|
||||
final num = player.attr("data-nume");
|
||||
final resUrl = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/wp-json/dooplayer/v1/post/$id?type=$type&source=$num")))
|
||||
.body;
|
||||
final url =
|
||||
substringBefore(substringAfter(resUrl, "\"embed_url\":\""), "\",")
|
||||
.replaceAll("\\", "");
|
||||
final resUrl =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/wp-json/dooplayer/v1/post/$id?type=$type&source=$num",
|
||||
),
|
||||
)).body;
|
||||
final url = substringBefore(
|
||||
substringAfter(resUrl, "\"embed_url\":\""),
|
||||
"\",",
|
||||
).replaceAll("\\", "");
|
||||
videos.addAll(await extractVideos(url, name));
|
||||
}
|
||||
return sortVideos(videos, source.id);
|
||||
@@ -100,8 +112,11 @@ class AnimeOnlineNinja extends MProvider {
|
||||
return await extractFromMulti(url);
|
||||
} else if (["filemoon", "moon", "filemooon"].any((a) => url.contains(a))) {
|
||||
a = await filemoonExtractor(url, "$lang Filemoon - ", "");
|
||||
} else if (["https://dood", "https://ds2play", "https://d0"]
|
||||
.any((a) => url.contains(a))) {
|
||||
} else if ([
|
||||
"https://dood",
|
||||
"https://ds2play",
|
||||
"https://d0",
|
||||
].any((a) => url.contains(a))) {
|
||||
a = await doodExtractor(url, "$lang DoodStream");
|
||||
} else if (["streamtape", "stp", "stape"].any((a) => url.contains(a))) {
|
||||
a = await streamTapeExtractor(url, "$lang StreamTape");
|
||||
@@ -111,8 +126,10 @@ class AnimeOnlineNinja extends MProvider {
|
||||
final resUrl = (await client.get(Uri.parse(url))).body;
|
||||
final jsData =
|
||||
parseHtml(resUrl).selectFirst("script:contains(sources)").text;
|
||||
final videoUrl =
|
||||
substringBefore(substringAfter(jsData, "{file:\""), "\"");
|
||||
final videoUrl = substringBefore(
|
||||
substringAfter(jsData, "{file:\""),
|
||||
"\"",
|
||||
);
|
||||
|
||||
MVideo video = MVideo();
|
||||
video
|
||||
@@ -121,13 +138,20 @@ class AnimeOnlineNinja extends MProvider {
|
||||
..quality = "$lang WolfStream";
|
||||
|
||||
a = [video];
|
||||
} else if (["wishembed", "streamwish", "strwish", "wish"]
|
||||
.any((a) => url.contains(a))) {
|
||||
} else if ([
|
||||
"wishembed",
|
||||
"streamwish",
|
||||
"strwish",
|
||||
"wish",
|
||||
].any((a) => url.contains(a))) {
|
||||
a = await streamWishExtractor(url, "$lang StreamWish");
|
||||
} else if (url.contains("mp4upload")) {
|
||||
a = await mp4UploadExtractor(url, null, "$lang", "");
|
||||
} else if (["vidhide", "filelions.top", "vid."]
|
||||
.any((a) => url.contains(a))) {
|
||||
} else if ([
|
||||
"vidhide",
|
||||
"filelions.top",
|
||||
"vid.",
|
||||
].any((a) => url.contains(a))) {
|
||||
a = await streamHideExtractor(url, lang);
|
||||
}
|
||||
videos.addAll(a);
|
||||
@@ -139,14 +163,17 @@ class AnimeOnlineNinja extends MProvider {
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final masterUrl = substringBefore(
|
||||
substringAfter(
|
||||
substringAfter(
|
||||
substringAfter(unpackJs(res), "sources:"), "file:\""),
|
||||
"src:\""),
|
||||
'"');
|
||||
substringAfter(substringAfter(unpackJs(res), "sources:"), "file:\""),
|
||||
"src:\"",
|
||||
),
|
||||
'"',
|
||||
);
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
List<MVideo> videos = [];
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -168,16 +195,20 @@ class AnimeOnlineNinja extends MProvider {
|
||||
}
|
||||
|
||||
Future<List<MVideo>> uqloadExtractor(String url, String lang) async {
|
||||
final Client client =
|
||||
Client(source, json.encode({"useDartHttpClient": true}));
|
||||
final Client client = Client(
|
||||
source,
|
||||
json.encode({"useDartHttpClient": true}),
|
||||
);
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final js = xpath(res, '//script[contains(text(), "sources:")]/text()');
|
||||
if (js.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
final videoUrl =
|
||||
substringBefore(substringAfter(js.first, "sources: [\""), '"');
|
||||
final videoUrl = substringBefore(
|
||||
substringAfter(js.first, "sources: [\""),
|
||||
'"',
|
||||
);
|
||||
MVideo video = MVideo();
|
||||
video
|
||||
..url = videoUrl
|
||||
@@ -200,12 +231,16 @@ class AnimeOnlineNinja extends MProvider {
|
||||
}
|
||||
List<MVideo> videos = [];
|
||||
for (var element in document.select("div.ODDIV $langSelector > li")) {
|
||||
final hosterUrl =
|
||||
substringBefore(substringAfter(element.attr("onclick"), "('"), "')");
|
||||
final hosterUrl = substringBefore(
|
||||
substringAfter(element.attr("onclick"), "('"),
|
||||
"')",
|
||||
);
|
||||
String lang = "";
|
||||
if (langSelector == "div") {
|
||||
lang = substringBefore(
|
||||
substringAfter(element.parent?.attr("class"), "OD_", ""), " ");
|
||||
substringAfter(element.parent?.attr("class"), "OD_", ""),
|
||||
" ",
|
||||
);
|
||||
} else {
|
||||
lang = prefLang;
|
||||
}
|
||||
@@ -215,8 +250,11 @@ class AnimeOnlineNinja extends MProvider {
|
||||
return videos;
|
||||
}
|
||||
|
||||
MPages parseAnimeList(String res,
|
||||
{String selector = "article.w_item_a > a", bool hasNextPage = false}) {
|
||||
MPages parseAnimeList(
|
||||
String res, {
|
||||
String selector = "article.w_item_a > a",
|
||||
bool hasNextPage = false,
|
||||
}) {
|
||||
final elements = parseHtml(res).select(selector);
|
||||
List<MManga> animeList = [];
|
||||
for (var element in elements) {
|
||||
@@ -225,7 +263,8 @@ class AnimeOnlineNinja extends MProvider {
|
||||
MManga anime = MManga();
|
||||
final img = element.selectFirst("img");
|
||||
anime.name = img.attr("alt");
|
||||
anime.imageUrl = img?.attr("data-src") ??
|
||||
anime.imageUrl =
|
||||
img?.attr("data-src") ??
|
||||
img?.attr("data-lazy-src") ??
|
||||
img?.attr("srcset") ??
|
||||
img?.getSrc;
|
||||
@@ -245,7 +284,8 @@ class AnimeOnlineNinja extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["SUB", "All", "ES", "LAT"],
|
||||
entryValues: ["SUB", "", "ES", "LAT"]),
|
||||
entryValues: ["SUB", "", "ES", "LAT"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_server1",
|
||||
title: "Preferred server",
|
||||
@@ -260,7 +300,7 @@ class AnimeOnlineNinja extends MProvider {
|
||||
"saidochesto.top",
|
||||
"VidHide",
|
||||
"StreamWish",
|
||||
"Mp4Upload"
|
||||
"Mp4Upload",
|
||||
],
|
||||
entryValues: [
|
||||
"Filemoon",
|
||||
@@ -271,8 +311,9 @@ class AnimeOnlineNinja extends MProvider {
|
||||
"saidochesto.top",
|
||||
"VidHide",
|
||||
"StreamWish",
|
||||
"Mp4Upload"
|
||||
]),
|
||||
"Mp4Upload",
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _animeonlineninjaSource = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/es/animeonlineninja/icon.png",
|
||||
sourceCodeUrl: _animeonlineninjaSourceCodeUrl,
|
||||
version: _animeonlineninjaVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -11,15 +11,20 @@ class AnimeSama extends MProvider {
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final doc = (await client.get(Uri.parse("${source.baseUrl}/#$page"))).body;
|
||||
final regex = RegExp(r"""^\s*carteClassique\(\s*.*?\s*,\s*"(.*?)".*\)""",
|
||||
multiLine: true);
|
||||
final regex = RegExp(
|
||||
r"""^\s*carteClassique\(\s*.*?\s*,\s*"(.*?)".*\)""",
|
||||
multiLine: true,
|
||||
);
|
||||
var matches = regex.allMatches(doc).toList();
|
||||
List<List<RegExpMatch>> chunks = chunked(matches, 5);
|
||||
List<MManga> seasons = [];
|
||||
if (page > 0 && page <= chunks.length) {
|
||||
for (RegExpMatch match in chunks[page - 1]) {
|
||||
seasons.addAll(await fetchAnimeSeasons(
|
||||
"${source.baseUrl}/catalogue/${match.group(1)}"));
|
||||
seasons.addAll(
|
||||
await fetchAnimeSeasons(
|
||||
"${source.baseUrl}/catalogue/${match.group(1)}",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return MPages(seasons, page < chunks.length);
|
||||
@@ -29,18 +34,26 @@ class AnimeSama extends MProvider {
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client.get(Uri.parse(source.baseUrl))).body;
|
||||
var document = parseHtml(res);
|
||||
final latest = document
|
||||
final latest =
|
||||
document
|
||||
.select("h2")
|
||||
.where((MElement e) =>
|
||||
e.outerHtml.toLowerCase().contains("derniers épisodes ajoutés"))
|
||||
.where(
|
||||
(MElement e) => e.outerHtml.toLowerCase().contains(
|
||||
"derniers épisodes ajoutés",
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
final seasonElements = (latest.first.parent.nextElementSibling as MElement)
|
||||
final seasonElements =
|
||||
(latest.first.parent.nextElementSibling as MElement)
|
||||
.select("div")
|
||||
.toList();
|
||||
List<MManga> seasons = [];
|
||||
for (var seasonElement in seasonElements) {
|
||||
seasons.addAll(await fetchAnimeSeasons(
|
||||
(seasonElement as MElement).getElementsByTagName("a").first.getHref));
|
||||
seasons.addAll(
|
||||
await fetchAnimeSeasons(
|
||||
(seasonElement as MElement).getElementsByTagName("a").first.getHref,
|
||||
),
|
||||
);
|
||||
}
|
||||
return MPages(seasons, false);
|
||||
}
|
||||
@@ -48,47 +61,72 @@ class AnimeSama extends MProvider {
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
final filters = filterList.filters;
|
||||
final res = (await client
|
||||
.get(Uri.parse("${source.baseUrl}/catalogue/listing_all.php")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/catalogue/listing_all.php"),
|
||||
)).body;
|
||||
var databaseElements = parseHtml(res).select(".cardListAnime");
|
||||
List<MElement> elements = [];
|
||||
elements = databaseElements
|
||||
.where((MElement element) => element.select("h1, p").any((MElement e) =>
|
||||
e.text.toLowerCase().contains(query.toLowerCase().trim())))
|
||||
elements =
|
||||
databaseElements
|
||||
.where(
|
||||
(MElement element) => element
|
||||
.select("h1, p")
|
||||
.any(
|
||||
(MElement e) => e.text.toLowerCase().contains(
|
||||
query.toLowerCase().trim(),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
for (var filter in filters) {
|
||||
if (filter.type == "TypeFilter") {
|
||||
final types = (filter.state as List).where((e) => e.state).toList();
|
||||
elements = elements
|
||||
.where((MElement element) =>
|
||||
elements =
|
||||
elements
|
||||
.where(
|
||||
(MElement element) =>
|
||||
types.isEmpty ||
|
||||
types.any((p) => element.className.contains(p.value)))
|
||||
types.any((p) => element.className.contains(p.value)),
|
||||
)
|
||||
.toList();
|
||||
} else if (filter.type == "LanguageFilter") {
|
||||
final language = (filter.state as List).where((e) => e.state).toList();
|
||||
elements = elements
|
||||
.where((MElement element) =>
|
||||
elements =
|
||||
elements
|
||||
.where(
|
||||
(MElement element) =>
|
||||
language.isEmpty ||
|
||||
language.any((p) => element.className.contains(p.value)))
|
||||
language.any((p) => element.className.contains(p.value)),
|
||||
)
|
||||
.toList();
|
||||
} else if (filter.type == "GenreFilter") {
|
||||
final included = (filter.state as List)
|
||||
final included =
|
||||
(filter.state as List)
|
||||
.where((e) => e.state == 1 ? true : false)
|
||||
.toList();
|
||||
final excluded = (filter.state as List)
|
||||
final excluded =
|
||||
(filter.state as List)
|
||||
.where((e) => e.state == 2 ? true : false)
|
||||
.toList();
|
||||
if (included.isNotEmpty) {
|
||||
elements = elements
|
||||
.where((MElement element) =>
|
||||
included.every((p) => element.className.contains(p.value)))
|
||||
elements =
|
||||
elements
|
||||
.where(
|
||||
(MElement element) => included.every(
|
||||
(p) => element.className.contains(p.value),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
if (excluded.isNotEmpty) {
|
||||
elements = elements
|
||||
.where((MElement element) =>
|
||||
excluded.every((p) => element.className.contains(p.value)))
|
||||
elements =
|
||||
elements
|
||||
.where(
|
||||
(MElement element) => excluded.every(
|
||||
(p) => element.className.contains(p.value),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -97,8 +135,11 @@ class AnimeSama extends MProvider {
|
||||
if (chunks.isEmpty) return MPages([], false);
|
||||
List<MManga> seasons = [];
|
||||
for (var seasonElement in chunks[page - 1]) {
|
||||
seasons.addAll(await fetchAnimeSeasons(
|
||||
seasonElement.getElementsByTagName("a").first.getHref));
|
||||
seasons.addAll(
|
||||
await fetchAnimeSeasons(
|
||||
seasonElement.getElementsByTagName("a").first.getHref,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return MPages(seasons, page < chunks.length);
|
||||
@@ -108,8 +149,9 @@ class AnimeSama extends MProvider {
|
||||
Future<MManga> getDetail(String url) async {
|
||||
var animeUrl =
|
||||
"${source.baseUrl}${substringBeforeLast(getUrlWithoutDomain(url), "/")}";
|
||||
var movie =
|
||||
int.tryParse(url.split("#").length >= 2 ? url.split("#")[1] : "");
|
||||
var movie = int.tryParse(
|
||||
url.split("#").length >= 2 ? url.split("#")[1] : "",
|
||||
);
|
||||
List<Map<String, dynamic>> playersList = [];
|
||||
for (var lang in ["vostfr", "vf"]) {
|
||||
final players = await fetchPlayers("$animeUrl/$lang");
|
||||
@@ -181,22 +223,23 @@ class AnimeSama extends MProvider {
|
||||
}
|
||||
|
||||
Future<List<MVideo>> vidmolyExtractor(String url, String lang) async {
|
||||
final headers = {
|
||||
'Referer': 'https://vidmoly.to',
|
||||
};
|
||||
final headers = {'Referer': 'https://vidmoly.to'};
|
||||
List<MVideo> videos = [];
|
||||
final playListUrlResponse = (await client.get(Uri.parse(url))).body;
|
||||
final playlistUrl =
|
||||
RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ??
|
||||
"";
|
||||
if (playlistUrl.isEmpty) return [];
|
||||
final masterPlaylistRes =
|
||||
await client.get(Uri.parse(playlistUrl), headers: headers);
|
||||
final masterPlaylistRes = await client.get(
|
||||
Uri.parse(playlistUrl),
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (masterPlaylistRes.statusCode == 200) {
|
||||
for (var it
|
||||
in substringAfter(masterPlaylistRes.body, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes.body,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -230,8 +273,10 @@ class AnimeSama extends MProvider {
|
||||
if (masterUrl.contains(".m3u8")) {
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -317,14 +362,16 @@ class AnimeSama extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080", "720", "480", "360"]),
|
||||
entryValues: ["1080", "720", "480", "360"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "voices_preference",
|
||||
title: "Préférence des voix",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Préférer VOSTFR", "Préférer VF"],
|
||||
entryValues: ["vostfr", "vf"]),
|
||||
entryValues: ["vostfr", "vf"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -349,8 +396,10 @@ class AnimeSama extends MProvider {
|
||||
var moviesUrl = "$url/$seasonStem";
|
||||
var movies = await fetchPlayers(moviesUrl);
|
||||
if (movies.isNotEmpty) {
|
||||
var movieNameRegex =
|
||||
RegExp("^\\s*newSPF\\(\"(.*)\"\\);", multiLine: true);
|
||||
var movieNameRegex = RegExp(
|
||||
"^\\s*newSPF\\(\"(.*)\"\\);",
|
||||
multiLine: true,
|
||||
);
|
||||
var moviesDoc = (await client.get(Uri.parse(moviesUrl))).body;
|
||||
List<RegExpMatch> matches =
|
||||
movieNameRegex.allMatches(moviesDoc).toList();
|
||||
@@ -369,11 +418,14 @@ class AnimeSama extends MProvider {
|
||||
MManga anime = MManga();
|
||||
anime.imageUrl = document.getElementById("coverOeuvre")?.getSrc;
|
||||
anime.genre = (document.xpathFirst(
|
||||
'//h2[contains(text(),"Genres")]/following-sibling::a/text()') ??
|
||||
'//h2[contains(text(),"Genres")]/following-sibling::a/text()',
|
||||
) ??
|
||||
"")
|
||||
.split(",");
|
||||
anime.description = document.xpathFirst(
|
||||
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()') ??
|
||||
anime.description =
|
||||
document.xpathFirst(
|
||||
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()',
|
||||
) ??
|
||||
"";
|
||||
|
||||
anime.name = title;
|
||||
@@ -386,11 +438,14 @@ class AnimeSama extends MProvider {
|
||||
MManga anime = MManga();
|
||||
anime.imageUrl = document.getElementById("coverOeuvre")?.getSrc;
|
||||
anime.genre = (document.xpathFirst(
|
||||
'//h2[contains(text(),"Genres")]/following-sibling::a/text()') ??
|
||||
'//h2[contains(text(),"Genres")]/following-sibling::a/text()',
|
||||
) ??
|
||||
"")
|
||||
.split(",");
|
||||
anime.description = document.xpathFirst(
|
||||
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()') ??
|
||||
anime.description =
|
||||
document.xpathFirst(
|
||||
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()',
|
||||
) ??
|
||||
"";
|
||||
anime.name =
|
||||
'$animeName ${substringBefore(seasonName, ',').replaceAll('"', "")}';
|
||||
@@ -448,7 +503,9 @@ class AnimeSama extends MProvider {
|
||||
|
||||
String sanitizeEpisodesJs(String doc) {
|
||||
return doc.replaceAll(
|
||||
RegExp(r'(?<=\[|\,)\s*\"\s*(https?://[^\s\"]+)\s*\"\s*(?=\,|\])'), '');
|
||||
RegExp(r'(?<=\[|\,)\s*\"\s*(https?://[^\s\"]+)\s*\"\s*(?=\,|\])'),
|
||||
'',
|
||||
);
|
||||
}
|
||||
|
||||
List<List<dynamic>> chunked(List<dynamic> list, int size) {
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _animesama = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesama/icon.png",
|
||||
sourceCodeUrl: animesamaCodeUrl,
|
||||
version: animesamaVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -16,12 +16,18 @@ class AnimesUltra extends MProvider {
|
||||
final res = (await client.get(Uri.parse(baseUrl))).body;
|
||||
|
||||
List<MManga> animeList = [];
|
||||
final urls = xpath(res,
|
||||
'//*[contains(@class,"swiper-slide item-qtip")]/div[@class="item"]/a/@href');
|
||||
final names = xpath(res,
|
||||
'//*[contains(@class,"swiper-slide item-qtip")]/div[@class="item"]/a/img/@title');
|
||||
final images = xpath(res,
|
||||
'//*[contains(@class,"swiper-slide item-qtip")]/div[@class="item"]/a/img/@data-src');
|
||||
final urls = xpath(
|
||||
res,
|
||||
'//*[contains(@class,"swiper-slide item-qtip")]/div[@class="item"]/a/@href',
|
||||
);
|
||||
final names = xpath(
|
||||
res,
|
||||
'//*[contains(@class,"swiper-slide item-qtip")]/div[@class="item"]/a/img/@title',
|
||||
);
|
||||
final images = xpath(
|
||||
res,
|
||||
'//*[contains(@class,"swiper-slide item-qtip")]/div[@class="item"]/a/img/@data-src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -39,12 +45,18 @@ class AnimesUltra extends MProvider {
|
||||
final res = (await client.get(Uri.parse(baseUrl))).body;
|
||||
|
||||
List<MManga> animeList = [];
|
||||
final urls = xpath(res,
|
||||
'//*[@class="block_area block_area_home"]/div[@class="tab-content"]/div[contains(@class,"block_area-content block_area-list")]/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]/a/@href');
|
||||
final names = xpath(res,
|
||||
'//*[@class="block_area block_area_home"]/div[@class="tab-content"]/div[contains(@class,"block_area-content block_area-list")]/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]/a/@title');
|
||||
final images = xpath(res,
|
||||
'//*[@class="block_area block_area_home"]/div[@class="tab-content"]/div[contains(@class,"block_area-content block_area-list")]/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]/img/@data-src');
|
||||
final urls = xpath(
|
||||
res,
|
||||
'//*[@class="block_area block_area_home"]/div[@class="tab-content"]/div[contains(@class,"block_area-content block_area-list")]/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]/a/@href',
|
||||
);
|
||||
final names = xpath(
|
||||
res,
|
||||
'//*[@class="block_area block_area_home"]/div[@class="tab-content"]/div[contains(@class,"block_area-content block_area-list")]/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]/a/@title',
|
||||
);
|
||||
final images = xpath(
|
||||
res,
|
||||
'//*[@class="block_area block_area_home"]/div[@class="tab-content"]/div[contains(@class,"block_area-content block_area-list")]/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]/img/@data-src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -60,9 +72,12 @@ class AnimesUltra extends MProvider {
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
query = query.trim().replaceAll(" ", "+");
|
||||
final res = (await client.get(Uri.parse(
|
||||
"$baseUrl/index.php?do=search&subaction=search&story=$query")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"$baseUrl/index.php?do=search&subaction=search&story=$query",
|
||||
),
|
||||
)).body;
|
||||
|
||||
List<MManga> animeList = [];
|
||||
final urls = xpath(res, '//*[@class="film-poster"]/a/@href');
|
||||
@@ -83,7 +98,7 @@ class AnimesUltra extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"En cours": 0, "Terminé": 1}
|
||||
{"En cours": 0, "Terminé": 1},
|
||||
];
|
||||
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
@@ -92,17 +107,25 @@ class AnimesUltra extends MProvider {
|
||||
anime.description =
|
||||
xpath(res, '//*[@class="film-description m-hide"]/text()').first;
|
||||
|
||||
final status = xpath(res,
|
||||
'//*[@class="item item-title" and contains(text(),"Status:")]/span[2]/text()')
|
||||
.first;
|
||||
final status =
|
||||
xpath(
|
||||
res,
|
||||
'//*[@class="item item-title" and contains(text(),"Status:")]/span[2]/text()',
|
||||
).first;
|
||||
anime.status = parseStatus(status, statusList);
|
||||
anime.genre = xpath(res,
|
||||
'//*[@class="item item-list" and contains(text(),"Genres:")]/a/text()');
|
||||
anime.genre = xpath(
|
||||
res,
|
||||
'//*[@class="item item-list" and contains(text(),"Genres:")]/a/text()',
|
||||
);
|
||||
anime.author = doc.xpathFirst(
|
||||
'//*[@class="item item-title" and contains(text(),"Studio:")]/span[2]/text()');
|
||||
final episodesLength = int.parse(substringBefore(
|
||||
doc.xpathFirst('//*[@class="film-stats"]/span[7]/text()'), "/")
|
||||
.replaceAll("Ep", ""));
|
||||
'//*[@class="item item-title" and contains(text(),"Studio:")]/span[2]/text()',
|
||||
);
|
||||
final episodesLength = int.parse(
|
||||
substringBefore(
|
||||
doc.xpathFirst('//*[@class="film-stats"]/span[7]/text()'),
|
||||
"/",
|
||||
).replaceAll("Ep", ""),
|
||||
);
|
||||
List<MChapter>? episodesList = [];
|
||||
|
||||
for (var i = 0; i < episodesLength; i++) {
|
||||
@@ -119,18 +142,23 @@ class AnimesUltra extends MProvider {
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
final resHtml = (await client.get(Uri.parse(url))).body;
|
||||
final id = url.split('/')[4].split('-')[0];
|
||||
final resServer = (await client
|
||||
.get(Uri.parse("$baseUrl/engine/ajax/full-story.php?newsId=$id")))
|
||||
.body;
|
||||
final resServer =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/engine/ajax/full-story.php?newsId=$id"),
|
||||
)).body;
|
||||
|
||||
final serverIds =
|
||||
xpath(resHtml, '//*[@class="ps__-list"]/div/@data-server-id');
|
||||
final serverIds = xpath(
|
||||
resHtml,
|
||||
'//*[@class="ps__-list"]/div/@data-server-id',
|
||||
);
|
||||
final serverNames = xpath(resHtml, '//*[@class="ps__-list"]/div/a/text()');
|
||||
List<String> serverUrls = [];
|
||||
for (var id in serverIds) {
|
||||
final serversUrls = xpath(jsonDecode(resServer)["html"],
|
||||
'//*[@id="content_player_${id}"]/text()')
|
||||
.first;
|
||||
final serversUrls =
|
||||
xpath(
|
||||
jsonDecode(resServer)["html"],
|
||||
'//*[@id="content_player_${id}"]/text()',
|
||||
).first;
|
||||
serverUrls.add(serversUrls);
|
||||
}
|
||||
List<MVideo> videos = [];
|
||||
@@ -140,10 +168,13 @@ class AnimesUltra extends MProvider {
|
||||
List<MVideo> a = [];
|
||||
if (name.contains("Sendvid")) {
|
||||
a = await sendVidExtractorr(
|
||||
url.replaceAll("https:////", "https://"), "");
|
||||
url.replaceAll("https:////", "https://"),
|
||||
"",
|
||||
);
|
||||
} else if (name.contains("Sibnet")) {
|
||||
a = await sibnetExtractor(
|
||||
"https://video.sibnet.ru/shell.php?videoid=$url");
|
||||
"https://video.sibnet.ru/shell.php?videoid=$url",
|
||||
);
|
||||
} else if (name.contains("Mytv")) {
|
||||
a = await myTvExtractor("https://www.myvi.tv/embed/$url");
|
||||
} else if (name.contains("Fmoon")) {
|
||||
@@ -170,8 +201,10 @@ class AnimesUltra extends MProvider {
|
||||
if (masterUrl.contains(".m3u8")) {
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
|
||||
@@ -14,4 +14,5 @@ Source _animesultraSource = Source(
|
||||
sourceCodeUrl: _animesultraSourceCodeUrl,
|
||||
version: _animesultraVersion,
|
||||
itemType: ItemType.anime,
|
||||
isFullData: false);
|
||||
isFullData: false,
|
||||
);
|
||||
|
||||
@@ -58,7 +58,7 @@ class AniZone extends MProvider {
|
||||
"status": [],
|
||||
"season": [],
|
||||
"lang": [],
|
||||
"genre": []
|
||||
"genre": [],
|
||||
};
|
||||
|
||||
// Regroupement des filtres avec une logique générique
|
||||
@@ -67,7 +67,7 @@ class AniZone extends MProvider {
|
||||
"LanguageFilter": "lang",
|
||||
"SaisonFilter": "season",
|
||||
"StatusFilter": "status",
|
||||
"GenreFilter": "genre"
|
||||
"GenreFilter": "genre",
|
||||
};
|
||||
|
||||
for (var filter in filterList.filters) {
|
||||
@@ -99,8 +99,10 @@ class AniZone extends MProvider {
|
||||
final description = xpath(doc, '//p[contains(@class,"short")]/text()');
|
||||
anime.description = description.isNotEmpty ? description.first : "";
|
||||
|
||||
final statusList = xpath(doc,
|
||||
'//div[contains(@class,"col2")]//div[contains(@class,"item")]//div[contains(@class,"item-content")]/text()');
|
||||
final statusList = xpath(
|
||||
doc,
|
||||
'//div[contains(@class,"col2")]//div[contains(@class,"item")]//div[contains(@class,"item-content")]/text()',
|
||||
);
|
||||
if (statusList.isNotEmpty) {
|
||||
if (statusList[0] == "Terminer") {
|
||||
anime.status = MStatus.completed;
|
||||
@@ -113,8 +115,10 @@ class AniZone extends MProvider {
|
||||
anime.status = MStatus.unknown;
|
||||
}
|
||||
|
||||
anime.genre = xpath(doc,
|
||||
'//div[contains(@class,"item")]//div[contains(@class,"item-content")]//a[contains(@href,"genre")]/text()');
|
||||
anime.genre = xpath(
|
||||
doc,
|
||||
'//div[contains(@class,"item")]//div[contains(@class,"item-content")]//a[contains(@href,"genre")]/text()',
|
||||
);
|
||||
|
||||
final regex = RegExp(r'(\d+)$');
|
||||
final match = regex.firstMatch(url);
|
||||
@@ -123,14 +127,16 @@ class AniZone extends MProvider {
|
||||
throw Exception('Numéro de l\'épisode non trouvé dans l\'URL.');
|
||||
}
|
||||
|
||||
final res = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/ajax/episode/list/${match.group(1)}")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/ajax/episode/list/${match.group(1)}"),
|
||||
)).body;
|
||||
|
||||
List<MChapter> episodesList = [];
|
||||
|
||||
final episodeElements =
|
||||
parseHtml(json.decode(res)["html"]).select(".ep-item");
|
||||
final episodeElements = parseHtml(
|
||||
json.decode(res)["html"],
|
||||
).select(".ep-item");
|
||||
|
||||
// Associer chaque titre à son URL et récupérer les vidéos
|
||||
for (var element in episodeElements) {
|
||||
@@ -152,16 +158,24 @@ class AniZone extends MProvider {
|
||||
|
||||
@override
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
final videoRes = (await client
|
||||
.get(Uri.parse(url), headers: {"Referer": "${source.baseUrl}/"}))
|
||||
.body;
|
||||
final videoRes =
|
||||
(await client.get(
|
||||
Uri.parse(url),
|
||||
headers: {"Referer": "${source.baseUrl}/"},
|
||||
)).body;
|
||||
|
||||
final lang = xpath(videoRes.replaceAll(r'\', ''),
|
||||
'//div[contains(@class,"item server-item")]/@data-type');
|
||||
final links = xpath(videoRes.replaceAll(r'\', ''),
|
||||
'//div[contains(@class,"item server-item")]/@data-id');
|
||||
final playersNames = xpath(videoRes.replaceAll(r'\', ''),
|
||||
'//div[contains(@class,"item server-item")]/text()');
|
||||
final lang = xpath(
|
||||
videoRes.replaceAll(r'\', ''),
|
||||
'//div[contains(@class,"item server-item")]/@data-type',
|
||||
);
|
||||
final links = xpath(
|
||||
videoRes.replaceAll(r'\', ''),
|
||||
'//div[contains(@class,"item server-item")]/@data-id',
|
||||
);
|
||||
final playersNames = xpath(
|
||||
videoRes.replaceAll(r'\', ''),
|
||||
'//div[contains(@class,"item server-item")]/text()',
|
||||
);
|
||||
List<Map<String, String>> players = [];
|
||||
for (int j = 0; j < links.length; j++) {
|
||||
// schema of players https://v1.animesz.xyz/ajax/episode/servers?episodeId=(id_episode)
|
||||
@@ -215,14 +229,17 @@ class AniZone extends MProvider {
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final masterUrl = substringBefore(
|
||||
substringAfter(
|
||||
substringAfter(
|
||||
substringAfter(unpackJs(res), "sources:"), "file:\""),
|
||||
"src:\""),
|
||||
'"');
|
||||
substringAfter(substringAfter(unpackJs(res), "sources:"), "file:\""),
|
||||
"src:\"",
|
||||
),
|
||||
'"',
|
||||
);
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
List<MVideo> videos = [];
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -314,7 +331,7 @@ class AniZone extends MProvider {
|
||||
CheckBoxFilter("Vampire", "32"),
|
||||
CheckBoxFilter("Yaoi", "33"),
|
||||
CheckBoxFilter("Yuri", "34"),
|
||||
])
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -327,14 +344,16 @@ class AniZone extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080", "720", "480", "360"]),
|
||||
entryValues: ["1080", "720", "480", "360"],
|
||||
),
|
||||
ListPreference(
|
||||
key: "voices_preference",
|
||||
title: "Préférence des voix",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["Préférer VOSTFR", "Préférer VF"],
|
||||
entryValues: ["vostfr", "vf"]),
|
||||
entryValues: ["vostfr", "vf"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -383,8 +402,10 @@ class AniZone extends MProvider {
|
||||
if (masterUrl.contains(".m3u8")) {
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -437,7 +458,8 @@ class AniZone extends MProvider {
|
||||
final masterPlaylistRes = await client.get(Uri.parse(masterUrl));
|
||||
if (masterPlaylistRes.statusCode != 200) {
|
||||
print(
|
||||
"Error lors de la récupération de la playlist M3U8 : ${masterPlaylistRes.statusCode}");
|
||||
"Error lors de la récupération de la playlist M3U8 : ${masterPlaylistRes.statusCode}",
|
||||
);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _aniZoneSource = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/icon.png",
|
||||
sourceCodeUrl: _aniZoneSourceCodeUrl,
|
||||
version: _aniZoneVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -46,8 +46,9 @@ class FrAnime extends MProvider {
|
||||
var seasonsJson = seasons.first;
|
||||
|
||||
if (url.contains("s=")) {
|
||||
int seasonNumber =
|
||||
int.parse(substringBefore(substringAfter(url, "s="), "&"));
|
||||
int seasonNumber = int.parse(
|
||||
substringBefore(substringAfter(url, "s="), "&"),
|
||||
);
|
||||
seasonsJson = seasons[seasonNumber - 1];
|
||||
}
|
||||
|
||||
@@ -103,8 +104,9 @@ class FrAnime extends MProvider {
|
||||
videoBaseUrl += "/$animeId/";
|
||||
|
||||
if (url.contains("s=")) {
|
||||
int seasonNumber =
|
||||
int.parse(substringBefore(substringAfter(url, "s="), "&"));
|
||||
int seasonNumber = int.parse(
|
||||
substringBefore(substringAfter(url, "s="), "&"),
|
||||
);
|
||||
videoBaseUrl += "${seasonNumber - 1}/";
|
||||
seasonsJson = seasons[seasonNumber - 1];
|
||||
} else {
|
||||
@@ -141,17 +143,21 @@ class FrAnime extends MProvider {
|
||||
|
||||
MVideo video = MVideo();
|
||||
|
||||
final playerUrl = (await client.get(Uri.parse(apiUrl),
|
||||
headers: {"Referer": "https://franime.fr/"}))
|
||||
.body;
|
||||
final playerUrl =
|
||||
(await client.get(
|
||||
Uri.parse(apiUrl),
|
||||
headers: {"Referer": "https://franime.fr/"},
|
||||
)).body;
|
||||
|
||||
List<MVideo> a = [];
|
||||
print(playerName);
|
||||
if (playerName.contains("vido")) {
|
||||
videos.add(video
|
||||
videos.add(
|
||||
video
|
||||
..url = playerUrl
|
||||
..originalUrl = playerUrl
|
||||
..quality = "FRAnime (Vido)");
|
||||
..quality = "FRAnime (Vido)",
|
||||
);
|
||||
} else if (playerName.contains("sendvid")) {
|
||||
a = await sendVidExtractorr(playerUrl, "");
|
||||
} else if (playerName.contains("sibnet")) {
|
||||
@@ -165,7 +171,7 @@ class FrAnime extends MProvider {
|
||||
|
||||
MPages animeResList(String res) {
|
||||
final statusList = [
|
||||
{"EN COURS": 0, "TERMINÉ": 1}
|
||||
{"EN COURS": 0, "TERMINÉ": 1},
|
||||
];
|
||||
List<MManga> animeList = [];
|
||||
|
||||
@@ -233,7 +239,7 @@ class FrAnime extends MProvider {
|
||||
|
||||
MPages animeSeachFetch(String res, String query) {
|
||||
final statusList = [
|
||||
{"EN COURS": 0, "TERMINÉ": 1}
|
||||
{"EN COURS": 0, "TERMINÉ": 1},
|
||||
];
|
||||
List<MManga> animeList = [];
|
||||
final jsonResList = json.decode(res);
|
||||
@@ -241,20 +247,23 @@ class FrAnime extends MProvider {
|
||||
MManga anime = MManga();
|
||||
|
||||
final titleO = getMapValue(json.encode(animeJson), "titleO");
|
||||
final titleAlt =
|
||||
getMapValue(json.encode(animeJson), "titles", encode: true);
|
||||
final containsEn = getMapValue(titleAlt, "en")
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.contains(query.toLowerCase());
|
||||
final containsEnJp = getMapValue(titleAlt, "en_jp")
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.contains(query.toLowerCase());
|
||||
final containsJaJp = getMapValue(titleAlt, "ja_jp")
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.contains(query.toLowerCase());
|
||||
final titleAlt = getMapValue(
|
||||
json.encode(animeJson),
|
||||
"titles",
|
||||
encode: true,
|
||||
);
|
||||
final containsEn = getMapValue(
|
||||
titleAlt,
|
||||
"en",
|
||||
).toString().toLowerCase().contains(query.toLowerCase());
|
||||
final containsEnJp = getMapValue(
|
||||
titleAlt,
|
||||
"en_jp",
|
||||
).toString().toLowerCase().contains(query.toLowerCase());
|
||||
final containsJaJp = getMapValue(
|
||||
titleAlt,
|
||||
"ja_jp",
|
||||
).toString().toLowerCase().contains(query.toLowerCase());
|
||||
final containsTitleO = titleO.toLowerCase().contains(query.toLowerCase());
|
||||
|
||||
if (containsEn || containsEnJp || containsJaJp || containsTitleO) {
|
||||
@@ -319,16 +328,19 @@ class FrAnime extends MProvider {
|
||||
}
|
||||
|
||||
Future<String> dataBase() async {
|
||||
return (await client.get(Uri.parse("https://api.franime.fr/api/animes/"),
|
||||
headers: {"Referer": "https://franime.fr/"}))
|
||||
.body;
|
||||
return (await client.get(
|
||||
Uri.parse("https://api.franime.fr/api/animes/"),
|
||||
headers: {"Referer": "https://franime.fr/"},
|
||||
)).body;
|
||||
}
|
||||
|
||||
String databaseAnimeByTitleO(String res, String titleO) {
|
||||
final datas = json.decode(res) as List<Map<String, dynamic>>;
|
||||
for (var data in datas) {
|
||||
String title =
|
||||
(data["titleO"] as String).replaceAll(RegExp("[^A-Za-z0-9 ]"), "");
|
||||
String title = (data["titleO"] as String).replaceAll(
|
||||
RegExp("[^A-Za-z0-9 ]"),
|
||||
"",
|
||||
);
|
||||
if (title.replaceAll(" ", "-").toLowerCase() == "${titleO}") {
|
||||
return json.encode(data);
|
||||
}
|
||||
@@ -351,8 +363,10 @@ class FrAnime extends MProvider {
|
||||
if (masterUrl.contains(".m3u8")) {
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
|
||||
@@ -15,4 +15,5 @@ Source _franimeSource = Source(
|
||||
sourceCodeUrl: _franimeSourceCodeUrl,
|
||||
version: _franimeVersion,
|
||||
itemType: ItemType.anime,
|
||||
isFullData: true);
|
||||
isFullData: true,
|
||||
);
|
||||
|
||||
@@ -16,12 +16,18 @@ class OtakuFr extends MProvider {
|
||||
final res =
|
||||
(await client.get(Uri.parse("$baseUrl/en-cours/page/$page"))).body;
|
||||
List<MManga> animeList = [];
|
||||
final urls =
|
||||
xpath(res, '//*[@class="list"]/article/div/div/figure/a/@href');
|
||||
final names =
|
||||
xpath(res, '//*[@class="list"]/article/div/div/figure/a/img/@title');
|
||||
final images =
|
||||
xpath(res, '//*[@class="list"]/article/div/div/figure/a/img/@src');
|
||||
final urls = xpath(
|
||||
res,
|
||||
'//*[@class="list"]/article/div/div/figure/a/@href',
|
||||
);
|
||||
final names = xpath(
|
||||
res,
|
||||
'//*[@class="list"]/article/div/div/figure/a/img/@title',
|
||||
);
|
||||
final images = xpath(
|
||||
res,
|
||||
'//*[@class="list"]/article/div/div/figure/a/img/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -43,12 +49,14 @@ class OtakuFr extends MProvider {
|
||||
final namess = xpath(res, '//*[@class="episode"]/div/a/text()');
|
||||
List<String> names = [];
|
||||
for (var name in namess) {
|
||||
names.add(regExp(
|
||||
names.add(
|
||||
regExp(
|
||||
name,
|
||||
r'(?<=\bS\d\s*|)\d{2}\s*(?=\b(Vostfr|vostfr|VF|Vf|vf|\(VF\)|\(vf\)|\(Vf\)|\(Vostfr\)\b))?',
|
||||
'',
|
||||
0,
|
||||
0)
|
||||
0,
|
||||
)
|
||||
.replaceAll(' vostfr', '')
|
||||
.replaceAll(' Vostfr', '')
|
||||
.replaceAll(' VF', '')
|
||||
@@ -58,7 +66,8 @@ class OtakuFr extends MProvider {
|
||||
.replaceAll(' (vf)', '')
|
||||
.replaceAll(' (vf)', '')
|
||||
.replaceAll(' (Vf)', '')
|
||||
.replaceAll(' (Vostfr)', ''));
|
||||
.replaceAll(' (Vostfr)', ''),
|
||||
);
|
||||
}
|
||||
final images = xpath(res, '//*[@class="episode"]/div/figure/a/img/@src');
|
||||
|
||||
@@ -98,12 +107,18 @@ class OtakuFr extends MProvider {
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
|
||||
List<MManga> animeList = [];
|
||||
final urls =
|
||||
xpath(res, '//*[@class="list"]/article/div/div/figure/a/@href');
|
||||
final names =
|
||||
xpath(res, '//*[@class="list"]/article/div/div/figure/a/img/@title');
|
||||
final images =
|
||||
xpath(res, '//*[@class="list"]/article/div/div/figure/a/img/@src');
|
||||
final urls = xpath(
|
||||
res,
|
||||
'//*[@class="list"]/article/div/div/figure/a/@href',
|
||||
);
|
||||
final names = xpath(
|
||||
res,
|
||||
'//*[@class="list"]/article/div/div/figure/a/img/@title',
|
||||
);
|
||||
final images = xpath(
|
||||
res,
|
||||
'//*[@class="list"]/article/div/div/figure/a/img/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -119,35 +134,48 @@ class OtakuFr extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"En cours": 0, "Terminé": 1}
|
||||
{"En cours": 0, "Terminé": 1},
|
||||
];
|
||||
String res =
|
||||
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
|
||||
.body;
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl${getUrlWithoutDomain(url)}"),
|
||||
)).body;
|
||||
MManga anime = MManga();
|
||||
final originalUrl = xpath(res,
|
||||
'//*[@class="breadcrumb"]/li[@class="breadcrumb-item"][2]/a/@href');
|
||||
final originalUrl = xpath(
|
||||
res,
|
||||
'//*[@class="breadcrumb"]/li[@class="breadcrumb-item"][2]/a/@href',
|
||||
);
|
||||
if (originalUrl.isNotEmpty) {
|
||||
res = (await client.get(Uri.parse(originalUrl.first))).body;
|
||||
}
|
||||
final description =
|
||||
xpath(res, '//*[@class="episode fz-sm synop"]/p/text()');
|
||||
final description = xpath(
|
||||
res,
|
||||
'//*[@class="episode fz-sm synop"]/p/text()',
|
||||
);
|
||||
if (description.isNotEmpty) {
|
||||
anime.description = description.first.replaceAll("Synopsis:", "");
|
||||
}
|
||||
final status = xpath(res,
|
||||
'//*[@class="list-unstyled"]/li[contains(text(),"Statut")]/text()');
|
||||
final status = xpath(
|
||||
res,
|
||||
'//*[@class="list-unstyled"]/li[contains(text(),"Statut")]/text()',
|
||||
);
|
||||
if (status.isNotEmpty) {
|
||||
anime.status =
|
||||
parseStatus(status.first.replaceAll("Statut: ", ""), statusList);
|
||||
anime.status = parseStatus(
|
||||
status.first.replaceAll("Statut: ", ""),
|
||||
statusList,
|
||||
);
|
||||
}
|
||||
|
||||
anime.genre = xpath(res,
|
||||
'//*[@class="list-unstyled"]/li[contains(text(),"Genre")]/ul/li/a/text()');
|
||||
anime.genre = xpath(
|
||||
res,
|
||||
'//*[@class="list-unstyled"]/li[contains(text(),"Genre")]/ul/li/a/text()',
|
||||
);
|
||||
|
||||
final epUrls = xpath(res, '//*[@class="list-episodes list-group"]/a/@href');
|
||||
final dates =
|
||||
xpath(res, '//*[@class="list-episodes list-group"]/a/span/text()');
|
||||
final dates = xpath(
|
||||
res,
|
||||
'//*[@class="list-episodes list-group"]/a/span/text()',
|
||||
);
|
||||
final names = xpath(res, '//*[@class="list-episodes list-group"]/a/text()');
|
||||
List<String> episodes = [];
|
||||
|
||||
@@ -155,7 +183,8 @@ class OtakuFr extends MProvider {
|
||||
final date = dates[i];
|
||||
final name = names[i];
|
||||
episodes.add(
|
||||
"Episode ${regExp(name.replaceAll(date, ""), r".* (\d*) [VvfF]{1,1}", '', 1, 1)}");
|
||||
"Episode ${regExp(name.replaceAll(date, ""), r".* (\d*) [VvfF]{1,1}", '', 1, 1)}",
|
||||
);
|
||||
}
|
||||
final dateUploads = parseDates(dates, "dd MMMM yyyy", "fr");
|
||||
|
||||
@@ -175,19 +204,23 @@ class OtakuFr extends MProvider {
|
||||
@override
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
final res =
|
||||
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
|
||||
.body;
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl${getUrlWithoutDomain(url)}"),
|
||||
)).body;
|
||||
|
||||
final servers = parseHtml(res).select("div.tab-content iframe[src]");
|
||||
List<MVideo> videos = [];
|
||||
final hosterSelection = preferenceHosterSelection(source.id);
|
||||
for (var url in servers) {
|
||||
final urll = url.getSrc != "about:blank" ? url.getSrc : url.getDataSrc;
|
||||
final resServer = (await client.get(Uri.parse(fixUrl(urll)),
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"}))
|
||||
.body;
|
||||
final serverUrl =
|
||||
fixUrl(regExp(resServer, r"data-url='([^']+)'", '', 1, 1));
|
||||
final resServer =
|
||||
(await client.get(
|
||||
Uri.parse(fixUrl(urll)),
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"},
|
||||
)).body;
|
||||
final serverUrl = fixUrl(
|
||||
regExp(resServer, r"data-url='([^']+)'", '', 1, 1),
|
||||
);
|
||||
List<MVideo> a = [];
|
||||
if (serverUrl.contains("https://streamwish") &&
|
||||
hosterSelection.contains("Streamwish")) {
|
||||
@@ -278,13 +311,13 @@ class OtakuFr extends MProvider {
|
||||
SelectFilterOption("Suspense", "/genre/suspense/"),
|
||||
SelectFilterOption("Thriller", "/genre/thriller/"),
|
||||
SelectFilterOption("Tranche de vie", "/genre/tranche-de-vie/"),
|
||||
SelectFilterOption("Vampire", "/genre/vampire/")
|
||||
SelectFilterOption("Vampire", "/genre/vampire/"),
|
||||
]),
|
||||
SelectFilter("SubPageFilter", "Sous page", 0, [
|
||||
SelectFilterOption("<Selectionner>", ""),
|
||||
SelectFilterOption("Terminé", "/termine/"),
|
||||
SelectFilterOption("Film", "/film/"),
|
||||
])
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -298,14 +331,16 @@ class OtakuFr extends MProvider {
|
||||
value: "https://otakufr.cc",
|
||||
dialogTitle: "Changer l'url de base",
|
||||
dialogMessage: "",
|
||||
text: "https://otakufr.cc"),
|
||||
text: "https://otakufr.cc",
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_quality",
|
||||
title: "Qualité préférée",
|
||||
summary: "",
|
||||
valueIndex: 1,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080", "720", "480", "360"]),
|
||||
entryValues: ["1080", "720", "480", "360"],
|
||||
),
|
||||
MultiSelectListPreference(
|
||||
key: "hoster_selection_",
|
||||
title: "Enable/Disable Hosts",
|
||||
@@ -318,7 +353,7 @@ class OtakuFr extends MProvider {
|
||||
"Okru",
|
||||
"Voe",
|
||||
"Sibnet",
|
||||
"Upstream"
|
||||
"Upstream",
|
||||
],
|
||||
entryValues: [
|
||||
"Streamwish",
|
||||
@@ -328,7 +363,7 @@ class OtakuFr extends MProvider {
|
||||
"Okru",
|
||||
"Voe",
|
||||
"Sibnet",
|
||||
"Upstream"
|
||||
"Upstream",
|
||||
],
|
||||
values: [
|
||||
"Streamwish",
|
||||
@@ -338,8 +373,9 @@ class OtakuFr extends MProvider {
|
||||
"Okru",
|
||||
"Voe",
|
||||
"Sibnet",
|
||||
"Upstream"
|
||||
]),
|
||||
"Upstream",
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -389,8 +425,10 @@ class OtakuFr extends MProvider {
|
||||
if (masterUrl.contains(".m3u8")) {
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -433,12 +471,16 @@ class OtakuFr extends MProvider {
|
||||
if (js.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
final masterUrl =
|
||||
substringBefore(substringAfter(unpackJs(js.first), "{file:\""), "\"}");
|
||||
final masterUrl = substringBefore(
|
||||
substringAfter(unpackJs(js.first), "{file:\""),
|
||||
"\"}",
|
||||
);
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
List<MVideo> videos = [];
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
|
||||
@@ -14,4 +14,5 @@ Source _otakufr = Source(
|
||||
sourceCodeUrl: otakufrCodeUrl,
|
||||
version: otakufrVersion,
|
||||
itemType: ItemType.anime,
|
||||
isFullData: false);
|
||||
isFullData: false,
|
||||
);
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _yomoviesSource = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/hi/yomovies/icon.png",
|
||||
sourceCodeUrl: _yomoviesSourceCodeUrl,
|
||||
version: _yomoviesVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -23,8 +23,8 @@ class YoMovies extends MProvider {
|
||||
final document = parseHtml(res);
|
||||
return animeFromElement(
|
||||
document.select("div.movies-list > div.ml-item"),
|
||||
document.selectFirst("ul.pagination > li.active + li")?.getHref !=
|
||||
null);
|
||||
document.selectFirst("ul.pagination > li.active + li")?.getHref != null,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -54,8 +54,8 @@ class YoMovies extends MProvider {
|
||||
final document = parseHtml(res);
|
||||
return animeFromElement(
|
||||
document.select("div.movies-list > div.ml-item"),
|
||||
document.selectFirst("ul.pagination > li.active + li")?.getHref !=
|
||||
null);
|
||||
document.selectFirst("ul.pagination > li.active + li")?.getHref != null,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -68,8 +68,10 @@ class YoMovies extends MProvider {
|
||||
var infoElement = document.selectFirst("div.mvi-content");
|
||||
anime.description = infoElement.selectFirst("p.f-desc")?.text ?? "";
|
||||
|
||||
anime.genre = xpath(res,
|
||||
'//div[@class="mvici-left" and contains(text(),"Genre:")]/p/a/text()');
|
||||
anime.genre = xpath(
|
||||
res,
|
||||
'//div[@class="mvici-left" and contains(text(),"Genre:")]/p/a/text()',
|
||||
);
|
||||
|
||||
List<MChapter> episodeList = [];
|
||||
final seasonListElements = document.select("div#seasons > div.tvseason");
|
||||
@@ -124,14 +126,16 @@ class YoMovies extends MProvider {
|
||||
value: "https://yomovies.boo",
|
||||
dialogTitle: "Override BaseUrl",
|
||||
dialogMessage: "",
|
||||
text: "https://yomovies.boo"),
|
||||
text: "https://yomovies.boo",
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_quality",
|
||||
title: "Preferred quality",
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080", "720", "480", "360"])
|
||||
entryValues: ["1080", "720", "480", "360"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -142,11 +146,15 @@ class YoMovies extends MProvider {
|
||||
(await client.get(Uri.parse(url), headers: {"Referer": url})).body;
|
||||
final script = xpath(res, '//script[contains(text(),"sources:")]/text()');
|
||||
if (script.isEmpty) return [];
|
||||
final masterUrl =
|
||||
substringBefore(substringAfter(script.first, "file:\""), '"');
|
||||
final masterUrl = substringBefore(
|
||||
substringAfter(script.first, "file:\""),
|
||||
'"',
|
||||
);
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -207,38 +215,57 @@ class YoMovies extends MProvider {
|
||||
List<dynamic> getFilterList() {
|
||||
return [
|
||||
HeaderFilter(
|
||||
"Note: Only one selection at a time works, and it ignores text search"),
|
||||
"Note: Only one selection at a time works, and it ignores text search",
|
||||
),
|
||||
SeparatorFilter(),
|
||||
SelectFilter("BollywoodFilter", "Bollywood", 0, [
|
||||
SelectFilterOption("<select>", ""),
|
||||
SelectFilterOption("Bollywood", "/genre/bollywood"),
|
||||
SelectFilterOption("Trending", "/genre/top-rated"),
|
||||
SelectFilterOption("Bollywood (2024)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2024&wpas=1"),
|
||||
SelectFilterOption("Bollywood (2023)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2023&wpas=1"),
|
||||
SelectFilterOption("Bollywood (2022)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2022&wpas=1"),
|
||||
SelectFilterOption("Bollywood (2021)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2021&wpas=1"),
|
||||
SelectFilterOption(
|
||||
"Bollywood (2024)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2024&wpas=1",
|
||||
),
|
||||
SelectFilterOption(
|
||||
"Bollywood (2023)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2023&wpas=1",
|
||||
),
|
||||
SelectFilterOption(
|
||||
"Bollywood (2022)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2022&wpas=1",
|
||||
),
|
||||
SelectFilterOption(
|
||||
"Bollywood (2021)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2021&wpas=1",
|
||||
),
|
||||
]),
|
||||
SelectFilter("DualAudioFilter", "Dual Audio", 0, [
|
||||
SelectFilterOption("<select>", ""),
|
||||
SelectFilterOption("Dual Audio", "/genre/dual-audio"),
|
||||
SelectFilterOption("Hollywood Dubbed",
|
||||
"/account/?ptype=post&tax_category%5B%5D=dual-audio&wpas=1"),
|
||||
SelectFilterOption("South Dubbed",
|
||||
"/account/?ptype=post&tax_category%5B%5D=dual-audio&tax_category%5B%5D=south-special&wpas=1"),
|
||||
SelectFilterOption(
|
||||
"Hollywood Dubbed",
|
||||
"/account/?ptype=post&tax_category%5B%5D=dual-audio&wpas=1",
|
||||
),
|
||||
SelectFilterOption(
|
||||
"South Dubbed",
|
||||
"/account/?ptype=post&tax_category%5B%5D=dual-audio&tax_category%5B%5D=south-special&wpas=1",
|
||||
),
|
||||
]),
|
||||
SelectFilter("HollywoodFilter", "Hollywood", 0, [
|
||||
SelectFilterOption("<select>", ""),
|
||||
SelectFilterOption("Hollywood", "/genre/hollywood"),
|
||||
SelectFilterOption("Hollywood (2023)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2023&wpas=1"),
|
||||
SelectFilterOption("Hollywood (2022)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2022&wpas=1"),
|
||||
SelectFilterOption("Hollywood (2021)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2021&wpas=1"),
|
||||
SelectFilterOption(
|
||||
"Hollywood (2023)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2023&wpas=1",
|
||||
),
|
||||
SelectFilterOption(
|
||||
"Hollywood (2022)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2022&wpas=1",
|
||||
),
|
||||
SelectFilterOption(
|
||||
"Hollywood (2021)",
|
||||
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2021&wpas=1",
|
||||
),
|
||||
]),
|
||||
SelectFilter("EnglishSeriesFilter", "Hindi Series", 0, [
|
||||
SelectFilterOption("<select>", ""),
|
||||
@@ -319,13 +346,17 @@ class YoMovies extends MProvider {
|
||||
SelectFilterOption("Hootzy", "/director/hootzy-channel"),
|
||||
SelectFilterOption("Balloons", "/director/balloons-originals"),
|
||||
SelectFilterOption(
|
||||
"Big Movie Zoo", "/director/big-movie-zoo-originals"),
|
||||
"Big Movie Zoo",
|
||||
"/director/big-movie-zoo-originals",
|
||||
),
|
||||
SelectFilterOption("Bambooflix", "/director/bambooflix"),
|
||||
SelectFilterOption("Piliflix", "/director/piliflix-originals"),
|
||||
SelectFilterOption("11upmovies", "/director/11upmovies-originals"),
|
||||
SelectFilterOption("Eightshots", "/director/eightshots-originals"),
|
||||
SelectFilterOption(
|
||||
"I-Entertainment", "/director/i-entertainment-exclusive"),
|
||||
"I-Entertainment",
|
||||
"/director/i-entertainment-exclusive",
|
||||
),
|
||||
SelectFilterOption("Hotprime", "/director/hotprime-originals"),
|
||||
SelectFilterOption("BananaPrime", "/director/banana-prime"),
|
||||
SelectFilterOption("HotHitFilms", "/director/hothitfilms"),
|
||||
|
||||
@@ -15,8 +15,10 @@ class NimeGami extends MProvider {
|
||||
List<MManga> animeList = [];
|
||||
final urls = xpath(res, '//div[@class="wrapper-2-a"]/article/a/@href');
|
||||
final names = xpath(res, '//div[@class="wrapper-2-a"]/article/a/@title');
|
||||
final images =
|
||||
xpath(res, '//div[@class="wrapper-2-a"]/article/a/div/img/@src');
|
||||
final images = xpath(
|
||||
res,
|
||||
'//div[@class="wrapper-2-a"]/article/a/div/img/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -34,10 +36,14 @@ class NimeGami extends MProvider {
|
||||
(await client.get(Uri.parse("${source.baseUrl}/page/$page"))).body;
|
||||
List<MManga> animeList = [];
|
||||
final urls = xpath(res, '//div[@class="post-article"]/article/div/a/@href');
|
||||
final names =
|
||||
xpath(res, '//div[@class="post-article"]/article/div/a/@title');
|
||||
final images =
|
||||
xpath(res, '//div[@class="post-article"]/article/div/a/img/@src');
|
||||
final names = xpath(
|
||||
res,
|
||||
'//div[@class="post-article"]/article/div/a/@title',
|
||||
);
|
||||
final images = xpath(
|
||||
res,
|
||||
'//div[@class="post-article"]/article/div/a/img/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -51,14 +57,17 @@ class NimeGami extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
final res = (await client.get(
|
||||
Uri.parse("${source.baseUrl}/page/$page/?s=$query&post_type=post")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/page/$page/?s=$query&post_type=post"),
|
||||
)).body;
|
||||
List<MManga> animeList = [];
|
||||
final urls = xpath(res, '//div[@class="archive-a"]/article/div/a/@href');
|
||||
final names = xpath(res, '//div[@class="archive-a"]/article/h2/a/@title');
|
||||
final images =
|
||||
xpath(res, '//div[@class="archive-a"]/article/div/a/img/@src');
|
||||
final images = xpath(
|
||||
res,
|
||||
'//div[@class="archive-a"]/article/div/a/img/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -84,21 +93,25 @@ class NimeGami extends MProvider {
|
||||
anime.author = author.first;
|
||||
}
|
||||
anime.genre = xpath(res, '//tr/td[@class="info_a"]/a/text()');
|
||||
final epUrls = xpath(res, '//div[@class="list_eps_stream"]/li/@data')
|
||||
.reversed
|
||||
.toList();
|
||||
final epUrls =
|
||||
xpath(
|
||||
res,
|
||||
'//div[@class="list_eps_stream"]/li/@data',
|
||||
).reversed.toList();
|
||||
final epNums =
|
||||
xpath(res, '//div[@class="list_eps_stream"]/li/@id').reversed.toList();
|
||||
final names = xpath(res, '//div[@class="list_eps_stream"]/li/text()')
|
||||
.reversed
|
||||
.toList();
|
||||
final names =
|
||||
xpath(
|
||||
res,
|
||||
'//div[@class="list_eps_stream"]/li/text()',
|
||||
).reversed.toList();
|
||||
List<MChapter>? episodesList = [];
|
||||
for (var i = 0; i < epUrls.length; i++) {
|
||||
MChapter episode = MChapter();
|
||||
episode.name = names[i];
|
||||
episode.url = json.encode({
|
||||
"episodeIndex": int.parse(substringAfterLast(epNums[i], '_')),
|
||||
'urls': json.decode(utf8.decode(base64Url.decode(epUrls[i])))
|
||||
'urls': json.decode(utf8.decode(base64Url.decode(epUrls[i]))),
|
||||
});
|
||||
episodesList.add(episode);
|
||||
}
|
||||
@@ -126,7 +139,8 @@ class NimeGami extends MProvider {
|
||||
List<MVideo> videos = [];
|
||||
if (url.contains("video.nimegami.id")) {
|
||||
final realUrl = utf8.decode(
|
||||
base64Url.decode(substringBefore(substringAfter(url, "url="), "&")));
|
||||
base64Url.decode(substringBefore(substringAfter(url, "url="), "&")),
|
||||
);
|
||||
final a = await extractHXFileVideos(realUrl, quality);
|
||||
videos.addAll(a);
|
||||
} else if (url.contains("berkasdrive") || url.contains("drive.nimegami")) {
|
||||
@@ -148,15 +162,19 @@ class NimeGami extends MProvider {
|
||||
url = url.replaceAll(".co/", ".co/embed-") + ".html";
|
||||
}
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final script = xpath(res,
|
||||
'//script[contains(text(), "eval") and contains(text(), "p,a,c,k,e,d")]/text()');
|
||||
final script = xpath(
|
||||
res,
|
||||
'//script[contains(text(), "eval") and contains(text(), "p,a,c,k,e,d")]/text()',
|
||||
);
|
||||
if (script.isNotEmpty) {
|
||||
final videoUrl = substringBefore(
|
||||
substringAfter(
|
||||
substringAfter(unpackJs(script.first), "sources:[", ""),
|
||||
"file\":\"",
|
||||
""),
|
||||
'"');
|
||||
"",
|
||||
),
|
||||
'"',
|
||||
);
|
||||
if (videoUrl.isNotEmpty) {
|
||||
return [toVideo(videoUrl, "HXFile - $quality")];
|
||||
}
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _nimegami = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/nimegami/icon.png",
|
||||
sourceCodeUrl: _nimegamiCodeUrl,
|
||||
version: _nimegamiVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -10,32 +10,35 @@ class OploVerz extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client.get(Uri.parse(
|
||||
"${source.baseUrl}/anime-list/page/$page/?order=popular")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/anime-list/page/$page/?order=popular"),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client.get(
|
||||
Uri.parse("${source.baseUrl}/anime-list/page/$page/?order=latest")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/anime-list/page/$page/?order=latest"),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
final res = (await client.get(
|
||||
Uri.parse("${source.baseUrl}/anime-list/page/$page/?title=$query")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/anime-list/page/$page/?title=$query"),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"ongoing": 0, "completed": 1}
|
||||
{"ongoing": 0, "completed": 1},
|
||||
];
|
||||
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
@@ -47,12 +50,18 @@ class OploVerz extends MProvider {
|
||||
anime.description = xpath(res, '//*[@class="desc"]/div/text()').first;
|
||||
|
||||
anime.genre = xpath(res, '//*[@class="genre-info"]/a/text()');
|
||||
final epUrls =
|
||||
xpath(res, '//div[@class="epsleft")]/span[@class="lchx"]/a/@href');
|
||||
final names =
|
||||
xpath(res, '//div[@class="epsleft")]/span[@class="lchx"]/a/text()');
|
||||
final dates =
|
||||
xpath(res, '//div[@class="epsleft")]/span[@class="date"]/text()');
|
||||
final epUrls = xpath(
|
||||
res,
|
||||
'//div[@class="epsleft")]/span[@class="lchx"]/a/@href',
|
||||
);
|
||||
final names = xpath(
|
||||
res,
|
||||
'//div[@class="epsleft")]/span[@class="lchx"]/a/text()',
|
||||
);
|
||||
final dates = xpath(
|
||||
res,
|
||||
'//div[@class="epsleft")]/span[@class="date"]/text()',
|
||||
);
|
||||
final dateUploads = parseDates(dates, "dd/MM/yyyy", "id");
|
||||
List<MChapter>? episodesList = [];
|
||||
for (var i = 0; i < epUrls.length; i++) {
|
||||
@@ -70,28 +79,33 @@ class OploVerz extends MProvider {
|
||||
@override
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final dataPost = xpath(res,
|
||||
'//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-post')
|
||||
.first;
|
||||
final dataNume = xpath(res,
|
||||
'//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-nume')
|
||||
.first;
|
||||
final dataType = xpath(res,
|
||||
'//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-type')
|
||||
.first;
|
||||
final dataPost =
|
||||
xpath(
|
||||
res,
|
||||
'//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-post',
|
||||
).first;
|
||||
final dataNume =
|
||||
xpath(
|
||||
res,
|
||||
'//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-nume',
|
||||
).first;
|
||||
final dataType =
|
||||
xpath(
|
||||
res,
|
||||
'//*[@id="server"]/ul/li/div[contains(@id,"player-option")]/@data-type',
|
||||
).first;
|
||||
|
||||
final ress = (await client.post(
|
||||
final ress =
|
||||
(await client.post(
|
||||
Uri.parse("${source.baseUrl}/wp-admin/admin-ajax.php"),
|
||||
headers: {
|
||||
"_": "_"
|
||||
},
|
||||
headers: {"_": "_"},
|
||||
body: {
|
||||
"action": "player_ajax",
|
||||
"post": dataPost,
|
||||
"nume": dataNume,
|
||||
"type": dataType
|
||||
}))
|
||||
.body;
|
||||
"type": dataType,
|
||||
},
|
||||
)).body;
|
||||
|
||||
final playerLink =
|
||||
xpath(ress, '//iframe[@class="playeriframe"]/@src').first;
|
||||
@@ -127,8 +141,10 @@ class OploVerz extends MProvider {
|
||||
List<MManga> animeList = [];
|
||||
final urls = xpath(res, '//div[@class="relat"]/article/div/div/a/@href');
|
||||
final names = xpath(res, '//div[@class="relat"]/article/div/div/a/@title');
|
||||
final images =
|
||||
xpath(res, '//div[@class="relat"]/article/div/div/a/div/img/@src');
|
||||
final images = xpath(
|
||||
res,
|
||||
'//div[@class="relat"]/article/div/div/a/div/img/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -138,8 +154,10 @@ class OploVerz extends MProvider {
|
||||
animeList.add(anime);
|
||||
}
|
||||
final pages = xpath(res, '//div[@class="pagination"]/a/@href');
|
||||
final pageNumberCurrent = xpath(res,
|
||||
'//div[@class="pagination"]/span[@class="page-numbers current"]/text()');
|
||||
final pageNumberCurrent = xpath(
|
||||
res,
|
||||
'//div[@class="pagination"]/span[@class="page-numbers current"]/text()',
|
||||
);
|
||||
|
||||
bool hasNextPage = true;
|
||||
if (pageNumberCurrent.isNotEmpty && pages.isNotEmpty) {
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _oploverz = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/oploverz/icon.png",
|
||||
sourceCodeUrl: _oploverzCodeUrl,
|
||||
version: _oploverzVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -14,8 +14,9 @@ class OtakuDesu extends MProvider {
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res =
|
||||
(await client.get(Uri.parse("$baseUrl/complete-anime/page/$page")))
|
||||
.body;
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/complete-anime/page/$page"),
|
||||
)).body;
|
||||
return parseAnimeList(res);
|
||||
}
|
||||
|
||||
@@ -29,8 +30,9 @@ class OtakuDesu extends MProvider {
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
final res =
|
||||
(await client.get(Uri.parse("$baseUrl/?s=$query&post_type=anime")))
|
||||
.body;
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/?s=$query&post_type=anime"),
|
||||
)).body;
|
||||
List<MManga> animeList = [];
|
||||
final images = xpath(res, '//ul[@class="chivsrc"]/li/img/@src');
|
||||
final names = xpath(res, '//ul[@class="chivsrc"]/li/h2/a/text()');
|
||||
@@ -49,12 +51,14 @@ class OtakuDesu extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"Ongoing": 0, "Completed": 1}
|
||||
{"Ongoing": 0, "Completed": 1},
|
||||
];
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
MManga anime = MManga();
|
||||
final status = xpath(
|
||||
res, '//*[@class="infozingle"]/p[contains(text(), "Status")]/text()');
|
||||
res,
|
||||
'//*[@class="infozingle"]/p[contains(text(), "Status")]/text()',
|
||||
);
|
||||
if (status.isNotEmpty) {
|
||||
anime.status = parseStatus(status.first.split(':').last, statusList);
|
||||
}
|
||||
@@ -64,7 +68,9 @@ class OtakuDesu extends MProvider {
|
||||
}
|
||||
|
||||
final genre = xpath(
|
||||
res, '//*[@class="infozingle"]/p[contains(text(), "Genre")]/text()');
|
||||
res,
|
||||
'//*[@class="infozingle"]/p[contains(text(), "Genre")]/text()',
|
||||
);
|
||||
if (genre.isNotEmpty) {
|
||||
anime.genre = genre.first.split(':').last.split(',');
|
||||
}
|
||||
@@ -73,7 +79,9 @@ class OtakuDesu extends MProvider {
|
||||
final names = xpath(res, '//div[@class="episodelist"]/ul/li/span/a/text()');
|
||||
|
||||
final dates = xpath(
|
||||
res, '//div[@class="episodelist"]/ul/li/span[@class="zeebr"]/text()');
|
||||
res,
|
||||
'//div[@class="episodelist"]/ul/li/span[@class="zeebr"]/text()',
|
||||
);
|
||||
final dateUploads = parseDates(dates, "d MMMM,yyyy", "id");
|
||||
List<MChapter>? episodesList = [];
|
||||
for (var i = 1; i < epUrls.length; i++) {
|
||||
@@ -93,18 +101,23 @@ class OtakuDesu extends MProvider {
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final script =
|
||||
xpath(res, '//script[contains(text(), "{action:")]/text()').first;
|
||||
final nonceAction =
|
||||
substringBefore(substringAfter(script, "{action:\""), '"');
|
||||
final nonceAction = substringBefore(
|
||||
substringAfter(script, "{action:\""),
|
||||
'"',
|
||||
);
|
||||
final action = substringBefore(substringAfter(script, "action:\""), '"');
|
||||
|
||||
final resNonceAction = (await client.post(
|
||||
final resNonceAction =
|
||||
(await client.post(
|
||||
Uri.parse("$baseUrl/wp-admin/admin-ajax.php"),
|
||||
headers: {"_": "_"},
|
||||
body: {"action": nonceAction}))
|
||||
.body;
|
||||
body: {"action": nonceAction},
|
||||
)).body;
|
||||
final nonce = substringBefore(substringAfter(resNonceAction, ":\""), '"');
|
||||
final mirrorstream =
|
||||
xpath(res, '//*[@class="mirrorstream"]/ul/li/a/@data-content');
|
||||
final mirrorstream = xpath(
|
||||
res,
|
||||
'//*[@class="mirrorstream"]/ul/li/a/@data-content',
|
||||
);
|
||||
for (var stream in mirrorstream) {
|
||||
List<MVideo> a = [];
|
||||
final decodedData = json.decode(utf8.decode(base64Url.decode(stream)));
|
||||
@@ -112,17 +125,12 @@ class OtakuDesu extends MProvider {
|
||||
final id = decodedData["id"];
|
||||
final i = decodedData["i"];
|
||||
|
||||
final res = (await client
|
||||
.post(Uri.parse("$baseUrl/wp-admin/admin-ajax.php"), headers: {
|
||||
"_": "_"
|
||||
}, body: {
|
||||
"i": i,
|
||||
"id": id,
|
||||
"q": q,
|
||||
"nonce": nonce,
|
||||
"action": action
|
||||
}))
|
||||
.body;
|
||||
final res =
|
||||
(await client.post(
|
||||
Uri.parse("$baseUrl/wp-admin/admin-ajax.php"),
|
||||
headers: {"_": "_"},
|
||||
body: {"i": i, "id": id, "q": q, "nonce": nonce, "action": action},
|
||||
)).body;
|
||||
final resJson = json.decode(res);
|
||||
final html = utf8.decode(base64Url.decode(resJson["data"]));
|
||||
String url = xpath(html, '//iframe/@src').first;
|
||||
@@ -152,8 +160,10 @@ class OtakuDesu extends MProvider {
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
final script =
|
||||
xpath(res, '//script[contains(text(), "player.src")]/text()').first;
|
||||
final videoUrl =
|
||||
substringBefore(substringAfter(script, "src: \""), '"');
|
||||
final videoUrl = substringBefore(
|
||||
substringAfter(script, "src: \""),
|
||||
'"',
|
||||
);
|
||||
MVideo video = MVideo();
|
||||
video
|
||||
..url = videoUrl
|
||||
@@ -196,12 +206,18 @@ class OtakuDesu extends MProvider {
|
||||
|
||||
MPages parseAnimeList(String res) {
|
||||
List<MManga> animeList = [];
|
||||
final urls =
|
||||
xpath(res, '//div[@class="detpost"]/div[@class="thumb"]/a/@href');
|
||||
final names = xpath(res,
|
||||
'//div[@class="detpost"]/div[@class="thumb"]/a/div[@class="thumbz"]/h2/text()');
|
||||
final images = xpath(res,
|
||||
'//div[@class="detpost"]/div[@class="thumb"]/a/div[@class="thumbz"]/img/@src');
|
||||
final urls = xpath(
|
||||
res,
|
||||
'//div[@class="detpost"]/div[@class="thumb"]/a/@href',
|
||||
);
|
||||
final names = xpath(
|
||||
res,
|
||||
'//div[@class="detpost"]/div[@class="thumb"]/a/div[@class="thumbz"]/h2/text()',
|
||||
);
|
||||
final images = xpath(
|
||||
res,
|
||||
'//div[@class="detpost"]/div[@class="thumb"]/a/div[@class="thumbz"]/img/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -211,7 +227,9 @@ class OtakuDesu extends MProvider {
|
||||
animeList.add(anime);
|
||||
}
|
||||
final pages = xpath(
|
||||
res, '//div[@class="pagenavix"]/a[@class="next page-numbers"]/@href');
|
||||
res,
|
||||
'//div[@class="pagenavix"]/a[@class="next page-numbers"]/@href',
|
||||
);
|
||||
return MPages(animeList, pages.isNotEmpty);
|
||||
}
|
||||
|
||||
@@ -224,14 +242,16 @@ class OtakuDesu extends MProvider {
|
||||
value: "https://otakudesu.cloud",
|
||||
dialogTitle: "Override BaseUrl",
|
||||
dialogMessage: "",
|
||||
text: "https://otakudesu.cloud"),
|
||||
text: "https://otakudesu.cloud",
|
||||
),
|
||||
ListPreference(
|
||||
key: "preferred_quality",
|
||||
title: "Preferred quality",
|
||||
summary: "",
|
||||
valueIndex: 1,
|
||||
entries: ["1080p", "720p", "480p", "360p"],
|
||||
entryValues: ["1080", "720", "480", "360"])
|
||||
entryValues: ["1080", "720", "480", "360"],
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _otakudesu = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/otakudesu/icon.png",
|
||||
sourceCodeUrl: _otakudesuCodeUrl,
|
||||
version: _otakudesuVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -10,20 +10,27 @@ class AnimeSaturn extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client
|
||||
.get(Uri.parse("${source.baseUrl}/animeincorso?page=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/animeincorso?page=$page"),
|
||||
)).body;
|
||||
|
||||
List<MManga> animeList = [];
|
||||
|
||||
final urls = xpath(res,
|
||||
'//*[@class="sebox"]/div[@class="msebox"]/div[@class="headsebox"]/div[@class="tisebox"]/h2/a/@href');
|
||||
final urls = xpath(
|
||||
res,
|
||||
'//*[@class="sebox"]/div[@class="msebox"]/div[@class="headsebox"]/div[@class="tisebox"]/h2/a/@href',
|
||||
);
|
||||
|
||||
final names = xpath(res,
|
||||
'//*[@class="sebox"]/div[@class="msebox"]/div[@class="headsebox"]/div[@class="tisebox"]/h2/a/text()');
|
||||
final names = xpath(
|
||||
res,
|
||||
'//*[@class="sebox"]/div[@class="msebox"]/div[@class="headsebox"]/div[@class="tisebox"]/h2/a/text()',
|
||||
);
|
||||
|
||||
final images = xpath(res,
|
||||
'//*[@class="sebox"]/div[@class="msebox"]/div[@class="bigsebox"]/div/img[@class="attachment-post-thumbnail size-post-thumbnail wp-post-image"]/@src');
|
||||
final images = xpath(
|
||||
res,
|
||||
'//*[@class="sebox"]/div[@class="msebox"]/div[@class="bigsebox"]/div/img[@class="attachment-post-thumbnail size-post-thumbnail wp-post-image"]/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -38,8 +45,9 @@ class AnimeSaturn extends MProvider {
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res =
|
||||
(await client.get(Uri.parse("${source.baseUrl}/newest?page=$page")))
|
||||
.body;
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/newest?page=$page"),
|
||||
)).body;
|
||||
|
||||
List<MManga> animeList = [];
|
||||
|
||||
@@ -47,8 +55,10 @@ class AnimeSaturn extends MProvider {
|
||||
|
||||
final names = xpath(res, '//*[@class="card mb-4 shadow-sm"]/a/@title');
|
||||
|
||||
final images = xpath(res,
|
||||
'//*[@class="card mb-4 shadow-sm"]/a/img[@class="new-anime"]/@src');
|
||||
final images = xpath(
|
||||
res,
|
||||
'//*[@class="card mb-4 shadow-sm"]/a/img[@class="new-anime"]/@src',
|
||||
);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
MManga anime = MManga();
|
||||
@@ -114,21 +124,29 @@ class AnimeSaturn extends MProvider {
|
||||
List<String> names = [];
|
||||
List<String> images = [];
|
||||
if (query.isNotEmpty) {
|
||||
urls = xpath(res,
|
||||
'//*[@class="list-group"]/li[@class="list-group-item bg-dark-as-box-shadow"]/div[@class="item-archivio"]/div[@class="info-archivio"]/h3/a[@class="badge badge-archivio badge-light"]/@href');
|
||||
urls = xpath(
|
||||
res,
|
||||
'//*[@class="list-group"]/li[@class="list-group-item bg-dark-as-box-shadow"]/div[@class="item-archivio"]/div[@class="info-archivio"]/h3/a[@class="badge badge-archivio badge-light"]/@href',
|
||||
);
|
||||
|
||||
names = xpath(res,
|
||||
'//*[@class="list-group"]/li[@class="list-group-item bg-dark-as-box-shadow"]/div[@class="item-archivio"]/div[@class="info-archivio"]/h3/a[@class="badge badge-archivio badge-light"]/text()');
|
||||
names = xpath(
|
||||
res,
|
||||
'//*[@class="list-group"]/li[@class="list-group-item bg-dark-as-box-shadow"]/div[@class="item-archivio"]/div[@class="info-archivio"]/h3/a[@class="badge badge-archivio badge-light"]/text()',
|
||||
);
|
||||
|
||||
images = xpath(res,
|
||||
'//*[@class="list-group"]/li[@class="list-group-item bg-dark-as-box-shadow"]/div[@class="item-archivio"]/a/img/@src');
|
||||
images = xpath(
|
||||
res,
|
||||
'//*[@class="list-group"]/li[@class="list-group-item bg-dark-as-box-shadow"]/div[@class="item-archivio"]/a/img/@src',
|
||||
);
|
||||
} else {
|
||||
urls = xpath(res, '//*[@class="card mb-4 shadow-sm"]/a/@href');
|
||||
|
||||
names = xpath(res, '//*[@class="card mb-4 shadow-sm"]/a/text()');
|
||||
|
||||
images = xpath(res,
|
||||
'//*[@class="card mb-4 shadow-sm"]/a/img[@class="new-anime"]/@src');
|
||||
images = xpath(
|
||||
res,
|
||||
'//*[@class="card mb-4 shadow-sm"]/a/img[@class="new-anime"]/@src',
|
||||
);
|
||||
}
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
@@ -144,20 +162,25 @@ class AnimeSaturn extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"In corso": 0, "Finito": 1}
|
||||
{"In corso": 0, "Finito": 1},
|
||||
];
|
||||
|
||||
final res = (await client.get(Uri.parse(url))).body;
|
||||
MManga anime = MManga();
|
||||
final detailsList = xpath(res,
|
||||
'//div[@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100 text-white"]/text()');
|
||||
final detailsList = xpath(
|
||||
res,
|
||||
'//div[@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100 text-white"]/text()',
|
||||
);
|
||||
if (detailsList.isNotEmpty) {
|
||||
final details = detailsList.first;
|
||||
|
||||
anime.status = parseStatus(
|
||||
details.substring(
|
||||
details.indexOf("Stato:") + 6, details.indexOf("Data di uscita:")),
|
||||
statusList);
|
||||
details.indexOf("Stato:") + 6,
|
||||
details.indexOf("Data di uscita:"),
|
||||
),
|
||||
statusList,
|
||||
);
|
||||
anime.author = details.substring(7, details.indexOf("Stato:"));
|
||||
}
|
||||
|
||||
@@ -174,14 +197,20 @@ class AnimeSaturn extends MProvider {
|
||||
}
|
||||
}
|
||||
|
||||
anime.genre = xpath(res,
|
||||
'//*[@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100"]/a/text()');
|
||||
anime.genre = xpath(
|
||||
res,
|
||||
'//*[@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100"]/a/text()',
|
||||
);
|
||||
|
||||
final epUrls = xpath(res,
|
||||
'//*[@class="btn-group episodes-button episodi-link-button"]/a/@href');
|
||||
final epUrls = xpath(
|
||||
res,
|
||||
'//*[@class="btn-group episodes-button episodi-link-button"]/a/@href',
|
||||
);
|
||||
|
||||
final titles = xpath(res,
|
||||
'//*[@class="btn-group episodes-button episodi-link-button"]/a/text()');
|
||||
final titles = xpath(
|
||||
res,
|
||||
'//*[@class="btn-group episodes-button episodi-link-button"]/a/text()',
|
||||
);
|
||||
|
||||
List<MChapter>? episodesList = [];
|
||||
for (var i = 0; i < epUrls.length; i++) {
|
||||
@@ -211,8 +240,10 @@ class AnimeSaturn extends MProvider {
|
||||
List<MVideo> videos = [];
|
||||
if (masterUrl.endsWith("playlist.m3u8")) {
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -325,7 +356,8 @@ class AnimeSaturn extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["1080p", "720p", "480p", "360p", "240p", "144p"],
|
||||
entryValues: ["1080", "720", "480", "360", "240", "144"]),
|
||||
entryValues: ["1080", "720", "480", "360", "240", "144"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _animesaturn = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/it/animesaturn/icon.png",
|
||||
sourceCodeUrl: _animesaturnCodeUrl,
|
||||
version: _animesaturnVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -14,15 +14,16 @@ class AnimesVision extends MProvider {
|
||||
@override
|
||||
Map<String, String> get headers => {
|
||||
"Referer": baseUrl,
|
||||
"Accept-Language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7"
|
||||
"Accept-Language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||
};
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client.get(Uri.parse(baseUrl), headers: headers)).body;
|
||||
final document = parseHtml(res);
|
||||
final elements =
|
||||
document.select("div#anime-trending div.item > a.film-poster");
|
||||
final elements = document.select(
|
||||
"div#anime-trending div.item > a.film-poster",
|
||||
);
|
||||
List<MManga> animeList = [];
|
||||
for (var element in elements) {
|
||||
var anime = MManga();
|
||||
@@ -37,12 +38,15 @@ class AnimesVision extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client.get(Uri.parse("$baseUrl/lancamentos?page=$page"),
|
||||
headers: headers))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/lancamentos?page=$page"),
|
||||
headers: headers,
|
||||
)).body;
|
||||
final document = parseHtml(res);
|
||||
final elements =
|
||||
document.select("div.container div.screen-items > div.item");
|
||||
final elements = document.select(
|
||||
"div.container div.screen-items > div.item",
|
||||
);
|
||||
List<MManga> animeList = [];
|
||||
for (var element in elements) {
|
||||
var anime = MManga();
|
||||
@@ -56,9 +60,10 @@ class AnimesVision extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> search(String query, int page, FilterList filterList) async {
|
||||
final res = (await client
|
||||
.get(Uri.parse("$baseUrl/search-anime?nome=$query&page=$page")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("$baseUrl/search-anime?nome=$query&page=$page"),
|
||||
)).body;
|
||||
final document = parseHtml(res);
|
||||
final elements = document.select("div.film_list-wrap div.film-poster");
|
||||
List<MManga> animeList = [];
|
||||
@@ -76,7 +81,7 @@ class AnimesVision extends MProvider {
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final statusList = [
|
||||
{"Atualmente sendo exibido": 0, "Fim da exibição": 1}
|
||||
{"Atualmente sendo exibido": 0, "Fim da exibição": 1},
|
||||
];
|
||||
MManga anime = MManga();
|
||||
final res = (await client.get(Uri.parse("$baseUrl$url"))).body;
|
||||
@@ -113,8 +118,9 @@ class AnimesVision extends MProvider {
|
||||
|
||||
while (hasNextPage(document)) {
|
||||
if (episodeList.isNotEmpty) {
|
||||
final nextUrl =
|
||||
nextPageElements(document)[0].selectFirst("a").attr("href");
|
||||
final nextUrl = nextPageElements(
|
||||
document,
|
||||
)[0].selectFirst("a").attr("href");
|
||||
document = parseHtml((await client.get(Uri.parse(nextUrl))).body);
|
||||
}
|
||||
for (var element
|
||||
@@ -131,13 +137,15 @@ class AnimesVision extends MProvider {
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
final res = (await client.get(Uri.parse("$baseUrl$url"))).body;
|
||||
final document = parseHtml(res);
|
||||
final encodedScript = document
|
||||
final encodedScript =
|
||||
document
|
||||
.selectFirst("div.player-frame div#playerglobalapi ~ script")
|
||||
.text;
|
||||
final decodedScript = decodeScriptFromString(encodedScript);
|
||||
List<MVideo> videos = [];
|
||||
for (RegExpMatch match in RegExp(r'"file":"(\S+?)",.*?"label":"(.*?)"')
|
||||
.allMatches(decodedScript)) {
|
||||
for (RegExpMatch match in RegExp(
|
||||
r'"file":"(\S+?)",.*?"label":"(.*?)"',
|
||||
).allMatches(decodedScript)) {
|
||||
final videoUrl = match.group(1)!.replaceAll('\\', '');
|
||||
final qualityName = match.group(2);
|
||||
var video = MVideo();
|
||||
@@ -155,10 +163,14 @@ class AnimesVision extends MProvider {
|
||||
}
|
||||
|
||||
List<MElement> nextPageElements(MDocument document) {
|
||||
final elements = document
|
||||
final elements =
|
||||
document
|
||||
.select("ul.pagination li.page-item")
|
||||
.where((MElement e) =>
|
||||
e.outerHtml.contains("›") && !e.outerHtml.contains("disabled"))
|
||||
.where(
|
||||
(MElement e) =>
|
||||
e.outerHtml.contains("›") &&
|
||||
!e.outerHtml.contains("disabled"),
|
||||
)
|
||||
.toList();
|
||||
return elements;
|
||||
}
|
||||
@@ -173,7 +185,8 @@ class AnimesVision extends MProvider {
|
||||
}
|
||||
|
||||
String getInfo(MElement element, String key) {
|
||||
final divs = element
|
||||
final divs =
|
||||
element
|
||||
.select("div.item")
|
||||
.where((MElement e) => e.outerHtml.contains(key))
|
||||
.toList();
|
||||
@@ -235,7 +248,8 @@ class AnimesVision extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 1,
|
||||
entries: ["480p", "720p", "1080p", "4K"],
|
||||
entryValues: ["1080", "720", "480", "4K"]),
|
||||
entryValues: ["1080", "720", "480", "4K"],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -251,7 +265,11 @@ class AnimesVision extends MProvider {
|
||||
}
|
||||
|
||||
String decodeScript(
|
||||
String encodedString, String magicStr, int offset, int limit) {
|
||||
String encodedString,
|
||||
String magicStr,
|
||||
int offset,
|
||||
int limit,
|
||||
) {
|
||||
RegExp regex = RegExp('\\w');
|
||||
List<String> parts = encodedString.split(magicStr[limit]);
|
||||
List<String> decodedParts = [];
|
||||
@@ -259,7 +277,9 @@ class AnimesVision extends MProvider {
|
||||
String replaced = part;
|
||||
for (Match match in regex.allMatches(part)) {
|
||||
replaced = replaced.replaceFirst(
|
||||
match.group(0)!, magicStr.indexOf(match.group(0)!).toString());
|
||||
match.group(0)!,
|
||||
magicStr.indexOf(match.group(0)!).toString(),
|
||||
);
|
||||
}
|
||||
int charInt = convertToNum(replaced, limit) - offset;
|
||||
decodedParts.add(String.fromCharCode(charInt));
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _animesvision = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/pt/animesvision/icon.png",
|
||||
sourceCodeUrl: _animesvisionCodeUrl,
|
||||
version: _animesvisionVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -6,8 +6,10 @@ class Filma24 extends MProvider {
|
||||
|
||||
MSource source;
|
||||
|
||||
final Client client =
|
||||
Client(source, json.encode({"useDartHttpClient": true}));
|
||||
final Client client = Client(
|
||||
source,
|
||||
json.encode({"useDartHttpClient": true}),
|
||||
);
|
||||
|
||||
@override
|
||||
String get baseUrl => getPreferenceValue(source.id, "pref_domain_new");
|
||||
@@ -128,7 +130,8 @@ class Filma24 extends MProvider {
|
||||
value: "https://www.filma24.band",
|
||||
dialogTitle: "Domeni i përdorur aktualisht",
|
||||
dialogMessage: "",
|
||||
text: "https://www.filma24.band"),
|
||||
text: "https://www.filma24.band",
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -192,22 +195,23 @@ class Filma24 extends MProvider {
|
||||
}
|
||||
|
||||
Future<List<MVideo>> vidmolyExtractor(String url) async {
|
||||
final headers = {
|
||||
'Referer': 'https://vidmoly.to',
|
||||
};
|
||||
final headers = {'Referer': 'https://vidmoly.to'};
|
||||
List<MVideo> videos = [];
|
||||
final playListUrlResponse = (await client.get(Uri.parse(url))).body;
|
||||
final playlistUrl =
|
||||
RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ??
|
||||
"";
|
||||
if (playlistUrl.isEmpty) return [];
|
||||
final masterPlaylistRes =
|
||||
await client.get(Uri.parse(playlistUrl), headers: headers);
|
||||
final masterPlaylistRes = await client.get(
|
||||
Uri.parse(playlistUrl),
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (masterPlaylistRes.statusCode == 200) {
|
||||
for (var it
|
||||
in substringAfter(masterPlaylistRes.body, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes.body,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -234,8 +238,10 @@ class Filma24 extends MProvider {
|
||||
"";
|
||||
if (playlistUrl.isEmpty) return [];
|
||||
final masterPlaylistRes = (await client.get(Uri.parse(playlistUrl))).body;
|
||||
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
|
||||
.split("#EXT-X-STREAM-INF:")) {
|
||||
for (var it in substringAfter(
|
||||
masterPlaylistRes,
|
||||
"#EXT-X-STREAM-INF:",
|
||||
).split("#EXT-X-STREAM-INF:")) {
|
||||
final quality =
|
||||
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
|
||||
|
||||
@@ -258,8 +264,10 @@ class Filma24 extends MProvider {
|
||||
return [];
|
||||
}
|
||||
|
||||
final videoUrl =
|
||||
substringBefore(substringAfter(js.first, "sources: [\""), '"');
|
||||
final videoUrl = substringBefore(
|
||||
substringAfter(js.first, "sources: [\""),
|
||||
'"',
|
||||
);
|
||||
MVideo video = MVideo();
|
||||
video
|
||||
..url = videoUrl
|
||||
@@ -283,8 +291,10 @@ class Filma24 extends MProvider {
|
||||
mangaList.add(manga);
|
||||
}
|
||||
|
||||
return MPages(mangaList,
|
||||
document.selectFirst("div > a.nextpostslink")?.attr("href") != null);
|
||||
return MPages(
|
||||
mangaList,
|
||||
document.selectFirst("div > a.nextpostslink")?.attr("href") != null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _filma24 = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/sq/filma24/icon.png",
|
||||
sourceCodeUrl: _filma24CodeUrl,
|
||||
version: _filma24Version,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -15,7 +15,9 @@ class DiziWatch extends MProvider {
|
||||
Map<String, String> get headers => {};
|
||||
|
||||
Future<MPages> parseMainList(int index) async {
|
||||
MDocument dom = parseHtml((await client.get(Uri.parse(source.baseUrl))) .body);
|
||||
MDocument dom = parseHtml(
|
||||
(await client.get(Uri.parse(source.baseUrl))).body,
|
||||
);
|
||||
List<MManga> list = [];
|
||||
MElement containingElement = dom.select("#list-series-hizala2")[index];
|
||||
List<MElement> results = containingElement.select("#list-series-main");
|
||||
@@ -59,7 +61,13 @@ class DiziWatch extends MProvider {
|
||||
genre = filter.values[filter.state].value;
|
||||
}
|
||||
}
|
||||
MDocument dom = parseHtml((await client.get(Uri.parse("${source.baseUrl}/anime-arsivi/page/${page}/?orderby=${orderby}&yil=${year}&imdb=${imdb}&isim=${query}&tur=${genre}"))) .body);
|
||||
MDocument dom = parseHtml(
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/anime-arsivi/page/${page}/?orderby=${orderby}&yil=${year}&imdb=${imdb}&isim=${query}&tur=${genre}",
|
||||
),
|
||||
)).body,
|
||||
);
|
||||
List<MElement> results = dom.select("#list-series");
|
||||
List<MManga> list = [];
|
||||
for (MElement result in results) {
|
||||
@@ -73,7 +81,9 @@ class DiziWatch extends MProvider {
|
||||
}
|
||||
|
||||
MElement paginateLinksDiv = dom.selectFirst("div.paginate-links");
|
||||
int lastPage = int.parse(paginateLinksDiv.selectFirst("a.next").previousElementSibling.text ?? "1");
|
||||
int lastPage = int.parse(
|
||||
paginateLinksDiv.selectFirst("a.next").previousElementSibling.text ?? "1",
|
||||
);
|
||||
|
||||
return MPages(list, lastPage > page);
|
||||
}
|
||||
@@ -98,7 +108,10 @@ class DiziWatch extends MProvider {
|
||||
for (MElement result in results) {
|
||||
MElement a = result.select("a")[1];
|
||||
MChapter chapter = new MChapter();
|
||||
chapter.name = result.selectFirst(".baslik").text + " | " + result.selectFirst("#bolum-ismi").text;
|
||||
chapter.name =
|
||||
result.selectFirst(".baslik").text +
|
||||
" | " +
|
||||
result.selectFirst("#bolum-ismi").text;
|
||||
chapter.url = a.getHref;
|
||||
chapters.add(chapter);
|
||||
}
|
||||
@@ -111,7 +124,14 @@ class DiziWatch extends MProvider {
|
||||
Future<List<MVideo>> getVideoList(String url) async {
|
||||
MDocument dom = parseHtml((await client.get(Uri.parse(url))).body);
|
||||
String id = dom.selectFirst("#takip_et_izledim_Calis").attr("data-ilanid");
|
||||
var json = json.decode((await client.get(Uri.parse("${source.baseUrl}/wp-admin/admin-ajax.php?action=playlist&pid=${id}"))).body)[0];
|
||||
var json =
|
||||
json.decode(
|
||||
(await client.get(
|
||||
Uri.parse(
|
||||
"${source.baseUrl}/wp-admin/admin-ajax.php?action=playlist&pid=${id}",
|
||||
),
|
||||
)).body,
|
||||
)[0];
|
||||
var sources = json["sources"];
|
||||
List<MVideo> videos = [];
|
||||
for (var source in sources) {
|
||||
@@ -124,7 +144,11 @@ class DiziWatch extends MProvider {
|
||||
}
|
||||
|
||||
String quality = getPreferenceValue(source.id, "preferred_quality");
|
||||
videos.sort((MVideo a, MVideo b) => (b.quality.contains(quality) ? 1 : 0) - (a.quality.contains(quality) ? 1 : 0));
|
||||
videos.sort(
|
||||
(MVideo a, MVideo b) =>
|
||||
(b.quality.contains(quality) ? 1 : 0) -
|
||||
(a.quality.contains(quality) ? 1 : 0),
|
||||
);
|
||||
|
||||
return videos;
|
||||
}
|
||||
@@ -136,7 +160,7 @@ class DiziWatch extends MProvider {
|
||||
SelectFilter("Sort", "Sırala", 0, [
|
||||
SelectFilterOption("IMDb Puanına Göre", "meta_value"),
|
||||
SelectFilterOption("Alfabetik", "name"),
|
||||
SelectFilterOption("Eklenme Tarihine Göre", "ID")
|
||||
SelectFilterOption("Eklenme Tarihine Göre", "ID"),
|
||||
]),
|
||||
TextFilter("Year", "Yapım Yılı"),
|
||||
SelectFilter("Genre", "Tür", 0, [
|
||||
@@ -178,10 +202,13 @@ class DiziWatch extends MProvider {
|
||||
SelectFilterOption("Tarihi", "tarihi"),
|
||||
SelectFilterOption("Uzay", "uzay"),
|
||||
SelectFilterOption("Vampir", "vampir"),
|
||||
SelectFilterOption("Yaşamdan Kesitler", "yasam")
|
||||
SelectFilterOption("Yaşamdan Kesitler", "yasam"),
|
||||
]),
|
||||
SelectFilter("MinIMDBRating", "Min. IMBD Puanı", 0, [
|
||||
SelectFilterOption("1", "0"), // value 1 looks like buggy so use 0 it wont make any difference.
|
||||
SelectFilterOption(
|
||||
"1",
|
||||
"0",
|
||||
), // value 1 looks like buggy so use 0 it wont make any difference.
|
||||
SelectFilterOption("2", "2"),
|
||||
SelectFilterOption("3", "3"),
|
||||
SelectFilterOption("4", "4"),
|
||||
@@ -189,8 +216,8 @@ class DiziWatch extends MProvider {
|
||||
SelectFilterOption("6", "6"),
|
||||
SelectFilterOption("7", "7"),
|
||||
SelectFilterOption("8", "8"),
|
||||
SelectFilterOption("9", "9")
|
||||
])
|
||||
SelectFilterOption("9", "9"),
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -203,7 +230,8 @@ class DiziWatch extends MProvider {
|
||||
summary: "",
|
||||
valueIndex: 0,
|
||||
entries: ["1080p", "480p"], // I only saw 1080p and 480p in diziWatch.
|
||||
entryValues: ["1080", "480"])
|
||||
entryValues: ["1080", "480"],
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,5 @@ Source _diziwatchSource = Source(
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/tr/diziwatch/icon.png",
|
||||
sourceCodeUrl: _diziwatchSourceCodeUrl,
|
||||
version: _diziwatchVersion,
|
||||
itemType: ItemType.anime);
|
||||
itemType: ItemType.anime,
|
||||
);
|
||||
|
||||
@@ -12,5 +12,5 @@ List<Source> dartMangasourceList = [
|
||||
...mmrcmsSourcesList,
|
||||
mangahereSource,
|
||||
...nepnepSourcesList,
|
||||
...mangaboxSourcesList
|
||||
...mangaboxSourcesList,
|
||||
];
|
||||
|
||||
@@ -10,18 +10,20 @@ class Madara extends MProvider {
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final res = (await client.get(
|
||||
Uri.parse("${source.baseUrl}/manga/page/$page/?m_orderby=views")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/manga/page/$page/?m_orderby=views"),
|
||||
)).body;
|
||||
final document = parseHtml(res);
|
||||
return mangaFromElements(document.select("div.page-item-detail"));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final res = (await client.get(
|
||||
Uri.parse("${source.baseUrl}/manga/page/$page/?m_orderby=latest")))
|
||||
.body;
|
||||
final res =
|
||||
(await client.get(
|
||||
Uri.parse("${source.baseUrl}/manga/page/$page/?m_orderby=latest"),
|
||||
)).body;
|
||||
final document = parseHtml(res);
|
||||
return mangaFromElements(document.select("div.page-item-detail"));
|
||||
}
|
||||
@@ -95,7 +97,10 @@ class Madara extends MProvider {
|
||||
var chd = element.selectFirst("span.chapter-release-date");
|
||||
if (chd != null && chd.text.isNotEmpty) {
|
||||
var dates = parseDates(
|
||||
[chd.text], source.dateFormat, source.dateFormatLocale);
|
||||
[chd.text],
|
||||
source.dateFormat,
|
||||
source.dateFormatLocale,
|
||||
);
|
||||
chapter.dateUpload = dates[0];
|
||||
} else {
|
||||
chapter.dateUpload =
|
||||
@@ -153,7 +158,7 @@ class Madara extends MProvider {
|
||||
"En espera": 2,
|
||||
"Canceled": 3,
|
||||
"Cancelado": 3,
|
||||
}
|
||||
},
|
||||
];
|
||||
MManga manga = MManga();
|
||||
String res = "";
|
||||
@@ -161,19 +166,23 @@ class Madara extends MProvider {
|
||||
final document = parseHtml(res);
|
||||
manga.author = document.selectFirst("div.author-content > a")?.text ?? "";
|
||||
|
||||
manga.description = document
|
||||
manga.description =
|
||||
document
|
||||
.selectFirst(
|
||||
"div.description-summary div.summary__content, div.summary_content div.post-content_item > h5 + div, div.summary_content div.manga-excerpt, div.sinopsis div.contenedor, .description-summary > p")
|
||||
"div.description-summary div.summary__content, div.summary_content div.post-content_item > h5 + div, div.summary_content div.manga-excerpt, div.sinopsis div.contenedor, .description-summary > p",
|
||||
)
|
||||
?.text ??
|
||||
"";
|
||||
|
||||
final imageElement = document.selectFirst("div.summary_image img");
|
||||
manga.imageUrl = imageElement?.attr("data-src") ??
|
||||
manga.imageUrl =
|
||||
imageElement?.attr("data-src") ??
|
||||
imageElement?.attr("data-lazy-src") ??
|
||||
imageElement?.attr("srcset") ??
|
||||
imageElement?.getSrc;
|
||||
|
||||
final id = document
|
||||
final id =
|
||||
document
|
||||
.selectFirst("div[id^=manga-chapters-holder]")
|
||||
?.attr("data-id") ??
|
||||
"";
|
||||
@@ -193,11 +202,14 @@ class Madara extends MProvider {
|
||||
final oldXhrChaptersRequest = await client.post(
|
||||
Uri.parse("${baseUrl}wp-admin/admin-ajax.php"),
|
||||
headers: headers,
|
||||
body: {"action": "manga_get_chapters", "manga": mangaId});
|
||||
body: {"action": "manga_get_chapters", "manga": mangaId},
|
||||
);
|
||||
if (oldXhrChaptersRequest.statusCode == 400) {
|
||||
res = (await client.post(Uri.parse("${url}ajax/chapters"),
|
||||
headers: headers))
|
||||
.body;
|
||||
res =
|
||||
(await client.post(
|
||||
Uri.parse("${url}ajax/chapters"),
|
||||
headers: headers,
|
||||
)).body;
|
||||
} else {
|
||||
res = oldXhrChaptersRequest.body;
|
||||
}
|
||||
@@ -205,9 +217,11 @@ class Madara extends MProvider {
|
||||
MDocument chapDoc = parseHtml(res);
|
||||
manga.chapters = getChapters(chapDoc);
|
||||
if (manga.chapters.isEmpty) {
|
||||
res = (await client.post(Uri.parse("${url}ajax/chapters"),
|
||||
headers: headers))
|
||||
.body;
|
||||
res =
|
||||
(await client.post(
|
||||
Uri.parse("${url}ajax/chapters"),
|
||||
headers: headers,
|
||||
)).body;
|
||||
chapDoc = parseHtml(res);
|
||||
manga.chapters = getChapters(chapDoc);
|
||||
}
|
||||
@@ -221,13 +235,15 @@ class Madara extends MProvider {
|
||||
final document = parseHtml(res.body);
|
||||
|
||||
final pageElements = document.select(
|
||||
"div.page-break, li.blocks-gallery-item, .reading-content .text-left:not(:has(.blocks-gallery-item)) img");
|
||||
"div.page-break, li.blocks-gallery-item, .reading-content .text-left:not(:has(.blocks-gallery-item)) img",
|
||||
);
|
||||
|
||||
List<String> imgs = [];
|
||||
for (var element in pageElements) {
|
||||
try {
|
||||
final imgElement = element.selectFirst("img");
|
||||
final img = imgElement.attr("src") ??
|
||||
final img =
|
||||
imgElement.attr("src") ??
|
||||
imgElement.attr("data-src") ??
|
||||
imgElement.attr("data-lazy-src") ??
|
||||
imgElement.attr("srcset");
|
||||
@@ -261,7 +277,8 @@ class Madara extends MProvider {
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
final postTitle = elements[i].selectFirst("div.post-title a");
|
||||
final imageElement = elements[i].selectFirst("img");
|
||||
final image = imageElement?.attr("data-src") ??
|
||||
final image =
|
||||
imageElement?.attr("data-src") ??
|
||||
imageElement?.attr("data-lazy-src") ??
|
||||
imageElement?.attr("srcset") ??
|
||||
imageElement?.getSrc ??
|
||||
@@ -301,7 +318,7 @@ class Madara extends MProvider {
|
||||
SelectFilterOption("All", ""),
|
||||
SelectFilterOption("None", "0"),
|
||||
SelectFilterOption("Only", "1"),
|
||||
])
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +190,8 @@ const madaraSourceCodeUrl =
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/madara.dart";
|
||||
|
||||
List<Source> get madaraSourcesList => _madaraSourcesList;
|
||||
List<Source> _madaraSourcesList = [
|
||||
List<Source> _madaraSourcesList =
|
||||
[
|
||||
//1st Kiss-Manga (unoriginal) (EN)
|
||||
firstkissdashmangaSource,
|
||||
//AQUA Scans (EN)
|
||||
@@ -570,8 +571,11 @@ List<Source> _madaraSourcesList = [
|
||||
//Webtoon Hatti (TR)
|
||||
webtoonhattiSource,
|
||||
]
|
||||
.map((e) => e
|
||||
.map(
|
||||
(e) =>
|
||||
e
|
||||
..itemType = ItemType.manga
|
||||
..sourceCodeUrl = madaraSourceCodeUrl
|
||||
..version = madaraVersion)
|
||||
..version = madaraVersion,
|
||||
)
|
||||
.toList();
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "pt-BR",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/akumanotenshi/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/akumanotenshi/icon.png",
|
||||
dateFormat: "dd/MM/yyyy",
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _alonescanlatorSource = Source(
|
||||
lang: "pt-br",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/alonescanlator/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/alonescanlator/icon.png",
|
||||
dateFormat: "dd/MM/yyyy",
|
||||
dateFormatLocale:"pt-br"
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "tr",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/anikiga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/anikiga/icon.png",
|
||||
dateFormat: "d MMMMM yyyy",
|
||||
dateFormatLocale: "tr",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "tr",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/araznovel/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/araznovel/icon.png",
|
||||
dateFormat: "d MMMM yyyy",
|
||||
dateFormatLocale: "en",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "pt-BR",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/arthurscan/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/arthurscan/icon.png",
|
||||
dateFormat: "MMMMM dd, yyyy",
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "fr",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/astralmanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/astralmanga/icon.png",
|
||||
dateFormat: "dd/mm/yyyy",
|
||||
dateFormatLocale: "fr",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/asurascansus/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/asurascansus/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _atikrostSource = Source(
|
||||
lang: "tr",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/atikrost/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/atikrost/icon.png",
|
||||
dateFormat: "d MMMM yyyy",
|
||||
dateFormatLocale:"tr"
|
||||
dateFormatLocale: "tr",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "es",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/barmanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/barmanga/icon.png",
|
||||
dateFormat: "MM/dd/yyyy",
|
||||
dateFormatLocale: "es",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "ru",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/bestmanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/bestmanga/icon.png",
|
||||
dateFormat: "dd.MM.yyyy",
|
||||
dateFormatLocale: "ru",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _bokugentranslationSource = Source(
|
||||
lang: "es",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/bokugentranslation/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/bokugentranslation/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale:"es"
|
||||
dateFormatLocale: "es",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _borutoexplorerSource = Source(
|
||||
lang: "pt-br",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/borutoexplorer/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/borutoexplorer/icon.png",
|
||||
dateFormat: "dd 'de' MMMMM 'de' yyyy",
|
||||
dateFormatLocale:"pt-br"
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/chibimanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/chibimanga/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "tr",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/clovermanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/clovermanga/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "tr",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "es",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/cocorip/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/cocorip/icon.png",
|
||||
dateFormat: "dd/MM/yyyy",
|
||||
dateFormatLocale: "es",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/coffeemanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/coffeemanga/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _crystalcomicsSource = Source(
|
||||
lang: "pt-br",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/crystalcomics/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/crystalcomics/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale:"pt-br"
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _daprobSource = Source(
|
||||
lang: "es",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/daprob/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/daprob/icon.png",
|
||||
dateFormat: "dd/MM/yyy",
|
||||
dateFormatLocale:"en"
|
||||
dateFormatLocale: "en",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _demanhuasSource = Source(
|
||||
lang: "es",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/demanhuas/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/demanhuas/icon.png",
|
||||
dateFormat: "MMMM d, yyyy",
|
||||
dateFormatLocale:"es"
|
||||
dateFormatLocale: "es",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _diamondfansubSource = Source(
|
||||
lang: "tr",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/diamondfansub/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/diamondfansub/icon.png",
|
||||
dateFormat: "d MMMM",
|
||||
dateFormatLocale:"tr-tr"
|
||||
dateFormatLocale: "tr-tr",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "th",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/doodmanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/doodmanga/icon.png",
|
||||
dateFormat: "dd MMMMM yyyy",
|
||||
dateFormatLocale: "th",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _dragonteaSource = Source(
|
||||
lang: "en",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/dragontea/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/dragontea/icon.png",
|
||||
dateFormat: "MM/dd/yyyy",
|
||||
dateFormatLocale:"en_us"
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/elitemanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/elitemanga/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "es",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/emperorscan/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/emperorscan/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "es",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "tr",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/evascans/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/evascans/icon.png",
|
||||
dateFormat: "MMM d, yyy",
|
||||
dateFormatLocale: "tr",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/factmanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/factmanga/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -8,7 +8,6 @@ import '../../../../../../model/source.dart';
|
||||
lang: "ar",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/falconmanga/icon.png",
|
||||
|
||||
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/falconmanga/icon.png",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _fayscansSource = Source(
|
||||
lang: "pt-br",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/fayscans/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/fayscans/icon.png",
|
||||
dateFormat: "dd/MM/yyyy",
|
||||
dateFormatLocale:"pt-br"
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/firstkissdashmanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/firstkissdashmanga/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/freemangatop/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/freemangatop/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "fr",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/frscan/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/frscan/icon.png",
|
||||
dateFormat: "MMMM d, yyyy",
|
||||
dateFormatLocale: "fr",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _galinhasamuraiscanSource = Source(
|
||||
lang: "pt-br",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/galinhasamuraiscan/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/galinhasamuraiscan/icon.png",
|
||||
dateFormat: "dd/MM/yyyy",
|
||||
dateFormatLocale:"pt-br"
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _garciamangaSource = Source(
|
||||
lang: "tr",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/garciamanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/garciamanga/icon.png",
|
||||
dateFormat: "MMMM d, yyyy",
|
||||
dateFormatLocale:"tr"
|
||||
dateFormatLocale: "tr",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _gatemangaSource = Source(
|
||||
lang: "ar",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/gatemanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/gatemanga/icon.png",
|
||||
dateFormat: "d MMMM، yyyy",
|
||||
dateFormatLocale:"ar"
|
||||
dateFormatLocale: "ar",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _globalblogingSource = Source(
|
||||
lang: "en",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/globalbloging/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/globalbloging/icon.png",
|
||||
dateFormat: "dd MMMM yyyy",
|
||||
dateFormatLocale:"en_us"
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "tr",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/glorymanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/glorymanga/icon.png",
|
||||
dateFormat: "dd/MM/yyy",
|
||||
dateFormatLocale: "tr",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _gmangasiteSource = Source(
|
||||
lang: "ar",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/gmangasite/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/gmangasite/icon.png",
|
||||
dateFormat: "MMMM dd، yyyy",
|
||||
dateFormatLocale:"ar"
|
||||
dateFormatLocale: "ar",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _grabberzoneSource = Source(
|
||||
lang: "all",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/grabberzone/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/grabberzone/icon.png",
|
||||
dateFormat: "dd.MM.yyyy",
|
||||
dateFormatLocale:"en"
|
||||
dateFormatLocale: "en",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _guncelmangaSource = Source(
|
||||
lang: "tr",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/guncelmanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/guncelmanga/icon.png",
|
||||
dateFormat: "d MMMM yyyy",
|
||||
dateFormatLocale:"tr"
|
||||
dateFormatLocale: "tr",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/harimanga/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/harimanga/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _herenscanSource = Source(
|
||||
lang: "es",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/herenscan/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/herenscan/icon.png",
|
||||
dateFormat: "d 'de' MMM 'de' yyy",
|
||||
dateFormatLocale:"es"
|
||||
dateFormatLocale: "es",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _hikariganaiSource = Source(
|
||||
lang: "pt-br",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/hikariganai/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/hikariganai/icon.png",
|
||||
dateFormat: "d 'de' MMMM 'de' yyyy",
|
||||
dateFormatLocale:"pt-br"
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _housemangasSource = Source(
|
||||
lang: "es",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/housemangas/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/housemangas/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale:"es"
|
||||
dateFormatLocale: "es",
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ Source _hwagoSource = Source(
|
||||
lang: "id",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/hwago/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/hwago/icon.png",
|
||||
dateFormat: "d MMMM yyyy",
|
||||
dateFormatLocale:"en"
|
||||
dateFormatLocale: "en",
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import '../../../../../../model/source.dart';
|
||||
lang: "en",
|
||||
|
||||
typeSource: "madara",
|
||||
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/immortalupdates/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/immortalupdates/icon.png",
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en_us",
|
||||
);
|
||||
@@ -7,7 +7,8 @@ Source _imperiodabritanniaSource = Source(
|
||||
lang: "pt-br",
|
||||
isNsfw: false,
|
||||
typeSource: "madara",
|
||||
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/imperiodabritannia/icon.png",
|
||||
iconUrl:
|
||||
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/imperiodabritannia/icon.png",
|
||||
dateFormat: "dd 'de' MMMMM 'de' yyyy",
|
||||
dateFormatLocale:"pt-br"
|
||||
dateFormatLocale: "pt-br",
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user