dart format

This commit is contained in:
Moustapha Kodjo Amadou
2025-03-01 13:38:06 +01:00
parent 2388636458
commit 7d5e95679d
325 changed files with 6715 additions and 5516 deletions

View File

@@ -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(
Uri.parse(
"$baseUrl?do=search&subaction=search&story=$cleanQuery"),
headers: headers))
.body;
res =
(await client.post(
Uri.parse(
"$baseUrl?do=search&subaction=search&story=$cleanQuery",
),
headers: headers,
)).body;
} else {
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;
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;
}
} 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,10 +104,13 @@ class DataLifeEngine extends MProvider {
}
} else {
final doc = parseHtml(res);
final elements = doc
.select(".hostsblock div:has(a)")
.where((MElement e) => e.outerHtml.contains("loadVideo('https://"))
.toList();
final elements =
doc
.select(".hostsblock div:has(a)")
.where(
(MElement e) => e.outerHtml.contains("loadVideo('https://"),
)
.toList();
if (elements.isNotEmpty) {
for (var element in elements) {
element = element as MElement;
@@ -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);
@@ -191,15 +214,18 @@ class DataLifeEngine extends MProvider {
Future<List<MVideo>> streamHideExtractor(String url) async {
final res = (await client.get(Uri.parse(url))).body;
final masterUrl = substringBefore(
substringAfter(
substringAfter(
substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\""),
'"');
substringAfter(
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";
@@ -315,22 +348,24 @@ class DataLifeEngine extends MProvider {
return [
if (source.name == "Wiflix")
EditTextPreference(
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://wiflix-hd.vip",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://wiflix-hd.vip"),
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://wiflix-hd.vip",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://wiflix-hd.vip",
),
if (source.name == "French Anime")
EditTextPreference(
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://french-anime.com",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://french-anime.com"),
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://french-anime.com",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
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/"),

View File

@@ -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 = [
//French Anime (FR)
frenchanimeSource,
//Wiflix (FR)
wiflixSource,
]
.map((e) => e
..sourceCodeUrl = _datalifeengineSourceCodeUrl
..version = _datalifeengineVersion)
.toList();
List<Source> _datalifeengineSourcesList =
[
//French Anime (FR)
frenchanimeSource,
//Wiflix (FR)
wiflixSource,
]
.map(
(e) =>
e
..sourceCodeUrl = _datalifeengineSourceCodeUrl
..version = _datalifeengineVersion,
)
.toList();

View File

@@ -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(
Uri.parse("$serverUrl/ajax/embed-4/getSources?id=$id"),
headers: {"X-Requested-With": "XMLHttpRequest"}))
.body;
final resServer =
(await client.get(
Uri.parse("$serverUrl/ajax/embed-4/getSources?id=$id"),
headers: {"X-Requested-With": "XMLHttpRequest"},
)).body;
final encrypted = getMapValue(resServer, "encrypted");
String videoResJson = "";
@@ -192,11 +205,13 @@ class DopeFlix extends MProvider {
index += item.last;
}
videoResJson = decryptAESCryptoJS(ciphertext, password);
masterUrl = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['file'];
masterUrl =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['file'];
type = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['type'];
type =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['type'];
} else {
masterUrl =
((json.decode(resServer)["sources"] as List<Map<String, dynamic>>)
@@ -207,9 +222,10 @@ class DopeFlix extends MProvider {
.first)['type'];
}
final tracks = (json.decode(resServer)['tracks'] as List)
.where((e) => e['kind'] == 'captions' ? true : false)
.toList();
final tracks =
(json.decode(resServer)['tracks'] as List)
.where((e) => e['kind'] == 'captions' ? true : false)
.toList();
List<MTrack> subtitles = [];
for (var sub in tracks) {
@@ -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,28 +282,31 @@ 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
.split(",")
.map((String e) {
String value = substringAfter(e, "=");
if (value.contains("0x")) {
return int.parse(substringAfter(value, "0x"), radix: 16);
} else {
return int.parse(value);
}
})
.toList()
.skip(1)
.toList();
return chunked(list, 2)
.map((List<int> list) => list.reversed.toList())
.toList();
final list =
script
.split(",")
.map((String e) {
String value = substringAfter(e, "=");
if (value.contains("0x")) {
return int.parse(substringAfter(value, "0x"), radix: 16);
} else {
return int.parse(value);
}
})
.toList()
.skip(1)
.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"),
]),
];
}
@@ -422,72 +445,78 @@ class DopeFlix extends MProvider {
return [
if (source.name == "DopeBox")
ListPreference(
key: "preferred_domain",
title: "Preferred domain",
summary: "",
valueIndex: 0,
entries: ["dopebox.to", "dopebox.se"],
entryValues: ["https://dopebox.to", "https://dopebox.se"]),
key: "preferred_domain",
title: "Preferred domain",
summary: "",
valueIndex: 0,
entries: ["dopebox.to", "dopebox.se"],
entryValues: ["https://dopebox.to", "https://dopebox.se"],
),
if (source.name == "SFlix")
ListPreference(
key: "preferred_domain",
title: "Preferred domain",
summary: "",
valueIndex: 0,
entries: ["sflix.to", "sflix.se"],
entryValues: ["https://sflix.to", "https://sflix.se"]),
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
key: "preferred_domain",
title: "Preferred domain",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080p", "720p", "480p", "360p"]),
entries: ["sflix.to", "sflix.se"],
entryValues: ["https://sflix.to", "https://sflix.se"],
),
ListPreference(
key: "preferred_subLang",
title: "Preferred sub language",
summary: "",
valueIndex: 1,
entries: [
"Arabic",
"English",
"French",
"German",
"Hungarian",
"Italian",
"Japanese",
"Portuguese",
"Romanian",
"Russian",
"Spanish"
],
entryValues: [
"Arabic",
"English",
"French",
"German",
"Hungarian",
"Italian",
"Japanese",
"Portuguese",
"Romanian",
"Russian",
"Spanish"
]),
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080p", "720p", "480p", "360p"],
),
ListPreference(
key: "preferred_latest_page",
title: "Preferred latest page",
summary: "",
valueIndex: 0,
entries: ["Movies", "TV Shows"],
entryValues: ["Latest Movies", "Latest TV Shows"]),
key: "preferred_subLang",
title: "Preferred sub language",
summary: "",
valueIndex: 1,
entries: [
"Arabic",
"English",
"French",
"German",
"Hungarian",
"Italian",
"Japanese",
"Portuguese",
"Romanian",
"Russian",
"Spanish",
],
entryValues: [
"Arabic",
"English",
"French",
"German",
"Hungarian",
"Italian",
"Japanese",
"Portuguese",
"Romanian",
"Russian",
"Spanish",
],
),
ListPreference(
key: "preferred_popular_page",
title: "Preferred popular page",
summary: "",
valueIndex: 0,
entries: ["Movies", "TV Shows"],
entryValues: ["movie", "tv-show"]),
key: "preferred_latest_page",
title: "Preferred latest page",
summary: "",
valueIndex: 0,
entries: ["Movies", "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"],
),
];
}

View File

@@ -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 = [
//DopeBox (EN)
dopeboxSource,
//SFlix (EN)
sflixSource,
]
.map((e) => e
..sourceCodeUrl = _dopeflixSourceCodeUrl
..version = _dopeflixVersion)
.toList();
List<Source> _dopeflixSourcesList =
[
//DopeBox (EN)
dopeboxSource,
//SFlix (EN)
sflixSource,
]
.map(
(e) =>
e
..sourceCodeUrl = _dopeflixSourceCodeUrl
..version = _dopeflixVersion,
)
.toList();

View File

@@ -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 = [
//AniWatch.to (EN)
aniwatchSource,
//Kaido.to (EN)
kaidoSource,
]
.map((e) => e
..sourceCodeUrl = _zorothemeSourceCodeUrl
..version = _zorothemeVersion)
.toList();
List<Source> _zorothemeSourcesList =
[
//AniWatch.to (EN)
aniwatchSource,
//Kaido.to (EN)
kaidoSource,
]
.map(
(e) =>
e
..sourceCodeUrl = _zorothemeSourceCodeUrl
..version = _zorothemeVersion,
)
.toList();

View File

@@ -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(
Uri.parse(
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/servers?episodeId=$id"),
headers: {"referer": "${source.baseUrl}/$url"}))
.body;
final res =
(await client.get(
Uri.parse(
"${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(
Uri.parse(
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/sources?id=$id"),
headers: {"referer": "${source.baseUrl}/$url"}))
.body;
final resE =
(await client.get(
Uri.parse(
"${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"
}, [
cryptoStr,
decodePng,
getSrcStr,
"getSources('$id').then(s => window.flutter_inappwebview.callHandler('setResponse', JSON.stringify(s)))"
]);
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)))",
],
);
} else {
resServer = (await client.get(
Uri.parse('${serverUrl[serverType]}${sourceUrl[serverType]}$id'),
headers: {"X-Requested-With": "XMLHttpRequest"}))
.body;
resServer =
(await client.get(
Uri.parse('${serverUrl[serverType]}${sourceUrl[serverType]}$id'),
headers: {"X-Requested-With": "XMLHttpRequest"},
)).body;
}
final encrypted = getMapValue(resServer, "encrypted");
@@ -268,18 +288,21 @@ 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>>)
.first)['type'];
String type =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['type'];
final tracks = (json.decode(resServer)['tracks'] as List)
.where((e) => e['kind'] == 'captions' ? true : false)
.toList();
final tracks =
(json.decode(resServer)['tracks'] as List)
.where((e) => e['kind'] == 'captions' ? true : false)
.toList();
List<MTrack> subtitles = [];
for (var sub in tracks) {
@@ -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"),
]),
];
}
@@ -544,58 +585,65 @@ class ZoroTheme extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"],
),
if (source.name == "HiAnime")
ListPreference(
key: "preferred_server1",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: ["HD-1", "HD-2", "StreamTape"],
entryValues: ["HD-1", "HD-2", "StreamTape"]),
if (source.name != "HiAnime")
ListPreference(
key: "preferred_server1",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"]),
ListPreference(
key: "preferred_type1",
title: "Preferred Type",
key: "preferred_server1",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"]),
entries: ["HD-1", "HD-2", "StreamTape"],
entryValues: ["HD-1", "HD-2", "StreamTape"],
),
if (source.name != "HiAnime")
ListPreference(
key: "preferred_server1",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"],
),
ListPreference(
key: "preferred_type1",
title: "Preferred Type",
summary: "",
valueIndex: 0,
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"],
),
if (source.name != "HiAnime")
MultiSelectListPreference(
key: "hoster_selection1",
title: "Enable/Disable Hosts",
summary: "",
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"],
values: ["Vidstreaming", "VidCloud", "StreamTape"]),
key: "hoster_selection1",
title: "Enable/Disable Hosts",
summary: "",
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"],
values: ["Vidstreaming", "VidCloud", "StreamTape"],
),
if (source.name == "HiAnime")
MultiSelectListPreference(
key: "hoster_selection1",
title: "Enable/Disable Hosts",
summary: "",
entries: ["HD-1", "HD-2", "StreamTape"],
entryValues: ["HD-1", "HD-2", "StreamTape"],
values: ["HD-1", "HD-2", "StreamTape"]),
MultiSelectListPreference(
key: "type_selection_new",
title: "Enable/Disable Types",
key: "hoster_selection1",
title: "Enable/Disable Hosts",
summary: "",
entries: ["Sub", "Dub", "Raw"],
entryValues: ["sub", "dub"],
values: ["sub", "dub", "raw"]),
entries: ["HD-1", "HD-2", "StreamTape"],
entryValues: ["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"],
),
];
}