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

@@ -50,5 +50,5 @@ List<Source> dartAnimesourceList = [
animesvision,
diziwatchSource,
aniZoneSource,
animeonlineninjaSource
animeonlineninjaSource,
];

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"],
),
];
}

View File

@@ -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(
substringBefore(
substringAfter(res, "var season_list = "), "var season_label ="),
";")) as List<Map<String, dynamic>>;
'//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>>;
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,17 +163,25 @@ 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) =>
(e["type"] == "stream" ? true : false) &&
(e["url"] as String).isNotEmpty)
.toList()
.where((e) => language(source.lang).isEmpty ||
language(source.lang) == e["language"]
? true
: false)
.toList();
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,
)
.toList()
.where(
(e) =>
language(source.lang).isEmpty ||
language(source.lang) == e["language"]
? true
: false,
)
.toList();
List<MVideo> videos = [];
for (var stream in streams) {
String videoUrl = stream["url"];
@@ -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"),
@@ -348,12 +381,13 @@ class AnimeWorldIndia extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p", "240p"],
entryValues: ["1080", "720", "480", "360", "240"]),
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p", "240p"],
entryValues: ["1080", "720", "480", "360", "240"],
),
];
}

View File

@@ -20,14 +20,18 @@ List<String> _languages = [
];
List<Source> get animeworldindiaSourcesList => _animeworldindiaSourcesList;
List<Source> _animeworldindiaSourcesList = _languages
.map((e) => Source(
name: 'AnimeWorld India',
baseUrl: "https://anime-world.in",
lang: e,
typeSource: "multiple",
iconUrl: _iconUrl,
version: _animeworldindiaVersion,
itemType: ItemType.anime,
sourceCodeUrl: _animeworldindiaSourceCodeUrl))
.toList();
List<Source> _animeworldindiaSourcesList =
_languages
.map(
(e) => Source(
name: 'AnimeWorld India',
baseUrl: "https://anime-world.in",
lang: e,
typeSource: "multiple",
iconUrl: _iconUrl,
version: _animeworldindiaVersion,
itemType: ItemType.anime,
sourceCodeUrl: _animeworldindiaSourceCodeUrl,
),
)
.toList();

View File

@@ -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"),
]),
];
}
@@ -87,12 +93,13 @@ class Nyaa extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_categorie_page",
title: "Preferred categorie page",
summary: "",
valueIndex: 0,
entries: ["Anime", "Live Action"],
entryValues: ["1_0", "4_0"]),
key: "preferred_categorie_page",
title: "Preferred categorie page",
summary: "",
valueIndex: 0,
entries: ["Anime", "Live Action"],
entryValues: ["1_0", "4_0"],
),
];
}
@@ -100,19 +107,23 @@ 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
.select("td > a")
.where((MElement e) =>
e.outerHtml.contains("/view/") &&
!e.outerHtml.contains("#comments"))
.toList()
.first;
MElement firstElement =
value
.select("td > a")
.where(
(MElement e) =>
e.outerHtml.contains("/view/") &&
!e.outerHtml.contains("#comments"),
)
.toList()
.first;
anime.link =
"${source.baseUrl}${getUrlWithoutDomain(firstElement.getHref)}";
anime.name = firstElement.attr("title");
@@ -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);
}

View File

@@ -9,11 +9,12 @@ String _iconUrl =
Source get nyaaSource => _nyaaSource;
Source _nyaaSource = Source(
name: 'Nyaa',
baseUrl: "https://nyaa.si",
lang: "all",
typeSource: "torrent",
iconUrl: _iconUrl,
version: _nyaaVersion,
itemType: ItemType.anime,
sourceCodeUrl: _nyaaSourceCodeUrl);
name: 'Nyaa',
baseUrl: "https://nyaa.si",
lang: "all",
typeSource: "torrent",
iconUrl: _iconUrl,
version: _nyaaVersion,
itemType: ItemType.anime,
sourceCodeUrl: _nyaaSourceCodeUrl,
);

View File

@@ -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++) {
@@ -147,19 +156,21 @@ class OkAnime 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"],
),
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"]),
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"],
),
];
}

View File

@@ -5,12 +5,13 @@ const _okanimeVersion = "0.0.55";
const _okanimeSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/ar/okanime/okanime.dart";
Source _okanimeSource = Source(
name: "Okanime",
baseUrl: "https://www.okanime.xyz",
lang: "ar",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/ar/okanime/icon.png",
sourceCodeUrl: _okanimeSourceCodeUrl,
version: _okanimeVersion,
itemType: ItemType.anime);
name: "Okanime",
baseUrl: "https://www.okanime.xyz",
lang: "ar",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/ar/okanime/icon.png",
sourceCodeUrl: _okanimeSourceCodeUrl,
version: _okanimeVersion,
itemType: ItemType.anime,
);

View File

@@ -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");
}
@@ -213,19 +226,21 @@ class AnimeToast extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_hoster",
title: "Standard-Hoster",
summary: "",
valueIndex: 0,
entries: ["Voe", "DoodStream", "Filemoon", "Mp4upload"],
entryValues: ["voe", "doodStream", "filemoon", "mp4upload"]),
key: "preferred_hoster",
title: "Standard-Hoster",
summary: "",
valueIndex: 0,
entries: ["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"]),
key: "hoster_selection",
title: "Hoster auswählen",
summary: "",
entries: ["Voe", "DoodStream", "Filemoon", "Mp4upload"],
entryValues: ["voe", "dood", "filemoon", "mp4upload"],
values: ["voe", "dood", "filemoon", "mp4upload"],
),
];
}
}

View File

@@ -5,12 +5,13 @@ const _animetoastVersion = "0.0.2";
const _animetoastCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/animetoast/animetoast.dart";
Source _animetoast = Source(
name: "AnimeToast",
baseUrl: "https://animetoast.cc",
lang: "de",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/animetoast/icon.png",
sourceCodeUrl: _animetoastCodeUrl,
version: _animetoastVersion,
itemType: ItemType.anime);
name: "AnimeToast",
baseUrl: "https://animetoast.cc",
lang: "de",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/animetoast/icon.png",
sourceCodeUrl: _animetoastCodeUrl,
version: _animetoastVersion,
itemType: ItemType.anime,
);

View File

@@ -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(
Uri.parse("$baseUrl/api?m=search&l=8&q=$query"),
headers: headers))
.body;
final res =
(await client.get(
Uri.parse("$baseUrl/api?m=search&l=8&q=$query"),
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(
Uri.parse("$baseUrl/anime/$session?anime_id=$id"),
headers: headers))
.body;
final res =
(await client.get(
Uri.parse("$baseUrl/anime/$session?anime_id=$id"),
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: {
"referer": reskwik.request.url.toString(),
"cookie": cookie,
"user-agent":
getMapValue(json.encode(res.request.headers), "user-agent")
}, body: {
"_token": tok
});
source,
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},
);
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,12 +304,14 @@ 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.
// Preferred Audio: Videos with matching preferred audio are ranked highest.
// Prioritize audio first.
// Preferred Audio: Videos with matching preferred audio are ranked highest.
int audioMatchA = a.quality.contains(preferredAudio) ? 1 : 0;
int audioMatchB = b.quality.contains(preferredAudio) ? 1 : 0;
if (audioMatchA != audioMatchB) {
@@ -310,40 +347,40 @@ class AnimePahe extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_domain",
title: "Preferred domain",
summary: "",
valueIndex: 1,
entries: [
"animepahe.com",
"animepahe.ru",
"animepahe.org"
],
entryValues: [
"https://animepahe.com",
"https://animepahe.ru",
"https://animepahe.org"
]),
key: "preferred_domain",
title: "Preferred domain",
summary: "",
valueIndex: 1,
entries: ["animepahe.com", "animepahe.ru", "animepahe.org"],
entryValues: [
"https://animepahe.com",
"https://animepahe.ru",
"https://animepahe.org",
],
),
SwitchPreferenceCompat(
key: "preffered_link_type",
title: "Use HLS links",
summary: "Enable this if you are having Cloudflare issues.",
value: false),
key: "preffered_link_type",
title: "Use HLS links",
summary: "Enable this if you are having Cloudflare issues.",
value: false,
),
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "360p"],
entryValues: ["1080", "720", "360"]),
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "360p"],
entryValues: ["1080", "720", "360"],
),
ListPreference(
key: "preferred_audio", // Add new preference for audio
title: "Preferred Audio",
summary: "Select your preferred audio language (Japanese or English).",
valueIndex: 0, // Default to Japanese (or whichever you prefer)
entries: ["Japanese", "English"],
entryValues: ["jpn", "eng"]),
key: "preferred_audio", // Add new preference for audio
title: "Preferred Audio",
summary: "Select your preferred audio language (Japanese or English).",
valueIndex: 0, // Default to Japanese (or whichever you prefer)
entries: ["Japanese", "English"],
entryValues: ["jpn", "eng"],
),
];
}
}

View File

@@ -5,12 +5,13 @@ const _animepaheVersion = "0.0.5";
const _animepaheSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/animepahe/animepahe.dart";
Source _animepaheSource = Source(
name: "AnimePahe",
baseUrl: "https://www.animepahe.ru",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/animepahe/icon.png",
sourceCodeUrl: _animepaheSourceCodeUrl,
version: _animepaheVersion,
itemType: ItemType.anime);
name: "AnimePahe",
baseUrl: "https://www.animepahe.ru",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/animepahe/icon.png",
sourceCodeUrl: _animepaheSourceCodeUrl,
version: _animepaheVersion,
itemType: ItemType.anime,
);

File diff suppressed because it is too large Load Diff

View File

@@ -5,12 +5,13 @@ const _gogoanimeVersion = "0.1.15";
const _gogoanimeSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/gogoanime/gogoanime.dart";
Source _gogoanimeSource = Source(
name: "Gogoanime",
baseUrl: "https://anitaku.to",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/gogoanime/icon.png",
sourceCodeUrl: _gogoanimeSourceCodeUrl,
version: _gogoanimeVersion,
itemType: ItemType.anime);
name: "Gogoanime",
baseUrl: "https://anitaku.to",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/gogoanime/icon.png",
sourceCodeUrl: _gogoanimeSourceCodeUrl,
version: _gogoanimeVersion,
itemType: ItemType.anime,
);

View File

@@ -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(
Uri.parse('${serverUrl[serverType]}${sourceUrl[serverType]}$id'),
headers: {"X-Requested-With": "XMLHttpRequest"}))
.body;
final resServer =
(await client.get(
Uri.parse('${serverUrl[serverType]}${sourceUrl[serverType]}$id'),
headers: {"X-Requested-With": "XMLHttpRequest"},
)).body;
final encrypted = getMapValue(resServer, "encrypted");
String videoResJson = "";
List<MVideo> videos = [];
@@ -245,18 +262,21 @@ 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>>)
.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) {
@@ -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")]),
];
}
@@ -458,40 +485,45 @@ class NineAnimeTv 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"],
),
ListPreference(
key: "preferred_server",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: ["Vidstreaming", "VidCloud"],
entryValues: ["Vidstreaming", "VidCloud"]),
key: "preferred_server",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: ["Vidstreaming", "VidCloud"],
entryValues: ["Vidstreaming", "VidCloud"],
),
ListPreference(
key: "preferred_type",
title: "Preferred Type",
summary: "",
valueIndex: 0,
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"]),
key: "preferred_type",
title: "Preferred Type",
summary: "",
valueIndex: 0,
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"],
),
MultiSelectListPreference(
key: "hoster_selection",
title: "Enable/Disable Hosts",
summary: "",
entries: ["Vidstreaming", "VidCloud"],
entryValues: ["Vidstreaming", "Vidcloud"],
values: ["Vidstreaming", "Vidcloud"]),
key: "hoster_selection",
title: "Enable/Disable Hosts",
summary: "",
entries: ["Vidstreaming", "VidCloud"],
entryValues: ["Vidstreaming", "Vidcloud"],
values: ["Vidstreaming", "Vidcloud"],
),
MultiSelectListPreference(
key: "type_selection",
title: "Enable/Disable Types",
summary: "",
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"],
values: ["sub", "dub"]),
key: "type_selection",
title: "Enable/Disable Types",
summary: "",
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"],
values: ["sub", "dub"],
),
];
}

View File

@@ -5,12 +5,13 @@ const _nineanimetvVersion = "0.0.5";
const _nineanimetvCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/nineanimetv/nineanimetv.dart";
Source _nineanimetv = Source(
name: "9AnimeTv",
baseUrl: "https://9animetv.to",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/nineanimetv/icon.png",
sourceCodeUrl: _nineanimetvCodeUrl,
version: _nineanimetvVersion,
itemType: ItemType.anime);
name: "9AnimeTv",
baseUrl: "https://9animetv.to",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/nineanimetv/icon.png",
sourceCodeUrl: _nineanimetvCodeUrl,
version: _nineanimetvVersion,
itemType: ItemType.anime,
);

View File

@@ -5,12 +5,13 @@ const _uhdmoviesVersion = "0.0.45";
const _uhdmoviesSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/uhdmovies/uhdmovies.dart";
Source _uhdmoviesSource = Source(
name: "UHD Movies",
baseUrl: "https://uhdmovies.fans",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/uhdmovies/icon.png",
sourceCodeUrl: _uhdmoviesSourceCodeUrl,
version: _uhdmoviesVersion,
itemType: ItemType.anime);
name: "UHD Movies",
baseUrl: "https://uhdmovies.fans",
lang: "en",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/uhdmovies/icon.png",
sourceCodeUrl: _uhdmoviesSourceCodeUrl,
version: _uhdmoviesVersion,
itemType: ItemType.anime,
);

View File

@@ -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) {
@@ -126,13 +135,14 @@ class UHDMovies extends MProvider {
List<dynamic> getSourcePreferences() {
return [
EditTextPreference(
key: "pref_domain_new",
title: "Currently used domain",
summary: "",
value: "https://uhdmovies.fans",
dialogTitle: "Currently used domain",
dialogMessage: "",
text: "https://uhdmovies.fans"),
key: "pref_domain_new",
title: "Currently used domain",
summary: "",
value: "https://uhdmovies.fans",
dialogTitle: "Currently used domain",
dialogMessage: "",
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);
}
}

View File

@@ -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,
selector: "div.result-item div.image a",
hasNextPage: parseHtml(res)
.selectFirst(
"div.pagination > *:last-child:not(span):not(.current)")
?.text !=
null);
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)
.selectFirst(
"div.pagination > *:last-child:not(span):not(.current)",
)
?.text !=
null,
);
}
@override
@@ -39,11 +46,12 @@ class AnimeOnlineNinja extends MProvider {
MManga anime = MManga();
final document = parseHtml(res);
anime.description = document.selectFirst("div#info").text;
anime.genre = document
.selectFirst("div.sheader")
.select("div.data > div.sgeneros > a")
.map((e) => e.text)
.toList();
anime.genre =
document
.selectFirst("div.sheader")
.select("div.data > div.sgeneros > a")
.map((e) => e.text)
.toList();
List<MChapter>? episodesList = [];
final seasonElements = document.select("div#seasons > div");
@@ -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);
@@ -138,15 +162,18 @@ class AnimeOnlineNinja extends MProvider {
Future<List<MVideo>> streamHideExtractor(String url, String prefix) 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";
@@ -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;
@@ -240,39 +279,41 @@ class AnimeOnlineNinja extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_lang",
title: "Preferred language",
summary: "",
valueIndex: 0,
entries: ["SUB", "All", "ES", "LAT"],
entryValues: ["SUB", "", "ES", "LAT"]),
key: "preferred_lang",
title: "Preferred language",
summary: "",
valueIndex: 0,
entries: ["SUB", "All", "ES", "LAT"],
entryValues: ["SUB", "", "ES", "LAT"],
),
ListPreference(
key: "preferred_server1",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: [
"Filemoon",
"DoodStream",
"StreamTape",
"Uqload",
"WolfStream",
"saidochesto.top",
"VidHide",
"StreamWish",
"Mp4Upload"
],
entryValues: [
"Filemoon",
"DoodStream",
"StreamTape",
"Uqload",
"WolfStream",
"saidochesto.top",
"VidHide",
"StreamWish",
"Mp4Upload"
]),
key: "preferred_server1",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: [
"Filemoon",
"DoodStream",
"StreamTape",
"Uqload",
"WolfStream",
"saidochesto.top",
"VidHide",
"StreamWish",
"Mp4Upload",
],
entryValues: [
"Filemoon",
"DoodStream",
"StreamTape",
"Uqload",
"WolfStream",
"saidochesto.top",
"VidHide",
"StreamWish",
"Mp4Upload",
],
),
];
}

View File

@@ -5,12 +5,13 @@ const _animeonlineninjaVersion = "0.0.3";
const _animeonlineninjaSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/es/animeonlineninja/animeonlineninja.dart";
Source _animeonlineninjaSource = Source(
name: "AnimeOnline.Ninja",
baseUrl: "https://ww3.animeonline.ninja",
lang: "es",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/es/animeonlineninja/icon.png",
sourceCodeUrl: _animeonlineninjaSourceCodeUrl,
version: _animeonlineninjaVersion,
itemType: ItemType.anime);
name: "AnimeOnline.Ninja",
baseUrl: "https://ww3.animeonline.ninja",
lang: "es",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/es/animeonlineninja/icon.png",
sourceCodeUrl: _animeonlineninjaSourceCodeUrl,
version: _animeonlineninjaVersion,
itemType: ItemType.anime,
);

View File

@@ -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
.select("h2")
.where((MElement e) =>
e.outerHtml.toLowerCase().contains("derniers épisodes ajoutés"))
.toList();
final seasonElements = (latest.first.parent.nextElementSibling as MElement)
.select("div")
.toList();
final latest =
document
.select("h2")
.where(
(MElement e) => e.outerHtml.toLowerCase().contains(
"derniers épisodes ajoutés",
),
)
.toList();
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,48 +61,73 @@ 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())))
.toList();
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) =>
types.isEmpty ||
types.any((p) => element.className.contains(p.value)))
.toList();
elements =
elements
.where(
(MElement element) =>
types.isEmpty ||
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) =>
language.isEmpty ||
language.any((p) => element.className.contains(p.value)))
.toList();
elements =
elements
.where(
(MElement element) =>
language.isEmpty ||
language.any((p) => element.className.contains(p.value)),
)
.toList();
} else if (filter.type == "GenreFilter") {
final included = (filter.state as List)
.where((e) => e.state == 1 ? true : false)
.toList();
final excluded = (filter.state as List)
.where((e) => e.state == 2 ? true : false)
.toList();
final included =
(filter.state as List)
.where((e) => e.state == 1 ? true : false)
.toList();
final excluded =
(filter.state as List)
.where((e) => e.state == 2 ? true : false)
.toList();
if (included.isNotEmpty) {
elements = elements
.where((MElement element) =>
included.every((p) => element.className.contains(p.value)))
.toList();
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)))
.toList();
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";
@@ -312,19 +357,21 @@ class AnimeSama extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Qualité préférée",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
key: "preferred_quality",
title: "Qualité préférée",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
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"]),
key: "voices_preference",
title: "Préférence des voix",
summary: "",
valueIndex: 0,
entries: ["Préférer VOSTFR", "Préférer 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) {

View File

@@ -5,12 +5,13 @@ const animesamaVersion = "0.0.4";
const animesamaCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesama/animesama.dart";
Source _animesama = Source(
name: "Anime-Sama",
baseUrl: "https://anime-sama.fr",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesama/icon.png",
sourceCodeUrl: animesamaCodeUrl,
version: animesamaVersion,
itemType: ItemType.anime);
name: "Anime-Sama",
baseUrl: "https://anime-sama.fr",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesama/icon.png",
sourceCodeUrl: animesamaCodeUrl,
version: animesamaVersion,
itemType: ItemType.anime,
);

View File

@@ -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";

View File

@@ -5,13 +5,14 @@ const _animesultraVersion = "0.0.75";
const _animesultraSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesultra/animesultra.dart";
Source _animesultraSource = Source(
name: "AnimesUltra",
baseUrl: "https://w2.animesultra.net",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesultra/icon.png",
sourceCodeUrl: _animesultraSourceCodeUrl,
version: _animesultraVersion,
itemType: ItemType.anime,
isFullData: false);
name: "AnimesUltra",
baseUrl: "https://w2.animesultra.net",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesultra/icon.png",
sourceCodeUrl: _animesultraSourceCodeUrl,
version: _animesultraVersion,
itemType: ItemType.anime,
isFullData: false,
);

View File

@@ -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)
@@ -214,15 +228,18 @@ class AniZone extends MProvider {
Future<List<MVideo>> streamHideExtractor(String url, String prefix) 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";
@@ -314,7 +331,7 @@ class AniZone extends MProvider {
CheckBoxFilter("Vampire", "32"),
CheckBoxFilter("Yaoi", "33"),
CheckBoxFilter("Yuri", "34"),
])
]),
];
}
@@ -322,19 +339,21 @@ class AniZone extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Qualité préférée",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
key: "preferred_quality",
title: "Qualité préférée",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
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"]),
key: "voices_preference",
title: "Préférence des voix",
summary: "",
valueIndex: 0,
entries: ["Préférer VOSTFR", "Préférer 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 [];
}

View File

@@ -5,12 +5,13 @@ const _aniZoneVersion = "0.0.2";
const _aniZoneSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/anizone.dart";
Source _aniZoneSource = Source(
name: "AniZone",
baseUrl: "https://v1.animesz.xyz",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/icon.png",
sourceCodeUrl: _aniZoneSourceCodeUrl,
version: _aniZoneVersion,
itemType: ItemType.anime);
name: "AniZone",
baseUrl: "https://v1.animesz.xyz",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/icon.png",
sourceCodeUrl: _aniZoneSourceCodeUrl,
version: _aniZoneVersion,
itemType: ItemType.anime,
);

View File

@@ -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
..url = playerUrl
..originalUrl = playerUrl
..quality = "FRAnime (Vido)");
videos.add(
video
..url = playerUrl
..originalUrl = playerUrl
..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";

View File

@@ -5,14 +5,15 @@ const _franimeVersion = "0.0.75";
const _franimeSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/franime/franime.dart";
Source _franimeSource = Source(
name: "FrAnime",
baseUrl: "https://franime.fr",
apiUrl: "https://api.franime.fr",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/franime/icon.png",
sourceCodeUrl: _franimeSourceCodeUrl,
version: _franimeVersion,
itemType: ItemType.anime,
isFullData: true);
name: "FrAnime",
baseUrl: "https://franime.fr",
apiUrl: "https://api.franime.fr",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/franime/icon.png",
sourceCodeUrl: _franimeSourceCodeUrl,
version: _franimeVersion,
itemType: ItemType.anime,
isFullData: true,
);

View File

@@ -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,22 +49,25 @@ 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)
.replaceAll(' vostfr', '')
.replaceAll(' Vostfr', '')
.replaceAll(' VF', '')
.replaceAll(' Vf', '')
.replaceAll(' vf', '')
.replaceAll(' (VF)', '')
.replaceAll(' (vf)', '')
.replaceAll(' (vf)', '')
.replaceAll(' (Vf)', '')
.replaceAll(' (Vostfr)', ''));
0,
)
.replaceAll(' vostfr', '')
.replaceAll(' Vostfr', '')
.replaceAll(' VF', '')
.replaceAll(' Vf', '')
.replaceAll(' vf', '')
.replaceAll(' (VF)', '')
.replaceAll(' (vf)', '')
.replaceAll(' (vf)', '')
.replaceAll(' (Vf)', '')
.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/"),
])
]),
];
}
@@ -292,54 +325,57 @@ class OtakuFr extends MProvider {
List<dynamic> getSourcePreferences() {
return [
EditTextPreference(
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://otakufr.cc",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://otakufr.cc"),
key: "overrideBaseUrl",
title: "Changer l'url de base",
summary: "",
value: "https://otakufr.cc",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
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"]),
key: "preferred_quality",
title: "Qualité préférée",
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"],
),
MultiSelectListPreference(
key: "hoster_selection_",
title: "Enable/Disable Hosts",
summary: "",
entries: [
"Streamwish",
"Doodstream",
"Sendvid",
"VidBom",
"Okru",
"Voe",
"Sibnet",
"Upstream"
],
entryValues: [
"Streamwish",
"Doodstream",
"Sendvid",
"VidBom",
"Okru",
"Voe",
"Sibnet",
"Upstream"
],
values: [
"Streamwish",
"Doodstream",
"Sendvid",
"Vidbm",
"Okru",
"Voe",
"Sibnet",
"Upstream"
]),
key: "hoster_selection_",
title: "Enable/Disable Hosts",
summary: "",
entries: [
"Streamwish",
"Doodstream",
"Sendvid",
"VidBom",
"Okru",
"Voe",
"Sibnet",
"Upstream",
],
entryValues: [
"Streamwish",
"Doodstream",
"Sendvid",
"VidBom",
"Okru",
"Voe",
"Sibnet",
"Upstream",
],
values: [
"Streamwish",
"Doodstream",
"Sendvid",
"Vidbm",
"Okru",
"Voe",
"Sibnet",
"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";

View File

@@ -5,13 +5,14 @@ const otakufrVersion = "0.0.95";
const otakufrCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/otakufr/otakufr.dart";
Source _otakufr = Source(
name: "OtakuFr",
baseUrl: "https://otakufr.cc",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/otakufr/icon.png",
sourceCodeUrl: otakufrCodeUrl,
version: otakufrVersion,
itemType: ItemType.anime,
isFullData: false);
name: "OtakuFr",
baseUrl: "https://otakufr.cc",
lang: "fr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/otakufr/icon.png",
sourceCodeUrl: otakufrCodeUrl,
version: otakufrVersion,
itemType: ItemType.anime,
isFullData: false,
);

View File

@@ -5,12 +5,13 @@ const _yomoviesVersion = "0.0.25";
const _yomoviesSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/hi/yomovies/yomovies.dart";
Source _yomoviesSource = Source(
name: "YoMovies",
baseUrl: "https://yomovies.boo",
lang: "hi",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/hi/yomovies/icon.png",
sourceCodeUrl: _yomoviesSourceCodeUrl,
version: _yomoviesVersion,
itemType: ItemType.anime);
name: "YoMovies",
baseUrl: "https://yomovies.boo",
lang: "hi",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/hi/yomovies/icon.png",
sourceCodeUrl: _yomoviesSourceCodeUrl,
version: _yomoviesVersion,
itemType: ItemType.anime,
);

View File

@@ -22,9 +22,9 @@ class YoMovies extends MProvider {
(await client.get(Uri.parse("$baseUrl/most-favorites/$pageNu"))).body;
final document = parseHtml(res);
return animeFromElement(
document.select("div.movies-list > div.ml-item"),
document.selectFirst("ul.pagination > li.active + li")?.getHref !=
null);
document.select("div.movies-list > div.ml-item"),
document.selectFirst("ul.pagination > li.active + li")?.getHref != null,
);
}
@override
@@ -53,9 +53,9 @@ class YoMovies extends MProvider {
final res = (await client.get(Uri.parse(url))).body;
final document = parseHtml(res);
return animeFromElement(
document.select("div.movies-list > div.ml-item"),
document.selectFirst("ul.pagination > li.active + li")?.getHref !=
null);
document.select("div.movies-list > div.ml-item"),
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");
@@ -118,20 +120,22 @@ class YoMovies extends MProvider {
List<dynamic> getSourcePreferences() {
return [
EditTextPreference(
key: "overrideBaseUrl",
title: "Override BaseUrl",
summary: "",
value: "https://yomovies.boo",
dialogTitle: "Override BaseUrl",
dialogMessage: "",
text: "https://yomovies.boo"),
key: "overrideBaseUrl",
title: "Override BaseUrl",
summary: "",
value: "https://yomovies.boo",
dialogTitle: "Override BaseUrl",
dialogMessage: "",
text: "https://yomovies.boo",
),
ListPreference(
key: "preferred_quality",
title: "Preferred quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"])
key: "preferred_quality",
title: "Preferred quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
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";
@@ -169,7 +177,7 @@ class YoMovies extends MProvider {
anime.name = element.selectFirst("div.qtip-title").text;
anime.imageUrl =
element.selectFirst("img[data-original]")?.attr("data-original") ??
"";
"";
anime.link = element.selectFirst("a[href]").getHref;
animeList.add(anime);
}
@@ -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"),

View File

@@ -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\":\"",
""),
'"');
substringAfter(
substringAfter(unpackJs(script.first), "sources:[", ""),
"file\":\"",
"",
),
'"',
);
if (videoUrl.isNotEmpty) {
return [toVideo(videoUrl, "HXFile - $quality")];
}

View File

@@ -5,12 +5,13 @@ const _nimegamiVersion = "0.0.55";
const _nimegamiCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/nimegami/nimegami.dart";
Source _nimegami = Source(
name: "NimeGami",
baseUrl: "https://nimegami.id",
lang: "id",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/nimegami/icon.png",
sourceCodeUrl: _nimegamiCodeUrl,
version: _nimegamiVersion,
itemType: ItemType.anime);
name: "NimeGami",
baseUrl: "https://nimegami.id",
lang: "id",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/nimegami/icon.png",
sourceCodeUrl: _nimegamiCodeUrl,
version: _nimegamiVersion,
itemType: ItemType.anime,
);

View File

@@ -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(
Uri.parse("${source.baseUrl}/wp-admin/admin-ajax.php"),
headers: {
"_": "_"
},
body: {
"action": "player_ajax",
"post": dataPost,
"nume": dataNume,
"type": dataType
}))
.body;
final ress =
(await client.post(
Uri.parse("${source.baseUrl}/wp-admin/admin-ajax.php"),
headers: {"_": "_"},
body: {
"action": "player_ajax",
"post": dataPost,
"nume": dataNume,
"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) {

View File

@@ -5,12 +5,13 @@ const _oploverzVersion = "0.0.5";
const _oploverzCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/oploverz/oploverz.dart";
Source _oploverz = Source(
name: "Oploverz",
baseUrl: "https://oploverz.gold",
lang: "id",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/oploverz/icon.png",
sourceCodeUrl: _oploverzCodeUrl,
version: _oploverzVersion,
itemType: ItemType.anime);
name: "Oploverz",
baseUrl: "https://oploverz.gold",
lang: "id",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/oploverz/icon.png",
sourceCodeUrl: _oploverzCodeUrl,
version: _oploverzVersion,
itemType: ItemType.anime,
);

View File

@@ -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(
Uri.parse("$baseUrl/wp-admin/admin-ajax.php"),
headers: {"_": "_"},
body: {"action": nonceAction}))
.body;
final resNonceAction =
(await client.post(
Uri.parse("$baseUrl/wp-admin/admin-ajax.php"),
headers: {"_": "_"},
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,27 +227,31 @@ 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);
}
List<dynamic> getSourcePreferences() {
return [
EditTextPreference(
key: "overrideBaseUrl",
title: "Override BaseUrl",
summary: "",
value: "https://otakudesu.cloud",
dialogTitle: "Override BaseUrl",
dialogMessage: "",
text: "https://otakudesu.cloud"),
key: "overrideBaseUrl",
title: "Override BaseUrl",
summary: "",
value: "https://otakudesu.cloud",
dialogTitle: "Override BaseUrl",
dialogMessage: "",
text: "https://otakudesu.cloud",
),
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"],
),
];
}
}

View File

@@ -5,12 +5,13 @@ const _otakudesuVersion = "0.0.56";
const _otakudesuCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/otakudesu/otakudesu.dart";
Source _otakudesu = Source(
name: "OtakuDesu",
baseUrl: "https://otakudesu.cloud",
lang: "id",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/otakudesu/icon.png",
sourceCodeUrl: _otakudesuCodeUrl,
version: _otakudesuVersion,
itemType: ItemType.anime);
name: "OtakuDesu",
baseUrl: "https://otakudesu.cloud",
lang: "id",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/otakudesu/icon.png",
sourceCodeUrl: _otakudesuCodeUrl,
version: _otakudesuVersion,
itemType: ItemType.anime,
);

View File

@@ -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.substring(
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";
@@ -320,12 +351,13 @@ class AnimeSaturn extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Qualità preferita",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p", "240p", "144p"],
entryValues: ["1080", "720", "480", "360", "240", "144"]),
key: "preferred_quality",
title: "Qualità preferita",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p", "240p", "144p"],
entryValues: ["1080", "720", "480", "360", "240", "144"],
),
];
}
@@ -359,4 +391,4 @@ class AnimeSaturn extends MProvider {
AnimeSaturn main(MSource source) {
return AnimeSaturn(source: source);
}
}

View File

@@ -5,12 +5,13 @@ const _animesaturnVersion = "0.0.5";
const _animesaturnCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/it/animesaturn/animesaturn.dart";
Source _animesaturn = Source(
name: "AnimeSaturn",
baseUrl: "https://www.animesaturn.cx",
lang: "it",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/it/animesaturn/icon.png",
sourceCodeUrl: _animesaturnCodeUrl,
version: _animesaturnVersion,
itemType: ItemType.anime);
name: "AnimeSaturn",
baseUrl: "https://www.animesaturn.cx",
lang: "it",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/it/animesaturn/icon.png",
sourceCodeUrl: _animesaturnCodeUrl,
version: _animesaturnVersion,
itemType: ItemType.anime,
);

View File

@@ -13,16 +13,17 @@ 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"
};
"Referer": baseUrl,
"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
.selectFirst("div.player-frame div#playerglobalapi ~ script")
.text;
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,11 +163,15 @@ class AnimesVision extends MProvider {
}
List<MElement> nextPageElements(MDocument document) {
final elements = document
.select("ul.pagination li.page-item")
.where((MElement e) =>
e.outerHtml.contains("") && !e.outerHtml.contains("disabled"))
.toList();
final elements =
document
.select("ul.pagination li.page-item")
.where(
(MElement e) =>
e.outerHtml.contains("") &&
!e.outerHtml.contains("disabled"),
)
.toList();
return elements;
}
@@ -173,10 +185,11 @@ class AnimesVision extends MProvider {
}
String getInfo(MElement element, String key) {
final divs = element
.select("div.item")
.where((MElement e) => e.outerHtml.contains(key))
.toList();
final divs =
element
.select("div.item")
.where((MElement e) => e.outerHtml.contains(key))
.toList();
String text = "";
if (divs.isNotEmpty) {
MElement div = divs[0];
@@ -230,12 +243,13 @@ class AnimesVision extends MProvider {
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Qualidade preferida",
summary: "",
valueIndex: 1,
entries: ["480p", "720p", "1080p", "4K"],
entryValues: ["1080", "720", "480", "4K"]),
key: "preferred_quality",
title: "Qualidade preferida",
summary: "",
valueIndex: 1,
entries: ["480p", "720p", "1080p", "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));

View File

@@ -5,12 +5,13 @@ const _animesvisionVersion = "0.0.15";
const _animesvisionCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/pt/animesvision/animesvision.dart";
Source _animesvision = Source(
name: "AnimesVision",
baseUrl: "https://animes.vision",
lang: "pt-br",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/pt/animesvision/icon.png",
sourceCodeUrl: _animesvisionCodeUrl,
version: _animesvisionVersion,
itemType: ItemType.anime);
name: "AnimesVision",
baseUrl: "https://animes.vision",
lang: "pt-br",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/pt/animesvision/icon.png",
sourceCodeUrl: _animesvisionCodeUrl,
version: _animesvisionVersion,
itemType: ItemType.anime,
);

View File

@@ -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");
@@ -122,13 +124,14 @@ class Filma24 extends MProvider {
List<dynamic> getSourcePreferences() {
return [
EditTextPreference(
key: "pref_domain_new",
title: "Domeni i përdorur aktualisht",
summary: "",
value: "https://www.filma24.band",
dialogTitle: "Domeni i përdorur aktualisht",
dialogMessage: "",
text: "https://www.filma24.band"),
key: "pref_domain_new",
title: "Domeni i përdorur aktualisht",
summary: "",
value: "https://www.filma24.band",
dialogTitle: "Domeni i përdorur aktualisht",
dialogMessage: "",
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";
@@ -231,11 +235,13 @@ class Filma24 extends MProvider {
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))).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,
);
}
}

View File

@@ -5,12 +5,13 @@ const _filma24Version = "0.0.45";
const _filma24CodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/sq/filma24/filma24.dart";
Source _filma24 = Source(
name: "Filma24",
baseUrl: "https://www.filma24.band",
lang: "sq",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/sq/filma24/icon.png",
sourceCodeUrl: _filma24CodeUrl,
version: _filma24Version,
itemType: ItemType.anime);
name: "Filma24",
baseUrl: "https://www.filma24.band",
lang: "sq",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/sq/filma24/icon.png",
sourceCodeUrl: _filma24CodeUrl,
version: _filma24Version,
itemType: ItemType.anime,
);

View File

@@ -13,25 +13,27 @@ class DiziWatch extends MProvider {
@override
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");
for (MElement result in results) {
MElement a = result.selectFirst("a");
MElement img = a.selectFirst("img");
MElement img = a.selectFirst("img");
MManga anime = new MManga();
anime.name = img.attr("alt");
anime.link = a.getHref;
anime.imageUrl = img.getSrc;
list.add(anime);
}
return MPages(list, false);
}
}
return MPages(list, false);
}
@override
Future<MPages> getPopular(int page) async {
return parseMainList(1);
@@ -58,156 +60,182 @@ class DiziWatch extends MProvider {
} else if (filter.type == "Genre") {
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 = [];
List<MManga> list = [];
for (MElement result in results) {
MElement a = result.select("a")[1];
MElement img = a.selectFirst("img");
MElement img = a.selectFirst("img");
MManga anime = new MManga();
anime.name = result.selectFirst("div.cat-title a").text;
anime.link = a.getHref;
anime.imageUrl = img.getSrc;
list.add(anime);
}
}
MElement paginateLinksDiv = dom.selectFirst("div.paginate-links");
int lastPage = int.parse(paginateLinksDiv.selectFirst("a.next").previousElementSibling.text ?? "1");
return MPages(list, lastPage > page);
int lastPage = int.parse(
paginateLinksDiv.selectFirst("a.next").previousElementSibling.text ?? "1",
);
return MPages(list, lastPage > page);
}
@override
Future<MManga> getDetail(String url) async {
MDocument dom = parseHtml((await client.get(Uri.parse(url))) .body);
MDocument dom = parseHtml((await client.get(Uri.parse(url))).body);
var anime = new MManga();
anime.name = dom.selectFirst("h1.title-border").text;
anime.link = url;
anime.imageUrl = dom.selectFirst("div.category_image img").getSrc;
anime.imageUrl = dom.selectFirst("div.category_image img").getSrc;
anime.description = dom.selectFirst("div#series-info").text;
List<String> genres = dom.selectFirst("span.dizi-tur").text.split(", ");
List<String> genres = dom.selectFirst("span.dizi-tur").text.split(", ");
genres.remove("Anime"); // not needed
anime.genre = genres;
anime.genre = genres;
List<MElement> results = dom.select("div.bolumust");
List<MChapter> chapters = [];
List<MChapter> chapters = [];
for (MElement result in results) {
MElement a = result.select("a")[1];
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);
}
}
anime.chapters = chapters.reversed.toList();
return anime;
return anime;
}
@override
Future<List<MVideo>> getVideoList(String url) async {
MDocument dom = parseHtml((await client.get(Uri.parse(url))) .body);
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 = [];
List<MVideo> videos = [];
for (var source in sources) {
MVideo video = new MVideo();
video.url = source["file"];
video.url = source["file"];
video.originalUrl = source["file"];
video.quality = source["label"];
video.headers = {"Referer": url};
videos.add(video);
videos.add(video);
}
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));
return videos;
videos.sort(
(MVideo a, MVideo b) =>
(b.quality.contains(quality) ? 1 : 0) -
(a.quality.contains(quality) ? 1 : 0),
);
return videos;
}
@override
List<dynamic> getFilterList() {
return [
HeaderFilter("Filtrele"),
SelectFilter("Sort", "Sırala", 0, [
SelectFilterOption("IMDb Puanına Göre", "meta_value"),
SelectFilterOption("Alfabetik", "name"),
SelectFilterOption("Eklenme Tarihine Göre", "ID")
]),
TextFilter("Year", "Yapım Yılı"),
SelectFilter("Genre", "Tür", 0, [
SelectFilterOption("Kategori Seçin", ""),
SelectFilterOption("Aksiyon", "aksiyon"),
SelectFilterOption("Arabalar", "araba"),
SelectFilterOption("Askeri", "askeri"),
SelectFilterOption("Bilim Kurgu", "bilim"),
SelectFilterOption("Büyü", "buyu"),
SelectFilterOption("Doğaüstü Güçler", "doga"),
SelectFilterOption("Dövüş Sanatları", "dovus"),
SelectFilterOption("Dram", "dram"),
SelectFilterOption("Ecchi", "ecchi"),
SelectFilterOption("Fantastik", "fantastik"),
SelectFilterOption("Gerilim", "gerilim"),
SelectFilterOption("Gizem", "gizem"),
SelectFilterOption("Harem", "harem"),
SelectFilterOption("Isekai", "isekai"),
SelectFilterOption("Komedi", "komedi"),
SelectFilterOption("Korku", "korku"),
SelectFilterOption("Macera", "macera"),
SelectFilterOption("Mecha", "mecha"),
SelectFilterOption("Müzik", "muzik"),
SelectFilterOption("Okul", "okul"),
SelectFilterOption("Oyun", "oyun"),
SelectFilterOption("Parodi", "parodi"),
SelectFilterOption("Polisiye", "polisiye"),
SelectFilterOption("Psikolojik", "psikolojik"),
SelectFilterOption("Romantizm", "romantizm"),
SelectFilterOption("Samuray", "samuray"),
SelectFilterOption("Seinen", "seinen"),
SelectFilterOption("Shoujo", "shoujo"),
SelectFilterOption("Shounen", "shounen"),
SelectFilterOption("Spor", "spor"),
SelectFilterOption("Suç", "suc"),
SelectFilterOption("Süper Güçler", "super"),
SelectFilterOption("Şeytanlar", "seytan"),
SelectFilterOption("Şizofreni", "sizofreni"),
SelectFilterOption("Tarihi", "tarihi"),
SelectFilterOption("Uzay", "uzay"),
SelectFilterOption("Vampir", "vampir"),
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("2", "2"),
SelectFilterOption("3", "3"),
SelectFilterOption("4", "4"),
SelectFilterOption("5", "5"),
SelectFilterOption("6", "6"),
SelectFilterOption("7", "7"),
SelectFilterOption("8", "8"),
SelectFilterOption("9", "9")
])
HeaderFilter("Filtrele"),
SelectFilter("Sort", "Sırala", 0, [
SelectFilterOption("IMDb Puanına Göre", "meta_value"),
SelectFilterOption("Alfabetik", "name"),
SelectFilterOption("Eklenme Tarihine Göre", "ID"),
]),
TextFilter("Year", "Yapım Yılı"),
SelectFilter("Genre", "Tür", 0, [
SelectFilterOption("Kategori Seçin", ""),
SelectFilterOption("Aksiyon", "aksiyon"),
SelectFilterOption("Arabalar", "araba"),
SelectFilterOption("Askeri", "askeri"),
SelectFilterOption("Bilim Kurgu", "bilim"),
SelectFilterOption("Büyü", "buyu"),
SelectFilterOption("Doğaüstü Güçler", "doga"),
SelectFilterOption("Dövüş Sanatları", "dovus"),
SelectFilterOption("Dram", "dram"),
SelectFilterOption("Ecchi", "ecchi"),
SelectFilterOption("Fantastik", "fantastik"),
SelectFilterOption("Gerilim", "gerilim"),
SelectFilterOption("Gizem", "gizem"),
SelectFilterOption("Harem", "harem"),
SelectFilterOption("Isekai", "isekai"),
SelectFilterOption("Komedi", "komedi"),
SelectFilterOption("Korku", "korku"),
SelectFilterOption("Macera", "macera"),
SelectFilterOption("Mecha", "mecha"),
SelectFilterOption("Müzik", "muzik"),
SelectFilterOption("Okul", "okul"),
SelectFilterOption("Oyun", "oyun"),
SelectFilterOption("Parodi", "parodi"),
SelectFilterOption("Polisiye", "polisiye"),
SelectFilterOption("Psikolojik", "psikolojik"),
SelectFilterOption("Romantizm", "romantizm"),
SelectFilterOption("Samuray", "samuray"),
SelectFilterOption("Seinen", "seinen"),
SelectFilterOption("Shoujo", "shoujo"),
SelectFilterOption("Shounen", "shounen"),
SelectFilterOption("Spor", "spor"),
SelectFilterOption("Suç", "suc"),
SelectFilterOption("Süper Güçler", "super"),
SelectFilterOption("Şeytanlar", "seytan"),
SelectFilterOption("Şizofreni", "sizofreni"),
SelectFilterOption("Tarihi", "tarihi"),
SelectFilterOption("Uzay", "uzay"),
SelectFilterOption("Vampir", "vampir"),
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("2", "2"),
SelectFilterOption("3", "3"),
SelectFilterOption("4", "4"),
SelectFilterOption("5", "5"),
SelectFilterOption("6", "6"),
SelectFilterOption("7", "7"),
SelectFilterOption("8", "8"),
SelectFilterOption("9", "9"),
]),
];
}
@override
List<dynamic> getSourcePreferences() {
return [
ListPreference(
key: "preferred_quality",
title: "Tercih edilen kalite",
summary: "",
valueIndex: 0,
entries: ["1080p", "480p"], // I only saw 1080p and 480p in diziWatch.
entryValues: ["1080", "480"])
];
key: "preferred_quality",
title: "Tercih edilen kalite",
summary: "",
valueIndex: 0,
entries: ["1080p", "480p"], // I only saw 1080p and 480p in diziWatch.
entryValues: ["1080", "480"],
),
];
}
}
DiziWatch main(MSource source) {
return DiziWatch(source:source);
return DiziWatch(source: source);
}

View File

@@ -5,12 +5,13 @@ const _diziwatchVersion = "0.0.1";
const _diziwatchSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/tr/diziwatch/diziwatch.dart";
Source _diziwatchSource = Source(
name: "diziWatch",
baseUrl: "https://diziwatch.net",
lang: "tr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/tr/diziwatch/icon.png",
sourceCodeUrl: _diziwatchSourceCodeUrl,
version: _diziwatchVersion,
itemType: ItemType.anime);
name: "diziWatch",
baseUrl: "https://diziwatch.net",
lang: "tr",
typeSource: "single",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/tr/diziwatch/icon.png",
sourceCodeUrl: _diziwatchSourceCodeUrl,
version: _diziwatchVersion,
itemType: ItemType.anime,
);

View File

@@ -12,5 +12,5 @@ List<Source> dartMangasourceList = [
...mmrcmsSourcesList,
mangahereSource,
...nepnepSourcesList,
...mangaboxSourcesList
...mangaboxSourcesList,
];

View File

@@ -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") ??
imageElement?.attr("data-lazy-src") ??
imageElement?.attr("srcset") ??
imageElement?.getSrc;
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") ??
"";
@@ -185,19 +194,22 @@ class Madara extends MProvider {
manga.status = parseStatus(status, statusList);
manga.genre =
document.select("div.genres-content a")?.map((e) => e.text).toList() ??
[];
[];
final baseUrl = "${source.baseUrl}/";
final headers = {"Referer": baseUrl, "X-Requested-With": "XMLHttpRequest"};
final oldXhrChaptersRequest = await client.post(
Uri.parse("${baseUrl}wp-admin/admin-ajax.php"),
headers: headers,
body: {"action": "manga_get_chapters", "manga": mangaId});
Uri.parse("${baseUrl}wp-admin/admin-ajax.php"),
headers: headers,
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"),
])
]),
];
}

View File

@@ -190,388 +190,392 @@ const madaraSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/madara.dart";
List<Source> get madaraSourcesList => _madaraSourcesList;
List<Source> _madaraSourcesList = [
//1st Kiss-Manga (unoriginal) (EN)
firstkissdashmangaSource,
//AQUA Scans (EN)
manhwaworldSource,
//Akuma no Tenshi (PT-BR)
akumanotenshiSource,
//Anikiga (TR)
anikigaSource,
//ArazNovel (TR)
araznovelSource,
//Arthur Scan (PT-BR)
arthurscanSource,
//AstralManga (FR)
astralmangaSource,
//Asura Scans.us (unoriginal) (EN)
asurascansusSource,
//BarManga (ES)
barmangaSource,
//BestManga (RU)
bestmangaSource,
//Chibi Manga (EN)
chibimangaSource,
//Clover Manga (TR)
clovermangaSource,
//Coco Rip (ES)
cocoripSource,
//Coffee Manga (EN)
coffeemangaSource,
//Doodmanga (TH)
doodmangaSource,
//Elite Manga (EN)
elitemangaSource,
//Emperor Scan (ES)
emperorscanSource,
//EvaScans (TR)
evascansSource,
//FR-Scan (FR)
frscanSource,
//FactManga (EN)
factmangaSource,
//FreeMangaTop (EN)
freemangatopSource,
//Glory Manga (TR)
glorymangaSource,
//Harimanga (EN)
harimangaSource,
//Immortal Updates (EN)
immortalupdatesSource,
//Império Scans (PT-BR)
imperioscansSource,
//Inmortal Scan (ES)
inmortalscanSource,
//IsekaiScanManga (unoriginal) (EN)
isekaiscanmangaSource,
//Jimanga (EN)
jimangaSource,
//KSGroupScans (EN)
ksgroupscansSource,
//Kakusei Project (PT-BR)
kakuseiprojectSource,
//Kami Sama Explorer (PT-BR)
kamisamaexplorerSource,
//Komik Chan (EN)
komikchanSource,
//LHTranslation (EN)
lhtranslationSource,
//Lady Estelar Scan (PT-BR)
ladyestelarscanSource,
//Leviatan Scans (EN)
leviatanscansSource,
//Luffy Manga (EN)
luffymangaSource,
//Maid Scan (PT-BR)
maidscanSource,
//Manga Diyari (TR)
mangadiyariSource,
//Manga Fenix (ES)
mangafenixSource,
//Manga Galaxy (EN)
mangagalaxySource,
//Manga Read (EN)
mangareadSource,
//Manga Tx.gg (unoriginal) (EN)
mangatxggSource,
//Manga Weebs (EN)
mangaweebsSource,
//Manga Şehri (TR)
mangasehriSource,
//Manga-TX (EN)
mangatxunoriginalSource,
//MangaClash (EN)
mangaclashSource,
//MangaFreak.online (EN)
mangafreakonlineSource,
//MangaGreat (EN)
mangagreatSource,
//MangaKomi (EN)
mangakomiSource,
//MangaRead.org (EN)
mangareadorgSource,
//MangaRolls (EN)
mangarollsSource,
//MangaTyrant (EN)
mangatyrantSource,
//MangaUS (EN)
mangausSource,
//Mangasushi (EN)
mangasushiSource,
//Mangá Nanquim (PT-BR)
mangananquimSource,
//Manhua ES (EN)
manhuaesSource,
//ManhuaUS (EN)
manhuausSource,
//ManhuaZone (EN)
manhuazoneSource,
//ManhwaClan (EN)
manhwaclanSource,
//Manhwafull (EN)
manhwafullSource,
//Mantraz Scan (ES)
mantrazscanSource,
//Momo no Hana Scan (PT-BR)
momonohanascanSource,
//MonarcaManga (ES)
monarcamangaSource,
//Moon Witch In Love (PT-BR)
moonwitchinloveSource,
//NekoPost.co (unoriginal) (TH)
nekopostcoSource,
//Niji Translations (AR)
nijitranslationsSource,
//Pantheon Scan (FR)
pantheonscanSource,
//Pojok Manga (ID)
pojokmangaSource,
//Projeto Scanlator (PT-BR)
projetoscanlatorSource,
//ROG Mangás (PT-BR)
mangasoverallSource,
//Ragnarok Scanlation (ES)
ragnarokscanlationSource,
//Rainbow Fairy Scan (PT-BR)
rainbowfairyscanSource,
//Random Scan (PT-BR)
randomscanSource,
//ReaderGen (FR)
readergenSource,
//RichtoScan (ES)
richtoscanSource,
//Rightdark Scan (ES)
rightdarkscanSource,
//Rio2 Manga (EN)
rio2mangaSource,
//Romantik Manga (TR)
romantikmangaSource,
//S2Manga (EN)
s2mangaSource,
//SamuraiScan (ES)
samuraiscanSource,
//ScamberTraslator (ES)
scambertraslatorSource,
//Scantrad-VF (FR)
scantradvfSource,
//Shadowtrad (FR)
shadowtradSource,
//Shiba Manga (EN)
shibamangaSource,
//Sinensis Scan (PT-BR)
sinensisSource,
//Sweet Time Scan (PT-BR)
sweettimescanSource,
//Tatakae Scan (PT-BR)
tatakaescanSource,
//Taurus Fansub (ES)
taurusfansubSource,
//The Beginning After The End (FR)
thebeginningaftertheendSource,
//Tortuga Ceviri (TR)
tortugaceviriSource,
//Wicked Witch Scan (PT-BR)
wickedwitchscanSource,
//Winter Scan (PT-BR)
winterscanSource,
//Wonderland Scan (PT-BR)
wonderlandscanSource,
//Yuri Verso (PT-BR)
yuriversoSource,
//فالكون مانجا (AR)
falconmangaSource,
//مانجا العاشق (AR)
manga3asqSource,
//Grabber Zone (ALL)
grabberzoneSource,
//Gatemanga (AR)
gatemangaSource,
//GMANGA (unoriginal) (AR)
gmangasiteSource,
//مانجا لينك (AR)
mangalinkSource,
//MangaLionz (AR)
mangalionzSource,
//Manga Rose (AR)
mangaroseSource,
//MangaSpark (AR)
mangasparkSource,
//Manga Starz (AR)
mangastarzSource,
//Manga Time (AR)
mangatimeSource,
//Olaoe (AR)
olaoeSource,
//Rocks Manga (AR)
rocksmangaSource,
//DragonTea (EN)
dragonteaSource,
//Global Bloging (EN)
globalblogingSource,
//Manga347 (EN)
manga347Source,
//MangaEffect (EN)
mangaeffectSource,
//Manga-fast.com (EN)
mangafastcomSource,
//Manga Leveling (EN)
mangalevelingSource,
//NeatManga (EN)
neatmangaSource,
//NvManga (EN)
nvmangaSource,
//PMScans (EN)
pmscansSource,
//ReadManhua (EN)
readmanhuaSource,
//StoneScape (EN)
stonescapeSource,
//TappyToon.Net (EN)
tappytoonnetSource,
//Zinmanga.net (EN)
zinmanganetSource,
//BokugenTranslation (ES)
bokugentranslationSource,
//DapRob (ES)
daprobSource,
//DeManhuas (ES)
demanhuasSource,
//HerenScan (ES)
herenscanSource,
//HouseMangas (ES)
housemangasSource,
//InfraFandub (ES)
infrafandubSource,
//Inmoral No Fansub (ES)
inmoralnofansubSource,
//JeazScans (ES)
jeazscansSource,
//Jobsibe (ES)
jobsibeSource,
//LegnMangas (ES)
legendsnofansubSource,
//Manga Crab (ES)
mangacrabSource,
//MMFenix (ES)
mangafenixSource,
//Mangas No Sekai (ES)
mangasnosekaiSource,
//Manhua Online (ES)
manhuaonlineSource,
//MHScans (ES)
mhscansSource,
//Visormonarca (ES)
monarcamangaSource,
//Noblesse Translations (ES)
noblessetranslationsSource,
//Prince Ediciones (ES)
princedicionesSource,
//SapphireScan (ES)
sapphirescanSource,
//Tres Daos Scan (ES)
tresdaosscanSource,
//Unitoon (ES)
unitoonSource,
//Manga-Scantrad (FR)
mangascantradSource,
//Mangas-Origines.fr (FR)
mangasoriginesfrSource,
//Raijin Scans (FR)
raijinscansSource,
//Reaper Scans (EN)
reaperscansSource,
//Soft Epsilon Scan (FR)
softepsilonscanSource,
//Hwago (ID)
hwagoSource,
//KlikManga (ID)
klikmangaSource,
//Komikuzan (ID)
komikuzanSource,
//MG Komik (ID)
mgkomikSource,
//Siimanga (ID)
siimangaSource,
//Yubikiri (ID)
yubikiriSource,
//MangaHoNa (PL)
mangahonaSource,
//Alone Scanlator (PT-BR)
alonescanlatorSource,
//Boruto Explorer (PT-BR)
borutoexplorerSource,
//Crystal Comics (PT-BR)
crystalcomicsSource,
//Fay Scans (PT-BR)
fayscansSource,
//Galinha Samurai Scan (PT-BR)
galinhasamuraiscanSource,
//Hikari Ga Nai (PT-BR)
hikariganaiSource,
//Sagrado Império da Britannia (PT-BR)
imperiodabritanniaSource,
//Neroxus (PT-BR)
imperioscansSource,
//Leitor de Mangá (PT-BR)
leitordemangaSource,
//L Scans (PT-BR)
lscansSource,
//Lunar Scan (PT-BR)
lunarscanSource,
//MiniTwo Scan (PT-BR)
minitwoscanSource,
//Nexo Scans (PT-BR)
nexoscansSource,
//Ninja Scan (PT-BR)
ninjascanSource,
//One Piece TECA (PT-BR)
onepiecetecaSource,
//Demon Sect (PT-BR)
prismascansSource,
//Sussy Scan (PT-BR)
sussyscanSource,
//Kings-Manga (TH)
kingsmangaSource,
//MangaDeemak (TH)
mangadeemakSource,
//ManhuaBug (TH)
manhuabugSource,
//ManhuaThai (TH)
manhuathaiSource,
//ManhwaBreakup (TH)
manhwabreakupSource,
//Atikrost (TR)
atikrostSource,
//DiamondFansub (TR)
diamondfansubSource,
//ManWe (TR)
evascansSource,
//Garcia Manga (TR)
garciamangaSource,
//GuncelManga (TR)
guncelmangaSource,
//LilyumFansub (TR)
lilyumfansubSource,
//MangaGezgini (TR)
mangagezginiSource,
//Manga Keyfi (TR)
mangakeyfiSource,
//Manga Oku (TR)
mangaokuSource,
//MangaWOW (TR)
mangawowSource,
//Merlin Scans (TR)
merlinscansSource,
//Rüya Manga (TR)
ruyamangaSource,
//Türkçe Manga Oku (TR)
turkcemangaokuSource,
//Webtoon Hatti (TR)
webtoonhattiSource,
]
.map((e) => e
..itemType = ItemType.manga
..sourceCodeUrl = madaraSourceCodeUrl
..version = madaraVersion)
.toList();
List<Source> _madaraSourcesList =
[
//1st Kiss-Manga (unoriginal) (EN)
firstkissdashmangaSource,
//AQUA Scans (EN)
manhwaworldSource,
//Akuma no Tenshi (PT-BR)
akumanotenshiSource,
//Anikiga (TR)
anikigaSource,
//ArazNovel (TR)
araznovelSource,
//Arthur Scan (PT-BR)
arthurscanSource,
//AstralManga (FR)
astralmangaSource,
//Asura Scans.us (unoriginal) (EN)
asurascansusSource,
//BarManga (ES)
barmangaSource,
//BestManga (RU)
bestmangaSource,
//Chibi Manga (EN)
chibimangaSource,
//Clover Manga (TR)
clovermangaSource,
//Coco Rip (ES)
cocoripSource,
//Coffee Manga (EN)
coffeemangaSource,
//Doodmanga (TH)
doodmangaSource,
//Elite Manga (EN)
elitemangaSource,
//Emperor Scan (ES)
emperorscanSource,
//EvaScans (TR)
evascansSource,
//FR-Scan (FR)
frscanSource,
//FactManga (EN)
factmangaSource,
//FreeMangaTop (EN)
freemangatopSource,
//Glory Manga (TR)
glorymangaSource,
//Harimanga (EN)
harimangaSource,
//Immortal Updates (EN)
immortalupdatesSource,
//Império Scans (PT-BR)
imperioscansSource,
//Inmortal Scan (ES)
inmortalscanSource,
//IsekaiScanManga (unoriginal) (EN)
isekaiscanmangaSource,
//Jimanga (EN)
jimangaSource,
//KSGroupScans (EN)
ksgroupscansSource,
//Kakusei Project (PT-BR)
kakuseiprojectSource,
//Kami Sama Explorer (PT-BR)
kamisamaexplorerSource,
//Komik Chan (EN)
komikchanSource,
//LHTranslation (EN)
lhtranslationSource,
//Lady Estelar Scan (PT-BR)
ladyestelarscanSource,
//Leviatan Scans (EN)
leviatanscansSource,
//Luffy Manga (EN)
luffymangaSource,
//Maid Scan (PT-BR)
maidscanSource,
//Manga Diyari (TR)
mangadiyariSource,
//Manga Fenix (ES)
mangafenixSource,
//Manga Galaxy (EN)
mangagalaxySource,
//Manga Read (EN)
mangareadSource,
//Manga Tx.gg (unoriginal) (EN)
mangatxggSource,
//Manga Weebs (EN)
mangaweebsSource,
//Manga Şehri (TR)
mangasehriSource,
//Manga-TX (EN)
mangatxunoriginalSource,
//MangaClash (EN)
mangaclashSource,
//MangaFreak.online (EN)
mangafreakonlineSource,
//MangaGreat (EN)
mangagreatSource,
//MangaKomi (EN)
mangakomiSource,
//MangaRead.org (EN)
mangareadorgSource,
//MangaRolls (EN)
mangarollsSource,
//MangaTyrant (EN)
mangatyrantSource,
//MangaUS (EN)
mangausSource,
//Mangasushi (EN)
mangasushiSource,
//Mangá Nanquim (PT-BR)
mangananquimSource,
//Manhua ES (EN)
manhuaesSource,
//ManhuaUS (EN)
manhuausSource,
//ManhuaZone (EN)
manhuazoneSource,
//ManhwaClan (EN)
manhwaclanSource,
//Manhwafull (EN)
manhwafullSource,
//Mantraz Scan (ES)
mantrazscanSource,
//Momo no Hana Scan (PT-BR)
momonohanascanSource,
//MonarcaManga (ES)
monarcamangaSource,
//Moon Witch In Love (PT-BR)
moonwitchinloveSource,
//NekoPost.co (unoriginal) (TH)
nekopostcoSource,
//Niji Translations (AR)
nijitranslationsSource,
//Pantheon Scan (FR)
pantheonscanSource,
//Pojok Manga (ID)
pojokmangaSource,
//Projeto Scanlator (PT-BR)
projetoscanlatorSource,
//ROG Mangás (PT-BR)
mangasoverallSource,
//Ragnarok Scanlation (ES)
ragnarokscanlationSource,
//Rainbow Fairy Scan (PT-BR)
rainbowfairyscanSource,
//Random Scan (PT-BR)
randomscanSource,
//ReaderGen (FR)
readergenSource,
//RichtoScan (ES)
richtoscanSource,
//Rightdark Scan (ES)
rightdarkscanSource,
//Rio2 Manga (EN)
rio2mangaSource,
//Romantik Manga (TR)
romantikmangaSource,
//S2Manga (EN)
s2mangaSource,
//SamuraiScan (ES)
samuraiscanSource,
//ScamberTraslator (ES)
scambertraslatorSource,
//Scantrad-VF (FR)
scantradvfSource,
//Shadowtrad (FR)
shadowtradSource,
//Shiba Manga (EN)
shibamangaSource,
//Sinensis Scan (PT-BR)
sinensisSource,
//Sweet Time Scan (PT-BR)
sweettimescanSource,
//Tatakae Scan (PT-BR)
tatakaescanSource,
//Taurus Fansub (ES)
taurusfansubSource,
//The Beginning After The End (FR)
thebeginningaftertheendSource,
//Tortuga Ceviri (TR)
tortugaceviriSource,
//Wicked Witch Scan (PT-BR)
wickedwitchscanSource,
//Winter Scan (PT-BR)
winterscanSource,
//Wonderland Scan (PT-BR)
wonderlandscanSource,
//Yuri Verso (PT-BR)
yuriversoSource,
//فالكون مانجا (AR)
falconmangaSource,
//مانجا العاشق (AR)
manga3asqSource,
//Grabber Zone (ALL)
grabberzoneSource,
//Gatemanga (AR)
gatemangaSource,
//GMANGA (unoriginal) (AR)
gmangasiteSource,
//مانجا لينك (AR)
mangalinkSource,
//MangaLionz (AR)
mangalionzSource,
//Manga Rose (AR)
mangaroseSource,
//MangaSpark (AR)
mangasparkSource,
//Manga Starz (AR)
mangastarzSource,
//Manga Time (AR)
mangatimeSource,
//Olaoe (AR)
olaoeSource,
//Rocks Manga (AR)
rocksmangaSource,
//DragonTea (EN)
dragonteaSource,
//Global Bloging (EN)
globalblogingSource,
//Manga347 (EN)
manga347Source,
//MangaEffect (EN)
mangaeffectSource,
//Manga-fast.com (EN)
mangafastcomSource,
//Manga Leveling (EN)
mangalevelingSource,
//NeatManga (EN)
neatmangaSource,
//NvManga (EN)
nvmangaSource,
//PMScans (EN)
pmscansSource,
//ReadManhua (EN)
readmanhuaSource,
//StoneScape (EN)
stonescapeSource,
//TappyToon.Net (EN)
tappytoonnetSource,
//Zinmanga.net (EN)
zinmanganetSource,
//BokugenTranslation (ES)
bokugentranslationSource,
//DapRob (ES)
daprobSource,
//DeManhuas (ES)
demanhuasSource,
//HerenScan (ES)
herenscanSource,
//HouseMangas (ES)
housemangasSource,
//InfraFandub (ES)
infrafandubSource,
//Inmoral No Fansub (ES)
inmoralnofansubSource,
//JeazScans (ES)
jeazscansSource,
//Jobsibe (ES)
jobsibeSource,
//LegnMangas (ES)
legendsnofansubSource,
//Manga Crab (ES)
mangacrabSource,
//MMFenix (ES)
mangafenixSource,
//Mangas No Sekai (ES)
mangasnosekaiSource,
//Manhua Online (ES)
manhuaonlineSource,
//MHScans (ES)
mhscansSource,
//Visormonarca (ES)
monarcamangaSource,
//Noblesse Translations (ES)
noblessetranslationsSource,
//Prince Ediciones (ES)
princedicionesSource,
//SapphireScan (ES)
sapphirescanSource,
//Tres Daos Scan (ES)
tresdaosscanSource,
//Unitoon (ES)
unitoonSource,
//Manga-Scantrad (FR)
mangascantradSource,
//Mangas-Origines.fr (FR)
mangasoriginesfrSource,
//Raijin Scans (FR)
raijinscansSource,
//Reaper Scans (EN)
reaperscansSource,
//Soft Epsilon Scan (FR)
softepsilonscanSource,
//Hwago (ID)
hwagoSource,
//KlikManga (ID)
klikmangaSource,
//Komikuzan (ID)
komikuzanSource,
//MG Komik (ID)
mgkomikSource,
//Siimanga (ID)
siimangaSource,
//Yubikiri (ID)
yubikiriSource,
//MangaHoNa (PL)
mangahonaSource,
//Alone Scanlator (PT-BR)
alonescanlatorSource,
//Boruto Explorer (PT-BR)
borutoexplorerSource,
//Crystal Comics (PT-BR)
crystalcomicsSource,
//Fay Scans (PT-BR)
fayscansSource,
//Galinha Samurai Scan (PT-BR)
galinhasamuraiscanSource,
//Hikari Ga Nai (PT-BR)
hikariganaiSource,
//Sagrado Império da Britannia (PT-BR)
imperiodabritanniaSource,
//Neroxus (PT-BR)
imperioscansSource,
//Leitor de Mangá (PT-BR)
leitordemangaSource,
//L Scans (PT-BR)
lscansSource,
//Lunar Scan (PT-BR)
lunarscanSource,
//MiniTwo Scan (PT-BR)
minitwoscanSource,
//Nexo Scans (PT-BR)
nexoscansSource,
//Ninja Scan (PT-BR)
ninjascanSource,
//One Piece TECA (PT-BR)
onepiecetecaSource,
//Demon Sect (PT-BR)
prismascansSource,
//Sussy Scan (PT-BR)
sussyscanSource,
//Kings-Manga (TH)
kingsmangaSource,
//MangaDeemak (TH)
mangadeemakSource,
//ManhuaBug (TH)
manhuabugSource,
//ManhuaThai (TH)
manhuathaiSource,
//ManhwaBreakup (TH)
manhwabreakupSource,
//Atikrost (TR)
atikrostSource,
//DiamondFansub (TR)
diamondfansubSource,
//ManWe (TR)
evascansSource,
//Garcia Manga (TR)
garciamangaSource,
//GuncelManga (TR)
guncelmangaSource,
//LilyumFansub (TR)
lilyumfansubSource,
//MangaGezgini (TR)
mangagezginiSource,
//Manga Keyfi (TR)
mangakeyfiSource,
//Manga Oku (TR)
mangaokuSource,
//MangaWOW (TR)
mangawowSource,
//Merlin Scans (TR)
merlinscansSource,
//Rüya Manga (TR)
ruyamangaSource,
//Türkçe Manga Oku (TR)
turkcemangaokuSource,
//Webtoon Hatti (TR)
webtoonhattiSource,
]
.map(
(e) =>
e
..itemType = ItemType.manga
..sourceCodeUrl = madaraSourceCodeUrl
..version = madaraVersion,
)
.toList();

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get akumanotenshiSource => _akumanotenshiSource;
Source _akumanotenshiSource = Source(
name: "Akuma no Tenshi",
baseUrl: "https://akumanotenshi.com",
lang: "pt-BR",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/akumanotenshi/icon.png",
dateFormat:"dd/MM/yyyy",
dateFormatLocale:"pt-br",
);
Source get akumanotenshiSource => _akumanotenshiSource;
Source _akumanotenshiSource = Source(
name: "Akuma no Tenshi",
baseUrl: "https://akumanotenshi.com",
lang: "pt-BR",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/akumanotenshi/icon.png",
dateFormat: "dd/MM/yyyy",
dateFormatLocale: "pt-br",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get alonescanlatorSource => _alonescanlatorSource;
Source _alonescanlatorSource = Source(
name: "Alone Scanlator",
baseUrl: "https://alonescanlator.com.br",
lang: "pt-br",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/alonescanlator/icon.png",
dateFormat:"dd/MM/yyyy",
dateFormatLocale:"pt-br"
);
name: "Alone Scanlator",
baseUrl: "https://alonescanlator.com.br",
lang: "pt-br",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/alonescanlator/icon.png",
dateFormat: "dd/MM/yyyy",
dateFormatLocale: "pt-br",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get anikigaSource => _anikigaSource;
Source _anikigaSource = Source(
name: "Anikiga",
baseUrl: "https://anikiga.com",
lang: "tr",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/anikiga/icon.png",
dateFormat:"d MMMMM yyyy",
dateFormatLocale:"tr",
);
Source get anikigaSource => _anikigaSource;
Source _anikigaSource = Source(
name: "Anikiga",
baseUrl: "https://anikiga.com",
lang: "tr",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/anikiga/icon.png",
dateFormat: "d MMMMM yyyy",
dateFormatLocale: "tr",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get araznovelSource => _araznovelSource;
Source _araznovelSource = Source(
name: "ArazNovel",
baseUrl: "https://www.araznovel.com",
lang: "tr",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/araznovel/icon.png",
dateFormat:"d MMMM yyyy",
dateFormatLocale:"en",
);
Source get araznovelSource => _araznovelSource;
Source _araznovelSource = Source(
name: "ArazNovel",
baseUrl: "https://www.araznovel.com",
lang: "tr",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/araznovel/icon.png",
dateFormat: "d MMMM yyyy",
dateFormatLocale: "en",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get arthurscanSource => _arthurscanSource;
Source _arthurscanSource = Source(
name: "Arthur Scan",
baseUrl: "https://arthurscan.xyz",
lang: "pt-BR",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/arthurscan/icon.png",
dateFormat:"MMMMM dd, yyyy",
dateFormatLocale:"pt-br",
);
Source get arthurscanSource => _arthurscanSource;
Source _arthurscanSource = Source(
name: "Arthur Scan",
baseUrl: "https://arthurscan.xyz",
lang: "pt-BR",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/arthurscan/icon.png",
dateFormat: "MMMMM dd, yyyy",
dateFormatLocale: "pt-br",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get astralmangaSource => _astralmangaSource;
Source _astralmangaSource = Source(
name: "AstralManga",
baseUrl: "https://astral-manga.fr",
lang: "fr",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/astralmanga/icon.png",
dateFormat:"dd/mm/yyyy",
dateFormatLocale:"fr",
);
Source get astralmangaSource => _astralmangaSource;
Source _astralmangaSource = Source(
name: "AstralManga",
baseUrl: "https://astral-manga.fr",
lang: "fr",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/astralmanga/icon.png",
dateFormat: "dd/mm/yyyy",
dateFormatLocale: "fr",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get asurascansusSource => _asurascansusSource;
Source _asurascansusSource = Source(
name: "Asura Scans.us (unoriginal)",
baseUrl: "https://asurascans.us",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/asurascansus/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get asurascansusSource => _asurascansusSource;
Source _asurascansusSource = Source(
name: "Asura Scans.us (unoriginal)",
baseUrl: "https://asurascans.us",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/asurascansus/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get atikrostSource => _atikrostSource;
Source _atikrostSource = Source(
name: "Atikrost",
baseUrl: "https://www.atikrost.com",
lang: "tr",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/atikrost/icon.png",
dateFormat:"d MMMM yyyy",
dateFormatLocale:"tr"
);
name: "Atikrost",
baseUrl: "https://www.atikrost.com",
lang: "tr",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/atikrost/icon.png",
dateFormat: "d MMMM yyyy",
dateFormatLocale: "tr",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get barmangaSource => _barmangaSource;
Source _barmangaSource = Source(
name: "BarManga",
baseUrl: "https://barmanga.com",
lang: "es",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/barmanga/icon.png",
dateFormat:"MM/dd/yyyy",
dateFormatLocale:"es",
);
Source get barmangaSource => _barmangaSource;
Source _barmangaSource = Source(
name: "BarManga",
baseUrl: "https://barmanga.com",
lang: "es",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/barmanga/icon.png",
dateFormat: "MM/dd/yyyy",
dateFormatLocale: "es",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get bestmangaSource => _bestmangaSource;
Source _bestmangaSource = Source(
name: "BestManga",
baseUrl: "https://bestmanga.club",
lang: "ru",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/bestmanga/icon.png",
dateFormat:"dd.MM.yyyy",
dateFormatLocale:"ru",
);
Source get bestmangaSource => _bestmangaSource;
Source _bestmangaSource = Source(
name: "BestManga",
baseUrl: "https://bestmanga.club",
lang: "ru",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/bestmanga/icon.png",
dateFormat: "dd.MM.yyyy",
dateFormatLocale: "ru",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get bokugentranslationSource => _bokugentranslationSource;
Source _bokugentranslationSource = Source(
name: "BokugenTranslation",
baseUrl: "https://bokugents.com",
lang: "es",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/bokugentranslation/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"es"
);
name: "BokugenTranslation",
baseUrl: "https://bokugents.com",
lang: "es",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/bokugentranslation/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "es",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get borutoexplorerSource => _borutoexplorerSource;
Source _borutoexplorerSource = Source(
name: "Boruto Explorer",
baseUrl: "https://leitor.borutoexplorer.com.br",
lang: "pt-br",
isNsfw:false,
typeSource: "madara",
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"
);
name: "Boruto Explorer",
baseUrl: "https://leitor.borutoexplorer.com.br",
lang: "pt-br",
isNsfw: false,
typeSource: "madara",
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",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get chibimangaSource => _chibimangaSource;
Source _chibimangaSource = Source(
name: "Chibi Manga",
baseUrl: "https://www.cmreader.info",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/chibimanga/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get chibimangaSource => _chibimangaSource;
Source _chibimangaSource = Source(
name: "Chibi Manga",
baseUrl: "https://www.cmreader.info",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/chibimanga/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get clovermangaSource => _clovermangaSource;
Source _clovermangaSource = Source(
name: "Clover Manga",
baseUrl: "https://clover-manga.com",
lang: "tr",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/clovermanga/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"tr",
);
Source get clovermangaSource => _clovermangaSource;
Source _clovermangaSource = Source(
name: "Clover Manga",
baseUrl: "https://clover-manga.com",
lang: "tr",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/clovermanga/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "tr",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get cocoripSource => _cocoripSource;
Source _cocoripSource = Source(
name: "Coco Rip",
baseUrl: "https://cocorip.net",
lang: "es",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/cocorip/icon.png",
dateFormat:"dd/MM/yyyy",
dateFormatLocale:"es",
);
Source get cocoripSource => _cocoripSource;
Source _cocoripSource = Source(
name: "Coco Rip",
baseUrl: "https://cocorip.net",
lang: "es",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/cocorip/icon.png",
dateFormat: "dd/MM/yyyy",
dateFormatLocale: "es",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get coffeemangaSource => _coffeemangaSource;
Source _coffeemangaSource = Source(
name: "Coffee Manga",
baseUrl: "https://coffeemanga.io",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/coffeemanga/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get coffeemangaSource => _coffeemangaSource;
Source _coffeemangaSource = Source(
name: "Coffee Manga",
baseUrl: "https://coffeemanga.io",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/coffeemanga/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get crystalcomicsSource => _crystalcomicsSource;
Source _crystalcomicsSource = Source(
name: "Crystal Comics",
baseUrl: "https://crystalcomics.com",
lang: "pt-br",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/crystalcomics/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"pt-br"
);
name: "Crystal Comics",
baseUrl: "https://crystalcomics.com",
lang: "pt-br",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/crystalcomics/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "pt-br",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get daprobSource => _daprobSource;
Source _daprobSource = Source(
name: "DapRob",
baseUrl: "https://daprob.com",
lang: "es",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/daprob/icon.png",
dateFormat:"dd/MM/yyy",
dateFormatLocale:"en"
);
name: "DapRob",
baseUrl: "https://daprob.com",
lang: "es",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/daprob/icon.png",
dateFormat: "dd/MM/yyy",
dateFormatLocale: "en",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get demanhuasSource => _demanhuasSource;
Source _demanhuasSource = Source(
name: "DeManhuas",
baseUrl: "https://demanhuas.com",
lang: "es",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/demanhuas/icon.png",
dateFormat:"MMMM d, yyyy",
dateFormatLocale:"es"
);
name: "DeManhuas",
baseUrl: "https://demanhuas.com",
lang: "es",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/demanhuas/icon.png",
dateFormat: "MMMM d, yyyy",
dateFormatLocale: "es",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get diamondfansubSource => _diamondfansubSource;
Source _diamondfansubSource = Source(
name: "DiamondFansub",
baseUrl: "https://diamondfansub.com",
lang: "tr",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/diamondfansub/icon.png",
dateFormat:"d MMMM",
dateFormatLocale:"tr-tr"
);
name: "DiamondFansub",
baseUrl: "https://diamondfansub.com",
lang: "tr",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/diamondfansub/icon.png",
dateFormat: "d MMMM",
dateFormatLocale: "tr-tr",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get doodmangaSource => _doodmangaSource;
Source _doodmangaSource = Source(
name: "Doodmanga",
baseUrl: "https://www.doodmanga.com",
lang: "th",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/doodmanga/icon.png",
dateFormat:"dd MMMMM yyyy",
dateFormatLocale:"th",
);
Source get doodmangaSource => _doodmangaSource;
Source _doodmangaSource = Source(
name: "Doodmanga",
baseUrl: "https://www.doodmanga.com",
lang: "th",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/doodmanga/icon.png",
dateFormat: "dd MMMMM yyyy",
dateFormatLocale: "th",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get dragonteaSource => _dragonteaSource;
Source _dragonteaSource = Source(
name: "DragonTea",
baseUrl: "https://dragontea.ink",
lang: "en",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/dragontea/icon.png",
dateFormat:"MM/dd/yyyy",
dateFormatLocale:"en_us"
);
name: "DragonTea",
baseUrl: "https://dragontea.ink",
lang: "en",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/dragontea/icon.png",
dateFormat: "MM/dd/yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get elitemangaSource => _elitemangaSource;
Source _elitemangaSource = Source(
name: "Elite Manga",
baseUrl: "https://www.elitemanga.org",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/elitemanga/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get elitemangaSource => _elitemangaSource;
Source _elitemangaSource = Source(
name: "Elite Manga",
baseUrl: "https://www.elitemanga.org",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/elitemanga/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get emperorscanSource => _emperorscanSource;
Source _emperorscanSource = Source(
name: "Emperor Scan",
baseUrl: "https://emperorscan.com",
lang: "es",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/emperorscan/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"es",
);
Source get emperorscanSource => _emperorscanSource;
Source _emperorscanSource = Source(
name: "Emperor Scan",
baseUrl: "https://emperorscan.com",
lang: "es",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/emperorscan/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "es",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get evascansSource => _evascansSource;
Source _evascansSource = Source(
name: "EvaScans",
baseUrl: "https://evascans.com",
lang: "tr",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/evascans/icon.png",
dateFormat:"MMM d, yyy",
dateFormatLocale:"tr",
);
Source get evascansSource => _evascansSource;
Source _evascansSource = Source(
name: "EvaScans",
baseUrl: "https://evascans.com",
lang: "tr",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/evascans/icon.png",
dateFormat: "MMM d, yyy",
dateFormatLocale: "tr",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get factmangaSource => _factmangaSource;
Source _factmangaSource = Source(
name: "FactManga",
baseUrl: "https://factmanga.com",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/factmanga/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get factmangaSource => _factmangaSource;
Source _factmangaSource = Source(
name: "FactManga",
baseUrl: "https://factmanga.com",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/factmanga/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -1,14 +1,13 @@
import '../../../../../../model/source.dart';
Source get falconmangaSource => _falconmangaSource;
Source _falconmangaSource = Source(
name: "فالكون مانجا",
baseUrl: "https://falconmanga.com",
lang: "ar",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/falconmanga/icon.png",
);
Source get falconmangaSource => _falconmangaSource;
Source _falconmangaSource = Source(
name: "فالكون مانجا",
baseUrl: "https://falconmanga.com",
lang: "ar",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/falconmanga/icon.png",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get fayscansSource => _fayscansSource;
Source _fayscansSource = Source(
name: "Fay Scans",
baseUrl: "https://fayscans.net",
lang: "pt-br",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/fayscans/icon.png",
dateFormat:"dd/MM/yyyy",
dateFormatLocale:"pt-br"
);
name: "Fay Scans",
baseUrl: "https://fayscans.net",
lang: "pt-br",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/fayscans/icon.png",
dateFormat: "dd/MM/yyyy",
dateFormatLocale: "pt-br",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get firstkissdashmangaSource => _firstkissdashmangaSource;
Source _firstkissdashmangaSource = Source(
name: "1st Kiss-Manga (unoriginal)",
baseUrl: "https://1stkiss-manga.com",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/firstkissdashmanga/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get firstkissdashmangaSource => _firstkissdashmangaSource;
Source _firstkissdashmangaSource = Source(
name: "1st Kiss-Manga (unoriginal)",
baseUrl: "https://1stkiss-manga.com",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/firstkissdashmanga/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get freemangatopSource => _freemangatopSource;
Source _freemangatopSource = Source(
name: "FreeMangaTop",
baseUrl: "https://freemangatop.com",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/freemangatop/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get freemangatopSource => _freemangatopSource;
Source _freemangatopSource = Source(
name: "FreeMangaTop",
baseUrl: "https://freemangatop.com",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/freemangatop/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get frscanSource => _frscanSource;
Source _frscanSource = Source(
name: "FR-Scan",
baseUrl: "https://fr-scan.com",
lang: "fr",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/frscan/icon.png",
dateFormat:"MMMM d, yyyy",
dateFormatLocale:"fr",
);
Source get frscanSource => _frscanSource;
Source _frscanSource = Source(
name: "FR-Scan",
baseUrl: "https://fr-scan.com",
lang: "fr",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/frscan/icon.png",
dateFormat: "MMMM d, yyyy",
dateFormatLocale: "fr",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get galinhasamuraiscanSource => _galinhasamuraiscanSource;
Source _galinhasamuraiscanSource = Source(
name: "Galinha Samurai Scan",
baseUrl: "https://galinhasamurai.com",
lang: "pt-br",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/galinhasamuraiscan/icon.png",
dateFormat:"dd/MM/yyyy",
dateFormatLocale:"pt-br"
);
name: "Galinha Samurai Scan",
baseUrl: "https://galinhasamurai.com",
lang: "pt-br",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/galinhasamuraiscan/icon.png",
dateFormat: "dd/MM/yyyy",
dateFormatLocale: "pt-br",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get garciamangaSource => _garciamangaSource;
Source _garciamangaSource = Source(
name: "Garcia Manga",
baseUrl: "https://garciamanga.com",
lang: "tr",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/garciamanga/icon.png",
dateFormat:"MMMM d, yyyy",
dateFormatLocale:"tr"
);
name: "Garcia Manga",
baseUrl: "https://garciamanga.com",
lang: "tr",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/garciamanga/icon.png",
dateFormat: "MMMM d, yyyy",
dateFormatLocale: "tr",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get gatemangaSource => _gatemangaSource;
Source _gatemangaSource = Source(
name: "Gatemanga",
baseUrl: "https://gatemanga.com",
lang: "ar",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/gatemanga/icon.png",
dateFormat:"d MMMM، yyyy",
dateFormatLocale:"ar"
);
name: "Gatemanga",
baseUrl: "https://gatemanga.com",
lang: "ar",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/gatemanga/icon.png",
dateFormat: "d MMMM، yyyy",
dateFormatLocale: "ar",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get globalblogingSource => _globalblogingSource;
Source _globalblogingSource = Source(
name: "Global Bloging",
baseUrl: "https://globalbloging.com",
lang: "en",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/globalbloging/icon.png",
dateFormat:"dd MMMM yyyy",
dateFormatLocale:"en_us"
);
name: "Global Bloging",
baseUrl: "https://globalbloging.com",
lang: "en",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/globalbloging/icon.png",
dateFormat: "dd MMMM yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get glorymangaSource => _glorymangaSource;
Source _glorymangaSource = Source(
name: "Glory Manga",
baseUrl: "https://glorymanga.com",
lang: "tr",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/glorymanga/icon.png",
dateFormat:"dd/MM/yyy",
dateFormatLocale:"tr",
);
Source get glorymangaSource => _glorymangaSource;
Source _glorymangaSource = Source(
name: "Glory Manga",
baseUrl: "https://glorymanga.com",
lang: "tr",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/glorymanga/icon.png",
dateFormat: "dd/MM/yyy",
dateFormatLocale: "tr",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get gmangasiteSource => _gmangasiteSource;
Source _gmangasiteSource = Source(
name: "GMANGA (unoriginal)",
baseUrl: "https://gmanga.site",
lang: "ar",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/gmangasite/icon.png",
dateFormat:"MMMM dd، yyyy",
dateFormatLocale:"ar"
);
name: "GMANGA (unoriginal)",
baseUrl: "https://gmanga.site",
lang: "ar",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/gmangasite/icon.png",
dateFormat: "MMMM dd، yyyy",
dateFormatLocale: "ar",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get grabberzoneSource => _grabberzoneSource;
Source _grabberzoneSource = Source(
name: "Grabber Zone",
baseUrl: "https://grabber.zone",
lang: "all",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/grabberzone/icon.png",
dateFormat:"dd.MM.yyyy",
dateFormatLocale:"en"
);
name: "Grabber Zone",
baseUrl: "https://grabber.zone",
lang: "all",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/grabberzone/icon.png",
dateFormat: "dd.MM.yyyy",
dateFormatLocale: "en",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get guncelmangaSource => _guncelmangaSource;
Source _guncelmangaSource = Source(
name: "GuncelManga",
baseUrl: "https://guncelmanga.net",
lang: "tr",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/guncelmanga/icon.png",
dateFormat:"d MMMM yyyy",
dateFormatLocale:"tr"
);
name: "GuncelManga",
baseUrl: "https://guncelmanga.net",
lang: "tr",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/guncelmanga/icon.png",
dateFormat: "d MMMM yyyy",
dateFormatLocale: "tr",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get harimangaSource => _harimangaSource;
Source _harimangaSource = Source(
name: "Harimanga",
baseUrl: "https://harimanga.com",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/harimanga/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get harimangaSource => _harimangaSource;
Source _harimangaSource = Source(
name: "Harimanga",
baseUrl: "https://harimanga.com",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/harimanga/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get herenscanSource => _herenscanSource;
Source _herenscanSource = Source(
name: "HerenScan",
baseUrl: "https://herenscan.com",
lang: "es",
isNsfw:false,
typeSource: "madara",
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"
);
name: "HerenScan",
baseUrl: "https://herenscan.com",
lang: "es",
isNsfw: false,
typeSource: "madara",
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",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get hikariganaiSource => _hikariganaiSource;
Source _hikariganaiSource = Source(
name: "Hikari Ga Nai",
baseUrl: "https://hikariganai.xyz",
lang: "pt-br",
isNsfw:false,
typeSource: "madara",
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"
);
name: "Hikari Ga Nai",
baseUrl: "https://hikariganai.xyz",
lang: "pt-br",
isNsfw: false,
typeSource: "madara",
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",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get housemangasSource => _housemangasSource;
Source _housemangasSource = Source(
name: "HouseMangas",
baseUrl: "https://housemangas.com",
lang: "es",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/housemangas/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"es"
);
name: "HouseMangas",
baseUrl: "https://housemangas.com",
lang: "es",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/housemangas/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "es",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get hwagoSource => _hwagoSource;
Source _hwagoSource = Source(
name: "Hwago",
baseUrl: "https://hwago.org",
lang: "id",
isNsfw:false,
typeSource: "madara",
iconUrl: "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/hwago/icon.png",
dateFormat:"d MMMM yyyy",
dateFormatLocale:"en"
);
name: "Hwago",
baseUrl: "https://hwago.org",
lang: "id",
isNsfw: false,
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/dart/manga/multisrc/madara/src/hwago/icon.png",
dateFormat: "d MMMM yyyy",
dateFormatLocale: "en",
);

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get immortalupdatesSource => _immortalupdatesSource;
Source _immortalupdatesSource = Source(
name: "Immortal Updates",
baseUrl: "https://immortalupdates.com",
lang: "en",
typeSource: "madara",
iconUrl:"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/immortalupdates/icon.png",
dateFormat:"MMMM dd, yyyy",
dateFormatLocale:"en_us",
);
Source get immortalupdatesSource => _immortalupdatesSource;
Source _immortalupdatesSource = Source(
name: "Immortal Updates",
baseUrl: "https://immortalupdates.com",
lang: "en",
typeSource: "madara",
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/immortalupdates/icon.png",
dateFormat: "MMMM dd, yyyy",
dateFormatLocale: "en_us",
);

View File

@@ -2,12 +2,13 @@ import '../../../../../../model/source.dart';
Source get imperiodabritanniaSource => _imperiodabritanniaSource;
Source _imperiodabritanniaSource = Source(
name: "Sagrado Império da Britannia",
baseUrl: "https://imperiodabritannia.com",
lang: "pt-br",
isNsfw:false,
typeSource: "madara",
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"
);
name: "Sagrado Império da Britannia",
baseUrl: "https://imperiodabritannia.com",
lang: "pt-br",
isNsfw: false,
typeSource: "madara",
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",
);

Some files were not shown because too many files have changed in this diff Show More