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(
res =
(await client.post(
Uri.parse(
"$baseUrl?do=search&subaction=search&story=$cleanQuery"),
headers: headers))
.body;
"$baseUrl?do=search&subaction=search&story=$cleanQuery",
),
headers: headers,
)).body;
} else {
res = (await client.post(
res =
(await client.post(
Uri.parse(
"$baseUrl?do=search&subaction=search&search_start=$page&full_search=0&result_from=11&story=$cleanQuery"),
headers: headers))
.body;
"$baseUrl?do=search&subaction=search&search_start=$page&full_search=0&result_from=11&story=$cleanQuery",
),
headers: headers,
)).body;
}
} else {
String url = "";
@@ -76,8 +83,9 @@ class DataLifeEngine extends MProvider {
@override
Future<MManga> getDetail(String url) async {
String res =
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
.body;
(await client.get(
Uri.parse("$baseUrl${getUrlWithoutDomain(url)}"),
)).body;
MManga anime = MManga();
final description = xpath(res, '//span[@itemprop="description"]/text()');
anime.description = description.isNotEmpty ? description.first : "";
@@ -96,9 +104,12 @@ class DataLifeEngine extends MProvider {
}
} else {
final doc = parseHtml(res);
final elements = doc
final elements =
doc
.select(".hostsblock div:has(a)")
.where((MElement e) => e.outerHtml.contains("loadVideo('https://"))
.where(
(MElement e) => e.outerHtml.contains("loadVideo('https://"),
)
.toList();
if (elements.isNotEmpty) {
for (var element in elements) {
@@ -110,8 +121,12 @@ class DataLifeEngine extends MProvider {
.replaceAll("vf", " VF");
ep.url = element
.select("a")
.map((MElement e) => substringBefore(
substringAfter(e.attr('onclick'), "loadVideo('"), "')"))
.map(
(MElement e) => substringBefore(
substringAfter(e.attr('onclick'), "loadVideo('"),
"')",
),
)
.toList()
.join(",")
.replaceAll("/vd.php?u=", "");
@@ -124,8 +139,12 @@ class DataLifeEngine extends MProvider {
ep.url = doc
.select("a")
.where((MElement e) => e.outerHtml.contains("loadVideo('https://"))
.map((MElement e) => substringBefore(
substringAfter(e.attr('onclick'), "loadVideo('"), "')"))
.map(
(MElement e) => substringBefore(
substringAfter(e.attr('onclick'), "loadVideo('"),
"')",
),
)
.toList()
.join(",")
.replaceAll("/vd.php?u=", "");
@@ -145,8 +164,12 @@ class DataLifeEngine extends MProvider {
List<MVideo> a = [];
if (sUrl.contains("dood") || sUrl.contains("d000")) {
a = await doodExtractor(sUrl, "DoodStream");
} else if (["streamhide", "guccihide", "streamvid", "dhtpre"]
.any((a) => sUrl.contains(a))) {
} else if ([
"streamhide",
"guccihide",
"streamvid",
"dhtpre",
].any((a) => sUrl.contains(a))) {
a = await streamHideExtractor(sUrl);
} else if (sUrl.contains("uqload")) {
a = await uqloadExtractor(sUrl);
@@ -192,14 +215,17 @@ class DataLifeEngine extends MProvider {
final res = (await client.get(Uri.parse(url))).body;
final masterUrl = substringBefore(
substringAfter(
substringAfter(
substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\""),
'"');
substringAfter(substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\"",
),
'"',
);
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
List<MVideo> videos = [];
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -226,12 +252,16 @@ class DataLifeEngine extends MProvider {
if (js.isEmpty) {
return [];
}
final masterUrl =
substringBefore(substringAfter(unpackJs(js.first), "{file:\""), "\"}");
final masterUrl = substringBefore(
substringAfter(unpackJs(js.first), "{file:\""),
"\"}",
);
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
List<MVideo> videos = [];
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -259,8 +289,10 @@ class DataLifeEngine extends MProvider {
return [];
}
final videoUrl =
substringBefore(substringAfter(js.first, "sources: [\""), '"');
final videoUrl = substringBefore(
substringAfter(js.first, "sources: [\""),
'"',
);
MVideo video = MVideo();
video
..url = videoUrl
@@ -271,22 +303,23 @@ class DataLifeEngine extends MProvider {
}
Future<List<MVideo>> vidmolyExtractor(String url) async {
final headers = {
'Referer': 'https://vidmoly.to',
};
final headers = {'Referer': 'https://vidmoly.to'};
List<MVideo> videos = [];
final playListUrlResponse = (await client.get(Uri.parse(url))).body;
final playlistUrl =
RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ??
"";
if (playlistUrl.isEmpty) return [];
final masterPlaylistRes =
await client.get(Uri.parse(playlistUrl), headers: headers);
final masterPlaylistRes = await client.get(
Uri.parse(playlistUrl),
headers: headers,
);
if (masterPlaylistRes.statusCode == 200) {
for (var it
in substringAfter(masterPlaylistRes.body, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes.body,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -321,7 +354,8 @@ class DataLifeEngine extends MProvider {
value: "https://wiflix-hd.vip",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://wiflix-hd.vip"),
text: "https://wiflix-hd.vip",
),
if (source.name == "French Anime")
EditTextPreference(
key: "overrideBaseUrl",
@@ -330,7 +364,8 @@ class DataLifeEngine extends MProvider {
value: "https://french-anime.com",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://french-anime.com"),
text: "https://french-anime.com",
),
];
}
@@ -360,20 +395,20 @@ class DataLifeEngine extends MProvider {
SelectFilterOption("Seinen", "/genre/seinen/"),
SelectFilterOption("Horreur", "/genre/horreur/"),
SelectFilterOption("Tranche de vie", "/genre/tranchedevie/"),
SelectFilterOption("Psychologique", "/genre/psychologique/")
SelectFilterOption("Psychologique", "/genre/psychologique/"),
]),
if (source.name == "French Anime")
SelectFilter("GenresFilter", "Genres", 0, [
SelectFilterOption("<Sélectionner>", ""),
SelectFilterOption("Animes VF", "/animes-vf/"),
SelectFilterOption("Animes VOSTFR", "/animes-vostfr/"),
SelectFilterOption("Films VF et VOSTFR", "/films-vf-vostfr/")
SelectFilterOption("Films VF et VOSTFR", "/films-vf-vostfr/"),
]),
if (source.name == "Wiflix")
SelectFilter("CategoriesFilter", "Catégories", 0, [
SelectFilterOption("<Sélectionner>", ""),
SelectFilterOption("Séries", "/serie-en-streaming/"),
SelectFilterOption("Films", "/film-en-streaming/")
SelectFilterOption("Films", "/film-en-streaming/"),
]),
if (source.name == "Wiflix")
SelectFilter("GenresFilter", "Genres", 0, [
@@ -381,17 +416,25 @@ class DataLifeEngine extends MProvider {
SelectFilterOption("Action", "/film-en-streaming/action/"),
SelectFilterOption("Animation", "/film-en-streaming/animation/"),
SelectFilterOption(
"Arts Martiaux", "/film-en-streaming/arts-martiaux/"),
"Arts Martiaux",
"/film-en-streaming/arts-martiaux/",
),
SelectFilterOption("Aventure", "/film-en-streaming/aventure/"),
SelectFilterOption("Biopic", "/film-en-streaming/biopic/"),
SelectFilterOption("Comédie", "/film-en-streaming/comedie/"),
SelectFilterOption(
"Comédie Dramatique", "/film-en-streaming/comedie-dramatique/"),
"Comédie Dramatique",
"/film-en-streaming/comedie-dramatique/",
),
SelectFilterOption(
"Épouvante Horreur", "/film-en-streaming/horreur/"),
"Épouvante Horreur",
"/film-en-streaming/horreur/",
),
SelectFilterOption("Drame", "/film-en-streaming/drame/"),
SelectFilterOption(
"Documentaire", "/film-en-streaming/documentaire/"),
"Documentaire",
"/film-en-streaming/documentaire/",
),
SelectFilterOption("Espionnage", "/film-en-streaming/espionnage/"),
SelectFilterOption("Famille", "/film-en-streaming/famille/"),
SelectFilterOption("Fantastique", "/film-en-streaming/fantastique/"),
@@ -401,7 +444,9 @@ class DataLifeEngine extends MProvider {
SelectFilterOption("Policier", "/film-en-streaming/policier/"),
SelectFilterOption("Romance", "/film-en-streaming/romance/"),
SelectFilterOption(
"Science-Fiction", "/film-en-streaming/science-fiction/"),
"Science-Fiction",
"/film-en-streaming/science-fiction/",
),
SelectFilterOption("Spectacles", "/film-en-streaming/spectacles/"),
SelectFilterOption("Thriller", "/film-en-streaming/thriller/"),
SelectFilterOption("Western", "/film-en-streaming/western/"),

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)
List<Source> _datalifeengineSourcesList =
[
//French Anime (FR)
frenchanimeSource,
//Wiflix (FR)
//Wiflix (FR)
wiflixSource,
]
.map((e) => e
]
.map(
(e) =>
e
..sourceCodeUrl = _datalifeengineSourceCodeUrl
..version = _datalifeengineVersion)
..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(
final resServer =
(await client.get(
Uri.parse("$serverUrl/ajax/embed-4/getSources?id=$id"),
headers: {"X-Requested-With": "XMLHttpRequest"}))
.body;
headers: {"X-Requested-With": "XMLHttpRequest"},
)).body;
final encrypted = getMapValue(resServer, "encrypted");
String videoResJson = "";
@@ -192,10 +205,12 @@ class DopeFlix extends MProvider {
index += item.last;
}
videoResJson = decryptAESCryptoJS(ciphertext, password);
masterUrl = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
masterUrl =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['file'];
type = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
type =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['type'];
} else {
masterUrl =
@@ -207,7 +222,8 @@ class DopeFlix extends MProvider {
.first)['type'];
}
final tracks = (json.decode(resServer)['tracks'] as List)
final tracks =
(json.decode(resServer)['tracks'] as List)
.where((e) => e['kind'] == 'captions' ? true : false)
.toList();
List<MTrack> subtitles = [];
@@ -227,8 +243,10 @@ class DopeFlix extends MProvider {
final masterPlaylistRes =
(await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -264,13 +282,15 @@ class DopeFlix extends MProvider {
}
Future<List<List<int>>> generateIndexPairs() async {
final res = (await client.get(Uri.parse(
"https://rabbitstream.net/js/player/prod/e4-player.min.js")))
.body;
final res =
(await client.get(
Uri.parse("https://rabbitstream.net/js/player/prod/e4-player.min.js"),
)).body;
String script = substringBefore(substringAfter(res, "const "), "()");
script = script.substring(0, script.lastIndexOf(','));
final list = script
final list =
script
.split(",")
.map((String e) {
String value = substringAfter(e, "=");
@@ -283,9 +303,10 @@ class DopeFlix extends MProvider {
.toList()
.skip(1)
.toList();
return chunked(list, 2)
.map((List<int> list) => list.reversed.toList())
.toList();
return chunked(
list,
2,
).map((List<int> list) => list.reversed.toList()).toList();
}
List<List<int>> chunked(List<int> list, int size) {
@@ -316,7 +337,9 @@ class DopeFlix extends MProvider {
animeList.add(anime);
}
final pages = xpath(
res, '//ul[contains(@class,"pagination")]/li/a[@title="Next"]/@title');
res,
'//ul[contains(@class,"pagination")]/li/a[@title="Next"]/@title',
);
return MPages(animeList, pages.isNotEmpty);
}
@@ -326,13 +349,13 @@ class DopeFlix extends MProvider {
SelectFilter("TypeFilter", "Type", 0, [
SelectFilterOption("All", "all"),
SelectFilterOption("Movies", "movies"),
SelectFilterOption("TV Shows", "tv")
SelectFilterOption("TV Shows", "tv"),
]),
SelectFilter("QualityFilter", "Quality", 0, [
SelectFilterOption("All", "all"),
SelectFilterOption("HD", "HD"),
SelectFilterOption("SD", "SD"),
SelectFilterOption("CAM", "CAM")
SelectFilterOption("CAM", "CAM"),
]),
SelectFilter("ReleaseYearFilter", "Released at", 0, [
SelectFilterOption("All", "all"),
@@ -343,7 +366,7 @@ class DopeFlix extends MProvider {
SelectFilterOption("2020", "2020"),
SelectFilterOption("2019", "2019"),
SelectFilterOption("2018", "2018"),
SelectFilterOption("Older", "older-2018")
SelectFilterOption("Older", "older-2018"),
]),
SeparatorFilter(),
GroupFilter("GenresFilter", "Genre", [
@@ -374,7 +397,7 @@ class DopeFlix extends MProvider {
CheckBoxFilter("TV Movie", "8"),
CheckBoxFilter("War", "17"),
CheckBoxFilter("War & Politics", "28"),
CheckBoxFilter("Western", "6")
CheckBoxFilter("Western", "6"),
]),
GroupFilter("CountriesFilter", "Countries", [
CheckBoxFilter("Argentina", "11"),
@@ -412,7 +435,7 @@ class DopeFlix extends MProvider {
CheckBoxFilter("Taiwan", "119"),
CheckBoxFilter("Thailand", "57"),
CheckBoxFilter("United Kingdom", "180"),
CheckBoxFilter("United States of America", "129")
CheckBoxFilter("United States of America", "129"),
]),
];
}
@@ -427,7 +450,8 @@ class DopeFlix extends MProvider {
summary: "",
valueIndex: 0,
entries: ["dopebox.to", "dopebox.se"],
entryValues: ["https://dopebox.to", "https://dopebox.se"]),
entryValues: ["https://dopebox.to", "https://dopebox.se"],
),
if (source.name == "SFlix")
ListPreference(
key: "preferred_domain",
@@ -435,14 +459,16 @@ class DopeFlix extends MProvider {
summary: "",
valueIndex: 0,
entries: ["sflix.to", "sflix.se"],
entryValues: ["https://sflix.to", "https://sflix.se"]),
entryValues: ["https://sflix.to", "https://sflix.se"],
),
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080p", "720p", "480p", "360p"]),
entryValues: ["1080p", "720p", "480p", "360p"],
),
ListPreference(
key: "preferred_subLang",
title: "Preferred sub language",
@@ -459,7 +485,7 @@ class DopeFlix extends MProvider {
"Portuguese",
"Romanian",
"Russian",
"Spanish"
"Spanish",
],
entryValues: [
"Arabic",
@@ -472,22 +498,25 @@ class DopeFlix extends MProvider {
"Portuguese",
"Romanian",
"Russian",
"Spanish"
]),
"Spanish",
],
),
ListPreference(
key: "preferred_latest_page",
title: "Preferred latest page",
summary: "",
valueIndex: 0,
entries: ["Movies", "TV Shows"],
entryValues: ["Latest Movies", "Latest TV Shows"]),
entryValues: ["Latest Movies", "Latest TV Shows"],
),
ListPreference(
key: "preferred_popular_page",
title: "Preferred popular page",
summary: "",
valueIndex: 0,
entries: ["Movies", "TV Shows"],
entryValues: ["movie", "tv-show"]),
entryValues: ["movie", "tv-show"],
),
];
}

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)
List<Source> _dopeflixSourcesList =
[
//DopeBox (EN)
dopeboxSource,
//SFlix (EN)
//SFlix (EN)
sflixSource,
]
.map((e) => e
]
.map(
(e) =>
e
..sourceCodeUrl = _dopeflixSourceCodeUrl
..version = _dopeflixVersion)
..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)
List<Source> _zorothemeSourcesList =
[
//AniWatch.to (EN)
aniwatchSource,
//Kaido.to (EN)
//Kaido.to (EN)
kaidoSource,
]
.map((e) => e
]
.map(
(e) =>
e
..sourceCodeUrl = _zorothemeSourceCodeUrl
..version = _zorothemeVersion)
..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(
final res =
(await client.get(
Uri.parse(
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/servers?episodeId=$id"),
headers: {"referer": "${source.baseUrl}/$url"}))
.body;
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/servers?episodeId=$id",
),
headers: {"referer": "${source.baseUrl}/$url"},
)).body;
final html = json.decode(res)["html"];
final serverElements = parseHtml(html).select("div.server-item");
@@ -194,11 +206,13 @@ class ZoroTheme extends MProvider {
final id = serverElement.attr("data-id");
final subDub = serverElement.attr("data-type");
final resE = (await client.get(
final resE =
(await client.get(
Uri.parse(
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/sources?id=$id"),
headers: {"referer": "${source.baseUrl}/$url"}))
.body;
"${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/sources?id=$id",
),
headers: {"referer": "${source.baseUrl}/$url"},
)).body;
String epUrl = substringBefore(substringAfter(resE, "\"link\":\""), "\"");
List<MVideo> a = [];
if (hosterSelection.contains(name) && typeSelection.contains(subDub)) {
@@ -222,30 +236,36 @@ class ZoroTheme extends MProvider {
Future<List<MVideo>> rapidCloudExtractor(String url, String name) async {
final serverUrl = ['https://megacloud.tv', 'https://rapid-cloud.co'];
final serverType = url.startsWith('https://megacloud.tv') || url.startsWith('https://megacloud.club') ? 0 : 1;
final serverType =
url.startsWith('https://megacloud.tv') ||
url.startsWith('https://megacloud.club')
? 0
: 1;
final sourceUrl = [
'/embed-2/ajax/e-1/getSources?id=',
'/ajax/embed-6-v2/getSources?id='
'/ajax/embed-6-v2/getSources?id=',
];
final sourceSpliter = ['/e-1/', '/embed-6-v2/'];
final id = url.split(sourceSpliter[serverType]).last.split('?').first;
String resServer = "";
if (serverType == 0) {
resServer =
await evaluateJavascriptViaWebview("https://megacloud.tv/about", {
"X-Requested-With": "org.lineageos.jelly"
}, [
resServer = await evaluateJavascriptViaWebview(
"https://megacloud.tv/about",
{"X-Requested-With": "org.lineageos.jelly"},
[
cryptoStr,
decodePng,
getSrcStr,
"getSources('$id').then(s => window.flutter_inappwebview.callHandler('setResponse', JSON.stringify(s)))"
]);
"getSources('$id').then(s => window.flutter_inappwebview.callHandler('setResponse', JSON.stringify(s)))",
],
);
} else {
resServer = (await client.get(
resServer =
(await client.get(
Uri.parse('${serverUrl[serverType]}${sourceUrl[serverType]}$id'),
headers: {"X-Requested-With": "XMLHttpRequest"}))
.body;
headers: {"X-Requested-With": "XMLHttpRequest"},
)).body;
}
final encrypted = getMapValue(resServer, "encrypted");
@@ -268,16 +288,19 @@ class ZoroTheme extends MProvider {
videoResJson = decryptAESCryptoJS(ciphertext, password);
} else {
videoResJson = json.encode(
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>));
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>),
);
}
String masterUrl =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['file'];
String type = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
String type =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['type'];
final tracks = (json.decode(resServer)['tracks'] as List)
final tracks =
(json.decode(resServer)['tracks'] as List)
.where((e) => e['kind'] == 'captions' ? true : false)
.toList();
List<MTrack> subtitles = [];
@@ -295,8 +318,10 @@ class ZoroTheme extends MProvider {
if (type == "hls") {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -330,19 +355,22 @@ class ZoroTheme extends MProvider {
Future<List<List<int>>> generateIndexPairs(int serverType) async {
final jsPlayerUrl = [
"https://megacloud.tv/js/player/a/prod/e1-player.min.js",
"https://rapid-cloud.co/js/player/prod/e6-player-v2.min.js"
"https://rapid-cloud.co/js/player/prod/e6-player-v2.min.js",
];
final scriptText =
(await client.get(Uri.parse(jsPlayerUrl[serverType]))).body;
final switchCode = scriptText.substring(
scriptText.lastIndexOf('switch'), scriptText.indexOf('=partKey'));
scriptText.lastIndexOf('switch'),
scriptText.indexOf('=partKey'),
);
List<int> indexes = [];
for (var variableMatch
in RegExp(r'=(\w+)').allMatches(switchCode).toList()) {
final regex = RegExp(
',${(variableMatch as RegExpMatch).group(1)}=((?:0x)?([0-9a-fA-F]+))');
',${(variableMatch as RegExpMatch).group(1)}=((?:0x)?([0-9a-fA-F]+))',
);
Match? match = regex.firstMatch(scriptText);
if (match != null) {
@@ -374,13 +402,19 @@ class ZoroTheme extends MProvider {
List<MManga> animeList = [];
final urls = xpath(
res, '//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@href');
res,
'//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@href',
);
final names = xpath(res,
'//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@data-jname');
final names = xpath(
res,
'//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@data-jname',
);
final images = xpath(
res, '//*[@class^="flw-item"]/div[@class="film-poster"]/img/@data-src');
res,
'//*[@class^="flw-item"]/div[@class="film-poster"]/img/@data-src',
);
for (var i = 0; i < names.length; i++) {
MManga anime = MManga();
anime.name = names[i];
@@ -388,8 +422,11 @@ class ZoroTheme extends MProvider {
anime.link = urls[i];
animeList.add(anime);
}
final nextPage =
xpath(res, '//li[@class="page-item"]/a[@title="Next"]/@href', "");
final nextPage = xpath(
res,
'//li[@class="page-item"]/a[@title="Next"]/@href',
"",
);
return MPages(animeList, !nextPage.isEmpty);
}
@@ -403,7 +440,7 @@ class ZoroTheme extends MProvider {
List<SelectFilterOption> yearList = [
for (var i = 1917; i < 2024; i++)
SelectFilterOption(i.toString(), i.toString()),
SelectFilterOption("All", "")
SelectFilterOption("All", ""),
];
@override
@@ -416,13 +453,13 @@ class ZoroTheme extends MProvider {
SelectFilterOption("OVA", "3"),
SelectFilterOption("ONA", "4"),
SelectFilterOption("Special", "5"),
SelectFilterOption("Music", "6")
SelectFilterOption("Music", "6"),
]),
SelectFilter("StatusFilter", "Status", 0, [
SelectFilterOption("All", ""),
SelectFilterOption("Finished Airing", "1"),
SelectFilterOption("Currently Airing", "2"),
SelectFilterOption("Not yet aired", "3")
SelectFilterOption("Not yet aired", "3"),
]),
SelectFilter("RatedFilter", "Rated", 0, [
SelectFilterOption("All", ""),
@@ -431,7 +468,7 @@ class ZoroTheme extends MProvider {
SelectFilterOption("PG-13", "3"),
SelectFilterOption("R", "4"),
SelectFilterOption("R+", "5"),
SelectFilterOption("Rx", "6")
SelectFilterOption("Rx", "6"),
]),
SelectFilter("ScoreFilter", "Score", 0, [
SelectFilterOption("All", ""),
@@ -444,20 +481,20 @@ class ZoroTheme extends MProvider {
SelectFilterOption("(7) Good", "7"),
SelectFilterOption("(8) Very Good", "8"),
SelectFilterOption("(9) Great", "9"),
SelectFilterOption("(10) Masterpiece", "10")
SelectFilterOption("(10) Masterpiece", "10"),
]),
SelectFilter("SeasonFilter", "Season", 0, [
SelectFilterOption("All", ""),
SelectFilterOption("Spring", "1"),
SelectFilterOption("Summer", "2"),
SelectFilterOption("Fall", "3"),
SelectFilterOption("Winter", "4")
SelectFilterOption("Winter", "4"),
]),
SelectFilter("LanguageFilter", "Language", 0, [
SelectFilterOption("All", ""),
SelectFilterOption("SUB", "1"),
SelectFilterOption("DUB", "2"),
SelectFilterOption("SUB & DUB", "3")
SelectFilterOption("SUB & DUB", "3"),
]),
SelectFilter("SortFilter", "Sort by", 0, [
SelectFilterOption("All", ""),
@@ -467,14 +504,18 @@ class ZoroTheme extends MProvider {
SelectFilterOption("Score", "score"),
SelectFilterOption("Name A-Z", "name_az"),
SelectFilterOption("Released Date", "released_date"),
SelectFilterOption("Most Watched", "most_watched")
SelectFilterOption("Most Watched", "most_watched"),
]),
SelectFilter(
"StartYearFilter", "Start year", 0, yearList.reversed.toList()),
"StartYearFilter",
"Start year",
0,
yearList.reversed.toList(),
),
SelectFilter("StartMonthFilter", "Start month", 0, [
SelectFilterOption("All", ""),
for (var i = 1; i < 13; i++)
SelectFilterOption(i.toString(), i.toString())
SelectFilterOption(i.toString(), i.toString()),
]),
SelectFilter("StartDayFilter", "Start day", 0, [
SelectFilterOption("All", ""),
@@ -485,12 +526,12 @@ class ZoroTheme extends MProvider {
SelectFilter("EndmonthFilter", "End month", 0, [
SelectFilterOption("All", ""),
for (var i = 1; i < 32; i++)
SelectFilterOption(i.toString(), i.toString())
SelectFilterOption(i.toString(), i.toString()),
]),
SelectFilter("EndDayFilter", "End day", 0, [
SelectFilterOption("All", ""),
for (var i = 1; i < 32; i++)
SelectFilterOption(i.toString(), i.toString())
SelectFilterOption(i.toString(), i.toString()),
]),
GroupFilter("GenreFilter", "Genre", [
CheckBoxFilter("Action", "1"),
@@ -535,7 +576,7 @@ class ZoroTheme extends MProvider {
CheckBoxFilter("Thriller", "41"),
CheckBoxFilter("Vampire", "32"),
CheckBoxFilter("Yaoi", "33"),
CheckBoxFilter("Yuri", "34")
CheckBoxFilter("Yuri", "34"),
]),
];
}
@@ -549,7 +590,8 @@ class ZoroTheme extends MProvider {
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
entryValues: ["1080", "720", "480", "360"],
),
if (source.name == "HiAnime")
ListPreference(
key: "preferred_server1",
@@ -557,7 +599,8 @@ class ZoroTheme extends MProvider {
summary: "",
valueIndex: 0,
entries: ["HD-1", "HD-2", "StreamTape"],
entryValues: ["HD-1", "HD-2", "StreamTape"]),
entryValues: ["HD-1", "HD-2", "StreamTape"],
),
if (source.name != "HiAnime")
ListPreference(
key: "preferred_server1",
@@ -565,14 +608,16 @@ class ZoroTheme extends MProvider {
summary: "",
valueIndex: 0,
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"]),
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"],
),
ListPreference(
key: "preferred_type1",
title: "Preferred Type",
summary: "",
valueIndex: 0,
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"]),
entryValues: ["sub", "dub"],
),
if (source.name != "HiAnime")
MultiSelectListPreference(
key: "hoster_selection1",
@@ -580,7 +625,8 @@ class ZoroTheme extends MProvider {
summary: "",
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"],
values: ["Vidstreaming", "VidCloud", "StreamTape"]),
values: ["Vidstreaming", "VidCloud", "StreamTape"],
),
if (source.name == "HiAnime")
MultiSelectListPreference(
key: "hoster_selection1",
@@ -588,14 +634,16 @@ class ZoroTheme extends MProvider {
summary: "",
entries: ["HD-1", "HD-2", "StreamTape"],
entryValues: ["HD-1", "HD-2", "StreamTape"],
values: ["HD-1", "HD-2", "StreamTape"]),
values: ["HD-1", "HD-2", "StreamTape"],
),
MultiSelectListPreference(
key: "type_selection_new",
title: "Enable/Disable Types",
summary: "",
entries: ["Sub", "Dub", "Raw"],
entryValues: ["sub", "dub"],
values: ["sub", "dub", "raw"]),
values: ["sub", "dub", "raw"],
),
];
}

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(
'//span[@class="leading-6"]/a[contains(@class,"border-opacity-30")]/text()',
);
final seasonsJson =
json.decode(
substringBeforeLast(
substringBefore(
substringAfter(res, "var season_list = "), "var season_label ="),
";")) as List<Map<String, dynamic>>;
substringAfter(res, "var season_list = "),
"var season_label =",
),
";",
),
)
as List<Map<String, dynamic>>;
bool isSingleSeason = seasonsJson.length == 1;
List<MChapter>? episodesList = [];
for (var i = 0; i < seasonsJson.length; i++) {
final seasonJson = seasonsJson[i];
final seasonName = isSingleSeason ? "" : "Season ${i + 1}";
final episodesJson =
(seasonJson["episodes"]["all"] as List<Map<String, dynamic>>)
.reversed
(seasonJson["episodes"]["all"] as List<Map<String, dynamic>>).reversed
.toList();
for (var j = 0; j < episodesJson.length; j++) {
final episodeJson = episodesJson[j];
@@ -148,16 +163,24 @@ class AnimeWorldIndia extends MProvider {
Future<List<MVideo>> getVideoList(String url) async {
final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body;
var resJson = substringBefore(
substringAfterLast(res, "\"players\":"), ",\"noplayer\":");
var streams = (json.decode(resJson) as List<Map<String, dynamic>>)
.where((e) =>
substringAfterLast(res, "\"players\":"),
",\"noplayer\":",
);
var streams =
(json.decode(resJson) as List<Map<String, dynamic>>)
.where(
(e) =>
(e["type"] == "stream" ? true : false) &&
(e["url"] as String).isNotEmpty)
(e["url"] as String).isNotEmpty,
)
.toList()
.where((e) => language(source.lang).isEmpty ||
.where(
(e) =>
language(source.lang).isEmpty ||
language(source.lang) == e["language"]
? true
: false)
: false,
)
.toList();
List<MVideo> videos = [];
for (var stream in streams) {
@@ -183,9 +206,11 @@ class AnimeWorldIndia extends MProvider {
"${source.baseUrl}${getUrlWithoutDomain(element.selectFirst("img").getSrc)}";
animeList.add(anime);
}
final hasNextPage = xpath(res,
'//li/span[@class="page-numbers current"]/parent::li//following-sibling::li/a/@href')
.isNotEmpty;
final hasNextPage =
xpath(
res,
'//li/span[@class="page-numbers current"]/parent::li//following-sibling::li/a/@href',
).isNotEmpty;
return MPages(animeList, hasNextPage);
}
@@ -199,7 +224,7 @@ class AnimeWorldIndia extends MProvider {
"ml": "malayalam",
"mr": "marathi",
"ta": "tamil",
"te": "telugu"
"te": "telugu",
};
return languages[lang] ?? "";
}
@@ -208,17 +233,23 @@ class AnimeWorldIndia extends MProvider {
List<MVideo> videos = [];
final res = (await client.get(Uri.parse(url))).body;
final streamCode = substringBefore(
substringAfter(substringAfter(res, "sniff("), ", \""), '"');
substringAfter(substringAfter(res, "sniff("), ", \""),
'"',
);
final streamUrl =
"${substringBefore(url, "/watch")}/m3u8/$streamCode/master.txt?s=1&cache=1";
final masterPlaylistRes = (await client.get(Uri.parse(streamUrl))).body;
List<MTrack> audios = [];
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-MEDIA:TYPE=AUDIO")
.split("#EXT-X-MEDIA:TYPE=AUDIO")) {
final line =
substringBefore(substringAfter(it, "#EXT-X-MEDIA:TYPE=AUDIO"), "\n");
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-MEDIA:TYPE=AUDIO",
).split("#EXT-X-MEDIA:TYPE=AUDIO")) {
final line = substringBefore(
substringAfter(it, "#EXT-X-MEDIA:TYPE=AUDIO"),
"\n",
);
final audioUrl = substringBefore(substringAfter(line, "URI=\""), "\"");
MTrack audio = MTrack();
audio
@@ -227,8 +258,10 @@ class AnimeWorldIndia extends MProvider {
audios.add(audio);
}
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -299,7 +332,7 @@ class AnimeWorldIndia extends MProvider {
SelectFilterOption("1993", "1993"),
SelectFilterOption("1992", "1992"),
SelectFilterOption("1991", "1991"),
SelectFilterOption("1990", "1990")
SelectFilterOption("1990", "1990"),
]),
SelectFilter("SortFilter", "Sort", 0, [
SelectFilterOption("Default", "default"),
@@ -353,7 +386,8 @@ class AnimeWorldIndia extends MProvider {
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p", "240p"],
entryValues: ["1080", "720", "480", "360", "240"]),
entryValues: ["1080", "720", "480", "360", "240"],
),
];
}

View File

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

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"),
]),
];
}
@@ -92,7 +98,8 @@ class Nyaa extends MProvider {
summary: "",
valueIndex: 0,
entries: ["Anime", "Live Action"],
entryValues: ["1_0", "4_0"]),
entryValues: ["1_0", "4_0"],
),
];
}
@@ -100,17 +107,21 @@ class Nyaa extends MProvider {
List<MManga> animeList = [];
final document = parseHtml(res);
final values = document
.select("body > div > div.table-responsive > table > tbody > tr");
final values = document.select(
"body > div > div.table-responsive > table > tbody > tr",
);
for (var value in values) {
MManga anime = MManga();
anime.imageUrl =
"${source.baseUrl}${getUrlWithoutDomain(value.selectFirst("td:nth-child(1) > a > img").getSrc)}";
MElement firstElement = value
MElement firstElement =
value
.select("td > a")
.where((MElement e) =>
.where(
(MElement e) =>
e.outerHtml.contains("/view/") &&
!e.outerHtml.contains("#comments"))
!e.outerHtml.contains("#comments"),
)
.toList()
.first;
anime.link =
@@ -120,8 +131,10 @@ class Nyaa extends MProvider {
}
final hasNextPage =
xpath(res, '//ul[@class="pagination"]/li[contains(text(),"»")]/a/@href')
.isNotEmpty;
xpath(
res,
'//ul[@class="pagination"]/li[contains(text(),"»")]/a/@href',
).isNotEmpty;
return MPages(animeList, hasNextPage);
}

View File

@@ -16,4 +16,5 @@ Source _nyaaSource = Source(
iconUrl: _iconUrl,
version: _nyaaVersion,
itemType: ItemType.anime,
sourceCodeUrl: _nyaaSourceCodeUrl);
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++) {
@@ -152,14 +161,16 @@ class OkAnime extends MProvider {
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
entryValues: ["1080", "720", "480", "360"],
),
MultiSelectListPreference(
key: "hoster_selection",
title: "Enable/Disable Hosts",
summary: "",
entries: ["Dood", "Voe", "Mp4upload", "VidBom", "Okru"],
entryValues: ["Dood", "Voe", "Mp4upload", "VidBom", "Okru"],
values: ["Dood", "Voe", "Mp4upload", "VidBom", "Okru"]),
values: ["Dood", "Voe", "Mp4upload", "VidBom", "Okru"],
),
];
}

View File

@@ -13,4 +13,5 @@ Source _okanimeSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/ar/okanime/icon.png",
sourceCodeUrl: _okanimeSourceCodeUrl,
version: _okanimeVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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");
}
@@ -218,14 +231,16 @@ class AnimeToast extends MProvider {
summary: "",
valueIndex: 0,
entries: ["Voe", "DoodStream", "Filemoon", "Mp4upload"],
entryValues: ["voe", "doodStream", "filemoon", "mp4upload"]),
entryValues: ["voe", "doodStream", "filemoon", "mp4upload"],
),
MultiSelectListPreference(
key: "hoster_selection",
title: "Hoster auswählen",
summary: "",
entries: ["Voe", "DoodStream", "Filemoon", "Mp4upload"],
entryValues: ["voe", "dood", "filemoon", "mp4upload"],
values: ["voe", "dood", "filemoon", "mp4upload"]),
values: ["voe", "dood", "filemoon", "mp4upload"],
),
];
}
}

View File

@@ -13,4 +13,5 @@ Source _animetoast = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/de/animetoast/icon.png",
sourceCodeUrl: _animetoastCodeUrl,
version: _animetoastVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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(
final res =
(await client.get(
Uri.parse("$baseUrl/api?m=search&l=8&q=$query"),
headers: headers))
.body;
headers: headers,
)).body;
final jsonResult = json.decode(res);
List<MManga> animeList = [];
for (var item in jsonResult["data"]) {
@@ -60,16 +63,17 @@ class AnimePahe extends MProvider {
@override
Future<MManga> getDetail(String url) async {
final statusList = [
{"Currently Airing": 0, "Finished Airing": 1}
{"Currently Airing": 0, "Finished Airing": 1},
];
MManga anime = MManga();
final id = substringBefore(substringAfterLast(url, "?anime_id="), "&name=");
final name = substringAfterLast(url, "&name=");
final session = await getSession(name, id);
final res = (await client.get(
final res =
(await client.get(
Uri.parse("$baseUrl/anime/$session?anime_id=$id"),
headers: headers))
.body;
headers: headers,
)).body;
final document = parseHtml(res);
final status =
(document.xpathFirst('//div/p[contains(text(),"Status:")]/text()') ??
@@ -85,8 +89,10 @@ class AnimePahe extends MProvider {
.replaceAll("Studio:\n", "")
.trim();
anime.imageUrl = document.selectFirst("div.anime-poster a").attr("href");
anime.genre =
xpath(res, '//*[contains(@class,"anime-genre")]/ul/li/text()');
anime.genre = xpath(
res,
'//*[contains(@class,"anime-genre")]/ul/li/text()',
);
final synonyms =
(document.xpathFirst('//div/p[contains(text(),"Synonyms:")]/text()') ??
"")
@@ -105,7 +111,10 @@ class AnimePahe extends MProvider {
}
Future<List<MChapter>> recursivePages(
String url, String res, String session) async {
String url,
String res,
String session,
) async {
final jsonResult = json.decode(res);
final page = jsonResult["current_page"];
final hasNextPage = page < jsonResult["last_page"];
@@ -128,13 +137,15 @@ class AnimePahe extends MProvider {
}
Future<String> getSession(String title, String animeId) async {
final res = (await client.get(Uri.parse("$baseUrl/api?m=search&q=$title"),
headers: headers))
.body;
final res =
(await client.get(
Uri.parse("$baseUrl/api?m=search&q=$title"),
headers: headers,
)).body;
return substringBefore(
substringAfter(
substringAfter(res, "\"id\":$animeId"), "\"session\":\""),
"\"");
substringAfter(substringAfter(res, "\"id\":$animeId"), "\"session\":\""),
"\"",
);
}
@override
@@ -150,24 +161,35 @@ class AnimePahe extends MProvider {
for (var i = 0; i < buttons.length; i++) {
final btn = buttons[i];
final audio = btn.attr("data-audio"); // Get audio type (jpn/eng). Japanese or Dubbed.
final audio = btn.attr(
"data-audio",
); // Get audio type (jpn/eng). Japanese or Dubbed.
final kwikLink = btn.attr("data-src");
final quality = btn.text;
final paheWinLink = downloadLinks[i].attr("href");
if (getPreferenceValue(source.id, "preffered_link_type")) {
final noRedirectClient = Client(source,
json.encode({"followRedirects": false, "useDartHttpClient": true}));
final noRedirectClient = Client(
source,
json.encode({"followRedirects": false, "useDartHttpClient": true}),
);
final kwikHeaders =
(await noRedirectClient.get(Uri.parse("${paheWinLink}/i"))).headers;
final kwikUrl =
"https://${substringAfterLast(getMapValue(json.encode(kwikHeaders), "location"), "https://")}";
final reskwik = (await client
.get(Uri.parse(kwikUrl), headers: {"Referer": "https://kwik.cx/"}));
final matches = RegExp(r'\("(\S+)",\d+,"(\S+)",(\d+),(\d+)')
.firstMatch(reskwik.body);
final token = decrypt(matches!.group(1)!, matches.group(2)!,
matches.group(3)!, int.parse(matches.group(4)!));
final reskwik = (await client.get(
Uri.parse(kwikUrl),
headers: {"Referer": "https://kwik.cx/"},
));
final matches = RegExp(
r'\("(\S+)",\d+,"(\S+)",(\d+),(\d+)',
).firstMatch(reskwik.body);
final token = decrypt(
matches!.group(1)!,
matches.group(2)!,
matches.group(3)!,
int.parse(matches.group(4)!),
);
final url = RegExp(r'action="([^"]+)"').firstMatch(token)!.group(1)!;
final tok = RegExp(r'value="([^"]+)"').firstMatch(token)!.group(1)!;
var code = 419;
@@ -175,22 +197,27 @@ class AnimePahe extends MProvider {
String location = "";
while (code != 302 && tries < 20) {
String cookie =
getMapValue(json.encode(res.request.headers), "cookie");
String cookie = getMapValue(
json.encode(res.request.headers),
"cookie",
);
cookie +=
"; ${getMapValue(json.encode(reskwik.headers), "set-cookie").replaceAll("path=/;", "")}";
final resNo = await Client(
source,
json.encode(
{"followRedirects": false, "useDartHttpClient": true}))
.post(Uri.parse(url), headers: {
json.encode({"followRedirects": false, "useDartHttpClient": true}),
).post(
Uri.parse(url),
headers: {
"referer": reskwik.request.url.toString(),
"cookie": cookie,
"user-agent":
getMapValue(json.encode(res.request.headers), "user-agent")
}, body: {
"_token": tok
});
"user-agent": getMapValue(
json.encode(res.request.headers),
"user-agent",
),
},
body: {"_token": tok},
);
code = resNo.statusCode;
tries++;
location = getMapValue(json.encode(resNo.headers), "location");
@@ -205,17 +232,24 @@ class AnimePahe extends MProvider {
..quality = quality;
videos.add(video);
} else {
final ress = (await client.get(Uri.parse(kwikLink),
headers: {"Referer": "https://animepahe.com"}));
final ress = (await client.get(
Uri.parse(kwikLink),
headers: {"Referer": "https://animepahe.com"},
));
final script = substringAfterLast(
xpath(ress.body,
'//script[contains(text(),"eval(function")]/text()')
.first,
"eval(function(");
xpath(
ress.body,
'//script[contains(text(),"eval(function")]/text()',
).first,
"eval(function(",
);
final videoUrl = substringBefore(
substringAfter(unpackJsAndCombine("eval(function($script"),
"const source=\\'"),
"\\';");
substringAfter(
unpackJsAndCombine("eval(function($script"),
"const source=\\'",
),
"\\';",
);
MVideo video = MVideo();
video
..url = videoUrl
@@ -235,7 +269,8 @@ class AnimePahe extends MProvider {
final n = cm.substring(0, b);
double mx = 0;
for (var index = 0; index < ctn.length; index++) {
mx += (int.tryParse(ctn[ctn.length - index - 1], radix: 10) ?? 0.0)
mx +=
(int.tryParse(ctn[ctn.length - index - 1], radix: 10) ?? 0.0)
.toInt() *
(pow(sep, index));
}
@@ -269,8 +304,10 @@ class AnimePahe extends MProvider {
List<MVideo> sortVideos(List<MVideo> videos) {
String quality = getPreferenceValue(source.id, "preferred_quality");
String preferredAudio = getPreferenceValue(source.id, "preferred_audio"); // get user's audio preference
String preferredAudio = getPreferenceValue(
source.id,
"preferred_audio",
); // get user's audio preference
videos.sort((MVideo a, MVideo b) {
// Prioritize audio first.
@@ -314,28 +351,27 @@ class AnimePahe extends MProvider {
title: "Preferred domain",
summary: "",
valueIndex: 1,
entries: [
"animepahe.com",
"animepahe.ru",
"animepahe.org"
],
entries: ["animepahe.com", "animepahe.ru", "animepahe.org"],
entryValues: [
"https://animepahe.com",
"https://animepahe.ru",
"https://animepahe.org"
]),
"https://animepahe.org",
],
),
SwitchPreferenceCompat(
key: "preffered_link_type",
title: "Use HLS links",
summary: "Enable this if you are having Cloudflare issues.",
value: false),
value: false,
),
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "360p"],
entryValues: ["1080", "720", "360"]),
entryValues: ["1080", "720", "360"],
),
ListPreference(
key: "preferred_audio", // Add new preference for audio
@@ -343,7 +379,8 @@ class AnimePahe extends MProvider {
summary: "Select your preferred audio language (Japanese or English).",
valueIndex: 0, // Default to Japanese (or whichever you prefer)
entries: ["Japanese", "English"],
entryValues: ["jpn", "eng"]),
entryValues: ["jpn", "eng"],
),
];
}
}

View File

@@ -13,4 +13,5 @@ Source _animepaheSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/animepahe/icon.png",
sourceCodeUrl: _animepaheSourceCodeUrl,
version: _animepaheVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

File diff suppressed because it is too large Load Diff

View File

@@ -13,4 +13,5 @@ Source _gogoanimeSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/gogoanime/icon.png",
sourceCodeUrl: _gogoanimeSourceCodeUrl,
version: _gogoanimeVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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(
final resServer =
(await client.get(
Uri.parse('${serverUrl[serverType]}${sourceUrl[serverType]}$id'),
headers: {"X-Requested-With": "XMLHttpRequest"}))
.body;
headers: {"X-Requested-With": "XMLHttpRequest"},
)).body;
final encrypted = getMapValue(resServer, "encrypted");
String videoResJson = "";
List<MVideo> videos = [];
@@ -245,16 +262,19 @@ class NineAnimeTv extends MProvider {
videoResJson = decryptAESCryptoJS(ciphertext, password);
} else {
videoResJson = json.encode(
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>));
(json.decode(resServer)["sources"] as List<Map<String, dynamic>>),
);
}
String masterUrl =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['file'];
String type = ((json.decode(videoResJson) as List<Map<String, dynamic>>)
String type =
((json.decode(videoResJson) as List<Map<String, dynamic>>)
.first)['type'];
final tracks = (json.decode(resServer)['tracks'] as List)
final tracks =
(json.decode(resServer)['tracks'] as List)
.where((e) => e['kind'] == 'captions' ? true : false)
.toList();
List<MTrack> subtitles = [];
@@ -272,8 +292,10 @@ class NineAnimeTv extends MProvider {
if (type == "hls") {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -307,19 +329,22 @@ class NineAnimeTv extends MProvider {
Future<List<List<int>>> generateIndexPairs(int serverType) async {
final jsPlayerUrl = [
"https://megacloud.tv/js/player/a/prod/e1-player.min.js",
"https://rapid-cloud.co/js/player/prod/e6-player-v2.min.js"
"https://rapid-cloud.co/js/player/prod/e6-player-v2.min.js",
];
final scriptText =
(await client.get(Uri.parse(jsPlayerUrl[serverType]))).body;
final switchCode = scriptText.substring(
scriptText.lastIndexOf('switch'), scriptText.indexOf('=partKey'));
scriptText.lastIndexOf('switch'),
scriptText.indexOf('=partKey'),
);
List<int> indexes = [];
for (var variableMatch
in RegExp(r'=(\w+)').allMatches(switchCode).toList()) {
final regex = RegExp(
',${(variableMatch as RegExpMatch).group(1)}=((?:0x)?([0-9a-fA-F]+))');
',${(variableMatch as RegExpMatch).group(1)}=((?:0x)?([0-9a-fA-F]+))',
);
Match? match = regex.firstMatch(scriptText);
if (match != null) {
@@ -391,13 +416,13 @@ class NineAnimeTv extends MProvider {
CheckBoxFilter("Super Power", "31"),
CheckBoxFilter("Supernatural", "37"),
CheckBoxFilter("Thriller", "41"),
CheckBoxFilter("Vampire", "32")
CheckBoxFilter("Vampire", "32"),
]),
GroupFilter("SeasonFilter", "Season", [
CheckBoxFilter("Fall", "3"),
CheckBoxFilter("Summer", "2"),
CheckBoxFilter("Spring", "1"),
CheckBoxFilter("Winter", "4")
CheckBoxFilter("Winter", "4"),
]),
GroupFilter("YearFilter", "Year", [
CheckBoxFilter("2024", "2024"),
@@ -423,7 +448,7 @@ class NineAnimeTv extends MProvider {
CheckBoxFilter("2004", "2004"),
CheckBoxFilter("2003", "2003"),
CheckBoxFilter("2002", "2002"),
CheckBoxFilter("2001", "2001")
CheckBoxFilter("2001", "2001"),
]),
SelectFilter("SortFilter", "Sort by", 0, [
SelectFilterOption("All", "all"),
@@ -433,7 +458,7 @@ class NineAnimeTv extends MProvider {
SelectFilterOption("Score", "score"),
SelectFilterOption("Name A-Z", "name_az"),
SelectFilterOption("Released Date", "released_date"),
SelectFilterOption("Most Watched", "most_watched")
SelectFilterOption("Most Watched", "most_watched"),
]),
GroupFilter("TypeFilter", "Type", [
CheckBoxFilter("Movie", "1"),
@@ -441,16 +466,18 @@ class NineAnimeTv extends MProvider {
CheckBoxFilter("OVA", "3"),
CheckBoxFilter("ONA", "4"),
CheckBoxFilter("Special", "5"),
CheckBoxFilter("Music", "6")
CheckBoxFilter("Music", "6"),
]),
SelectFilter("StatusFilter", "Status", 0, [
SelectFilterOption("All", "all"),
SelectFilterOption("Finished Airing", "1"),
SelectFilterOption("Currently Airing", "2"),
SelectFilterOption("Not yet aired", "3")
SelectFilterOption("Not yet aired", "3"),
]),
GroupFilter("LanguageFilter", "Language", [
CheckBoxFilter("Sub", "sub"),
CheckBoxFilter("Dub", "dub"),
]),
GroupFilter("LanguageFilter", "Language",
[CheckBoxFilter("Sub", "sub"), CheckBoxFilter("Dub", "dub")]),
];
}
@@ -463,35 +490,40 @@ class NineAnimeTv extends MProvider {
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
entryValues: ["1080", "720", "480", "360"],
),
ListPreference(
key: "preferred_server",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: ["Vidstreaming", "VidCloud"],
entryValues: ["Vidstreaming", "VidCloud"]),
entryValues: ["Vidstreaming", "VidCloud"],
),
ListPreference(
key: "preferred_type",
title: "Preferred Type",
summary: "",
valueIndex: 0,
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"]),
entryValues: ["sub", "dub"],
),
MultiSelectListPreference(
key: "hoster_selection",
title: "Enable/Disable Hosts",
summary: "",
entries: ["Vidstreaming", "VidCloud"],
entryValues: ["Vidstreaming", "Vidcloud"],
values: ["Vidstreaming", "Vidcloud"]),
values: ["Vidstreaming", "Vidcloud"],
),
MultiSelectListPreference(
key: "type_selection",
title: "Enable/Disable Types",
summary: "",
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"],
values: ["sub", "dub"]),
values: ["sub", "dub"],
),
];
}

View File

@@ -13,4 +13,5 @@ Source _nineanimetv = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/nineanimetv/icon.png",
sourceCodeUrl: _nineanimetvCodeUrl,
version: _nineanimetvVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

View File

@@ -13,4 +13,5 @@ Source _uhdmoviesSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/en/uhdmovies/icon.png",
sourceCodeUrl: _uhdmoviesSourceCodeUrl,
version: _uhdmoviesVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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) {
@@ -132,7 +141,8 @@ class UHDMovies extends MProvider {
value: "https://uhdmovies.fans",
dialogTitle: "Currently used domain",
dialogMessage: "",
text: "https://uhdmovies.fans"),
text: "https://uhdmovies.fans",
),
];
}
@@ -146,8 +156,9 @@ class UHDMovies extends MProvider {
final link = links[i];
String decodedLink = link;
if (!link.contains("workers.dev")) {
decodedLink = utf8
.decode(base64Url.decode(substringAfter(link, "download?url=")));
decodedLink = utf8.decode(
base64Url.decode(substringAfter(link, "download?url=")),
);
}
MVideo video = MVideo();
video
@@ -184,18 +195,25 @@ class UHDMovies extends MProvider {
final js = xpath(lastDoc, '//script[contains(text(), "/?go=")]/text()');
if (js.isEmpty) return "";
String script = js.first;
String nextUrl =
substringBefore(substringAfter(script, "\"href\",\""), '"');
String nextUrl = substringBefore(
substringAfter(script, "\"href\",\""),
'"',
);
if (!nextUrl.contains("http")) return "";
String cookieName = substringAfter(nextUrl, "go=");
String cookieValue =
substringBefore(substringAfter(script, "'$cookieName', '"), "'");
final response = (await client.get(Uri.parse(nextUrl),
headers: {"referer": url, "Cookie": "$cookieName=$cookieValue"}))
.body;
String cookieValue = substringBefore(
substringAfter(script, "'$cookieName', '"),
"'",
);
final response =
(await client.get(
Uri.parse(nextUrl),
headers: {"referer": url, "Cookie": "$cookieName=$cookieValue"},
)).body;
final lastRes =
parseHtml(response).selectFirst("meta[http-equiv]").attr("content");
final lastRes = parseHtml(
response,
).selectFirst("meta[http-equiv]").attr("content");
return substringAfter(lastRes, "url=");
}
@@ -222,9 +240,12 @@ class UHDMovies extends MProvider {
final name = xpath(html, '//input/@name').first;
final value = xpath(html, '//input/@value').first;
final body = {"$name": value};
final response = (await client.post(Uri.parse(urlR.first),
headers: {"referer": url}, body: body))
.body;
final response =
(await client.post(
Uri.parse(urlR.first),
headers: {"referer": url},
body: body,
)).body;
return recursiveDoc(url, response);
}
}

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,
final res =
(await client.get(
Uri.parse(
"${source.baseUrl}/$pageStr?s=${query.replaceAll(" ", "+")}",
),
)).body;
return parseAnimeList(
res,
selector: "div.result-item div.image a",
hasNextPage: parseHtml(res)
hasNextPage:
parseHtml(res)
.selectFirst(
"div.pagination > *:last-child:not(span):not(.current)")
"div.pagination > *:last-child:not(span):not(.current)",
)
?.text !=
null);
null,
);
}
@override
@@ -39,7 +46,8 @@ class AnimeOnlineNinja extends MProvider {
MManga anime = MManga();
final document = parseHtml(res);
anime.description = document.selectFirst("div#info").text;
anime.genre = document
anime.genre =
document
.selectFirst("div.sheader")
.select("div.data > div.sgeneros > a")
.map((e) => e.text)
@@ -82,12 +90,16 @@ class AnimeOnlineNinja extends MProvider {
final type = player.attr("data-type");
final id = player.attr("data-post");
final num = player.attr("data-nume");
final resUrl = (await client.get(Uri.parse(
"${source.baseUrl}/wp-json/dooplayer/v1/post/$id?type=$type&source=$num")))
.body;
final url =
substringBefore(substringAfter(resUrl, "\"embed_url\":\""), "\",")
.replaceAll("\\", "");
final resUrl =
(await client.get(
Uri.parse(
"${source.baseUrl}/wp-json/dooplayer/v1/post/$id?type=$type&source=$num",
),
)).body;
final url = substringBefore(
substringAfter(resUrl, "\"embed_url\":\""),
"\",",
).replaceAll("\\", "");
videos.addAll(await extractVideos(url, name));
}
return sortVideos(videos, source.id);
@@ -100,8 +112,11 @@ class AnimeOnlineNinja extends MProvider {
return await extractFromMulti(url);
} else if (["filemoon", "moon", "filemooon"].any((a) => url.contains(a))) {
a = await filemoonExtractor(url, "$lang Filemoon - ", "");
} else if (["https://dood", "https://ds2play", "https://d0"]
.any((a) => url.contains(a))) {
} else if ([
"https://dood",
"https://ds2play",
"https://d0",
].any((a) => url.contains(a))) {
a = await doodExtractor(url, "$lang DoodStream");
} else if (["streamtape", "stp", "stape"].any((a) => url.contains(a))) {
a = await streamTapeExtractor(url, "$lang StreamTape");
@@ -111,8 +126,10 @@ class AnimeOnlineNinja extends MProvider {
final resUrl = (await client.get(Uri.parse(url))).body;
final jsData =
parseHtml(resUrl).selectFirst("script:contains(sources)").text;
final videoUrl =
substringBefore(substringAfter(jsData, "{file:\""), "\"");
final videoUrl = substringBefore(
substringAfter(jsData, "{file:\""),
"\"",
);
MVideo video = MVideo();
video
@@ -121,13 +138,20 @@ class AnimeOnlineNinja extends MProvider {
..quality = "$lang WolfStream";
a = [video];
} else if (["wishembed", "streamwish", "strwish", "wish"]
.any((a) => url.contains(a))) {
} else if ([
"wishembed",
"streamwish",
"strwish",
"wish",
].any((a) => url.contains(a))) {
a = await streamWishExtractor(url, "$lang StreamWish");
} else if (url.contains("mp4upload")) {
a = await mp4UploadExtractor(url, null, "$lang", "");
} else if (["vidhide", "filelions.top", "vid."]
.any((a) => url.contains(a))) {
} else if ([
"vidhide",
"filelions.top",
"vid.",
].any((a) => url.contains(a))) {
a = await streamHideExtractor(url, lang);
}
videos.addAll(a);
@@ -139,14 +163,17 @@ class AnimeOnlineNinja extends MProvider {
final res = (await client.get(Uri.parse(url))).body;
final masterUrl = substringBefore(
substringAfter(
substringAfter(
substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\""),
'"');
substringAfter(substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\"",
),
'"',
);
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
List<MVideo> videos = [];
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -168,16 +195,20 @@ class AnimeOnlineNinja extends MProvider {
}
Future<List<MVideo>> uqloadExtractor(String url, String lang) async {
final Client client =
Client(source, json.encode({"useDartHttpClient": true}));
final Client client = Client(
source,
json.encode({"useDartHttpClient": true}),
);
final res = (await client.get(Uri.parse(url))).body;
final js = xpath(res, '//script[contains(text(), "sources:")]/text()');
if (js.isEmpty) {
return [];
}
final videoUrl =
substringBefore(substringAfter(js.first, "sources: [\""), '"');
final videoUrl = substringBefore(
substringAfter(js.first, "sources: [\""),
'"',
);
MVideo video = MVideo();
video
..url = videoUrl
@@ -200,12 +231,16 @@ class AnimeOnlineNinja extends MProvider {
}
List<MVideo> videos = [];
for (var element in document.select("div.ODDIV $langSelector > li")) {
final hosterUrl =
substringBefore(substringAfter(element.attr("onclick"), "('"), "')");
final hosterUrl = substringBefore(
substringAfter(element.attr("onclick"), "('"),
"')",
);
String lang = "";
if (langSelector == "div") {
lang = substringBefore(
substringAfter(element.parent?.attr("class"), "OD_", ""), " ");
substringAfter(element.parent?.attr("class"), "OD_", ""),
" ",
);
} else {
lang = prefLang;
}
@@ -215,8 +250,11 @@ class AnimeOnlineNinja extends MProvider {
return videos;
}
MPages parseAnimeList(String res,
{String selector = "article.w_item_a > a", bool hasNextPage = false}) {
MPages parseAnimeList(
String res, {
String selector = "article.w_item_a > a",
bool hasNextPage = false,
}) {
final elements = parseHtml(res).select(selector);
List<MManga> animeList = [];
for (var element in elements) {
@@ -225,7 +263,8 @@ class AnimeOnlineNinja extends MProvider {
MManga anime = MManga();
final img = element.selectFirst("img");
anime.name = img.attr("alt");
anime.imageUrl = img?.attr("data-src") ??
anime.imageUrl =
img?.attr("data-src") ??
img?.attr("data-lazy-src") ??
img?.attr("srcset") ??
img?.getSrc;
@@ -245,7 +284,8 @@ class AnimeOnlineNinja extends MProvider {
summary: "",
valueIndex: 0,
entries: ["SUB", "All", "ES", "LAT"],
entryValues: ["SUB", "", "ES", "LAT"]),
entryValues: ["SUB", "", "ES", "LAT"],
),
ListPreference(
key: "preferred_server1",
title: "Preferred server",
@@ -260,7 +300,7 @@ class AnimeOnlineNinja extends MProvider {
"saidochesto.top",
"VidHide",
"StreamWish",
"Mp4Upload"
"Mp4Upload",
],
entryValues: [
"Filemoon",
@@ -271,8 +311,9 @@ class AnimeOnlineNinja extends MProvider {
"saidochesto.top",
"VidHide",
"StreamWish",
"Mp4Upload"
]),
"Mp4Upload",
],
),
];
}

View File

@@ -13,4 +13,5 @@ Source _animeonlineninjaSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/es/animeonlineninja/icon.png",
sourceCodeUrl: _animeonlineninjaSourceCodeUrl,
version: _animeonlineninjaVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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
final latest =
document
.select("h2")
.where((MElement e) =>
e.outerHtml.toLowerCase().contains("derniers épisodes ajoutés"))
.where(
(MElement e) => e.outerHtml.toLowerCase().contains(
"derniers épisodes ajoutés",
),
)
.toList();
final seasonElements = (latest.first.parent.nextElementSibling as MElement)
final seasonElements =
(latest.first.parent.nextElementSibling as MElement)
.select("div")
.toList();
List<MManga> seasons = [];
for (var seasonElement in seasonElements) {
seasons.addAll(await fetchAnimeSeasons(
(seasonElement as MElement).getElementsByTagName("a").first.getHref));
seasons.addAll(
await fetchAnimeSeasons(
(seasonElement as MElement).getElementsByTagName("a").first.getHref,
),
);
}
return MPages(seasons, false);
}
@@ -48,47 +61,72 @@ class AnimeSama extends MProvider {
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
final filters = filterList.filters;
final res = (await client
.get(Uri.parse("${source.baseUrl}/catalogue/listing_all.php")))
.body;
final res =
(await client.get(
Uri.parse("${source.baseUrl}/catalogue/listing_all.php"),
)).body;
var databaseElements = parseHtml(res).select(".cardListAnime");
List<MElement> elements = [];
elements = databaseElements
.where((MElement element) => element.select("h1, p").any((MElement e) =>
e.text.toLowerCase().contains(query.toLowerCase().trim())))
elements =
databaseElements
.where(
(MElement element) => element
.select("h1, p")
.any(
(MElement e) => e.text.toLowerCase().contains(
query.toLowerCase().trim(),
),
),
)
.toList();
for (var filter in filters) {
if (filter.type == "TypeFilter") {
final types = (filter.state as List).where((e) => e.state).toList();
elements = elements
.where((MElement element) =>
elements =
elements
.where(
(MElement element) =>
types.isEmpty ||
types.any((p) => element.className.contains(p.value)))
types.any((p) => element.className.contains(p.value)),
)
.toList();
} else if (filter.type == "LanguageFilter") {
final language = (filter.state as List).where((e) => e.state).toList();
elements = elements
.where((MElement element) =>
elements =
elements
.where(
(MElement element) =>
language.isEmpty ||
language.any((p) => element.className.contains(p.value)))
language.any((p) => element.className.contains(p.value)),
)
.toList();
} else if (filter.type == "GenreFilter") {
final included = (filter.state as List)
final included =
(filter.state as List)
.where((e) => e.state == 1 ? true : false)
.toList();
final excluded = (filter.state as List)
final excluded =
(filter.state as List)
.where((e) => e.state == 2 ? true : false)
.toList();
if (included.isNotEmpty) {
elements = elements
.where((MElement element) =>
included.every((p) => element.className.contains(p.value)))
elements =
elements
.where(
(MElement element) => included.every(
(p) => element.className.contains(p.value),
),
)
.toList();
}
if (excluded.isNotEmpty) {
elements = elements
.where((MElement element) =>
excluded.every((p) => element.className.contains(p.value)))
elements =
elements
.where(
(MElement element) => excluded.every(
(p) => element.className.contains(p.value),
),
)
.toList();
}
}
@@ -97,8 +135,11 @@ class AnimeSama extends MProvider {
if (chunks.isEmpty) return MPages([], false);
List<MManga> seasons = [];
for (var seasonElement in chunks[page - 1]) {
seasons.addAll(await fetchAnimeSeasons(
seasonElement.getElementsByTagName("a").first.getHref));
seasons.addAll(
await fetchAnimeSeasons(
seasonElement.getElementsByTagName("a").first.getHref,
),
);
}
return MPages(seasons, page < chunks.length);
@@ -108,8 +149,9 @@ class AnimeSama extends MProvider {
Future<MManga> getDetail(String url) async {
var animeUrl =
"${source.baseUrl}${substringBeforeLast(getUrlWithoutDomain(url), "/")}";
var movie =
int.tryParse(url.split("#").length >= 2 ? url.split("#")[1] : "");
var movie = int.tryParse(
url.split("#").length >= 2 ? url.split("#")[1] : "",
);
List<Map<String, dynamic>> playersList = [];
for (var lang in ["vostfr", "vf"]) {
final players = await fetchPlayers("$animeUrl/$lang");
@@ -181,22 +223,23 @@ class AnimeSama extends MProvider {
}
Future<List<MVideo>> vidmolyExtractor(String url, String lang) async {
final headers = {
'Referer': 'https://vidmoly.to',
};
final headers = {'Referer': 'https://vidmoly.to'};
List<MVideo> videos = [];
final playListUrlResponse = (await client.get(Uri.parse(url))).body;
final playlistUrl =
RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ??
"";
if (playlistUrl.isEmpty) return [];
final masterPlaylistRes =
await client.get(Uri.parse(playlistUrl), headers: headers);
final masterPlaylistRes = await client.get(
Uri.parse(playlistUrl),
headers: headers,
);
if (masterPlaylistRes.statusCode == 200) {
for (var it
in substringAfter(masterPlaylistRes.body, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes.body,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -230,8 +273,10 @@ class AnimeSama extends MProvider {
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -317,14 +362,16 @@ class AnimeSama extends MProvider {
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
entryValues: ["1080", "720", "480", "360"],
),
ListPreference(
key: "voices_preference",
title: "Préférence des voix",
summary: "",
valueIndex: 0,
entries: ["Préférer VOSTFR", "Préférer VF"],
entryValues: ["vostfr", "vf"]),
entryValues: ["vostfr", "vf"],
),
];
}
@@ -349,8 +396,10 @@ class AnimeSama extends MProvider {
var moviesUrl = "$url/$seasonStem";
var movies = await fetchPlayers(moviesUrl);
if (movies.isNotEmpty) {
var movieNameRegex =
RegExp("^\\s*newSPF\\(\"(.*)\"\\);", multiLine: true);
var movieNameRegex = RegExp(
"^\\s*newSPF\\(\"(.*)\"\\);",
multiLine: true,
);
var moviesDoc = (await client.get(Uri.parse(moviesUrl))).body;
List<RegExpMatch> matches =
movieNameRegex.allMatches(moviesDoc).toList();
@@ -369,11 +418,14 @@ class AnimeSama extends MProvider {
MManga anime = MManga();
anime.imageUrl = document.getElementById("coverOeuvre")?.getSrc;
anime.genre = (document.xpathFirst(
'//h2[contains(text(),"Genres")]/following-sibling::a/text()') ??
'//h2[contains(text(),"Genres")]/following-sibling::a/text()',
) ??
"")
.split(",");
anime.description = document.xpathFirst(
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()') ??
anime.description =
document.xpathFirst(
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()',
) ??
"";
anime.name = title;
@@ -386,11 +438,14 @@ class AnimeSama extends MProvider {
MManga anime = MManga();
anime.imageUrl = document.getElementById("coverOeuvre")?.getSrc;
anime.genre = (document.xpathFirst(
'//h2[contains(text(),"Genres")]/following-sibling::a/text()') ??
'//h2[contains(text(),"Genres")]/following-sibling::a/text()',
) ??
"")
.split(",");
anime.description = document.xpathFirst(
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()') ??
anime.description =
document.xpathFirst(
'//h2[contains(text(),"Synopsis")]/following-sibling::p/text()',
) ??
"";
anime.name =
'$animeName ${substringBefore(seasonName, ',').replaceAll('"', "")}';
@@ -448,7 +503,9 @@ class AnimeSama extends MProvider {
String sanitizeEpisodesJs(String doc) {
return doc.replaceAll(
RegExp(r'(?<=\[|\,)\s*\"\s*(https?://[^\s\"]+)\s*\"\s*(?=\,|\])'), '');
RegExp(r'(?<=\[|\,)\s*\"\s*(https?://[^\s\"]+)\s*\"\s*(?=\,|\])'),
'',
);
}
List<List<dynamic>> chunked(List<dynamic> list, int size) {

View File

@@ -13,4 +13,5 @@ Source _animesama = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/animesama/icon.png",
sourceCodeUrl: animesamaCodeUrl,
version: animesamaVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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

@@ -14,4 +14,5 @@ Source _animesultraSource = Source(
sourceCodeUrl: _animesultraSourceCodeUrl,
version: _animesultraVersion,
itemType: ItemType.anime,
isFullData: false);
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)
@@ -215,14 +229,17 @@ class AniZone extends MProvider {
final res = (await client.get(Uri.parse(url))).body;
final masterUrl = substringBefore(
substringAfter(
substringAfter(
substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\""),
'"');
substringAfter(substringAfter(unpackJs(res), "sources:"), "file:\""),
"src:\"",
),
'"',
);
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
List<MVideo> videos = [];
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -314,7 +331,7 @@ class AniZone extends MProvider {
CheckBoxFilter("Vampire", "32"),
CheckBoxFilter("Yaoi", "33"),
CheckBoxFilter("Yuri", "34"),
])
]),
];
}
@@ -327,14 +344,16 @@ class AniZone extends MProvider {
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
entryValues: ["1080", "720", "480", "360"],
),
ListPreference(
key: "voices_preference",
title: "Préférence des voix",
summary: "",
valueIndex: 0,
entries: ["Préférer VOSTFR", "Préférer VF"],
entryValues: ["vostfr", "vf"]),
entryValues: ["vostfr", "vf"],
),
];
}
@@ -383,8 +402,10 @@ class AniZone extends MProvider {
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -437,7 +458,8 @@ class AniZone extends MProvider {
final masterPlaylistRes = await client.get(Uri.parse(masterUrl));
if (masterPlaylistRes.statusCode != 200) {
print(
"Error lors de la récupération de la playlist M3U8 : ${masterPlaylistRes.statusCode}");
"Error lors de la récupération de la playlist M3U8 : ${masterPlaylistRes.statusCode}",
);
return [];
}

View File

@@ -13,4 +13,5 @@ Source _aniZoneSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/icon.png",
sourceCodeUrl: _aniZoneSourceCodeUrl,
version: _aniZoneVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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
videos.add(
video
..url = playerUrl
..originalUrl = playerUrl
..quality = "FRAnime (Vido)");
..quality = "FRAnime (Vido)",
);
} else if (playerName.contains("sendvid")) {
a = await sendVidExtractorr(playerUrl, "");
} else if (playerName.contains("sibnet")) {
@@ -165,7 +171,7 @@ class FrAnime extends MProvider {
MPages animeResList(String res) {
final statusList = [
{"EN COURS": 0, "TERMINÉ": 1}
{"EN COURS": 0, "TERMINÉ": 1},
];
List<MManga> animeList = [];
@@ -233,7 +239,7 @@ class FrAnime extends MProvider {
MPages animeSeachFetch(String res, String query) {
final statusList = [
{"EN COURS": 0, "TERMINÉ": 1}
{"EN COURS": 0, "TERMINÉ": 1},
];
List<MManga> animeList = [];
final jsonResList = json.decode(res);
@@ -241,20 +247,23 @@ class FrAnime extends MProvider {
MManga anime = MManga();
final titleO = getMapValue(json.encode(animeJson), "titleO");
final titleAlt =
getMapValue(json.encode(animeJson), "titles", encode: true);
final containsEn = getMapValue(titleAlt, "en")
.toString()
.toLowerCase()
.contains(query.toLowerCase());
final containsEnJp = getMapValue(titleAlt, "en_jp")
.toString()
.toLowerCase()
.contains(query.toLowerCase());
final containsJaJp = getMapValue(titleAlt, "ja_jp")
.toString()
.toLowerCase()
.contains(query.toLowerCase());
final titleAlt = getMapValue(
json.encode(animeJson),
"titles",
encode: true,
);
final containsEn = getMapValue(
titleAlt,
"en",
).toString().toLowerCase().contains(query.toLowerCase());
final containsEnJp = getMapValue(
titleAlt,
"en_jp",
).toString().toLowerCase().contains(query.toLowerCase());
final containsJaJp = getMapValue(
titleAlt,
"ja_jp",
).toString().toLowerCase().contains(query.toLowerCase());
final containsTitleO = titleO.toLowerCase().contains(query.toLowerCase());
if (containsEn || containsEnJp || containsJaJp || containsTitleO) {
@@ -319,16 +328,19 @@ class FrAnime extends MProvider {
}
Future<String> dataBase() async {
return (await client.get(Uri.parse("https://api.franime.fr/api/animes/"),
headers: {"Referer": "https://franime.fr/"}))
.body;
return (await client.get(
Uri.parse("https://api.franime.fr/api/animes/"),
headers: {"Referer": "https://franime.fr/"},
)).body;
}
String databaseAnimeByTitleO(String res, String titleO) {
final datas = json.decode(res) as List<Map<String, dynamic>>;
for (var data in datas) {
String title =
(data["titleO"] as String).replaceAll(RegExp("[^A-Za-z0-9 ]"), "");
String title = (data["titleO"] as String).replaceAll(
RegExp("[^A-Za-z0-9 ]"),
"",
);
if (title.replaceAll(" ", "-").toLowerCase() == "${titleO}") {
return json.encode(data);
}
@@ -351,8 +363,10 @@ class FrAnime extends MProvider {
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";

View File

@@ -15,4 +15,5 @@ Source _franimeSource = Source(
sourceCodeUrl: _franimeSourceCodeUrl,
version: _franimeVersion,
itemType: ItemType.anime,
isFullData: true);
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,12 +49,14 @@ class OtakuFr extends MProvider {
final namess = xpath(res, '//*[@class="episode"]/div/a/text()');
List<String> names = [];
for (var name in namess) {
names.add(regExp(
names.add(
regExp(
name,
r'(?<=\bS\d\s*|)\d{2}\s*(?=\b(Vostfr|vostfr|VF|Vf|vf|\(VF\)|\(vf\)|\(Vf\)|\(Vostfr\)\b))?',
'',
0,
0)
0,
)
.replaceAll(' vostfr', '')
.replaceAll(' Vostfr', '')
.replaceAll(' VF', '')
@@ -58,7 +66,8 @@ class OtakuFr extends MProvider {
.replaceAll(' (vf)', '')
.replaceAll(' (vf)', '')
.replaceAll(' (Vf)', '')
.replaceAll(' (Vostfr)', ''));
.replaceAll(' (Vostfr)', ''),
);
}
final images = xpath(res, '//*[@class="episode"]/div/figure/a/img/@src');
@@ -98,12 +107,18 @@ class OtakuFr extends MProvider {
final res = (await client.get(Uri.parse(url))).body;
List<MManga> animeList = [];
final urls =
xpath(res, '//*[@class="list"]/article/div/div/figure/a/@href');
final names =
xpath(res, '//*[@class="list"]/article/div/div/figure/a/img/@title');
final images =
xpath(res, '//*[@class="list"]/article/div/div/figure/a/img/@src');
final urls = xpath(
res,
'//*[@class="list"]/article/div/div/figure/a/@href',
);
final names = xpath(
res,
'//*[@class="list"]/article/div/div/figure/a/img/@title',
);
final images = xpath(
res,
'//*[@class="list"]/article/div/div/figure/a/img/@src',
);
for (var i = 0; i < names.length; i++) {
MManga anime = MManga();
@@ -119,35 +134,48 @@ class OtakuFr extends MProvider {
@override
Future<MManga> getDetail(String url) async {
final statusList = [
{"En cours": 0, "Terminé": 1}
{"En cours": 0, "Terminé": 1},
];
String res =
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
.body;
(await client.get(
Uri.parse("$baseUrl${getUrlWithoutDomain(url)}"),
)).body;
MManga anime = MManga();
final originalUrl = xpath(res,
'//*[@class="breadcrumb"]/li[@class="breadcrumb-item"][2]/a/@href');
final originalUrl = xpath(
res,
'//*[@class="breadcrumb"]/li[@class="breadcrumb-item"][2]/a/@href',
);
if (originalUrl.isNotEmpty) {
res = (await client.get(Uri.parse(originalUrl.first))).body;
}
final description =
xpath(res, '//*[@class="episode fz-sm synop"]/p/text()');
final description = xpath(
res,
'//*[@class="episode fz-sm synop"]/p/text()',
);
if (description.isNotEmpty) {
anime.description = description.first.replaceAll("Synopsis:", "");
}
final status = xpath(res,
'//*[@class="list-unstyled"]/li[contains(text(),"Statut")]/text()');
final status = xpath(
res,
'//*[@class="list-unstyled"]/li[contains(text(),"Statut")]/text()',
);
if (status.isNotEmpty) {
anime.status =
parseStatus(status.first.replaceAll("Statut: ", ""), statusList);
anime.status = parseStatus(
status.first.replaceAll("Statut: ", ""),
statusList,
);
}
anime.genre = xpath(res,
'//*[@class="list-unstyled"]/li[contains(text(),"Genre")]/ul/li/a/text()');
anime.genre = xpath(
res,
'//*[@class="list-unstyled"]/li[contains(text(),"Genre")]/ul/li/a/text()',
);
final epUrls = xpath(res, '//*[@class="list-episodes list-group"]/a/@href');
final dates =
xpath(res, '//*[@class="list-episodes list-group"]/a/span/text()');
final dates = xpath(
res,
'//*[@class="list-episodes list-group"]/a/span/text()',
);
final names = xpath(res, '//*[@class="list-episodes list-group"]/a/text()');
List<String> episodes = [];
@@ -155,7 +183,8 @@ class OtakuFr extends MProvider {
final date = dates[i];
final name = names[i];
episodes.add(
"Episode ${regExp(name.replaceAll(date, ""), r".* (\d*) [VvfF]{1,1}", '', 1, 1)}");
"Episode ${regExp(name.replaceAll(date, ""), r".* (\d*) [VvfF]{1,1}", '', 1, 1)}",
);
}
final dateUploads = parseDates(dates, "dd MMMM yyyy", "fr");
@@ -175,19 +204,23 @@ class OtakuFr extends MProvider {
@override
Future<List<MVideo>> getVideoList(String url) async {
final res =
(await client.get(Uri.parse("$baseUrl${getUrlWithoutDomain(url)}")))
.body;
(await client.get(
Uri.parse("$baseUrl${getUrlWithoutDomain(url)}"),
)).body;
final servers = parseHtml(res).select("div.tab-content iframe[src]");
List<MVideo> videos = [];
final hosterSelection = preferenceHosterSelection(source.id);
for (var url in servers) {
final urll = url.getSrc != "about:blank" ? url.getSrc : url.getDataSrc;
final resServer = (await client.get(Uri.parse(fixUrl(urll)),
headers: {"X-Requested-With": "XMLHttpRequest"}))
.body;
final serverUrl =
fixUrl(regExp(resServer, r"data-url='([^']+)'", '', 1, 1));
final resServer =
(await client.get(
Uri.parse(fixUrl(urll)),
headers: {"X-Requested-With": "XMLHttpRequest"},
)).body;
final serverUrl = fixUrl(
regExp(resServer, r"data-url='([^']+)'", '', 1, 1),
);
List<MVideo> a = [];
if (serverUrl.contains("https://streamwish") &&
hosterSelection.contains("Streamwish")) {
@@ -278,13 +311,13 @@ class OtakuFr extends MProvider {
SelectFilterOption("Suspense", "/genre/suspense/"),
SelectFilterOption("Thriller", "/genre/thriller/"),
SelectFilterOption("Tranche de vie", "/genre/tranche-de-vie/"),
SelectFilterOption("Vampire", "/genre/vampire/")
SelectFilterOption("Vampire", "/genre/vampire/"),
]),
SelectFilter("SubPageFilter", "Sous page", 0, [
SelectFilterOption("<Selectionner>", ""),
SelectFilterOption("Terminé", "/termine/"),
SelectFilterOption("Film", "/film/"),
])
]),
];
}
@@ -298,14 +331,16 @@ class OtakuFr extends MProvider {
value: "https://otakufr.cc",
dialogTitle: "Changer l'url de base",
dialogMessage: "",
text: "https://otakufr.cc"),
text: "https://otakufr.cc",
),
ListPreference(
key: "preferred_quality",
title: "Qualité préférée",
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
entryValues: ["1080", "720", "480", "360"],
),
MultiSelectListPreference(
key: "hoster_selection_",
title: "Enable/Disable Hosts",
@@ -318,7 +353,7 @@ class OtakuFr extends MProvider {
"Okru",
"Voe",
"Sibnet",
"Upstream"
"Upstream",
],
entryValues: [
"Streamwish",
@@ -328,7 +363,7 @@ class OtakuFr extends MProvider {
"Okru",
"Voe",
"Sibnet",
"Upstream"
"Upstream",
],
values: [
"Streamwish",
@@ -338,8 +373,9 @@ class OtakuFr extends MProvider {
"Okru",
"Voe",
"Sibnet",
"Upstream"
]),
"Upstream",
],
),
];
}
@@ -389,8 +425,10 @@ class OtakuFr extends MProvider {
if (masterUrl.contains(".m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -433,12 +471,16 @@ class OtakuFr extends MProvider {
if (js.isEmpty) {
return [];
}
final masterUrl =
substringBefore(substringAfter(unpackJs(js.first), "{file:\""), "\"}");
final masterUrl = substringBefore(
substringAfter(unpackJs(js.first), "{file:\""),
"\"}",
);
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
List<MVideo> videos = [];
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";

View File

@@ -14,4 +14,5 @@ Source _otakufr = Source(
sourceCodeUrl: otakufrCodeUrl,
version: otakufrVersion,
itemType: ItemType.anime,
isFullData: false);
isFullData: false,
);

View File

@@ -13,4 +13,5 @@ Source _yomoviesSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/hi/yomovies/icon.png",
sourceCodeUrl: _yomoviesSourceCodeUrl,
version: _yomoviesVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

View File

@@ -23,8 +23,8 @@ class YoMovies extends MProvider {
final document = parseHtml(res);
return animeFromElement(
document.select("div.movies-list > div.ml-item"),
document.selectFirst("ul.pagination > li.active + li")?.getHref !=
null);
document.selectFirst("ul.pagination > li.active + li")?.getHref != null,
);
}
@override
@@ -54,8 +54,8 @@ class YoMovies extends MProvider {
final document = parseHtml(res);
return animeFromElement(
document.select("div.movies-list > div.ml-item"),
document.selectFirst("ul.pagination > li.active + li")?.getHref !=
null);
document.selectFirst("ul.pagination > li.active + li")?.getHref != null,
);
}
@override
@@ -68,8 +68,10 @@ class YoMovies extends MProvider {
var infoElement = document.selectFirst("div.mvi-content");
anime.description = infoElement.selectFirst("p.f-desc")?.text ?? "";
anime.genre = xpath(res,
'//div[@class="mvici-left" and contains(text(),"Genre:")]/p/a/text()');
anime.genre = xpath(
res,
'//div[@class="mvici-left" and contains(text(),"Genre:")]/p/a/text()',
);
List<MChapter> episodeList = [];
final seasonListElements = document.select("div#seasons > div.tvseason");
@@ -124,14 +126,16 @@ class YoMovies extends MProvider {
value: "https://yomovies.boo",
dialogTitle: "Override BaseUrl",
dialogMessage: "",
text: "https://yomovies.boo"),
text: "https://yomovies.boo",
),
ListPreference(
key: "preferred_quality",
title: "Preferred quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"])
entryValues: ["1080", "720", "480", "360"],
),
];
}
@@ -142,11 +146,15 @@ class YoMovies extends MProvider {
(await client.get(Uri.parse(url), headers: {"Referer": url})).body;
final script = xpath(res, '//script[contains(text(),"sources:")]/text()');
if (script.isEmpty) return [];
final masterUrl =
substringBefore(substringAfter(script.first, "file:\""), '"');
final masterUrl = substringBefore(
substringAfter(script.first, "file:\""),
'"',
);
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -207,38 +215,57 @@ class YoMovies extends MProvider {
List<dynamic> getFilterList() {
return [
HeaderFilter(
"Note: Only one selection at a time works, and it ignores text search"),
"Note: Only one selection at a time works, and it ignores text search",
),
SeparatorFilter(),
SelectFilter("BollywoodFilter", "Bollywood", 0, [
SelectFilterOption("<select>", ""),
SelectFilterOption("Bollywood", "/genre/bollywood"),
SelectFilterOption("Trending", "/genre/top-rated"),
SelectFilterOption("Bollywood (2024)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2024&wpas=1"),
SelectFilterOption("Bollywood (2023)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2023&wpas=1"),
SelectFilterOption("Bollywood (2022)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2022&wpas=1"),
SelectFilterOption("Bollywood (2021)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2021&wpas=1"),
SelectFilterOption(
"Bollywood (2024)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2024&wpas=1",
),
SelectFilterOption(
"Bollywood (2023)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2023&wpas=1",
),
SelectFilterOption(
"Bollywood (2022)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2022&wpas=1",
),
SelectFilterOption(
"Bollywood (2021)",
"/account/?ptype=post&tax_category%5B%5D=bollywood&tax_release-year=2021&wpas=1",
),
]),
SelectFilter("DualAudioFilter", "Dual Audio", 0, [
SelectFilterOption("<select>", ""),
SelectFilterOption("Dual Audio", "/genre/dual-audio"),
SelectFilterOption("Hollywood Dubbed",
"/account/?ptype=post&tax_category%5B%5D=dual-audio&wpas=1"),
SelectFilterOption("South Dubbed",
"/account/?ptype=post&tax_category%5B%5D=dual-audio&tax_category%5B%5D=south-special&wpas=1"),
SelectFilterOption(
"Hollywood Dubbed",
"/account/?ptype=post&tax_category%5B%5D=dual-audio&wpas=1",
),
SelectFilterOption(
"South Dubbed",
"/account/?ptype=post&tax_category%5B%5D=dual-audio&tax_category%5B%5D=south-special&wpas=1",
),
]),
SelectFilter("HollywoodFilter", "Hollywood", 0, [
SelectFilterOption("<select>", ""),
SelectFilterOption("Hollywood", "/genre/hollywood"),
SelectFilterOption("Hollywood (2023)",
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2023&wpas=1"),
SelectFilterOption("Hollywood (2022)",
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2022&wpas=1"),
SelectFilterOption("Hollywood (2021)",
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2021&wpas=1"),
SelectFilterOption(
"Hollywood (2023)",
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2023&wpas=1",
),
SelectFilterOption(
"Hollywood (2022)",
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2022&wpas=1",
),
SelectFilterOption(
"Hollywood (2021)",
"/account/?ptype=post&tax_category%5B%5D=hollywood&tax_release-year=2021&wpas=1",
),
]),
SelectFilter("EnglishSeriesFilter", "Hindi Series", 0, [
SelectFilterOption("<select>", ""),
@@ -319,13 +346,17 @@ class YoMovies extends MProvider {
SelectFilterOption("Hootzy", "/director/hootzy-channel"),
SelectFilterOption("Balloons", "/director/balloons-originals"),
SelectFilterOption(
"Big Movie Zoo", "/director/big-movie-zoo-originals"),
"Big Movie Zoo",
"/director/big-movie-zoo-originals",
),
SelectFilterOption("Bambooflix", "/director/bambooflix"),
SelectFilterOption("Piliflix", "/director/piliflix-originals"),
SelectFilterOption("11upmovies", "/director/11upmovies-originals"),
SelectFilterOption("Eightshots", "/director/eightshots-originals"),
SelectFilterOption(
"I-Entertainment", "/director/i-entertainment-exclusive"),
"I-Entertainment",
"/director/i-entertainment-exclusive",
),
SelectFilterOption("Hotprime", "/director/hotprime-originals"),
SelectFilterOption("BananaPrime", "/director/banana-prime"),
SelectFilterOption("HotHitFilms", "/director/hothitfilms"),

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

View File

@@ -13,4 +13,5 @@ Source _nimegami = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/nimegami/icon.png",
sourceCodeUrl: _nimegamiCodeUrl,
version: _nimegamiVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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(
final ress =
(await client.post(
Uri.parse("${source.baseUrl}/wp-admin/admin-ajax.php"),
headers: {
"_": "_"
},
headers: {"_": "_"},
body: {
"action": "player_ajax",
"post": dataPost,
"nume": dataNume,
"type": dataType
}))
.body;
"type": dataType,
},
)).body;
final playerLink =
xpath(ress, '//iframe[@class="playeriframe"]/@src').first;
@@ -127,8 +141,10 @@ class OploVerz extends MProvider {
List<MManga> animeList = [];
final urls = xpath(res, '//div[@class="relat"]/article/div/div/a/@href');
final names = xpath(res, '//div[@class="relat"]/article/div/div/a/@title');
final images =
xpath(res, '//div[@class="relat"]/article/div/div/a/div/img/@src');
final images = xpath(
res,
'//div[@class="relat"]/article/div/div/a/div/img/@src',
);
for (var i = 0; i < names.length; i++) {
MManga anime = MManga();
@@ -138,8 +154,10 @@ class OploVerz extends MProvider {
animeList.add(anime);
}
final pages = xpath(res, '//div[@class="pagination"]/a/@href');
final pageNumberCurrent = xpath(res,
'//div[@class="pagination"]/span[@class="page-numbers current"]/text()');
final pageNumberCurrent = xpath(
res,
'//div[@class="pagination"]/span[@class="page-numbers current"]/text()',
);
bool hasNextPage = true;
if (pageNumberCurrent.isNotEmpty && pages.isNotEmpty) {

View File

@@ -13,4 +13,5 @@ Source _oploverz = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/oploverz/icon.png",
sourceCodeUrl: _oploverzCodeUrl,
version: _oploverzVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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(
final resNonceAction =
(await client.post(
Uri.parse("$baseUrl/wp-admin/admin-ajax.php"),
headers: {"_": "_"},
body: {"action": nonceAction}))
.body;
body: {"action": nonceAction},
)).body;
final nonce = substringBefore(substringAfter(resNonceAction, ":\""), '"');
final mirrorstream =
xpath(res, '//*[@class="mirrorstream"]/ul/li/a/@data-content');
final mirrorstream = xpath(
res,
'//*[@class="mirrorstream"]/ul/li/a/@data-content',
);
for (var stream in mirrorstream) {
List<MVideo> a = [];
final decodedData = json.decode(utf8.decode(base64Url.decode(stream)));
@@ -112,17 +125,12 @@ class OtakuDesu extends MProvider {
final id = decodedData["id"];
final i = decodedData["i"];
final res = (await client
.post(Uri.parse("$baseUrl/wp-admin/admin-ajax.php"), headers: {
"_": "_"
}, body: {
"i": i,
"id": id,
"q": q,
"nonce": nonce,
"action": action
}))
.body;
final res =
(await client.post(
Uri.parse("$baseUrl/wp-admin/admin-ajax.php"),
headers: {"_": "_"},
body: {"i": i, "id": id, "q": q, "nonce": nonce, "action": action},
)).body;
final resJson = json.decode(res);
final html = utf8.decode(base64Url.decode(resJson["data"]));
String url = xpath(html, '//iframe/@src').first;
@@ -152,8 +160,10 @@ class OtakuDesu extends MProvider {
final res = (await client.get(Uri.parse(url))).body;
final script =
xpath(res, '//script[contains(text(), "player.src")]/text()').first;
final videoUrl =
substringBefore(substringAfter(script, "src: \""), '"');
final videoUrl = substringBefore(
substringAfter(script, "src: \""),
'"',
);
MVideo video = MVideo();
video
..url = videoUrl
@@ -196,12 +206,18 @@ class OtakuDesu extends MProvider {
MPages parseAnimeList(String res) {
List<MManga> animeList = [];
final urls =
xpath(res, '//div[@class="detpost"]/div[@class="thumb"]/a/@href');
final names = xpath(res,
'//div[@class="detpost"]/div[@class="thumb"]/a/div[@class="thumbz"]/h2/text()');
final images = xpath(res,
'//div[@class="detpost"]/div[@class="thumb"]/a/div[@class="thumbz"]/img/@src');
final urls = xpath(
res,
'//div[@class="detpost"]/div[@class="thumb"]/a/@href',
);
final names = xpath(
res,
'//div[@class="detpost"]/div[@class="thumb"]/a/div[@class="thumbz"]/h2/text()',
);
final images = xpath(
res,
'//div[@class="detpost"]/div[@class="thumb"]/a/div[@class="thumbz"]/img/@src',
);
for (var i = 0; i < names.length; i++) {
MManga anime = MManga();
@@ -211,7 +227,9 @@ class OtakuDesu extends MProvider {
animeList.add(anime);
}
final pages = xpath(
res, '//div[@class="pagenavix"]/a[@class="next page-numbers"]/@href');
res,
'//div[@class="pagenavix"]/a[@class="next page-numbers"]/@href',
);
return MPages(animeList, pages.isNotEmpty);
}
@@ -224,14 +242,16 @@ class OtakuDesu extends MProvider {
value: "https://otakudesu.cloud",
dialogTitle: "Override BaseUrl",
dialogMessage: "",
text: "https://otakudesu.cloud"),
text: "https://otakudesu.cloud",
),
ListPreference(
key: "preferred_quality",
title: "Preferred quality",
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"])
entryValues: ["1080", "720", "480", "360"],
),
];
}
}

View File

@@ -13,4 +13,5 @@ Source _otakudesu = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/id/otakudesu/icon.png",
sourceCodeUrl: _otakudesuCodeUrl,
version: _otakudesuVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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.indexOf("Stato:") + 6,
details.indexOf("Data di uscita:"),
),
statusList,
);
anime.author = details.substring(7, details.indexOf("Stato:"));
}
@@ -174,14 +197,20 @@ class AnimeSaturn extends MProvider {
}
}
anime.genre = xpath(res,
'//*[@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100"]/a/text()');
anime.genre = xpath(
res,
'//*[@class="container shadow rounded bg-dark-as-box mb-3 p-3 w-100"]/a/text()',
);
final epUrls = xpath(res,
'//*[@class="btn-group episodes-button episodi-link-button"]/a/@href');
final epUrls = xpath(
res,
'//*[@class="btn-group episodes-button episodi-link-button"]/a/@href',
);
final titles = xpath(res,
'//*[@class="btn-group episodes-button episodi-link-button"]/a/text()');
final titles = xpath(
res,
'//*[@class="btn-group episodes-button episodi-link-button"]/a/text()',
);
List<MChapter>? episodesList = [];
for (var i = 0; i < epUrls.length; i++) {
@@ -211,8 +240,10 @@ class AnimeSaturn extends MProvider {
List<MVideo> videos = [];
if (masterUrl.endsWith("playlist.m3u8")) {
final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -325,7 +356,8 @@ class AnimeSaturn extends MProvider {
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p", "240p", "144p"],
entryValues: ["1080", "720", "480", "360", "240", "144"]),
entryValues: ["1080", "720", "480", "360", "240", "144"],
),
];
}

View File

@@ -13,4 +13,5 @@ Source _animesaturn = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/it/animesaturn/icon.png",
sourceCodeUrl: _animesaturnCodeUrl,
version: _animesaturnVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

View File

@@ -14,15 +14,16 @@ class AnimesVision extends MProvider {
@override
Map<String, String> get headers => {
"Referer": baseUrl,
"Accept-Language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7"
"Accept-Language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7",
};
@override
Future<MPages> getPopular(int page) async {
final res = (await client.get(Uri.parse(baseUrl), headers: headers)).body;
final document = parseHtml(res);
final elements =
document.select("div#anime-trending div.item > a.film-poster");
final elements = document.select(
"div#anime-trending div.item > a.film-poster",
);
List<MManga> animeList = [];
for (var element in elements) {
var anime = MManga();
@@ -37,12 +38,15 @@ class AnimesVision extends MProvider {
@override
Future<MPages> getLatestUpdates(int page) async {
final res = (await client.get(Uri.parse("$baseUrl/lancamentos?page=$page"),
headers: headers))
.body;
final res =
(await client.get(
Uri.parse("$baseUrl/lancamentos?page=$page"),
headers: headers,
)).body;
final document = parseHtml(res);
final elements =
document.select("div.container div.screen-items > div.item");
final elements = document.select(
"div.container div.screen-items > div.item",
);
List<MManga> animeList = [];
for (var element in elements) {
var anime = MManga();
@@ -56,9 +60,10 @@ class AnimesVision extends MProvider {
@override
Future<MPages> search(String query, int page, FilterList filterList) async {
final res = (await client
.get(Uri.parse("$baseUrl/search-anime?nome=$query&page=$page")))
.body;
final res =
(await client.get(
Uri.parse("$baseUrl/search-anime?nome=$query&page=$page"),
)).body;
final document = parseHtml(res);
final elements = document.select("div.film_list-wrap div.film-poster");
List<MManga> animeList = [];
@@ -76,7 +81,7 @@ class AnimesVision extends MProvider {
@override
Future<MManga> getDetail(String url) async {
final statusList = [
{"Atualmente sendo exibido": 0, "Fim da exibição": 1}
{"Atualmente sendo exibido": 0, "Fim da exibição": 1},
];
MManga anime = MManga();
final res = (await client.get(Uri.parse("$baseUrl$url"))).body;
@@ -113,8 +118,9 @@ class AnimesVision extends MProvider {
while (hasNextPage(document)) {
if (episodeList.isNotEmpty) {
final nextUrl =
nextPageElements(document)[0].selectFirst("a").attr("href");
final nextUrl = nextPageElements(
document,
)[0].selectFirst("a").attr("href");
document = parseHtml((await client.get(Uri.parse(nextUrl))).body);
}
for (var element
@@ -131,13 +137,15 @@ class AnimesVision extends MProvider {
Future<List<MVideo>> getVideoList(String url) async {
final res = (await client.get(Uri.parse("$baseUrl$url"))).body;
final document = parseHtml(res);
final encodedScript = document
final encodedScript =
document
.selectFirst("div.player-frame div#playerglobalapi ~ script")
.text;
final decodedScript = decodeScriptFromString(encodedScript);
List<MVideo> videos = [];
for (RegExpMatch match in RegExp(r'"file":"(\S+?)",.*?"label":"(.*?)"')
.allMatches(decodedScript)) {
for (RegExpMatch match in RegExp(
r'"file":"(\S+?)",.*?"label":"(.*?)"',
).allMatches(decodedScript)) {
final videoUrl = match.group(1)!.replaceAll('\\', '');
final qualityName = match.group(2);
var video = MVideo();
@@ -155,10 +163,14 @@ class AnimesVision extends MProvider {
}
List<MElement> nextPageElements(MDocument document) {
final elements = document
final elements =
document
.select("ul.pagination li.page-item")
.where((MElement e) =>
e.outerHtml.contains("") && !e.outerHtml.contains("disabled"))
.where(
(MElement e) =>
e.outerHtml.contains("") &&
!e.outerHtml.contains("disabled"),
)
.toList();
return elements;
}
@@ -173,7 +185,8 @@ class AnimesVision extends MProvider {
}
String getInfo(MElement element, String key) {
final divs = element
final divs =
element
.select("div.item")
.where((MElement e) => e.outerHtml.contains(key))
.toList();
@@ -235,7 +248,8 @@ class AnimesVision extends MProvider {
summary: "",
valueIndex: 1,
entries: ["480p", "720p", "1080p", "4K"],
entryValues: ["1080", "720", "480", "4K"]),
entryValues: ["1080", "720", "480", "4K"],
),
];
}
@@ -251,7 +265,11 @@ class AnimesVision extends MProvider {
}
String decodeScript(
String encodedString, String magicStr, int offset, int limit) {
String encodedString,
String magicStr,
int offset,
int limit,
) {
RegExp regex = RegExp('\\w');
List<String> parts = encodedString.split(magicStr[limit]);
List<String> decodedParts = [];
@@ -259,7 +277,9 @@ class AnimesVision extends MProvider {
String replaced = part;
for (Match match in regex.allMatches(part)) {
replaced = replaced.replaceFirst(
match.group(0)!, magicStr.indexOf(match.group(0)!).toString());
match.group(0)!,
magicStr.indexOf(match.group(0)!).toString(),
);
}
int charInt = convertToNum(replaced, limit) - offset;
decodedParts.add(String.fromCharCode(charInt));

View File

@@ -13,4 +13,5 @@ Source _animesvision = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/pt/animesvision/icon.png",
sourceCodeUrl: _animesvisionCodeUrl,
version: _animesvisionVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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");
@@ -128,7 +130,8 @@ class Filma24 extends MProvider {
value: "https://www.filma24.band",
dialogTitle: "Domeni i përdorur aktualisht",
dialogMessage: "",
text: "https://www.filma24.band"),
text: "https://www.filma24.band",
),
];
}
@@ -192,22 +195,23 @@ class Filma24 extends MProvider {
}
Future<List<MVideo>> vidmolyExtractor(String url) async {
final headers = {
'Referer': 'https://vidmoly.to',
};
final headers = {'Referer': 'https://vidmoly.to'};
List<MVideo> videos = [];
final playListUrlResponse = (await client.get(Uri.parse(url))).body;
final playlistUrl =
RegExp(r'file:"(\S+?)"').firstMatch(playListUrlResponse)?.group(1) ??
"";
if (playlistUrl.isEmpty) return [];
final masterPlaylistRes =
await client.get(Uri.parse(playlistUrl), headers: headers);
final masterPlaylistRes = await client.get(
Uri.parse(playlistUrl),
headers: headers,
);
if (masterPlaylistRes.statusCode == 200) {
for (var it
in substringAfter(masterPlaylistRes.body, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes.body,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -234,8 +238,10 @@ class Filma24 extends MProvider {
"";
if (playlistUrl.isEmpty) return [];
final masterPlaylistRes = (await client.get(Uri.parse(playlistUrl))).body;
for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:")
.split("#EXT-X-STREAM-INF:")) {
for (var it in substringAfter(
masterPlaylistRes,
"#EXT-X-STREAM-INF:",
).split("#EXT-X-STREAM-INF:")) {
final quality =
"${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p";
@@ -258,8 +264,10 @@ class Filma24 extends MProvider {
return [];
}
final videoUrl =
substringBefore(substringAfter(js.first, "sources: [\""), '"');
final videoUrl = substringBefore(
substringAfter(js.first, "sources: [\""),
'"',
);
MVideo video = MVideo();
video
..url = videoUrl
@@ -283,8 +291,10 @@ class Filma24 extends MProvider {
mangaList.add(manga);
}
return MPages(mangaList,
document.selectFirst("div > a.nextpostslink")?.attr("href") != null);
return MPages(
mangaList,
document.selectFirst("div > a.nextpostslink")?.attr("href") != null,
);
}
}

View File

@@ -13,4 +13,5 @@ Source _filma24 = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/sq/filma24/icon.png",
sourceCodeUrl: _filma24CodeUrl,
version: _filma24Version,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

View File

@@ -15,7 +15,9 @@ class DiziWatch extends MProvider {
Map<String, String> get headers => {};
Future<MPages> parseMainList(int index) async {
MDocument dom = parseHtml((await client.get(Uri.parse(source.baseUrl))) .body);
MDocument dom = parseHtml(
(await client.get(Uri.parse(source.baseUrl))).body,
);
List<MManga> list = [];
MElement containingElement = dom.select("#list-series-hizala2")[index];
List<MElement> results = containingElement.select("#list-series-main");
@@ -59,7 +61,13 @@ class DiziWatch extends MProvider {
genre = filter.values[filter.state].value;
}
}
MDocument dom = parseHtml((await client.get(Uri.parse("${source.baseUrl}/anime-arsivi/page/${page}/?orderby=${orderby}&yil=${year}&imdb=${imdb}&isim=${query}&tur=${genre}"))) .body);
MDocument dom = parseHtml(
(await client.get(
Uri.parse(
"${source.baseUrl}/anime-arsivi/page/${page}/?orderby=${orderby}&yil=${year}&imdb=${imdb}&isim=${query}&tur=${genre}",
),
)).body,
);
List<MElement> results = dom.select("#list-series");
List<MManga> list = [];
for (MElement result in results) {
@@ -73,14 +81,16 @@ class DiziWatch extends MProvider {
}
MElement paginateLinksDiv = dom.selectFirst("div.paginate-links");
int lastPage = int.parse(paginateLinksDiv.selectFirst("a.next").previousElementSibling.text ?? "1");
int lastPage = int.parse(
paginateLinksDiv.selectFirst("a.next").previousElementSibling.text ?? "1",
);
return MPages(list, lastPage > page);
}
@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();
@@ -98,7 +108,10 @@ class DiziWatch extends MProvider {
for (MElement result in results) {
MElement a = result.select("a")[1];
MChapter chapter = new MChapter();
chapter.name = result.selectFirst(".baslik").text + " | " + result.selectFirst("#bolum-ismi").text;
chapter.name =
result.selectFirst(".baslik").text +
" | " +
result.selectFirst("#bolum-ismi").text;
chapter.url = a.getHref;
chapters.add(chapter);
}
@@ -109,9 +122,16 @@ class DiziWatch extends MProvider {
@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 = [];
for (var source in sources) {
@@ -124,7 +144,11 @@ class DiziWatch extends MProvider {
}
String quality = getPreferenceValue(source.id, "preferred_quality");
videos.sort((MVideo a, MVideo b) => (b.quality.contains(quality) ? 1 : 0) - (a.quality.contains(quality) ? 1 : 0));
videos.sort(
(MVideo a, MVideo b) =>
(b.quality.contains(quality) ? 1 : 0) -
(a.quality.contains(quality) ? 1 : 0),
);
return videos;
}
@@ -136,7 +160,7 @@ class DiziWatch extends MProvider {
SelectFilter("Sort", "Sırala", 0, [
SelectFilterOption("IMDb Puanına Göre", "meta_value"),
SelectFilterOption("Alfabetik", "name"),
SelectFilterOption("Eklenme Tarihine Göre", "ID")
SelectFilterOption("Eklenme Tarihine Göre", "ID"),
]),
TextFilter("Year", "Yapım Yılı"),
SelectFilter("Genre", "Tür", 0, [
@@ -178,10 +202,13 @@ class DiziWatch extends MProvider {
SelectFilterOption("Tarihi", "tarihi"),
SelectFilterOption("Uzay", "uzay"),
SelectFilterOption("Vampir", "vampir"),
SelectFilterOption("Yaşamdan Kesitler", "yasam")
SelectFilterOption("Yaşamdan Kesitler", "yasam"),
]),
SelectFilter("MinIMDBRating", "Min. IMBD Puanı", 0, [
SelectFilterOption("1", "0"), // value 1 looks like buggy so use 0 it wont make any difference.
SelectFilterOption(
"1",
"0",
), // value 1 looks like buggy so use 0 it wont make any difference.
SelectFilterOption("2", "2"),
SelectFilterOption("3", "3"),
SelectFilterOption("4", "4"),
@@ -189,8 +216,8 @@ class DiziWatch extends MProvider {
SelectFilterOption("6", "6"),
SelectFilterOption("7", "7"),
SelectFilterOption("8", "8"),
SelectFilterOption("9", "9")
])
SelectFilterOption("9", "9"),
]),
];
}
@@ -203,11 +230,12 @@ class DiziWatch extends MProvider {
summary: "",
valueIndex: 0,
entries: ["1080p", "480p"], // I only saw 1080p and 480p in diziWatch.
entryValues: ["1080", "480"])
entryValues: ["1080", "480"],
),
];
}
}
DiziWatch main(MSource source) {
return DiziWatch(source:source);
return DiziWatch(source: source);
}

View File

@@ -13,4 +13,5 @@ Source _diziwatchSource = Source(
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/tr/diziwatch/icon.png",
sourceCodeUrl: _diziwatchSourceCodeUrl,
version: _diziwatchVersion,
itemType: ItemType.anime);
itemType: ItemType.anime,
);

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") ??
manga.imageUrl =
imageElement?.attr("data-src") ??
imageElement?.attr("data-lazy-src") ??
imageElement?.attr("srcset") ??
imageElement?.getSrc;
final id = document
final id =
document
.selectFirst("div[id^=manga-chapters-holder]")
?.attr("data-id") ??
"";
@@ -193,11 +202,14 @@ class Madara extends MProvider {
final oldXhrChaptersRequest = await client.post(
Uri.parse("${baseUrl}wp-admin/admin-ajax.php"),
headers: headers,
body: {"action": "manga_get_chapters", "manga": mangaId});
body: {"action": "manga_get_chapters", "manga": mangaId},
);
if (oldXhrChaptersRequest.statusCode == 400) {
res = (await client.post(Uri.parse("${url}ajax/chapters"),
headers: headers))
.body;
res =
(await client.post(
Uri.parse("${url}ajax/chapters"),
headers: headers,
)).body;
} else {
res = oldXhrChaptersRequest.body;
}
@@ -205,9 +217,11 @@ class Madara extends MProvider {
MDocument chapDoc = parseHtml(res);
manga.chapters = getChapters(chapDoc);
if (manga.chapters.isEmpty) {
res = (await client.post(Uri.parse("${url}ajax/chapters"),
headers: headers))
.body;
res =
(await client.post(
Uri.parse("${url}ajax/chapters"),
headers: headers,
)).body;
chapDoc = parseHtml(res);
manga.chapters = getChapters(chapDoc);
}
@@ -221,13 +235,15 @@ class Madara extends MProvider {
final document = parseHtml(res.body);
final pageElements = document.select(
"div.page-break, li.blocks-gallery-item, .reading-content .text-left:not(:has(.blocks-gallery-item)) img");
"div.page-break, li.blocks-gallery-item, .reading-content .text-left:not(:has(.blocks-gallery-item)) img",
);
List<String> imgs = [];
for (var element in pageElements) {
try {
final imgElement = element.selectFirst("img");
final img = imgElement.attr("src") ??
final img =
imgElement.attr("src") ??
imgElement.attr("data-src") ??
imgElement.attr("data-lazy-src") ??
imgElement.attr("srcset");
@@ -261,7 +277,8 @@ class Madara extends MProvider {
for (var i = 0; i < elements.length; i++) {
final postTitle = elements[i].selectFirst("div.post-title a");
final imageElement = elements[i].selectFirst("img");
final image = imageElement?.attr("data-src") ??
final image =
imageElement?.attr("data-src") ??
imageElement?.attr("data-lazy-src") ??
imageElement?.attr("srcset") ??
imageElement?.getSrc ??
@@ -301,7 +318,7 @@ class Madara extends MProvider {
SelectFilterOption("All", ""),
SelectFilterOption("None", "0"),
SelectFilterOption("Only", "1"),
])
]),
];
}

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

View File

@@ -1,14 +1,15 @@
import '../../../../../../model/source.dart';
Source get akumanotenshiSource => _akumanotenshiSource;
Source get akumanotenshiSource => _akumanotenshiSource;
Source _akumanotenshiSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _alonescanlatorSource = Source(
name: "Alone Scanlator",
baseUrl: "https://alonescanlator.com.br",
lang: "pt-br",
isNsfw:false,
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"
);
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 get anikigaSource => _anikigaSource;
Source _anikigaSource = Source(
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",
);
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 get araznovelSource => _araznovelSource;
Source _araznovelSource = Source(
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",
);
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 get arthurscanSource => _arthurscanSource;
Source _arthurscanSource = Source(
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",
);
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 get astralmangaSource => _astralmangaSource;
Source _astralmangaSource = Source(
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",
);
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 get asurascansusSource => _asurascansusSource;
Source _asurascansusSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _atikrostSource = Source(
name: "Atikrost",
baseUrl: "https://www.atikrost.com",
lang: "tr",
isNsfw:false,
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"
);
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 get barmangaSource => _barmangaSource;
Source _barmangaSource = Source(
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",
);
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 get bestmangaSource => _bestmangaSource;
Source _bestmangaSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _bokugentranslationSource = Source(
name: "BokugenTranslation",
baseUrl: "https://bokugents.com",
lang: "es",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _borutoexplorerSource = Source(
name: "Boruto Explorer",
baseUrl: "https://leitor.borutoexplorer.com.br",
lang: "pt-br",
isNsfw:false,
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"
);
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 get chibimangaSource => _chibimangaSource;
Source _chibimangaSource = Source(
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",
);
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 get clovermangaSource => _clovermangaSource;
Source _clovermangaSource = Source(
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",
);
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 get cocoripSource => _cocoripSource;
Source _cocoripSource = Source(
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",
);
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 get coffeemangaSource => _coffeemangaSource;
Source _coffeemangaSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _crystalcomicsSource = Source(
name: "Crystal Comics",
baseUrl: "https://crystalcomics.com",
lang: "pt-br",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _daprobSource = Source(
name: "DapRob",
baseUrl: "https://daprob.com",
lang: "es",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _demanhuasSource = Source(
name: "DeManhuas",
baseUrl: "https://demanhuas.com",
lang: "es",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _diamondfansubSource = Source(
name: "DiamondFansub",
baseUrl: "https://diamondfansub.com",
lang: "tr",
isNsfw:false,
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"
);
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 get doodmangaSource => _doodmangaSource;
Source _doodmangaSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _dragonteaSource = Source(
name: "DragonTea",
baseUrl: "https://dragontea.ink",
lang: "en",
isNsfw:false,
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"
);
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 get elitemangaSource => _elitemangaSource;
Source _elitemangaSource = Source(
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",
);
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 get emperorscanSource => _emperorscanSource;
Source _emperorscanSource = Source(
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",
);
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 get evascansSource => _evascansSource;
Source _evascansSource = Source(
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",
);
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 get factmangaSource => _factmangaSource;
Source _factmangaSource = Source(
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",
);
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 get falconmangaSource => _falconmangaSource;
Source _falconmangaSource = Source(
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",
);
iconUrl:
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/manga/multisrc/madara/src/falconmanga/icon.png",
);

View File

@@ -5,9 +5,10 @@ Source _fayscansSource = Source(
name: "Fay Scans",
baseUrl: "https://fayscans.net",
lang: "pt-br",
isNsfw:false,
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"
);
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 get firstkissdashmangaSource => _firstkissdashmangaSource;
Source _firstkissdashmangaSource = Source(
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",
);
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 get freemangatopSource => _freemangatopSource;
Source _freemangatopSource = Source(
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",
);
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 get frscanSource => _frscanSource;
Source _frscanSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _galinhasamuraiscanSource = Source(
name: "Galinha Samurai Scan",
baseUrl: "https://galinhasamurai.com",
lang: "pt-br",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _garciamangaSource = Source(
name: "Garcia Manga",
baseUrl: "https://garciamanga.com",
lang: "tr",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _gatemangaSource = Source(
name: "Gatemanga",
baseUrl: "https://gatemanga.com",
lang: "ar",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _globalblogingSource = Source(
name: "Global Bloging",
baseUrl: "https://globalbloging.com",
lang: "en",
isNsfw:false,
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"
);
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 get glorymangaSource => _glorymangaSource;
Source _glorymangaSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _gmangasiteSource = Source(
name: "GMANGA (unoriginal)",
baseUrl: "https://gmanga.site",
lang: "ar",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _grabberzoneSource = Source(
name: "Grabber Zone",
baseUrl: "https://grabber.zone",
lang: "all",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _guncelmangaSource = Source(
name: "GuncelManga",
baseUrl: "https://guncelmanga.net",
lang: "tr",
isNsfw:false,
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"
);
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 get harimangaSource => _harimangaSource;
Source _harimangaSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _herenscanSource = Source(
name: "HerenScan",
baseUrl: "https://herenscan.com",
lang: "es",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _hikariganaiSource = Source(
name: "Hikari Ga Nai",
baseUrl: "https://hikariganai.xyz",
lang: "pt-br",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _housemangasSource = Source(
name: "HouseMangas",
baseUrl: "https://housemangas.com",
lang: "es",
isNsfw:false,
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"
);
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

@@ -5,9 +5,10 @@ Source _hwagoSource = Source(
name: "Hwago",
baseUrl: "https://hwago.org",
lang: "id",
isNsfw:false,
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"
);
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 get immortalupdatesSource => _immortalupdatesSource;
Source _immortalupdatesSource = Source(
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",
);
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

@@ -5,9 +5,10 @@ Source _imperiodabritanniaSource = Source(
name: "Sagrado Império da Britannia",
baseUrl: "https://imperiodabritannia.com",
lang: "pt-br",
isNsfw:false,
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"
);
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