add source preference

This commit is contained in:
kodjomoustapha
2023-12-02 18:58:02 +01:00
parent 6574fd044c
commit e0c2be06a3
9 changed files with 571 additions and 77 deletions

View File

@@ -6,18 +6,21 @@ class DopeFlix extends MProvider {
@override @override
Future<MPages> getPopular(MSource source, int page) async { Future<MPages> getPopular(MSource source, int page) async {
final data = {"url": "${source.baseUrl}/movie?page=$page"}; final data = {
"url":
"${preferenceBaseUrl(source.id)}/${getPreferenceValue(source.id, "preferred_popular_page")}?page=$page"
};
final res = await http('GET', json.encode(data)); final res = await http('GET', json.encode(data));
return parseAnimeList(res); return parseAnimeList(res);
} }
@override @override
Future<MPages> getLatestUpdates(MSource source, int page) async { Future<MPages> getLatestUpdates(MSource source, int page) async {
final data = {"url": "${source.baseUrl}/home"}; final data = {"url": "${preferenceBaseUrl(source.id)}/home"};
final res = await http('GET', json.encode(data)); final res = await http('GET', json.encode(data));
List<MManga> animeList = []; List<MManga> animeList = [];
final path = final path =
'//section[contains(text(),"Latest Movies")]/div/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]'; '//section[contains(text(),"${getPreferenceValue(source.id, "preferred_latest_page")}")]/div/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]';
final urls = xpath(res, '$path/a/@href'); final urls = xpath(res, '$path/a/@href');
final names = xpath(res, '$path/a/@title'); final names = xpath(res, '$path/a/@title');
final images = xpath(res, '$path/img/@data-src'); final images = xpath(res, '$path/img/@data-src');
@@ -36,7 +39,7 @@ class DopeFlix extends MProvider {
Future<MPages> search( Future<MPages> search(
MSource source, String query, int page, FilterList filterList) async { MSource source, String query, int page, FilterList filterList) async {
final filters = filterList.filters; final filters = filterList.filters;
String url = "${source.baseUrl}"; String url = "${preferenceBaseUrl(source.id)}";
if (query.isNotEmpty) { if (query.isNotEmpty) {
url += "/search/${query.replaceAll(" ", "-")}?page=$page"; url += "/search/${query.replaceAll(" ", "-")}?page=$page";
@@ -79,7 +82,7 @@ class DopeFlix extends MProvider {
@override @override
Future<MManga> getDetail(MSource source, String url) async { Future<MManga> getDetail(MSource source, String url) async {
url = Uri.parse(url).path; url = Uri.parse(url).path;
final data = {"url": "${source.baseUrl}$url"}; final data = {"url": "${preferenceBaseUrl(source.id)}$url"};
final res = await http('GET', json.encode(data)); final res = await http('GET', json.encode(data));
MManga anime = MManga(); MManga anime = MManga();
final description = xpath(res, '//div[@class="description"]/text()'); final description = xpath(res, '//div[@class="description"]/text()');
@@ -98,10 +101,12 @@ class DopeFlix extends MProvider {
if (dataType == "1") { if (dataType == "1") {
MChapter episode = MChapter(); MChapter episode = MChapter();
episode.name = "Movie"; episode.name = "Movie";
episode.url = "${source.baseUrl}/ajax/movie/episodes/$id"; episode.url = "${preferenceBaseUrl(source.id)}/ajax/movie/episodes/$id";
episodesList.add(episode); episodesList.add(episode);
} else { } else {
final dataS = {"url": "${source.baseUrl}/ajax/v2/tv/seasons/$id"}; final dataS = {
"url": "${preferenceBaseUrl(source.id)}/ajax/v2/tv/seasons/$id"
};
final resS = await http('GET', json.encode(dataS)); final resS = await http('GET', json.encode(dataS));
final seasonIds = final seasonIds =
@@ -112,7 +117,8 @@ class DopeFlix extends MProvider {
final seasonId = seasonIds[i]; final seasonId = seasonIds[i];
final seasonName = seasonNames[i]; final seasonName = seasonNames[i];
final dataE = { final dataE = {
"url": "${source.baseUrl}/ajax/v2/season/episodes/$seasonId" "url":
"${preferenceBaseUrl(source.id)}/ajax/v2/season/episodes/$seasonId"
}; };
final html = await http('GET', json.encode(dataE)); final html = await http('GET', json.encode(dataE));
final epsHtml = querySelectorAll(html, final epsHtml = querySelectorAll(html,
@@ -120,7 +126,8 @@ class DopeFlix extends MProvider {
typeElement: 2, typeElement: 2,
attributes: "", attributes: "",
typeRegExp: 0); typeRegExp: 0);
print("${source.baseUrl}/ajax/v2/season/episodes/$seasonId"); print(
"${preferenceBaseUrl(source.id)}/ajax/v2/season/episodes/$seasonId");
for (var epHtml in epsHtml) { for (var epHtml in epsHtml) {
final episodeId = final episodeId =
xpath(epHtml, '//div[contains(@class,"eps-item")]/@data-id') xpath(epHtml, '//div[contains(@class,"eps-item")]/@data-id')
@@ -130,7 +137,8 @@ class DopeFlix extends MProvider {
final epName = xpath(epHtml, '//h3[@class="film-name"]/text()').first; final epName = xpath(epHtml, '//h3[@class="film-name"]/text()').first;
MChapter episode = MChapter(); MChapter episode = MChapter();
episode.name = "$seasonName $epNum $epName"; episode.name = "$seasonName $epNum $epName";
episode.url = "${source.baseUrl}/ajax/v2/episode/servers/$episodeId"; episode.url =
"${preferenceBaseUrl(source.id)}/ajax/v2/episode/servers/$episodeId";
episodesList.add(episode); episodesList.add(episode);
} }
} }
@@ -142,8 +150,8 @@ class DopeFlix extends MProvider {
@override @override
Future<List<MVideo>> getVideoList(MSource source, String url) async { Future<List<MVideo>> getVideoList(MSource source, String url) async {
url = Uri.parse(url).path; url = Uri.parse(url).path;
final res = final res = await http(
await http('GET', json.encode({"url": "${source.baseUrl}/$url"})); 'GET', json.encode({"url": "${preferenceBaseUrl(source.id)}/$url"}));
final vidsHtml = querySelectorAll(res, final vidsHtml = querySelectorAll(res,
selector: "ul.fss-list a.btn-play", selector: "ul.fss-list a.btn-play",
typeElement: 2, typeElement: 2,
@@ -154,7 +162,9 @@ class DopeFlix extends MProvider {
final id = xpath(vidHtml, '//a/@data-id').first; final id = xpath(vidHtml, '//a/@data-id').first;
final name = xpath(vidHtml, '//span/text()').first; final name = xpath(vidHtml, '//span/text()').first;
final resSource = await http( final resSource = await http(
'GET', json.encode({"url": "${source.baseUrl}/ajax/sources/$id"})); 'GET',
json.encode(
{"url": "${preferenceBaseUrl(source.id)}/ajax/sources/$id"}));
final vidUrl = final vidUrl =
substringBefore(substringAfter(resSource, "\"link\":\""), "\""); substringBefore(substringAfter(resSource, "\"link\":\""), "\"");
List<MVideo> a = []; List<MVideo> a = [];
@@ -212,6 +222,7 @@ class DopeFlix extends MProvider {
subtitles.add(subtitle); subtitles.add(subtitle);
} catch (_) {} } catch (_) {}
} }
subtitles = sortSubs(subtitles, source.id);
if (type == "hls") { if (type == "hls") {
final masterPlaylistRes = final masterPlaylistRes =
await http('GET', json.encode({"url": masterUrl})); await http('GET', json.encode({"url": masterUrl}));
@@ -248,7 +259,7 @@ class DopeFlix extends MProvider {
videos.addAll(a); videos.addAll(a);
} }
return videos; return sortVideos(videos, source.id);
} }
Future<List<List<int>>> generateIndexPairs() async { Future<List<List<int>>> generateIndexPairs() async {
@@ -261,8 +272,8 @@ class DopeFlix extends MProvider {
script = script.substring(0, script.lastIndexOf(',')); script = script.substring(0, script.lastIndexOf(','));
final list = script final list = script
.split(",") .split(",")
.map((e) { .map((String e) {
String value = substringAfter((e as String), "="); String value = substringAfter(e, "=");
if (value.contains("0x")) { if (value.contains("0x")) {
return int.parse(substringAfter(value, "0x"), radix: 16); return int.parse(substringAfter(value, "0x"), radix: 16);
} else { } else {
@@ -273,7 +284,7 @@ class DopeFlix extends MProvider {
.skip(1) .skip(1)
.toList(); .toList();
return chunked(list, 2) return chunked(list, 2)
.map((list) => (list as List<int>).reversed.toList()) .map((List<int> list) => list.reversed.toList())
.toList(); .toList();
} }
@@ -405,6 +416,119 @@ class DopeFlix extends MProvider {
]; ];
} }
@override
List<dynamic> getSourcePreferences(MSource source) {
return [
ListPreference(
key: "preferred_domain",
title: "Preferred domain",
summary: "",
valueIndex: 0,
entries: ["dopebox.to", "dopebox.se"],
entryValues: ["https://dopebox.to", "https://dopebox.se"]),
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080p", "720p", "480p", "360p"]),
ListPreference(
key: "preferred_subLang",
title: "Preferred sub language",
summary: "",
valueIndex: 1,
entries: [
"Arabic",
"English",
"French",
"German",
"Hungarian",
"Italian",
"Japanese",
"Portuguese",
"Romanian",
"Russian",
"Spanish"
],
entryValues: [
"Arabic",
"English",
"French",
"German",
"Hungarian",
"Italian",
"Japanese",
"Portuguese",
"Romanian",
"Russian",
"Spanish"
]),
ListPreference(
key: "preferred_latest_page",
title: "Preferred latest page",
summary: "",
valueIndex: 0,
entries: ["Movies", "TV Shows"],
entryValues: ["Latest Movies", "Latest TV Shows"]),
ListPreference(
key: "preferred_popular_page",
title: "Preferred popular page",
summary: "",
valueIndex: 0,
entries: ["Movies", "TV Shows"],
entryValues: ["movie", "tv-show"]),
];
}
List<MVideo> sortVideos(List<MVideo> videos, int sourceId) {
String quality = getPreferenceValue(sourceId, "preferred_quality");
videos.sort((MVideo a, MVideo b) {
int qualityMatchA = 0;
if (a.quality.contains(quality)) {
qualityMatchA = 1;
}
int qualityMatchB = 0;
if (b.quality.contains(quality)) {
qualityMatchB = 1;
}
if (qualityMatchA != qualityMatchB) {
return qualityMatchB - qualityMatchA;
}
final regex = RegExp(r'(\d+)p');
final matchA = regex.firstMatch(a.quality);
final matchB = regex.firstMatch(b.quality);
final int qualityNumA = int.tryParse(matchA?.group(1) ?? '0') ?? 0;
final int qualityNumB = int.tryParse(matchB?.group(1) ?? '0') ?? 0;
return qualityNumB - qualityNumA;
});
return videos;
}
List<MTrack> sortSubs(List<MTrack> subs, int sourceId) {
String lang = getPreferenceValue(sourceId, "preferred_subLang");
subs.sort((MTrack a, MTrack b) {
int langMatchA = 0;
if (a.label.toLowerCase().contains(lang.toLowerCase())) {
langMatchA = 1;
}
int langMatchB = 0;
if (b.label.toLowerCase().contains(lang.toLowerCase())) {
langMatchB = 1;
}
return langMatchB - langMatchA;
});
return subs;
}
String preferenceBaseUrl(int sourceId) {
return getPreferenceValue(sourceId, "preferred_domain");
}
String ll(String url) { String ll(String url) {
if (url.contains("?")) { if (url.contains("?")) {
return "&"; return "&";

View File

@@ -1,7 +1,7 @@
import '../../../model/source.dart'; import '../../../model/source.dart';
import '../../../utils/utils.dart'; import '../../../utils/utils.dart';
const dopeflixVersion = "0.0.15"; const dopeflixVersion = "0.0.2";
const dopeflixSourceCodeUrl = const dopeflixSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/multisrc/dopeflix/dopeflix-v$dopeflixVersion.dart"; "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/multisrc/dopeflix/dopeflix-v$dopeflixVersion.dart";

View File

@@ -1,7 +1,7 @@
import '../../../model/source.dart'; import '../../../model/source.dart';
import '../../../utils/utils.dart'; import '../../../utils/utils.dart';
const zorothemeVersion = "0.0.5"; const zorothemeVersion = "0.0.55";
const zorothemeSourceCodeUrl = const zorothemeSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/multisrc/zorotheme/zorotheme-v$zorothemeVersion.dart"; "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/multisrc/zorotheme/zorotheme-v$zorothemeVersion.dart";

View File

@@ -223,7 +223,8 @@ class ZoroTheme extends MProvider {
typeRegExp: 0); typeRegExp: 0);
List<MVideo> videos = []; List<MVideo> videos = [];
final hosterSelection = preferenceHosterSelection(source.id);
final typeSelection = preferenceTypeSelection(source.id);
for (var i = 0; i < names.length; i++) { for (var i = 0; i < names.length; i++) {
final name = names[i]; final name = names[i];
final id = ids[i]; final id = ids[i];
@@ -236,8 +237,10 @@ class ZoroTheme extends MProvider {
final resE = await http('GET', json.encode(datasE)); final resE = await http('GET', json.encode(datasE));
String epUrl = substringBefore(substringAfter(resE, "\"link\":\""), "\""); String epUrl = substringBefore(substringAfter(resE, "\"link\":\""), "\"");
print(epUrl);
List<MVideo> a = []; List<MVideo> a = [];
if (hosterSelection.contains(name) && typeSelection.contains(subDub)) {
if (name.contains("Vidstreaming")) { if (name.contains("Vidstreaming")) {
a = await rapidCloudExtractor(epUrl, "Vidstreaming - $subDub"); a = await rapidCloudExtractor(epUrl, "Vidstreaming - $subDub");
} else if (name.contains("Vidcloud")) { } else if (name.contains("Vidcloud")) {
@@ -247,8 +250,9 @@ class ZoroTheme extends MProvider {
} }
videos.addAll(a); videos.addAll(a);
} }
}
return videos; return sortVideos(videos, source.id);
} }
MPages animeElementM(String res) { MPages animeElementM(String res) {
@@ -421,6 +425,98 @@ class ZoroTheme extends MProvider {
]; ];
} }
@override
List<dynamic> getSourcePreferences(MSource source) {
return [
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 1,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
ListPreference(
key: "preferred_server",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
entryValues: ["Vidstreaming", "VidCloud", "StreamTape"]),
ListPreference(
key: "preferred_type",
title: "Preferred Type",
summary: "",
valueIndex: 0,
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"]),
MultiSelectListPreference(
key: "hoster_selection",
title: "Enable/Disable Hosts",
summary: "",
entries: ["Vidstreaming", "VidCloud", "StreamTape"],
entryValues: ["Vidstreaming", "Vidcloud", "StreamTape"],
values: ["Vidstreaming", "Vidcloud", "StreamTape"]),
MultiSelectListPreference(
key: "type_selection",
title: "Enable/Disable Types",
summary: "",
entries: ["Sub", "Dub"],
entryValues: ["sub", "dub"],
values: ["sub", "dub"]),
];
}
List<MVideo> sortVideos(List<MVideo> videos, int sourceId) {
String quality = getPreferenceValue(sourceId, "preferred_quality");
String server = getPreferenceValue(sourceId, "preferred_server");
String type = getPreferenceValue(sourceId, "preferred_type");
videos = videos
.where(
(MVideo e) => e.quality.toLowerCase().contains(type.toLowerCase()))
.toList();
videos.sort((MVideo a, MVideo b) {
int qualityMatchA = 0;
if (a.quality.contains(quality)) {
qualityMatchA = 1;
}
int qualityMatchB = 0;
if (b.quality.contains(quality)) {
qualityMatchB = 1;
}
if (qualityMatchA != qualityMatchB) {
return qualityMatchB - qualityMatchA;
}
final regex = RegExp(r'(\d+)p');
final matchA = regex.firstMatch(a.quality);
final matchB = regex.firstMatch(b.quality);
final int qualityNumA = int.tryParse(matchA?.group(1) ?? '0') ?? 0;
final int qualityNumB = int.tryParse(matchB?.group(1) ?? '0') ?? 0;
return qualityNumB - qualityNumA;
});
videos.sort((MVideo a, MVideo b) {
int serverMatchA = 0;
if (a.quality.toLowerCase().contains(server.toLowerCase())) {
serverMatchA = 1;
}
int serverMatchB = 0;
if (b.quality.toLowerCase().contains(server.toLowerCase())) {
serverMatchB = 1;
}
return serverMatchB - serverMatchA;
});
return videos;
}
List<String> preferenceHosterSelection(int sourceId) {
return getPreferenceValue(sourceId, "hoster_selection");
}
List<String> preferenceTypeSelection(int sourceId) {
return getPreferenceValue(sourceId, "type_selection");
}
String ll(String url) { String ll(String url) {
if (url.contains("?")) { if (url.contains("?")) {
return "&"; return "&";

View File

@@ -6,7 +6,9 @@ class Aniwave extends MProvider {
@override @override
Future<MPages> getPopular(MSource source, int page) async { Future<MPages> getPopular(MSource source, int page) async {
final data = {"url": "${source.baseUrl}/filter?sort=trending&page=$page"}; final data = {
"url": "${preferenceBaseUrl(source.id)}/filter?sort=trending&page=$page"
};
final res = await http('GET', json.encode(data)); final res = await http('GET', json.encode(data));
return parseAnimeList(res); return parseAnimeList(res);
} }
@@ -14,7 +16,8 @@ class Aniwave extends MProvider {
@override @override
Future<MPages> getLatestUpdates(MSource source, int page) async { Future<MPages> getLatestUpdates(MSource source, int page) async {
final data = { final data = {
"url": "${source.baseUrl}/filter?sort=recently_updated&page=$page" "url":
"${preferenceBaseUrl(source.id)}/filter?sort=recently_updated&page=$page"
}; };
final res = await http('GET', json.encode(data)); final res = await http('GET', json.encode(data));
return parseAnimeList(res); return parseAnimeList(res);
@@ -24,7 +27,7 @@ class Aniwave extends MProvider {
Future<MPages> search( Future<MPages> search(
MSource source, String query, int page, FilterList filterList) async { MSource source, String query, int page, FilterList filterList) async {
final filters = filterList.filters; final filters = filterList.filters;
String url = "${source.baseUrl}/filter?keyword=$query"; String url = "${preferenceBaseUrl(source.id)}/filter?keyword=$query";
for (var filter in filters) { for (var filter in filters) {
if (filter.type == "OrderFilter") { if (filter.type == "OrderFilter") {
@@ -98,7 +101,7 @@ class Aniwave extends MProvider {
final statusList = [ final statusList = [
{"Releasing": 0, "Completed": 1} {"Releasing": 0, "Completed": 1}
]; ];
final data = {"url": "${source.baseUrl}${url}"}; final data = {"url": "${preferenceBaseUrl(source.id)}${url}"};
final res = await http('GET', json.encode(data)); final res = await http('GET', json.encode(data));
MManga anime = MManga(); MManga anime = MManga();
final status = xpath(res, '//div[contains(text(),"Status")]/span/text()'); final status = xpath(res, '//div[contains(text(),"Status")]/span/text()');
@@ -124,7 +127,9 @@ class Aniwave extends MProvider {
.first; .first;
final encrypt = vrfEncrypt(id); final encrypt = vrfEncrypt(id);
final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; final vrf = "vrf=${Uri.encodeComponent(encrypt)}";
final dataEp = {"url": "${source.baseUrl}/ajax/episode/list/$id?$vrf"}; final dataEp = {
"url": "${preferenceBaseUrl(source.id)}/ajax/episode/list/$id?$vrf"
};
final resEp = await http('GET', json.encode(dataEp)); final resEp = await http('GET', json.encode(dataEp));
final html = json.decode(resEp)["result"]; final html = json.decode(resEp)["result"];
List<MChapter>? episodesList = []; List<MChapter>? episodesList = [];
@@ -172,8 +177,11 @@ class Aniwave extends MProvider {
final ids = substringBefore(url, "&"); final ids = substringBefore(url, "&");
final encrypt = vrfEncrypt(ids); final encrypt = vrfEncrypt(ids);
final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; final vrf = "vrf=${Uri.encodeComponent(encrypt)}";
final res = await http('GET', final res = await http(
json.encode({"url": "${source.baseUrl}/ajax/server/list/$ids?$vrf"})); 'GET',
json.encode({
"url": "${preferenceBaseUrl(source.id)}/ajax/server/list/$ids?$vrf"
}));
final html = json.decode(res)["result"]; final html = json.decode(res)["result"];
final vidsHtml = querySelectorAll(html, final vidsHtml = querySelectorAll(html,
selector: "div.servers > div", selector: "div.servers > div",
@@ -191,25 +199,34 @@ class Aniwave extends MProvider {
final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; final vrf = "vrf=${Uri.encodeComponent(encrypt)}";
final res = await http( final res = await http(
'GET', 'GET',
json.encode( json.encode({
{"url": "${source.baseUrl}/ajax/server/$serverId?$vrf"})); "url":
"${preferenceBaseUrl(source.id)}/ajax/server/$serverId?$vrf"
}));
final status = json.decode(res)["status"]; final status = json.decode(res)["status"];
if (status == 200) { if (status == 200) {
List<MVideo> a = []; List<MVideo> a = [];
final url = vrfDecrypt(json.decode(res)["result"]["url"]); final url = vrfDecrypt(json.decode(res)["result"]["url"]);
if (url.contains("mp4upload")) { final hosterSelection = preferenceHosterSelection(source.id);
final typeSelection = preferenceTypeSelection(source.id);
if (typeSelection.contains(type.toLowerCase())) {
if (url.contains("mp4upload") &&
hosterSelection.contains("mp4upload")) {
a = await mp4UploadExtractor(url, null, "", type); a = await mp4UploadExtractor(url, null, "", type);
} else if (url.contains("streamtape")) { } else if (url.contains("streamtape") &&
hosterSelection.contains("streamtape")) {
a = await streamTapeExtractor(url, "StreamTape - $type"); a = await streamTapeExtractor(url, "StreamTape - $type");
} else if (url.contains("filemoon")) { } else if (url.contains("filemoon") &&
hosterSelection.contains("filemoon")) {
a = await filemoonExtractor(url, "", type); a = await filemoonExtractor(url, "", type);
} }
videos.addAll(a); videos.addAll(a);
} }
} }
} }
}
return videos; return sortVideos(videos, source.id);
} }
MPages parseAnimeList(String res) { MPages parseAnimeList(String res) {
@@ -427,6 +444,147 @@ class Aniwave extends MProvider {
]; ];
} }
@override
List<dynamic> getSourcePreferences(MSource source) {
return [
ListPreference(
key: "preferred_domain",
title: "Preferred domain",
summary: "",
valueIndex: 0,
entries: [
"aniwave.to",
"aniwave.bz",
"aniwave.ws"
],
entryValues: [
"https://aniwave.to",
"https://aniwave.bz",
"https://aniwave.ws"
]),
ListPreference(
key: "preferred_quality",
title: "Preferred Quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
ListPreference(
key: "preferred_language",
title: "Preferred Type",
summary: "",
valueIndex: 0,
entries: ["Sub", "Softsub", "Dub"],
entryValues: ["Sub", "Softsub", "Dub"]),
ListPreference(
key: "preferred_server",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: [
"VidPlay",
"MyCloud",
"Filemoon",
"StreamTape",
"Mp4Upload"
],
entryValues: [
"vidplay",
"mycloud",
"filemoon",
"streamtape",
"mp4upload"
]),
MultiSelectListPreference(
key: "hoster_selection",
title: "Enable/Disable Hosts",
summary: "",
entries: [
"VidPlay",
"MyCloud",
"Filemoon",
"StreamTape",
"Mp4Upload"
],
entryValues: [
"vidplay",
"mycloud",
"filemoon",
"streamtape",
"mp4upload"
],
values: [
"vidplay",
"mycloud",
"filemoon",
"streamtape",
"mp4upload"
]),
MultiSelectListPreference(
key: "type_selection",
title: "Enable/Disable Type",
summary: "",
entries: ["Sub", "Softsub", "Dub"],
entryValues: ["sub", "softsub", "dub"],
values: ["sub", "softsub", "dub"]),
];
}
String preferenceBaseUrl(int sourceId) {
return getPreferenceValue(sourceId, "preferred_domain");
}
List<String> preferenceHosterSelection(int sourceId) {
return getPreferenceValue(sourceId, "hoster_selection");
}
List<String> preferenceTypeSelection(int sourceId) {
return getPreferenceValue(sourceId, "type_selection");
}
List<MVideo> sortVideos(List<MVideo> videos, int sourceId) {
String quality = getPreferenceValue(sourceId, "preferred_quality");
String server = getPreferenceValue(sourceId, "preferred_server");
String lang = getPreferenceValue(sourceId, "preferred_language");
videos = videos
.where(
(MVideo e) => e.quality.toLowerCase().contains(lang.toLowerCase()))
.toList();
videos.sort((MVideo a, MVideo b) {
int qualityMatchA = 0;
if (a.quality.contains(quality)) {
qualityMatchA = 1;
}
int qualityMatchB = 0;
if (b.quality.contains(quality)) {
qualityMatchB = 1;
}
if (qualityMatchA != qualityMatchB) {
return qualityMatchB - qualityMatchA;
}
final regex = RegExp(r'(\d+)p');
final matchA = regex.firstMatch(a.quality);
final matchB = regex.firstMatch(b.quality);
final int qualityNumA = int.tryParse(matchA?.group(1) ?? '0') ?? 0;
final int qualityNumB = int.tryParse(matchB?.group(1) ?? '0') ?? 0;
return qualityNumB - qualityNumA;
});
videos.sort((MVideo a, MVideo b) {
int serverMatchA = 0;
if (a.quality.toLowerCase().contains(server.toLowerCase())) {
serverMatchA = 1;
}
int serverMatchB = 0;
if (b.quality.toLowerCase().contains(server.toLowerCase())) {
serverMatchB = 1;
}
return serverMatchB - serverMatchA;
});
return videos;
}
String ll(String url) { String ll(String url) {
if (url.contains("?")) { if (url.contains("?")) {
return "&"; return "&";
@@ -435,14 +593,6 @@ class Aniwave extends MProvider {
} }
} }
Map<String, String> getMirrorPref() {
return {
"aniwave.to": "https://aniwave.to",
"aniwave.bz": "https://aniwave.bz",
"aniwave.ws": "https://aniwave.ws",
};
}
Aniwave main() { Aniwave main() {
return Aniwave(); return Aniwave();
} }

View File

@@ -2,7 +2,7 @@ import '../../../../model/source.dart';
import '../../../../utils/utils.dart'; import '../../../../utils/utils.dart';
Source get aniwave => _aniwave; Source get aniwave => _aniwave;
const aniwaveVersion = "0.0.15"; const aniwaveVersion = "0.0.2";
const aniwaveCodeUrl = const aniwaveCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/en/aniwave/aniwave-v$aniwaveVersion.dart"; "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/en/aniwave/aniwave-v$aniwaveVersion.dart";
Source _aniwave = Source( Source _aniwave = Source(

View File

@@ -6,7 +6,9 @@ class GogoAnime extends MProvider {
@override @override
Future<MPages> getPopular(MSource source, int page) async { Future<MPages> getPopular(MSource source, int page) async {
final data = {"url": "${source.baseUrl}/popular.html?page=$page"}; final data = {
"url": "${preferenceBaseUrl(source.id)}/popular.html?page=$page"
};
final res = await http('GET', json.encode(data)); final res = await http('GET', json.encode(data));
List<MManga> animeList = []; List<MManga> animeList = [];
@@ -130,14 +132,15 @@ class GogoAnime extends MProvider {
} }
} }
if (genre.isNotEmpty) { if (genre.isNotEmpty) {
url = "${source.baseUrl}/genre/$genre?page=$page"; url = "${preferenceBaseUrl(source.id)}/genre/$genre?page=$page";
} else if (recent.isNotEmpty) { } else if (recent.isNotEmpty) {
url = url =
"https://ajax.gogo-load.com/ajax/page-recent-release.html?page=$page&type=$recent"; "https://ajax.gogo-load.com/ajax/page-recent-release.html?page=$page&type=$recent";
} else if (season.isNotEmpty) { } else if (season.isNotEmpty) {
url = "${source.baseUrl}/$season?page=$page"; url = "${preferenceBaseUrl(source.id)}/$season?page=$page";
} else { } else {
url = "${source.baseUrl}/filter.html?keyword=$query$filterStr&page=$page"; url =
"${preferenceBaseUrl(source.id)}/filter.html?keyword=$query$filterStr&page=$page";
} }
final data = {"url": url}; final data = {"url": url};
@@ -167,7 +170,7 @@ class GogoAnime extends MProvider {
"Completed": 1, "Completed": 1,
} }
]; ];
final data = {"url": "${source.baseUrl}$url"}; final data = {"url": "${preferenceBaseUrl(source.id)}$url"};
final res = await http('GET', json.encode(data)); final res = await http('GET', json.encode(data));
MManga anime = MManga(); MManga anime = MManga();
final status = xpath( final status = xpath(
@@ -213,7 +216,7 @@ class GogoAnime extends MProvider {
@override @override
Future<List<MVideo>> getVideoList(MSource source, String url) async { Future<List<MVideo>> getVideoList(MSource source, String url) async {
final datas = {"url": "${source.baseUrl}$url"}; final datas = {"url": "${preferenceBaseUrl(source.id)}$url"};
final res = await http('GET', json.encode(datas)); final res = await http('GET', json.encode(datas));
final serverUrls = final serverUrls =
@@ -221,10 +224,12 @@ class GogoAnime extends MProvider {
final serverNames = final serverNames =
xpath(res, '//*[@class="anime_muti_link"]/ul/li/@class'); xpath(res, '//*[@class="anime_muti_link"]/ul/li/@class');
List<MVideo> videos = []; List<MVideo> videos = [];
final hosterSelection = preferenceHosterSelection(source.id);
for (var i = 0; i < serverNames.length; i++) { for (var i = 0; i < serverNames.length; i++) {
final name = serverNames[i]; final name = serverNames[i];
final url = serverUrls[i]; final url = serverUrls[i];
List<MVideo> a = []; List<MVideo> a = [];
if (hosterSelection.contains(name)) {
if (name.contains("anime")) { if (name.contains("anime")) {
a = await gogoCdnExtractor(url); a = await gogoCdnExtractor(url);
} else if (name.contains("vidcdn")) { } else if (name.contains("vidcdn")) {
@@ -240,8 +245,9 @@ class GogoAnime extends MProvider {
} }
videos.addAll(a); videos.addAll(a);
} }
}
return videos; return sortVideos(videos, source.id);
} }
@override @override
@@ -1025,6 +1031,124 @@ class GogoAnime extends MProvider {
]), ]),
]; ];
} }
@override
List<dynamic> getSourcePreferences(MSource source) {
return [
EditTextPreference(
key: "override_baseurl_v${source.id}",
title: "Override BaseUrl",
summary:
"For temporary uses. Updating the extension will erase this setting.",
value: "https://gogoanime3.net",
dialogTitle: "Override BaseUrl",
dialogMessage: "Default: https://gogoanime3.net",
text: "https://gogoanime3.net"),
ListPreference(
key: "preferred_quality",
title: "Preferred quality",
summary: "",
valueIndex: 0,
entries: ["1080p", "720p", "480p", "360p"],
entryValues: ["1080", "720", "480", "360"]),
ListPreference(
key: "preferred_server",
title: "Preferred server",
summary: "",
valueIndex: 0,
entries: [
"Gogostream",
"Vidstreaming",
"Doodstream",
"StreamWish",
"Mp4upload",
"FileLions"
],
entryValues: [
"Gogostream",
"Vidstreaming",
"Doodstream",
"StreamWish",
"Mp4upload",
"FileLions"
]),
MultiSelectListPreference(
key: "hoster_selection",
title: "Enable/Disable Hosts",
summary: "",
entries: [
"Gogostream",
"Vidstreaming",
"Doodstream",
"StreamWish",
"Mp4upload",
"FileLions"
],
entryValues: [
"vidcdn",
"anime",
"doodstream",
"streamwish",
"mp4upload",
"filelions"
],
values: [
"vidcdn",
"anime",
"doodstream",
"streamwish",
"mp4upload",
"filelions"
]),
];
}
String preferenceBaseUrl(int sourceId) {
return getPreferenceValue(sourceId, "override_baseurl_v$sourceId");
}
List<String> preferenceHosterSelection(int sourceId) {
return getPreferenceValue(sourceId, "hoster_selection");
}
List<MVideo> sortVideos(List<MVideo> videos, int sourceId) {
String quality = getPreferenceValue(sourceId, "preferred_quality");
String server = getPreferenceValue(sourceId, "preferred_server");
videos.sort((MVideo a, MVideo b) {
int qualityMatchA = 0;
if (a.quality.contains(quality)) {
qualityMatchA = 1;
}
int qualityMatchB = 0;
if (b.quality.contains(quality)) {
qualityMatchB = 1;
}
if (qualityMatchA != qualityMatchB) {
return qualityMatchB - qualityMatchA;
}
final regex = RegExp(r'(\d+)p');
final matchA = regex.firstMatch(a.quality);
final matchB = regex.firstMatch(b.quality);
final int qualityNumA = int.tryParse(matchA?.group(1) ?? '0') ?? 0;
final int qualityNumB = int.tryParse(matchB?.group(1) ?? '0') ?? 0;
return qualityNumB - qualityNumA;
});
videos.sort((MVideo a, MVideo b) {
int serverMatchA = 0;
if (a.quality.contains(server)) {
serverMatchA = 1;
}
int serverMatchB = 0;
if (b.quality.contains(server)) {
serverMatchB = 1;
}
return serverMatchB - serverMatchA;
});
return videos;
}
} }
GogoAnime main() { GogoAnime main() {

View File

@@ -2,7 +2,7 @@ import '../../../../model/source.dart';
import '../../../../utils/utils.dart'; import '../../../../utils/utils.dart';
Source get gogoanimeSource => _gogoanimeSource; Source get gogoanimeSource => _gogoanimeSource;
const gogoanimeVersion = "0.0.4"; const gogoanimeVersion = "0.0.5";
const gogoanimeSourceCodeUrl = const gogoanimeSourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/en/gogoanime/gogoanime-v$gogoanimeVersion.dart"; "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/en/gogoanime/gogoanime-v$gogoanimeVersion.dart";
Source _gogoanimeSource = Source( Source _gogoanimeSource = Source(

View File

@@ -47,7 +47,7 @@ class Source {
this.version = "", this.version = "",
this.isManga = true, this.isManga = true,
this.isFullData = false, this.isFullData = false,
this.appMinVerReq = "0.1.1"}); this.appMinVerReq = "0.1.2"});
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {