diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe37091..fa0475c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,7 @@ and you will see this : import 'package:mangayomi/models/source.dart'; //For testing purposes, set to true -const useTestSourceCode = false; +const useTestSourceCode = true; final testSourceModelList = [ Source( @@ -51,60 +51,62 @@ final testSourceModelList = [ const testSourceCode = r''' import 'package:mangayomi/bridge_lib.dart'; -import 'dart:convert'; class TestSource extends MProvider { - TestSource(); + TestSource({required this.source}); + + MSource source; + + final Client client = Client(source); @override bool get supportsLatest => true; @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { // TODO: implement } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { // TODO: implement } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { // TODO: implement } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { // TODO: implement } // For anime episode video list @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { // TODO: implement } // For manga chapter pages @override - Future> getPageList(MSource source, String url) { + Future> getPageList(String url) { // TODO: implement } @override - List getFilterList(MSource source) { + List getFilterList() { // TODO: implement } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { // TODO: implement } } -TestSource main() { - return TestSource(); +TestSource main(MSource source) { + return TestSource(source:source); } '''; @@ -238,7 +240,7 @@ Return Response ```bash - Simple request -final client = Client(); +final Client client = Client(); final res = await client.get(Uri.parse("http://example.com")); @@ -246,7 +248,7 @@ print(res.body); - With headers -final client = Client(); +final Client client = Client(); final res = await client.get(Uri.parse("http://example.com"),headers:{"Referer": "http://example.com"}); @@ -254,7 +256,7 @@ print(res.body); - With body -final client = Client(); +final Client client = Client(); final res = await client.post(Uri.parse("http://example.com"),headers:{"Referer": "http://example.com"},'body':{'name':'test'}); diff --git a/anime/multisrc/datalifeengine/datalifeengine.dart b/anime/multisrc/datalifeengine/datalifeengine.dart index 6151581..471fb76 100644 --- a/anime/multisrc/datalifeengine/datalifeengine.dart +++ b/anime/multisrc/datalifeengine/datalifeengine.dart @@ -2,29 +2,30 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class DataLifeEngine extends MProvider { - DataLifeEngine(); + DataLifeEngine({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override bool get supportsLatest => false; @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client .get(Uri.parse("${source.baseUrl}${getPath(source)}page/$page"))) .body; - return animeFromElement(res, source.baseUrl); + return animeFromElement(res); } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { return MPages([], false); } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; final baseUrl = source.baseUrl; String res = ""; @@ -65,11 +66,11 @@ class DataLifeEngine extends MProvider { res = (await client.get(Uri.parse(url))).body; } - return animeFromElement(res, baseUrl); + return animeFromElement(res); } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { String res = (await client.get(Uri.parse(url))).body; MManga anime = MManga(); final description = xpath(res, '//span[@itemprop="description"]/text()'); @@ -116,7 +117,7 @@ class DataLifeEngine extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { List videos = []; final sUrls = url.split(','); for (var sUrl in sUrls) { @@ -143,7 +144,7 @@ class DataLifeEngine extends MProvider { return videos; } - MPages animeFromElement(String res, String baseUrl) { + MPages animeFromElement(String res) { final htmls = parseHtml(res).select("div#dle-content > div.mov"); List animeList = []; for (var h in htmls) { @@ -155,7 +156,7 @@ class DataLifeEngine extends MProvider { MManga anime = MManga(); anime.name = "$name ${season.isNotEmpty ? season.first.replaceAll("\n", " ") : ""}"; - anime.imageUrl = "$baseUrl$image"; + anime.imageUrl = "${source.baseUrl}$image"; anime.link = url; animeList.add(anime); } @@ -245,13 +246,13 @@ class DataLifeEngine extends MProvider { return [video]; } - String getPath(MSource source) { + String getPath() { if (source.name == "French Anime") return "/animes-vostfr/"; return "/serie-en-streaming/"; } @override - List getFilterList(MSource source) { + List getFilterList() { return [ HeaderFilter("La recherche de texte ignore les filtres"), if (source.name == "French Anime") @@ -326,6 +327,6 @@ class DataLifeEngine extends MProvider { } } -DataLifeEngine main() { - return DataLifeEngine(); +DataLifeEngine main(MSource source) { + return DataLifeEngine(source: source); } diff --git a/anime/multisrc/datalifeengine/sources.dart b/anime/multisrc/datalifeengine/sources.dart index af37a11..c1140ab 100644 --- a/anime/multisrc/datalifeengine/sources.dart +++ b/anime/multisrc/datalifeengine/sources.dart @@ -2,7 +2,7 @@ import '../../../model/source.dart'; import 'src/frenchanime/frenchanime.dart'; import 'src/wiflix/wiflix.dart'; -const _datalifeengineVersion = "0.0.25"; +const _datalifeengineVersion = "0.0.3"; const _datalifeengineSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/multisrc/datalifeengine/datalifeengine.dart"; diff --git a/anime/multisrc/dopeflix/dopeflix.dart b/anime/multisrc/dopeflix/dopeflix.dart index 2f38957..53047b9 100644 --- a/anime/multisrc/dopeflix/dopeflix.dart +++ b/anime/multisrc/dopeflix/dopeflix.dart @@ -2,23 +2,26 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class DopeFlix extends MProvider { - DopeFlix(); + DopeFlix({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + String get baseUrl => getPreferenceValue(source.id, "preferred_domain"); + + @override + Future getPopular(int page) async { final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/${getPreferenceValue(source.id, "preferred_popular_page")}?page=$page"))) + "$baseUrl/${getPreferenceValue(source.id, "preferred_popular_page")}?page=$page"))) .body; return parseAnimeList(res); } @override - Future getLatestUpdates(MSource source, int page) async { - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}/home"))) - .body; + Future getLatestUpdates(int page) async { + final res = (await client.get(Uri.parse("$baseUrl/home"))).body; List animeList = []; final path = '//section[contains(text(),"${getPreferenceValue(source.id, "preferred_latest_page")}")]/div/div[@class="film_list-wrap"]/div[@class="flw-item"]/div[@class="film-poster"]'; @@ -37,10 +40,9 @@ class DopeFlix extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; - String url = "${preferenceBaseUrl(source.id)}"; + String url = "$baseUrl"; if (query.isNotEmpty) { url += "/search/${query.replaceAll(" ", "-")}?page=$page"; @@ -81,11 +83,9 @@ class DopeFlix extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { url = getUrlWithoutDomain(url); - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; MManga anime = MManga(); final description = xpath(res, '//div[@class="description"]/text()'); if (description.isNotEmpty) { @@ -103,12 +103,11 @@ class DopeFlix extends MProvider { if (dataType == "1") { MChapter episode = MChapter(); episode.name = "Movie"; - episode.url = "${preferenceBaseUrl(source.id)}/ajax/movie/episodes/$id"; + episode.url = "$baseUrl/ajax/movie/episodes/$id"; episodesList.add(episode); } else { - final resS = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/ajax/v2/tv/seasons/$id"))) - .body; + 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'); @@ -118,8 +117,8 @@ class DopeFlix extends MProvider { final seasonId = seasonIds[i]; final seasonName = seasonNames[i]; - final html = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/ajax/v2/season/episodes/$seasonId"))) + final html = (await client + .get(Uri.parse("$baseUrl/ajax/v2/season/episodes/$seasonId"))) .body; final epsHtmls = parseHtml(html).select("div.eps-item"); @@ -134,8 +133,7 @@ class DopeFlix extends MProvider { final epName = xpath(epHtml, '//h3[@class="film-name"]/text()').first; MChapter episode = MChapter(); episode.name = "$seasonName $epNum $epName"; - episode.url = - "${preferenceBaseUrl(source.id)}/ajax/v2/episode/servers/$episodeId"; + episode.url = "$baseUrl/ajax/v2/episode/servers/$episodeId"; episodesList.add(episode); } } @@ -145,11 +143,9 @@ class DopeFlix extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { url = getUrlWithoutDomain(url); - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}/$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl/$url"))).body; final vidsHtmls = parseHtml(res).select("ul.fss-list a.btn-play"); @@ -158,9 +154,8 @@ class DopeFlix extends MProvider { final vidHtml = vidH.outerHtml; final id = xpath(vidHtml, '//a/@data-id').first; final name = xpath(vidHtml, '//span/text()').first; - final resSource = (await client.get( - Uri.parse("${preferenceBaseUrl(source.id)}/ajax/sources/$id"))) - .body; + final resSource = + (await client.get(Uri.parse("$baseUrl/ajax/sources/$id"))).body; final vidUrl = substringBefore(substringAfter(resSource, "\"link\":\""), "\""); @@ -317,7 +312,7 @@ class DopeFlix extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ SelectFilter("TypeFilter", "Type", 0, [ SelectFilterOption("All", "all"), @@ -413,7 +408,7 @@ class DopeFlix extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ if (source.name == "DopeBox") ListPreference( @@ -530,10 +525,6 @@ class DopeFlix extends MProvider { return subs; } - String preferenceBaseUrl(int sourceId) { - return getPreferenceValue(sourceId, "preferred_domain"); - } - String ll(String url) { if (url.contains("?")) { return "&"; @@ -542,6 +533,6 @@ class DopeFlix extends MProvider { } } -DopeFlix main() { - return DopeFlix(); +DopeFlix main(MSource source) { + return DopeFlix(source: source); } diff --git a/anime/multisrc/dopeflix/sources.dart b/anime/multisrc/dopeflix/sources.dart index c1e591e..8581f0a 100644 --- a/anime/multisrc/dopeflix/sources.dart +++ b/anime/multisrc/dopeflix/sources.dart @@ -2,7 +2,7 @@ import '../../../model/source.dart'; import 'src/dopebox/dopebox.dart'; import 'src/sflix/sflix.dart'; -const _dopeflixVersion = "0.0.35"; +const _dopeflixVersion = "0.0.4"; const _dopeflixSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/multisrc/dopeflix/dopeflix.dart"; diff --git a/anime/multisrc/zorotheme/sources.dart b/anime/multisrc/zorotheme/sources.dart index 5032053..30c1552 100644 --- a/anime/multisrc/zorotheme/sources.dart +++ b/anime/multisrc/zorotheme/sources.dart @@ -2,7 +2,7 @@ import '../../../model/source.dart'; import 'src/aniwatch/aniwatch.dart'; import 'src/kaido/kaido.dart'; -const _zorothemeVersion = "0.0.75"; +const _zorothemeVersion = "0.0.8"; const _zorothemeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/multisrc/zorotheme/zorotheme.dart"; diff --git a/anime/multisrc/zorotheme/zorotheme.dart b/anime/multisrc/zorotheme/zorotheme.dart index d6a2544..e997daa 100644 --- a/anime/multisrc/zorotheme/zorotheme.dart +++ b/anime/multisrc/zorotheme/zorotheme.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class ZoroTheme extends MProvider { - ZoroTheme(); + ZoroTheme({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client .get(Uri.parse("${source.baseUrl}/most-popular?page=$page"))) .body; @@ -16,7 +18,7 @@ class ZoroTheme extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client .get(Uri.parse("${source.baseUrl}/recently-updated?page=$page"))) .body; @@ -25,8 +27,7 @@ class ZoroTheme extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = "${source.baseUrl}/"; @@ -119,7 +120,7 @@ class ZoroTheme extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"Currently Airing": 0, "Finished Airing": 1} ]; @@ -170,7 +171,7 @@ class ZoroTheme extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final id = substringAfterLast(url, '?ep='); final res = (await client.get( @@ -384,7 +385,7 @@ class ZoroTheme extends MProvider { ]; @override - List getFilterList(MSource source) { + List getFilterList() { return [ SelectFilter("TypeFilter", "Type", 0, [ SelectFilterOption("All", ""), @@ -518,7 +519,7 @@ class ZoroTheme extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_quality", @@ -606,6 +607,6 @@ class ZoroTheme extends MProvider { } } -ZoroTheme main() { - return ZoroTheme(); +ZoroTheme main(MSource source) { + return ZoroTheme(source: source); } diff --git a/anime/source_generator.dart b/anime/source_generator.dart index 54e0c76..386735f 100644 --- a/anime/source_generator.dart +++ b/anime/source_generator.dart @@ -7,8 +7,10 @@ import 'multisrc/dopeflix/sources.dart'; import 'multisrc/zorotheme/sources.dart'; import 'src/all/animeworldindia/sources.dart'; import 'src/all/nyaa/source.dart'; +import 'src/all/yomiroll/source.dart'; import 'src/ar/okanime/source.dart'; import 'src/de/aniflix/source.dart'; +import 'src/en/animepahe/source.dart'; import 'src/en/aniwave/source.dart'; import 'src/en/dramacool/source.dart'; import 'src/en/gogoanime/source.dart'; @@ -50,7 +52,9 @@ void main() { nineanimetv, aniflix, ...animeworldindiaSourcesList, - nyaaSource + nyaaSource, + yomirollSource, + animepaheSource ]; final List> jsonList = _sourcesList.map((source) => source.toJson()).toList(); diff --git a/anime/src/all/animeworldindia/animeworldindia.dart b/anime/src/all/animeworldindia/animeworldindia.dart index 7be85ee..078cd21 100644 --- a/anime/src/all/animeworldindia/animeworldindia.dart +++ b/anime/src/all/animeworldindia/animeworldindia.dart @@ -2,31 +2,32 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class AnimeWorldIndia extends MProvider { - AnimeWorldIndia(); + AnimeWorldIndia({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future 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; - return parseAnimeList(res, source.baseUrl); + return parseAnimeList(res); } @override - Future getLatestUpdates(MSource source, int page) async { + Future 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; - return parseAnimeList(res, source.baseUrl); + return parseAnimeList(res); } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = "${source.baseUrl}/advanced-search/page/$page/?s_keyword=$query&s_lang=${source.lang}"; @@ -64,11 +65,11 @@ class AnimeWorldIndia extends MProvider { } final res = (await client.get(Uri.parse(url))).body; - return parseAnimeList(res, source.baseUrl); + return parseAnimeList(res); } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final res = (await client.get(Uri.parse(url))).body; MManga anime = MManga(); final document = parseHtml(res); @@ -143,7 +144,7 @@ class AnimeWorldIndia extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body; var resJson = substringBefore( substringAfterLast(res, "\"players\":"), ",\"noplayer\":"); @@ -168,7 +169,7 @@ class AnimeWorldIndia extends MProvider { return sortVideos(videos, source.id); } - MPages parseAnimeList(String res, String baseUrl) { + MPages parseAnimeList(String res) { List animeList = []; final document = parseHtml(res); @@ -178,7 +179,7 @@ class AnimeWorldIndia extends MProvider { element.selectFirst("div.font-medium.line-clamp-2.mb-3").text; anime.link = element.selectFirst("a").getHref; anime.imageUrl = - "$baseUrl${getUrlWithoutDomain(element.selectFirst("img").getSrc)}"; + "${source.baseUrl}${getUrlWithoutDomain(element.selectFirst("img").getSrc)}"; animeList.add(anime); } final hasNextPage = xpath(res, @@ -244,7 +245,7 @@ class AnimeWorldIndia extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ SelectFilter("TypeFilter", "Type", 0, [ SelectFilterOption("Any", "all"), @@ -343,7 +344,7 @@ class AnimeWorldIndia extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_quality", @@ -389,6 +390,6 @@ class AnimeWorldIndia extends MProvider { } } -AnimeWorldIndia main() { - return AnimeWorldIndia(); +AnimeWorldIndia main(MSource source) { + return AnimeWorldIndia(source: source); } diff --git a/anime/src/all/animeworldindia/sources.dart b/anime/src/all/animeworldindia/sources.dart index 840f095..3a3fa68 100644 --- a/anime/src/all/animeworldindia/sources.dart +++ b/anime/src/all/animeworldindia/sources.dart @@ -1,6 +1,6 @@ import '../../../../model/source.dart'; -const _animeworldindiaVersion = "0.0.15"; +const _animeworldindiaVersion = "0.0.2"; const _animeworldindiaSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/all/animeworldindia/animeworldindia.dart"; diff --git a/anime/src/all/nyaa/nyaa.dart b/anime/src/all/nyaa/nyaa.dart index 12d2169..00c2562 100644 --- a/anime/src/all/nyaa/nyaa.dart +++ b/anime/src/all/nyaa/nyaa.dart @@ -1,29 +1,30 @@ import 'package:mangayomi/bridge_lib.dart'; class Nyaa extends MProvider { - Nyaa(); + Nyaa({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future 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; - return parseAnimeList(res, source.baseUrl); + return parseAnimeList(res); } @override - Future getLatestUpdates(MSource source, int page) async { + Future 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; - return parseAnimeList(res, source.baseUrl); + return parseAnimeList(res); } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = ""; url = @@ -36,11 +37,11 @@ class Nyaa extends MProvider { } } final res = (await client.get(Uri.parse(url))).body; - return parseAnimeList(res, source.baseUrl); + return parseAnimeList(res); } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { MManga anime = MManga(); final res = (await client.get(Uri.parse(url))).body; final document = parseHtml(res); @@ -59,7 +60,7 @@ class Nyaa extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ SortFilter("SortFilter", "Sort by", SortState(0, true), [ SelectFilterOption("None", ""), @@ -73,7 +74,7 @@ class Nyaa extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_categorie_page", @@ -85,7 +86,7 @@ class Nyaa extends MProvider { ]; } - MPages parseAnimeList(String res, String baseUrl) { + MPages parseAnimeList(String res) { List animeList = []; final document = parseHtml(res); @@ -94,7 +95,7 @@ class Nyaa extends MProvider { for (var value in values) { MManga anime = MManga(); anime.imageUrl = - "$baseUrl${getUrlWithoutDomain(value.selectFirst("td:nth-child(1) > a > img").getSrc)}"; + "${source.baseUrl}${getUrlWithoutDomain(value.selectFirst("td:nth-child(1) > a > img").getSrc)}"; MElement firstElement = value .select("td > a") .where((MElement e) => @@ -102,7 +103,8 @@ class Nyaa extends MProvider { !e.outerHtml.contains("#comments")) .toList() .first; - anime.link = "$baseUrl${getUrlWithoutDomain(firstElement.getHref)}"; + anime.link = + "${source.baseUrl}${getUrlWithoutDomain(firstElement.getHref)}"; anime.name = firstElement.attr("title"); animeList.add(anime); } @@ -121,6 +123,6 @@ class Nyaa extends MProvider { } } -Nyaa main() { - return Nyaa(); +Nyaa main(MSource source) { + return Nyaa(source: source); } diff --git a/anime/src/all/nyaa/source.dart b/anime/src/all/nyaa/source.dart index 6f15a2d..69ab96a 100644 --- a/anime/src/all/nyaa/source.dart +++ b/anime/src/all/nyaa/source.dart @@ -1,6 +1,6 @@ import '../../../../model/source.dart'; -const _nyaaVersion = "0.0.1"; +const _nyaaVersion = "0.0.15"; const _nyaaSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/all/nyaa/nyaa.dart"; @@ -16,5 +16,4 @@ Source _nyaaSource = Source( iconUrl: _iconUrl, version: _nyaaVersion, isManga: false, - appMinVerReq: "0.1.65", sourceCodeUrl: _nyaaSourceCodeUrl); diff --git a/anime/src/all/yomiroll/icon.png b/anime/src/all/yomiroll/icon.png new file mode 100644 index 0000000..c0adfb0 Binary files /dev/null and b/anime/src/all/yomiroll/icon.png differ diff --git a/anime/src/all/yomiroll/source.dart b/anime/src/all/yomiroll/source.dart new file mode 100644 index 0000000..3a07837 --- /dev/null +++ b/anime/src/all/yomiroll/source.dart @@ -0,0 +1,19 @@ +import '../../../../model/source.dart'; + +const _yomirollVersion = "0.0.1"; +const _yomirollSourceCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/all/yomiroll/yomiroll.dart"; + +String _iconUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/all/yomiroll/icon.png"; + +Source get yomirollSource => _yomirollSource; +Source _yomirollSource = Source( + name: 'Yomiroll', + baseUrl: "https://crunchyroll.com", + lang: "all", + typeSource: "multiple", + iconUrl: _iconUrl, + version: _yomirollVersion, + isManga: false, + sourceCodeUrl: _yomirollSourceCodeUrl); diff --git a/anime/src/all/yomiroll/yomiroll.dart b/anime/src/all/yomiroll/yomiroll.dart new file mode 100644 index 0000000..7ac455a --- /dev/null +++ b/anime/src/all/yomiroll/yomiroll.dart @@ -0,0 +1,1153 @@ +import 'package:mangayomi/bridge_lib.dart'; +import 'dart:convert'; + +class YomiRoll extends MProvider { + YomiRoll({required this.source}); + + MSource source; + + final Client client = Client(source); + + String crUrl = "https://beta-api.crunchyroll.com"; + String crApiUrl = "https://beta-api.crunchyroll.com/content/v2"; + + @override + Future getPopular(int page) async { + final start = page != 1 ? "start=${(page - 1) * 36}&" : ""; + final res = await interceptAccesTokenAndGetResponse( + "$crApiUrl/discover/browse?${start}n=36&sort_by=popularity&locale=en-US"); + return await animeFromRes(res, start); + } + + @override + Future getLatestUpdates(int page) async { + final start = page != 1 ? "start=${(page - 1) * 36}&" : ""; + final res = await interceptAccesTokenAndGetResponse( + "$crApiUrl/discover/browse?${start}n=36&sort_by=newly_added&locale=en-US"); + return await animeFromRes(res, start); + } + + @override + Future search(String query, int page, FilterList filterList) async { + final filters = filterList.filters; + String url = ""; + final start = page != 1 ? "start=${(page - 1) * 36}&" : ""; + if (query.isNotEmpty) { + final typeFilter = filters + .where((e) => e.type == "TypeFilter" ? true : false) + .toList() + .first; + final type = typeFilter.values[typeFilter.state].value; + url = + "$crApiUrl/discover/search?${start}n=36&q=${query.toLowerCase().replaceAll(" ", "+")}&type=$type"; + } else { + url = "$crApiUrl/discover/browse?${start}n=36"; + for (var filter in filters) { + if (filter.type == "MediaFilter") { + url += filter.values[filter.state].value; + } else if (filter.type == "CategoryFilter") { + url += filter.values[filter.state].value; + } else if (filter.type == "SortFilter") { + url += "&sort_by=${filter.values[filter.state].value}"; + } else if (filter.type == "LanguageFilter") { + final categories = + (filter.state as List).where((e) => e.state).toList(); + if (categories.isNotEmpty) { + for (var st in categories) { + url += st.value; + } + } + } + } + } + String res = await interceptAccesTokenAndGetResponse(url); + if (query.isNotEmpty) { + final resJson = json.decode(res)["data"][0]; + res = json.encode({"total": resJson["count"], "data": resJson["items"]}); + } else {} + + return await animeFromRes(res, start); + } + + @override + Future getDetail(String url) async { + final media = json.decode(url); + final id = media["id"]; + final type = media["type"]; + bool isSerie = type == "series"; + String res = ""; + if (isSerie) { + res = await interceptAccesTokenAndGetResponse( + "$crApiUrl/cms/series/$id?locale=en-US"); + } else { + res = await interceptAccesTokenAndGetResponse( + "$crApiUrl/cms/movie_listings/$id/movies"); + } + Map data = + (json.decode(res)["data"] as List>).first; + MManga anime = MManga(); + anime.author = data["content_provider"]; + String description = data["description"]; + description += "\n\nLanguage:"; + if (data["is_subbed"]) { + description += " Sub"; + } + if (data["is_dubbed"]) { + description += " Dub"; + } + description += "\nMaturity Ratings: "; + description += (data["maturity_ratings"] as List).join(", "); + description += "\n\nAudio: "; + description += (data["audio_locales"] as List) + .map((e) => getLocale(e)) + .toList() + .toSet() + .toList() + .join(", "); + description += "\n\nSubs: "; + description += (data["subtitle_locales"] as List) + .map((e) => getLocale(e)) + .toList() + .toSet() + .toList() + .join(", "); + anime.description = description; + + String seasonsRes = ""; + if (isSerie) { + seasonsRes = await interceptAccesTokenAndGetResponse( + "$crApiUrl/cms/series/$id/seasons"); + } else { + seasonsRes = await interceptAccesTokenAndGetResponse( + "$crApiUrl/cms/movie_listings/$id/movies"); + } + + List> seasons = json.decode(seasonsRes)["data"]; + List? episodesList = []; + if (isSerie) { + seasons.sort((Map a, Map b) => + (a["season_number"] as int).compareTo((b["season_number"] as int))); + + for (var season in seasons) { + final episodesRes = await interceptAccesTokenAndGetResponse( + '$crApiUrl/cms/seasons/${season["id"]}/episodes'); + List> episodes = json.decode(episodesRes)["data"]; + episodes.sort((Map a, Map b) { + String aS = getMapValue(json.encode(a), "episode_number"); + if (aS.isEmpty) { + aS = "0"; + } + String bS = getMapValue(json.encode(b), "episode_number"); + if (bS.isEmpty) { + bS = "0"; + } + return int.parse(aS).compareTo(int.parse(bS)); + }); + for (var episode in episodes) { + MChapter ep = MChapter(); + List> urlMap = []; + List scanlator = []; + if (getMapValue(json.encode(episode), "versions").isNotEmpty) { + for (var version in episode["versions"]) { + urlMap.add({ + "media_id": version["media_guid"], + "audio": version["audio_locale"] + }); + scanlator.add(substringBefore(version["audio_locale"], "-")); + } + } else { + final mediaId = substringBefore( + substringAfter(episode["streams_link"], "videos/"), "/streams"); + scanlator.add(substringBefore(episode["audio_locale"], "-")); + urlMap.add({"media_id": mediaId, "audio": episode["audio_locale"]}); + } + + ep.url = json.encode(urlMap); + final epNumber = getMapValue(json.encode(episode), "episode_number"); + String name = ""; + if (epNumber.isNotEmpty) { + name = + "Season ${season["season_number"]} Ep $epNumber: ${episode["title"]}"; + } else { + name = episode["title"]; + } + ep.name = name; + ep.dateUpload = parseDates( + [episode["episode_air_date"]], "yyyy-MM-dd'T'HH:mm:ss", "en") + .first; + + ep.scanlator = scanlator.join(", "); + episodesList.add(ep); + } + } + } else { + for (var i = 0; i < seasons.length; i++) { + MChapter ep = MChapter(); + final movie = seasons[i]; + ep.name = "Movie ${i + 1}"; + ep.url = json.encode({"media_id": movie["id"], "audio": ""}); + ep.dateUpload = parseDates([movie["premium_available_date"]], + "yyyy-MM-dd'T'HH:mm:ss", "en") + .first; + episodesList.add(ep); + } + } + anime.chapters = episodesList.reversed.toList(); + return anime; + } + + @override + Future> getVideoList(String url) async { + List> jsonList = json.decode(url); + if (jsonList.isEmpty) throw "Episode List is empty"; + List videos = []; + List subtitles = []; + for (var v in jsonList) { + final mediaId = v["media_id"]; + String audio = v["audio"]; + + final res = await interceptAccesTokenAndGetResponse( + '$crUrl/cms/v2{0}/videos/$mediaId/streams?Policy={1}&Signature={2}&Key-Pair-Id={3}'); + + for (var ok + in (json.decode(res)["subtitles"] as Map).entries) { + try { + MTrack subtitle = MTrack(); + subtitle + ..label = getLocale(ok.value["locale"]) + ..file = ok.value["url"]; + subtitles.add(subtitle); + } catch (_) {} + } + if (audio.isEmpty) { + audio = getMapValue(res, "audio_locale"); + if (audio.isEmpty) { + audio = "ja-JP"; + } + } + audio = getLocale(audio); + for (var ok in (json.decode(res)["streams"]["adaptive_hls"] + as Map) + .entries) { + final url = ok.value["url"]; + + String hardsub = getMapValue(json.encode(ok.value), "hardsub_locale"); + if (hardsub.isNotEmpty) { + hardsub = " - HardSub: $hardsub"; + } + + final res = await client.get(Uri.parse(url)); + if (res.statusCode == 200) { + for (var it in substringAfter(res.body, "#EXT-X-STREAM-INF:") + .split("#EXT-X-STREAM-INF:")) { + final quality = + "${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p"; + + String videoUrl = substringBefore(substringAfter(it, "\n"), "\n"); + + MVideo video = MVideo(); + video + ..url = videoUrl + ..originalUrl = videoUrl + ..quality = "$quality - Aud: $audio $hardsub" + ..subtitles = sortSubs(subtitles); + videos.add(video); + } + } + } + } + return sortVideos(videos); + } + + List sortSubs(List subs) { + String lang = getPreferenceValue(source.id, "preferred_subLang"); + + subs.sort((MTrack a, MTrack b) { + int langMatchA = 0; + if (a.label.contains(getLocale(lang))) { + langMatchA = 1; + } + int langMatchB = 0; + if (b.label.contains(getLocale(lang))) { + langMatchB = 1; + } + return langMatchB - langMatchA; + }); + return subs; + } + + Future animeFromRes(String res, String page) async { + int position = int.tryParse(page) ?? 0; + bool hasNextPage = position + 36 < json.decode(res)["total"]; + List> dataListJson = json.decode(res)["data"]; + List animeList = []; + for (var data in dataListJson) { + MManga anime = MManga(); + final type = data["type"]; + final title = data["title"]; + if (type == "series") { + final res = getMapValue( + json.encode(data["series_metadata"]), "tenant_categories", + encode: true); + if (res.isNotEmpty) { + anime.genre = json.decode(res); + } + } else { + final res = getMapValue( + json.encode(data["movie_metadata"]), "tenant_categories", + encode: true); + if (res.isNotEmpty) { + anime.genre = json.decode(res); + anime.status = MStatus.completed; + } + } + String description = data["description"]; + String metadata = type == "series" ? "series_metadata" : "movie_metadata"; + description += "\n\nLanguage:"; + if (data[metadata]["is_subbed"]) { + description += " Sub"; + } + if (data[metadata]["is_dubbed"]) { + description += " Dub"; + } + description += "\nMaturity Ratings: "; + description += (data[metadata]["maturity_ratings"] as List).join(", "); + description += "\n\nAudio: "; + description += (data[metadata]["audio_locales"] as List) + .map((e) => getLocale(e)) + .toList() + .toSet() + .toList() + .join(", "); + description += "\n\nSubs: "; + description += (data[metadata]["subtitle_locales"] as List) + .map((e) => getLocale(e)) + .toList() + .toSet() + .toList() + .join(", "); + anime.description = description; + anime.name = title; + anime.imageUrl = ((data["images"]["poster_tall"][0] as List).last + as Map)["source"]; + anime.link = json.encode({"id": data["id"], "type": type}); + animeList.add(anime); + } + return MPages(animeList, hasNextPage); + } + + Future interceptAccesTokenAndGetResponse(String url) async { + final accessToken = await getAccessToken(false); + final res = await checkUrlForNewRequest(url, accessToken); + Response response = + await client.get(Uri.parse(res["url"]), headers: res["headers"]); + if (response.statusCode == 401) { + Map res; + final newAccessToken = await getAccessToken(false); + if (accessToken != newAccessToken) { + res = await checkUrlForNewRequest(url, newAccessToken); + } + final refreshedToken = await getAccessToken(true); + + res = await checkUrlForNewRequest(url, refreshedToken); + Response response = + await client.get(Uri.parse(res["url"]), headers: res["headers"]); + return response.body; + } else { + return response.body; + } + } + + Future> getAccessToken(bool force) async { + String token = getPrefStringValue(source.id, "access_token", ""); + if (!force && token.isNotEmpty) { + return json.decode(token); + } else { + final token = await refreshAccessToken(); + setPrefStringValue(source.id, "access_token", token); + return json.decode(token); + } + } + + Future> checkUrlForNewRequest( + String url, Map tokenData) async { + if (url.contains("/cms/v2")) { + url = url + .replaceAll("{0}", tokenData["bucket"]) + .replaceAll("{1}", tokenData["policy"]) + .replaceAll("{2}", tokenData["signature"]) + .replaceAll("{3}", tokenData["key_pair_id"]); + } + return ({ + "url": url, + "headers": { + "authorization": + "${tokenData["token_type"]} ${tokenData["access_token"]}" + } + }); + } + + Future refreshAccessToken() async { + setPrefStringValue(source.id, "access_token", ""); + Response response = await client.get(Uri.parse( + "https://raw.githubusercontent.com/Samfun75/File-host/main/aniyomi/refreshToken.txt")); + final refreshToken = response.body.replaceAll(RegExp(r'[\n\r]'), ''); + Response tokenResponse = await client.post( + Uri.parse("$crUrl/auth/v1/token"), + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': + 'Basic b2VkYXJteHN0bGgxanZhd2ltbnE6OWxFaHZIWkpEMzJqdVY1ZFc5Vk9TNTdkb3BkSnBnbzE=', + }, + body: { + 'grant_type': 'refresh_token', + 'refresh_token': refreshToken, + 'scope': 'offline_access', + }, + ); + final tokenJson = json.decode(tokenResponse.body); + + final res = await checkUrlForNewRequest("$crUrl/index/v2", { + "access_token": tokenJson["access_token"], + "token_type": tokenJson["token_type"] + }); + + final policyJson = json.decode( + (await client.get(Uri.parse(res["url"]), headers: res["headers"])) + .body); + + return json.encode({ + "access_token": tokenJson["access_token"], + "token_type": tokenJson["token_type"], + "policy": policyJson['cms']['policy'], + "signature": policyJson['cms']['signature'], + "key_pair_id": policyJson['cms']['key_pair_id'], + "bucket": policyJson['cms']['bucket'], + "expires": DateTime.parse("2024-02-02T14:06:52Z").microsecondsSinceEpoch, + }); + } + + List sortVideos(List videos) { + String quality = getPreferenceValue(source.id, "preferred_quality"); + String dub = getPreferenceValue(source.id, "preferred_audioLang"); + String sub = getPreferenceValue(source.id, "preferred_subLang"); + String subType = getPreferenceValue(source.id, "preferred_sub_type"); + videos.sort((MVideo a, MVideo b) { + int qualityMatchA = 0; + + if (a.quality.contains(quality) && + a.quality + .toLowerCase() + .contains("Aud: ${getLocale(dub)}".toLowerCase()) && + a.quality.toLowerCase().contains(subType.toLowerCase()) && + a.quality.toLowerCase().contains(sub.toLowerCase())) { + qualityMatchA = 1; + } + int qualityMatchB = 0; + if (b.quality.contains(quality) && + b.quality + .toLowerCase() + .contains("Aud: ${getLocale(dub)}".toLowerCase()) && + b.quality.toLowerCase().contains(subType.toLowerCase()) && + b.quality.toLowerCase().contains(sub.toLowerCase())) { + 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; + } + + String getLocale(String key) { + return getMapValue(json.encode(locale), key); + } + + Map locale = { + "ar-ME": "Arabic", + "ar-SA": "Arabic (Saudi Arabia)", + "de-DE": "German", + "en-US": "English", + "en-IN": "English (India)", + "es-419": "Spanish (América Latina)", + "es-ES": "Spanish (España)", + "es-LA": "Spanish (América Latina)", + "fr-FR": "French", + "ja-JP": "Japanese", + "hi-IN": "Hindi", + "it-IT": "Italian", + "ko-KR": "Korean", + "pt-BR": "Português (Brasil)", + "pt-PT": "Português (Portugal)", + "pl-PL": "Polish", + "ru-RU": "Russian", + "tr-TR": "Turkish", + "uk-UK": "Ukrainian", + "he-IL": "Hebrew", + "ro-RO": "Romanian", + "sv-SE": "Swedish", + "zh-CN": "Chinese (PRC)", + "zh-HK": "Chinese (Hong Kong)", + "zh-TW": "Chinese (Taiwan)", + "ca-ES": "Català", + "id-ID": "Bahasa Indonesia", + "ms-MY": "Bahasa Melayu", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th-TH": "Thai", + "vi-VN": "Vietnamese" + }; + @override + List getFilterList() { + return [ + HeaderFilter("Search Filter (ignored if browsing)"), + SelectFilter("TypeFilter", "Type", 0, [ + SelectFilterOption("Top Results", "top_results"), + SelectFilterOption("Series", "series"), + SelectFilterOption("Movies", "movie_listing") + ]), + SeparatorFilter(), + SelectFilter("CategoryFilter", "Category", 0, [ + { + "type": "SelectOption", + "filter": {"name": "-", "value": ""} + }, + { + "type": "SelectOption", + "filter": {"name": "Action", "value": "&categories=action"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Adventure", + "value": "&categories=action,adventure" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Comedy", + "value": "&categories=action,comedy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Drama", + "value": "&categories=action,drama" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Fantasy", + "value": "&categories=action,fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Historical", + "value": "&categories=action,historical" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Post-Apocalyptic", + "value": "&categories=action,post-apocalyptic" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Sci-Fi", + "value": "&categories=action,sci-fi" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Supernatural", + "value": "&categories=action,supernatural" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Action, Thriller", + "value": "&categories=action,thriller" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Adventure", "value": "&categories=adventure"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Adventure, Fantasy", + "value": "&categories=adventure,fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Adventure, Isekai", + "value": "&categories=adventure,isekai" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Adventure, Romance", + "value": "&categories=adventure,romance" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Adventure, Sci-Fi", + "value": "&categories=adventure,sci-fi" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Adventure, Supernatural", + "value": "&categories=adventure,supernatural" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Comedy", "value": "&categories=comedy"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Comedy, Drama", + "value": "&categories=comedy,drama" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Comedy, Fantasy", + "value": "&categories=comedy,fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Comedy, Historical", + "value": "&categories=comedy,historical" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Comedy, Music", + "value": "&categories=comedy,music" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Comedy, Romance", + "value": "&categories=comedy,romance" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Comedy, Sci-Fi", + "value": "&categories=comedy,sci-fi" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Comedy, Slice of life", + "value": "&categories=comedy,slice+of+life" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Comedy, Supernatural", + "value": "&categories=comedy,supernatural" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Drama", "value": "&categories=drama"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Drama, Adventure", + "value": "&categories=drama,adventure" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Drama, Fantasy", + "value": "&categories=drama,fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Drama, Historical", + "value": "&categories=drama,historical" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Drama, Mecha", "value": "&categories=drama,mecha"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Drama, Mystery", + "value": "&categories=drama,mystery" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Drama, Romance", + "value": "&categories=drama,romance" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Drama, Sci-Fi", + "value": "&categories=drama,sci-fi" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Drama, Slice of life", + "value": "&categories=drama,slice+of+life" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Fantasy", "value": "&categories=fantasy"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Fantasy, Historical", + "value": "&categories=fantasy,historical" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Fantasy, Isekai", + "value": "&categories=fantasy,isekai" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Fantasy, Mystery", + "value": "&categories=fantasy,mystery" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Fantasy, Romance", + "value": "&categories=fantasy,romance" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Fantasy, Supernatural", + "value": "&categories=fantasy,supernatural" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Music", "value": "&categories=music"} + }, + { + "type": "SelectOption", + "filter": {"name": "Music, Drama", "value": "&categories=music,drama"} + }, + { + "type": "SelectOption", + "filter": {"name": "Music, Idols", "value": "&categories=music,idols"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Music, slice of life", + "value": "&categories=music,slice+of+life" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Romance", "value": "&categories=romance"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Romance, Harem", + "value": "&categories=romance,harem" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Romance, Historical", + "value": "&categories=romance,historical" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Sci-Fi", "value": "&categories=sci-fi"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Sci-Fi, Fantasy", + "value": "&categories=sci-fi,Fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Sci-Fi, Historical", + "value": "&categories=sci-fi,historical" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Sci-Fi, Mecha", + "value": "&categories=sci-fi,mecha" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Seinen", "value": "&categories=seinen"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Seinen, Action", + "value": "&categories=seinen,action" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Seinen, Drama", + "value": "&categories=seinen,drama" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Seinen, Fantasy", + "value": "&categories=seinen,fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Seinen, Historical", + "value": "&categories=seinen,historical" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Seinen, Supernatural", + "value": "&categories=seinen,supernatural" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Shojo", "value": "&categories=shojo"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Shojo, Fantasy", + "value": "&categories=shojo,Fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shojo, Magical Girls", + "value": "&categories=shojo,magical-girls" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shojo, Romance", + "value": "&categories=shojo,romance" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shojo, Slice of life", + "value": "&categories=shojo,slice+of+life" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Shonen", "value": "&categories=shonen"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Shonen, Action", + "value": "&categories=shonen,action" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shonen, Adventure", + "value": "&categories=shonen,adventure" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shonen, Comedy", + "value": "&categories=shonen,comedy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shonen, Drama", + "value": "&categories=shonen,drama" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shonen, Fantasy", + "value": "&categories=shonen,fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shonen, Mystery", + "value": "&categories=shonen,mystery" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shonen, Post-Apocalyptic", + "value": "&categories=shonen,post-apocalyptic" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Shonen, Supernatural", + "value": "&categories=shonen,supernatural" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Slice of life", + "value": "&categories=slice+of+life" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Slice of life, Fantasy", + "value": "&categories=slice+of+life,fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Slice of life, Romance", + "value": "&categories=slice+of+life,romance" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Slice of life, Sci-Fi", + "value": "&categories=slice+of+life,sci-fi" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Sports", "value": "&categories=sports"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Sports, Action", + "value": "&categories=sports,action" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Sports, Comedy", + "value": "&categories=sports,comedy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Sports, Drama", + "value": "&categories=sports,drama" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Supernatural", + "value": "&categories=supernatural" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Supernatural, Drama", + "value": "&categories=supernatural,drama" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Supernatural, Historical", + "value": "&categories=supernatural,historical" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Supernatural, Mystery", + "value": "&categories=supernatural,mystery" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Supernatural, Slice of life", + "value": "&categories=supernatural,slice+of+life" + } + }, + { + "type": "SelectOption", + "filter": {"name": "Thriller", "value": "&categories=thriller"} + }, + { + "type": "SelectOption", + "filter": { + "name": "Thriller, Drama", + "value": "&categories=thriller,drama" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Thriller, Fantasy", + "value": "&categories=thriller,fantasy" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Thriller, Sci-Fi", + "value": "&categories=thriller,sci-fi" + } + }, + { + "type": "SelectOption", + "filter": { + "name": "Thriller, Supernatural", + "value": "&categories=thriller,supernatural" + } + } + ]), + HeaderFilter("Browse Filters (ignored if searching)"), + SelectFilter("SortFilter", "Sort By", 0, [ + SelectFilterOption("Popular", "popularity"), + SelectFilterOption("New", "newly_added"), + SelectFilterOption("Alphabetical", "alphabetical") + ]), + SelectFilter("MediaFilter", "Media", 0, [ + SelectFilterOption("All", ""), + SelectFilterOption("Series", "&type=series"), + SelectFilterOption("Movies", "&type=movie_listing"), + ]), + GroupFilter("LanguageFilter", "Language", [ + CheckBoxFilter("Sub", "&is_subbed=true"), + CheckBoxFilter("Dub", "&is_dubbed=true") + ]), + ]; + } + + @override + List getSourcePreferences() { + return [ + ListPreference( + key: "preferred_quality", + title: "Preferred Quality", + summary: "", + valueIndex: 0, + entries: ["1080p", "720p", "480p", "360p", "240p", "80p"], + entryValues: ["1080p", "720p", "480p", "360p", "240p", "80p"]), + ListPreference( + key: "preferred_audioLang", + title: "Preferred Audio Language", + summary: "", + valueIndex: 3, + entries: locale.entries.map((e) => e.value).toList(), + entryValues: locale.entries.map((e) => e.key).toList()), + ListPreference( + key: "preferred_subLang", + title: "Preferred Sub language", + summary: "", + valueIndex: 3, + entries: locale.entries.map((e) => e.value).toList(), + entryValues: locale.entries.map((e) => e.key).toList()), + ListPreference( + key: "preferred_sub_type", + title: "Preferred Sub Type", + summary: "", + valueIndex: 0, + entries: ["Softsub", "Hardsub"], + entryValues: ["", "Hardsub"]), + ]; + } +} + +YomiRoll main(MSource source) { + return YomiRoll(source: source); +} diff --git a/anime/src/ar/okanime/okanime.dart b/anime/src/ar/okanime/okanime.dart index f0b7e41..470b02b 100644 --- a/anime/src/ar/okanime/okanime.dart +++ b/anime/src/ar/okanime/okanime.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class OkAnime extends MProvider { - OkAnime(); + OkAnime({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client.get(Uri.parse(source.baseUrl))).body; List animeList = []; String path = @@ -27,7 +29,7 @@ class OkAnime extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client .get(Uri.parse("${source.baseUrl}/espisode-list?page=$page"))) .body; @@ -50,8 +52,7 @@ class OkAnime extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { String url = "${source.baseUrl}/search/?s=$query"; if (page > 1) { url += "&page=$page"; @@ -78,7 +79,7 @@ class OkAnime extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"يعرض الان": 0, "مكتمل": 1} ]; @@ -114,7 +115,7 @@ class OkAnime extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = (await client.get(Uri.parse(url))).body; final urls = xpath(res, '//*[@id="streamlinks"]/a/@data-src'); final qualities = xpath(res, '//*[@id="streamlinks"]/a/span/text()'); @@ -143,7 +144,7 @@ class OkAnime extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_quality", @@ -217,6 +218,6 @@ class OkAnime extends MProvider { } } -OkAnime main() { - return OkAnime(); +OkAnime main(MSource source) { + return OkAnime(source: source); } diff --git a/anime/src/ar/okanime/source.dart b/anime/src/ar/okanime/source.dart index 51c0f82..57c779b 100644 --- a/anime/src/ar/okanime/source.dart +++ b/anime/src/ar/okanime/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get okanimeSource => _okanimeSource; -const _okanimeVersion = "0.0.45"; +const _okanimeVersion = "0.0.5"; const _okanimeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/ar/okanime/okanime.dart"; Source _okanimeSource = Source( diff --git a/anime/src/de/aniflix/aniflix.dart b/anime/src/de/aniflix/aniflix.dart index da02862..3195d02 100644 --- a/anime/src/de/aniflix/aniflix.dart +++ b/anime/src/de/aniflix/aniflix.dart @@ -2,23 +2,25 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class AniFlix extends MProvider { - AniFlix(); + AniFlix({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final headers = getHeader(source.baseUrl); final res = (await client.get( Uri.parse("${source.baseUrl}/api/show/new/${page - 1}"), headers: headers)) .body; - return parseAnimeList(res, source.baseUrl, true); + return parseAnimeList(res, true); } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final headers = getHeader(source.baseUrl); final res = (await client.get( Uri.parse("${source.baseUrl}/api/show/airing/${page - 1}"), @@ -50,17 +52,16 @@ class AniFlix extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final res = await client.post( Uri.parse("${source.baseUrl}/api/show/search"), headers: {'Referer': source.baseUrl}, body: {"search": query}); - return parseAnimeList(res.body, source.baseUrl, false); + return parseAnimeList(res.body, false); } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final res = (await client.get(Uri.parse("${source.baseUrl}$url"))).body; MManga anime = MManga(); final jsonRes = json.decode(res); @@ -117,7 +118,7 @@ class AniFlix extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = (await client.get(Uri.parse("${source.baseUrl}$url"), headers: getHeader(source.baseUrl))) .body; @@ -147,15 +148,17 @@ class AniFlix extends MProvider { return sortVideos(videos, source.id); } - MPages parseAnimeList(String res, String baseUrl, bool hasNextPage) { + MPages parseAnimeList(String res, bool hasNextPage) { final datas = json.decode(res); List animeList = []; for (var data in datas) { MManga anime = MManga(); anime.name = data["name"]; - anime.imageUrl = "$baseUrl/storage/" + (data["cover_portrait"] ?? ""); - anime.link = getUrlWithoutDomain("$baseUrl/api/show/${data['url']}"); + anime.imageUrl = + "${source.baseUrl}/storage/" + (data["cover_portrait"] ?? ""); + anime.link = + getUrlWithoutDomain("${source.baseUrl}/api/show/${data['url']}"); anime.description = data["description"]; if (data["airing"] == 0) { anime.status = MStatus.completed; @@ -191,7 +194,7 @@ class AniFlix extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_hoster", @@ -232,6 +235,6 @@ Map getHeader(String url) { return {'Referer': url}; } -AniFlix main() { - return AniFlix(); +AniFlix main(MSource source) { + return AniFlix(source: source); } diff --git a/anime/src/de/aniflix/source.dart b/anime/src/de/aniflix/source.dart index 08516c9..73d67c2 100644 --- a/anime/src/de/aniflix/source.dart +++ b/anime/src/de/aniflix/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get aniflix => _aniflix; -const _aniflixVersion = "0.0.2"; +const _aniflixVersion = "0.0.25"; const _aniflixCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/de/aniflix/aniflix.dart"; Source _aniflix = Source( diff --git a/anime/src/en/animepahe/animepahe.dart b/anime/src/en/animepahe/animepahe.dart new file mode 100644 index 0000000..ca6a13c --- /dev/null +++ b/anime/src/en/animepahe/animepahe.dart @@ -0,0 +1,223 @@ +import 'package:mangayomi/bridge_lib.dart'; +import 'dart:convert'; +import 'dart:math'; + +class AnimePahe extends MProvider { + AnimePahe(this.source); + + final MSource source; + + final Client client = Client(source); + + @override + String get baseUrl => getPreferenceValue(source.id, "preferred_domain"); + + @override + Future getPopular(int page) async { + return await getLatestUpdates(page); + } + + @override + Future getLatestUpdates(int page) async { + final res = + (await client.get(Uri.parse("$baseUrl/api?m=airing&page=$page"))).body; + final jsonResult = json.decode(res); + final hasNextPage = jsonResult["current_page"] < jsonResult["last_page"]; + List animeList = []; + for (var item in jsonResult["data"]) { + MManga anime = MManga(); + anime.name = item["anime_title"]; + anime.imageUrl = item["snapshot"]; + anime.link = "/anime/?anime_id=${item["id"]}&name=${item["anime_title"]}"; + anime.artist = item["fansub"]; + animeList.add(anime); + } + return MPages(animeList, hasNextPage); + } + + @override + Future search(String query, int page, FilterList filterList) async { + final res = + (await client.get(Uri.parse("$baseUrl/api?m=search&l=8&q=$query"))) + .body; + final jsonResult = json.decode(res); + List animeList = []; + for (var item in jsonResult["data"]) { + MManga anime = MManga(); + anime.name = item["title"]; + anime.imageUrl = item["poster"]; + anime.link = "/anime/?anime_id=${item["id"]}&name=${item["title"]}"; + animeList.add(anime); + } + return MPages(animeList, false); + } + + @override + Future getDetail(String url) async { + final statusList = [ + {"Currently Airing": 0, "Finished Airing": 1} + ]; + MManga anime = MManga(); + final id = substringBefore(substringAfterLast(url, "?anime_id="), "&name="); + final name = substringAfterLast(url, "&name="); + print(name); + final session = await getSession(name, id); + print(session); + final res = + (await client.get(Uri.parse("$baseUrl/anime/$session?anime_id=$id"))) + .body; + final document = parseHtml(res); + final status = + (document.xpathFirst('//div/p[contains(text(),"Status:")]/text()') ?? + "") + .replaceAll("Status:\n", "") + .trim(); + anime.status = parseStatus(status, statusList); + + anime.name = document.selectFirst("div.title-wrapper > h1 > span").text; + anime.author = + (document.xpathFirst('//div/p[contains(text(),"Studio:")]/text()') ?? + "") + .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()'); + final synonyms = + (document.xpathFirst('//div/p[contains(text(),"Synonyms:")]/text()') ?? + "") + .replaceAll("Synonyms:\n", "") + .trim(); + anime.description = document.selectFirst("div.anime-summary").text; + if (synonyms.isNotEmpty) { + anime.description += "\n\n$synonyms"; + } + final epUrl = "$baseUrl/api?m=release&id=$session&sort=episode_desc&page=1"; + final resEp = (await client.get(Uri.parse(epUrl))).body; + final episodes = await recursivePages(epUrl, resEp, session); + + anime.chapters = episodes; + return anime; + } + + Future> recursivePages( + String url, String res, String session) async { + final jsonResult = json.decode(res); + final page = jsonResult["current_page"]; + final hasNextPage = page < jsonResult["last_page"]; + List animeList = []; + for (var item in jsonResult["data"]) { + MChapter episode = MChapter(); + episode.name = "Episode ${item["episode"]}"; + episode.url = "/play/$session/${item["session"]}"; + episode.dateUpload = + parseDates([item["created_at"]], "yyyy-MM-dd HH:mm:ss", "en")[0]; + animeList.add(episode); + } + if (hasNextPage) { + final newUrl = "${substringBeforeLast(url, "&page=")}&page=${page + 1}"; + final newRes = (await client.get(Uri.parse(newUrl))).body; + animeList.addAll(await recursivePages(newUrl, newRes, session)); + } + return animeList; + } + + Future getSession(String title, String animeId) async { + final res = + (await client.get(Uri.parse("$baseUrl/api?m=search&q=$title"))).body; + return substringBefore( + substringAfter( + substringAfter(res, "\"id\":$animeId"), "\"session\":\""), + "\""); + } + + @override + Future> getVideoList(String url) async { + final res = (await client.get(Uri.parse("${source.baseUrl}$url"))); + + final document = parseHtml(res.body); + final buttons = document.select("div#resolutionMenu > button"); + List videos = []; + for (var i = 0; i < buttons.length; i++) { + final btn = buttons[i]; + final kwikLink = btn.attr("data-src"); + final quality = btn.text; + 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("); + final videoUrl = substringBefore( + substringAfter(unpackJs("eval(function($script"), "const source=\\'"), + "\\';"); + MVideo video = MVideo(); + video + ..url = videoUrl + ..originalUrl = videoUrl + ..quality = quality + ..headers = {"referer": "https://kwik.cx"}; + videos.add(video); + } + return sortVideos(videos); + } + + List sortVideos(List videos) { + String quality = getPreferenceValue(source.id, "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; + } + + @override + List getSourcePreferences() { + return [ + ListPreference( + key: "preferred_domain", + title: "Preferred domain", + summary: "", + valueIndex: 1, + entries: [ + "animepahe.com", + "animepahe.ru", + "animepahe.org" + ], + entryValues: [ + "https://animepahe.com", + "https://animepahe.ru", + "https://animepahe.org" + ]), + ListPreference( + key: "preferred_quality", + title: "Preferred Quality", + summary: "", + valueIndex: 0, + entries: ["1080p", "720p", "360p"], + entryValues: ["1080", "720", "360"]), + ]; + } +} + +AnimePahe main(MSource source) { + return AnimePahe(source); +} diff --git a/anime/src/en/animepahe/icon.png b/anime/src/en/animepahe/icon.png new file mode 100644 index 0000000..4c3b009 Binary files /dev/null and b/anime/src/en/animepahe/icon.png differ diff --git a/anime/src/en/animepahe/source.dart b/anime/src/en/animepahe/source.dart new file mode 100644 index 0000000..2635e4b --- /dev/null +++ b/anime/src/en/animepahe/source.dart @@ -0,0 +1,16 @@ +import '../../../../model/source.dart'; + +Source get animepaheSource => _animepaheSource; +const _animepaheVersion = "0.0.1"; +const _animepaheSourceCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/ar/animepahe/animepahe.dart"; +Source _animepaheSource = Source( + name: "animepahe", + baseUrl: "https://www.animepahe.ru", + lang: "en", + typeSource: "single", + iconUrl: + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/ar/animepahe/icon.png", + sourceCodeUrl: _animepaheSourceCodeUrl, + version: _animepaheVersion, + isManga: false); diff --git a/anime/src/en/aniwave/aniwave.dart b/anime/src/en/aniwave/aniwave.dart index a7a0dde..ebe4886 100644 --- a/anime/src/en/aniwave/aniwave.dart +++ b/anime/src/en/aniwave/aniwave.dart @@ -2,31 +2,35 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class Aniwave extends MProvider { - Aniwave(); + Aniwave({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/filter?sort=trending&page=$page"))) + String get baseUrl => getPreferenceValue(source.id, "preferred_domain1"); + + @override + Future getPopular(int page) async { + final res = (await client + .get(Uri.parse("$baseUrl/filter?sort=trending&page=$page"))) .body; return parseAnimeList(res); } @override - Future getLatestUpdates(MSource source, int page) async { - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/filter?sort=recently_updated&page=$page"))) + Future getLatestUpdates(int page) async { + final res = (await client + .get(Uri.parse("$baseUrl/filter?sort=recently_updated&page=$page"))) .body; return parseAnimeList(res); } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; - String url = "${preferenceBaseUrl(source.id)}/filter?keyword=$query"; + String url = "$baseUrl/filter?keyword=$query"; for (var filter in filters) { if (filter.type == "OrderFilter") { @@ -96,13 +100,11 @@ class Aniwave extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"Releasing": 0, "Completed": 1} ]; - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; MManga anime = MManga(); final status = xpath(res, '//div[contains(text(),"Status")]/span/text()'); if (status.isNotEmpty) { @@ -123,9 +125,9 @@ class Aniwave extends MProvider { final encrypt = vrfEncrypt(id); final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; - final resEp = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/ajax/episode/list/$id?$vrf"))) - .body; + final resEp = + (await client.get(Uri.parse("$baseUrl/ajax/episode/list/$id?$vrf"))) + .body; final html = json.decode(resEp)["result"]; List? episodesList = []; @@ -168,13 +170,13 @@ class Aniwave extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final ids = substringBefore(url, "&"); final encrypt = vrfEncrypt(ids); final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/ajax/server/list/$ids?$vrf"))) - .body; + final res = + (await client.get(Uri.parse("$baseUrl/ajax/server/list/$ids?$vrf"))) + .body; final html = json.decode(res)["result"]; final vidsHtmls = parseHtml(html).select("div.servers > div"); @@ -189,9 +191,9 @@ class Aniwave extends MProvider { final encrypt = vrfEncrypt(serverId); final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/ajax/server/$serverId?$vrf"))) - .body; + final res = + (await client.get(Uri.parse("$baseUrl/ajax/server/$serverId?$vrf"))) + .body; final status = json.decode(res)["status"]; if (status == 200) { List a = []; @@ -412,7 +414,7 @@ class Aniwave extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ SelectFilter("OrderFilter", "Sort order", 0, [ SelectFilterOption("Most relevance", "most_relevance"), @@ -545,7 +547,7 @@ class Aniwave extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_domain1", @@ -632,10 +634,6 @@ class Aniwave extends MProvider { ]; } - String preferenceBaseUrl(int sourceId) { - return getPreferenceValue(sourceId, "preferred_domain1"); - } - List preferenceHosterSelection(int sourceId) { return getPreferenceValue(sourceId, "hoster_selection"); } @@ -685,6 +683,6 @@ class Aniwave extends MProvider { } } -Aniwave main() { - return Aniwave(); +Aniwave main(MSource source) { + return Aniwave(source: source); } diff --git a/anime/src/en/aniwave/source.dart b/anime/src/en/aniwave/source.dart index a8255e7..2d2dad2 100644 --- a/anime/src/en/aniwave/source.dart +++ b/anime/src/en/aniwave/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get aniwave => _aniwave; -const _aniwaveVersion = "0.0.55"; +const _aniwaveVersion = "0.0.6"; const _aniwaveCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/en/aniwave/aniwave.dart"; Source _aniwave = Source( diff --git a/anime/src/en/dramacool/dramacool.dart b/anime/src/en/dramacool/dramacool.dart index 19274f8..2bf0104 100644 --- a/anime/src/en/dramacool/dramacool.dart +++ b/anime/src/en/dramacool/dramacool.dart @@ -2,35 +2,39 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class DramaCool extends MProvider { - DramaCool(); + DramaCool({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/most-popular-drama?page=$page"))) - .body; + String get baseUrl => getPreferenceValue(source.id, "overrideBaseUrl"); + + @override + Future getPopular(int page) async { + final res = + (await client.get(Uri.parse("$baseUrl/most-popular-drama?page=$page"))) + .body; final document = parseHtml(res); return animeFromElement(document.select("ul.list-episode-item li a"), document.selectFirst("li.next a")?.attr("href") != null); } @override - Future getLatestUpdates(MSource source, int page) async { - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/recently-added?page=$page"))) - .body; + Future getLatestUpdates(int page) async { + final res = + (await client.get(Uri.parse("$baseUrl/recently-added?page=$page"))) + .body; final document = parseHtml(res); return animeFromElement(document.select("ul.switch-block a"), document.selectFirst("li.next a")?.attr("href") != null); } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/search?keyword=$query&page=$page"))) + Future search(String query, int page, FilterList filterList) async { + final res = (await client + .get(Uri.parse("$baseUrl/search?keyword=$query&page=$page"))) .body; final document = parseHtml(res); return animeFromElement(document.select("ul.list-episode-item li a"), @@ -38,22 +42,18 @@ class DramaCool extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"Ongoing": 0, "Completed": 1} ]; url = getUrlWithoutDomain(url); if (url.contains("-episode-") && url.endsWith(".html")) { - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; url = parseHtml(res).selectFirst("div.category a").attr("href"); } url = getUrlWithoutDomain(url); - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; final document = parseHtml(res); MManga anime = MManga(); anime.description = document @@ -100,12 +100,10 @@ class DramaCool extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { url = getUrlWithoutDomain(url); - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; final document = parseHtml(res); String iframeUrl = document.selectFirst("iframe")?.getSrc ?? ""; if (iframeUrl.isEmpty) return []; @@ -131,7 +129,7 @@ class DramaCool extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ EditTextPreference( key: "overrideBaseUrl", @@ -165,10 +163,6 @@ class DramaCool extends MProvider { ]; } - String preferenceBaseUrl(int sourceId) { - return getPreferenceValue(sourceId, "overrideBaseUrl"); - } - MPages animeFromElement(List elements, bool hasNextPage) { List animeList = []; for (var element in elements) { @@ -211,6 +205,6 @@ class DramaCool extends MProvider { } } -DramaCool main() { - return DramaCool(); +DramaCool main(MSource source) { + return DramaCool(source: source); } diff --git a/anime/src/en/dramacool/source.dart b/anime/src/en/dramacool/source.dart index 8cab821..89db770 100644 --- a/anime/src/en/dramacool/source.dart +++ b/anime/src/en/dramacool/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get dramacoolSource => _dramacoolSource; -const _dramacoolVersion = "0.0.15"; +const _dramacoolVersion = "0.0.2"; const _dramacoolSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/en/dramacool/dramacool.dart"; Source _dramacoolSource = Source( diff --git a/anime/src/en/gogoanime/gogoanime.dart b/anime/src/en/gogoanime/gogoanime.dart index b527c25..ea17861 100644 --- a/anime/src/en/gogoanime/gogoanime.dart +++ b/anime/src/en/gogoanime/gogoanime.dart @@ -2,15 +2,20 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class GogoAnime extends MProvider { - GogoAnime(); + GogoAnime({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/popular.html?page=$page"))) - .body; + String get baseUrl => + getPreferenceValue(source.id, "override_baseurl_v${source.id}"); + + @override + Future getPopular(int page) async { + final res = + (await client.get(Uri.parse("$baseUrl/popular.html?page=$page"))).body; List animeList = []; final urls = xpath(res, '//*[@class="img"]/a/@href'); @@ -29,7 +34,7 @@ class GogoAnime extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get(Uri.parse( "https://ajax.gogo-load.com/ajax/page-recent-release-ongoing.html?page=$page&type=1"))) .body; @@ -58,8 +63,7 @@ class GogoAnime extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String filterStr = ""; String url = ""; @@ -131,15 +135,14 @@ class GogoAnime extends MProvider { } } if (genre.isNotEmpty) { - url = "${preferenceBaseUrl(source.id)}/genre/$genre?page=$page"; + url = "$baseUrl/genre/$genre?page=$page"; } else if (recent.isNotEmpty) { url = "https://ajax.gogo-load.com/ajax/page-recent-release.html?page=$page&type=$recent"; } else if (season.isNotEmpty) { - url = "${preferenceBaseUrl(source.id)}/$season?page=$page"; + url = "$baseUrl/$season?page=$page"; } else { - url = - "${preferenceBaseUrl(source.id)}/filter.html?keyword=$query$filterStr&page=$page"; + url = "$baseUrl/filter.html?keyword=$query$filterStr&page=$page"; } final res = (await client.get(Uri.parse(url))).body; @@ -161,14 +164,12 @@ class GogoAnime extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"Ongoing": 0, "Completed": 1} ]; - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; MManga anime = MManga(); final status = xpath( res, '//*[@class="anime_info_body_bg"]/p[@class="type"][5]/text()') @@ -212,10 +213,8 @@ class GogoAnime extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + Future> getVideoList(String url) async { + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; final serverUrls = xpath(res, '//*[@class="anime_muti_link"]/ul/li/a/@data-video'); final serverNames = @@ -248,7 +247,7 @@ class GogoAnime extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ HeaderFilter("Advanced search"), GroupFilter("GenreFilter", "Genre", [ @@ -1030,7 +1029,7 @@ class GogoAnime extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ EditTextPreference( key: "override_baseurl_v${source.id}", @@ -1100,10 +1099,6 @@ class GogoAnime extends MProvider { ]; } - String preferenceBaseUrl(int sourceId) { - return getPreferenceValue(sourceId, "override_baseurl_v$sourceId"); - } - List preferenceHosterSelection(int sourceId) { return getPreferenceValue(sourceId, "hoster_selection"); } @@ -1137,6 +1132,6 @@ class GogoAnime extends MProvider { } } -GogoAnime main() { - return GogoAnime(); +GogoAnime main(MSource source) { + return GogoAnime(source: source); } diff --git a/anime/src/en/gogoanime/source.dart b/anime/src/en/gogoanime/source.dart index aec6e6e..78fdaf6 100644 --- a/anime/src/en/gogoanime/source.dart +++ b/anime/src/en/gogoanime/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get gogoanimeSource => _gogoanimeSource; -const _gogoanimeVersion = "0.0.7"; +const _gogoanimeVersion = "0.0.75"; const _gogoanimeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/en/gogoanime/gogoanime.dart"; Source _gogoanimeSource = Source( diff --git a/anime/src/en/kisskh/kisskh.dart b/anime/src/en/kisskh/kisskh.dart index 8c751c8..41ec1b3 100644 --- a/anime/src/en/kisskh/kisskh.dart +++ b/anime/src/en/kisskh/kisskh.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class KissKh extends MProvider { - KissKh(); + KissKh({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client.get(Uri.parse( "${source.baseUrl}/api/DramaList/List?page=$page&type=0&sub=0&country=0&status=0&order=1&pageSize=40"))) .body; @@ -30,7 +32,7 @@ class KissKh extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get(Uri.parse( "${source.baseUrl}/api/DramaList/List?page=$page&type=0&sub=0&country=0&status=0&order=12&pageSize=40"))) .body; @@ -54,8 +56,7 @@ class KissKh extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final res = (await client.get(Uri.parse( "${source.baseUrl}/api/DramaList/Search?q=$query&type=0"))) .body; @@ -73,7 +74,7 @@ class KissKh extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"Ongoing": 0, "Completed": 1} ]; @@ -114,7 +115,7 @@ class KissKh extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = (await client.get(Uri.parse(url))).body; final id = substringAfter(substringBefore(url, ".png"), "Episode/"); final jsonRes = json.decode(res); @@ -151,6 +152,6 @@ class KissKh extends MProvider { } } -KissKh main() { - return KissKh(); +KissKh main(MSource source) { + return KissKh(source: source); } diff --git a/anime/src/en/nineanimetv/nineanimetv.dart b/anime/src/en/nineanimetv/nineanimetv.dart index d58f7e3..9ddd481 100644 --- a/anime/src/en/nineanimetv/nineanimetv.dart +++ b/anime/src/en/nineanimetv/nineanimetv.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class NineAnimeTv extends MProvider { - NineAnimeTv(); + NineAnimeTv({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client .get(Uri.parse("${source.baseUrl}/filter?sort=all&page=$page"))) .body; @@ -15,7 +17,7 @@ class NineAnimeTv extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get(Uri.parse( "${source.baseUrl}/filter?sort=recently_updated&page=$page"))) .body; @@ -23,8 +25,7 @@ class NineAnimeTv extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = "${source.baseUrl}/filter?keyword=$query"; @@ -113,7 +114,7 @@ class NineAnimeTv extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"Currently Airing": 0, "Finished Airing": 1} ]; @@ -161,7 +162,7 @@ class NineAnimeTv extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = (await client.get( Uri.parse("${source.baseUrl}/ajax/episode/servers?episodeId=$url"))) .body; @@ -346,7 +347,7 @@ class NineAnimeTv extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ GroupFilter("GenreFilter", "Genre", [ CheckBoxFilter("Action", "1"), @@ -452,7 +453,7 @@ class NineAnimeTv extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_quality", @@ -540,6 +541,6 @@ class NineAnimeTv extends MProvider { } } -NineAnimeTv main() { - return NineAnimeTv(); +NineAnimeTv main(MSource source) { + return NineAnimeTv(source: source); } diff --git a/anime/src/en/nineanimetv/source.dart b/anime/src/en/nineanimetv/source.dart index 3ea44b5..e361dcd 100644 --- a/anime/src/en/nineanimetv/source.dart +++ b/anime/src/en/nineanimetv/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get nineanimetv => _nineanimetv; -const _nineanimetvVersion = "0.0.2"; +const _nineanimetvVersion = "0.0.25"; const _nineanimetvCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/en/nineanimetv/nineanimetv.dart"; Source _nineanimetv = Source( diff --git a/anime/src/en/uhdmovies/source.dart b/anime/src/en/uhdmovies/source.dart index 4a55e70..4292eb6 100644 --- a/anime/src/en/uhdmovies/source.dart +++ b/anime/src/en/uhdmovies/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get uhdmoviesSource => _uhdmoviesSource; -const _uhdmoviesVersion = "0.0.25"; +const _uhdmoviesVersion = "0.0.3"; const _uhdmoviesSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/en/uhdmovies/uhdmovies.dart"; Source _uhdmoviesSource = Source( diff --git a/anime/src/en/uhdmovies/uhdmovies.dart b/anime/src/en/uhdmovies/uhdmovies.dart index 354bde5..cda9677 100644 --- a/anime/src/en/uhdmovies/uhdmovies.dart +++ b/anime/src/en/uhdmovies/uhdmovies.dart @@ -2,41 +2,41 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class UHDMovies extends MProvider { - UHDMovies(); + UHDMovies({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override bool get supportsLatest => false; @override - Future getPopular(MSource source, int page) async { - final res = (await client - .get(Uri.parse("${preferenceBaseUrl(source.id)}/page/$page"))) - .body; + String get baseUrl => getPreferenceValue(source.id, "pref_domain"); + + @override + Future getPopular(int page) async { + final res = (await client.get(Uri.parse("$baseUrl/page/$page"))).body; return animeFromElement(res); } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { return MPages([], false); } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/page/$page/?s=${query.replaceAll(" ", "+")}"))) + Future search(String query, int page, FilterList filterList) async { + final res = (await client.get( + Uri.parse("$baseUrl/page/$page/?s=${query.replaceAll(" ", "+")}"))) .body; return animeFromElement(res); } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { url = getUrlWithoutDomain(url); - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}${url}"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl${url}"))).body; MManga anime = MManga(); final description = xpath(res, '//pre/span/text()'); if (description.isNotEmpty) { @@ -117,13 +117,13 @@ class UHDMovies extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = await getMediaUrl(url); return await extractVideos(res); } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ EditTextPreference( key: "pref_domain", @@ -136,10 +136,6 @@ class UHDMovies extends MProvider { ]; } - String preferenceBaseUrl(int sourceId) { - return getPreferenceValue(sourceId, "pref_domain"); - } - Future> extractVideos(String url) async { List videos = []; for (int type = 1; type < 3; type++) { @@ -233,6 +229,6 @@ class UHDMovies extends MProvider { } } -UHDMovies main() { - return UHDMovies(); +UHDMovies main(MSource source) { + return UHDMovies(source: source); } diff --git a/anime/src/fr/animesama/animesama.dart b/anime/src/fr/animesama/animesama.dart index aa59c97..6cec671 100644 --- a/anime/src/fr/animesama/animesama.dart +++ b/anime/src/fr/animesama/animesama.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class AnimeSama extends MProvider { - AnimeSama(); + AnimeSama({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future 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); @@ -24,7 +26,7 @@ class AnimeSama extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get(Uri.parse(source.baseUrl))).body; var document = parseHtml(res); final latest = document @@ -44,8 +46,7 @@ class AnimeSama extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future 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"))) @@ -104,7 +105,7 @@ class AnimeSama extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { var animeUrl = "${source.baseUrl}${substringBeforeLast(getUrlWithoutDomain(url), "/")}"; var movie = @@ -152,7 +153,7 @@ class AnimeSama extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final players = json.decode(url); List videos = []; for (var player in players) { @@ -178,7 +179,7 @@ class AnimeSama extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ GroupFilter("TypeFilter", "Type", [ CheckBoxFilter("Anime", "Anime"), @@ -218,7 +219,7 @@ class AnimeSama extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_quality", @@ -403,6 +404,6 @@ class AnimeSama extends MProvider { } } -AnimeSama main() { - return AnimeSama(); +AnimeSama main(MSource source) { + return AnimeSama(source: source); } diff --git a/anime/src/fr/animesama/source.dart b/anime/src/fr/animesama/source.dart index 3b324cb..39bb1f9 100644 --- a/anime/src/fr/animesama/source.dart +++ b/anime/src/fr/animesama/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get animesamaSource => _animesama; -const animesamaVersion = "0.0.15"; +const animesamaVersion = "0.0.2"; const animesamaCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/fr/animesama/animesama.dart"; Source _animesama = Source( diff --git a/anime/src/fr/animesultra/animesultra.dart b/anime/src/fr/animesultra/animesultra.dart index b49657d..8744749 100644 --- a/anime/src/fr/animesultra/animesultra.dart +++ b/anime/src/fr/animesultra/animesultra.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class AnimesUltra extends MProvider { - AnimesUltra(); + AnimesUltra({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client.get(Uri.parse(source.baseUrl))).body; List animeList = []; @@ -30,7 +32,7 @@ class AnimesUltra extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get(Uri.parse(source.baseUrl))).body; List animeList = []; @@ -53,8 +55,7 @@ class AnimesUltra extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final res = (await client.get(Uri.parse(source.baseUrl))).body; List animeList = []; @@ -74,7 +75,7 @@ class AnimesUltra extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"En cours": 0, "Terminé": 1} ]; @@ -116,7 +117,7 @@ class AnimesUltra extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final resWebview = await getHtmlViaWebview( url, '//*[@class="ps__-list"]/div/@data-server-id'); @@ -152,6 +153,6 @@ class AnimesUltra extends MProvider { } } -AnimesUltra main() { - return AnimesUltra(); +AnimesUltra main(MSource source) { + return AnimesUltra(source: source); } diff --git a/anime/src/fr/animesultra/source.dart b/anime/src/fr/animesultra/source.dart index c016f3f..7fef94a 100644 --- a/anime/src/fr/animesultra/source.dart +++ b/anime/src/fr/animesultra/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get animesultraSource => _animesultraSource; -const _animesultraVersion = "0.0.55"; +const _animesultraVersion = "0.0.6"; const _animesultraSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/fr/animesultra/animesultra.dart"; Source _animesultraSource = Source( diff --git a/anime/src/fr/franime/franime.dart b/anime/src/fr/franime/franime.dart index f5afb89..5c34b62 100644 --- a/anime/src/fr/franime/franime.dart +++ b/anime/src/fr/franime/franime.dart @@ -2,19 +2,21 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class FrAnime extends MProvider { - FrAnime(); + FrAnime({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = await dataBase(); return animeResList(res); } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = await dataBase(); List list = json.decode(res); @@ -22,15 +24,14 @@ class FrAnime extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final res = await dataBase(); return animeSeachFetch(res, query); } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { MManga anime = MManga(); String language = "vo".toString(); if (url.contains("lang=")) { @@ -84,7 +85,7 @@ class FrAnime extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { String language = "vo"; String videoBaseUrl = "https://api.franime.fr/api/anime"; if (url.contains("lang=")) { @@ -336,6 +337,6 @@ class FrAnime extends MProvider { } } -FrAnime main() { - return FrAnime(); +FrAnime main(MSource source) { + return FrAnime(source: source); } diff --git a/anime/src/fr/franime/source.dart b/anime/src/fr/franime/source.dart index 96cdb25..d59a117 100644 --- a/anime/src/fr/franime/source.dart +++ b/anime/src/fr/franime/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get franimeSource => _franimeSource; -const _franimeVersion = "0.0.6"; +const _franimeVersion = "0.0.65"; const _franimeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/fr/franime/franime.dart"; Source _franimeSource = Source( diff --git a/anime/src/fr/otakufr/otakufr.dart b/anime/src/fr/otakufr/otakufr.dart index e3d201c..baed814 100644 --- a/anime/src/fr/otakufr/otakufr.dart +++ b/anime/src/fr/otakufr/otakufr.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class OtakuFr extends MProvider { - OtakuFr(); + OtakuFr({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client.get(Uri.parse("${source.baseUrl}/en-cours/page/$page"))) .body; @@ -31,7 +33,7 @@ class OtakuFr extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get(Uri.parse("${source.baseUrl}/page/$page/"))).body; @@ -71,8 +73,7 @@ class OtakuFr extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = ""; if (query.isNotEmpty) { @@ -117,7 +118,7 @@ class OtakuFr extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"En cours": 0, "Terminé": 1} ]; @@ -171,7 +172,7 @@ class OtakuFr extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = (await client.get(Uri.parse(url))).body; final servers = xpath(res, '//*[@id="nav-tabContent"]/div/iframe/@src'); @@ -220,7 +221,7 @@ class OtakuFr extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ HeaderFilter("La recherche de texte ignore les filtres"), SelectFilter("GenreFilter", "Genre", 0, [ @@ -276,7 +277,7 @@ class OtakuFr extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_quality", @@ -436,6 +437,6 @@ class OtakuFr extends MProvider { } } -OtakuFr main() { - return OtakuFr(); +OtakuFr main(MSource source) { + return OtakuFr(source: source); } diff --git a/anime/src/fr/otakufr/source.dart b/anime/src/fr/otakufr/source.dart index 8ae61c8..ca1b5d2 100644 --- a/anime/src/fr/otakufr/source.dart +++ b/anime/src/fr/otakufr/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get otakufr => _otakufr; -const otakufrVersion = "0.0.7"; +const otakufrVersion = "0.0.75"; const otakufrCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/fr/otakufr/otakufr.dart"; Source _otakufr = Source( diff --git a/anime/src/hi/yomovies/yomovies.dart b/anime/src/hi/yomovies/yomovies.dart index 4abe838..fe1299f 100644 --- a/anime/src/hi/yomovies/yomovies.dart +++ b/anime/src/hi/yomovies/yomovies.dart @@ -2,20 +2,24 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class YoMovies extends MProvider { - YoMovies(); + YoMovies({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); + + @override + String get baseUrl => getPreferenceValue(source.id, "overrideBaseUrl"); @override bool get supportsLatest => false; @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { String pageNu = page == 1 ? "" : "page/$page/"; - final res = (await client.get(Uri.parse( - "${preferenceBaseUrl(source.id)}/most-favorites/$pageNu"))) - .body; + final res = + (await client.get(Uri.parse("$baseUrl/most-favorites/$pageNu"))).body; final document = parseHtml(res); return animeFromElement( document.select("div.movies-list > div.ml-item"), @@ -24,18 +28,17 @@ class YoMovies extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { return MPages([], false); } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = ""; String pageNu = page == 1 ? "" : "/page/$page"; if (query.isNotEmpty) { - url = "${preferenceBaseUrl(source.id)}$pageNu/?s=$query"; + url = "$baseUrl$pageNu/?s=$query"; } else { for (var filter in filters) { if (filter.type.isNotEmpty) { @@ -45,7 +48,7 @@ class YoMovies extends MProvider { } } } - url = "${preferenceBaseUrl(source.id)}$url$pageNu"; + url = "$baseUrl$url$pageNu"; } final res = (await client.get(Uri.parse(url))).body; final document = parseHtml(res); @@ -56,12 +59,10 @@ class YoMovies extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { url = getUrlWithoutDomain(url); - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; final document = parseHtml(res); MManga anime = MManga(); var infoElement = document.selectFirst("div.mvi-content"); @@ -96,11 +97,9 @@ class YoMovies extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { url = getUrlWithoutDomain(url); - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$url"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; final document = parseHtml(res); final serverElements = document.select("div.movieplay > iframe"); List videos = []; @@ -116,7 +115,7 @@ class YoMovies extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ EditTextPreference( key: "overrideBaseUrl", @@ -163,10 +162,6 @@ class YoMovies extends MProvider { return videos; } - String preferenceBaseUrl(int sourceId) { - return getPreferenceValue(sourceId, "overrideBaseUrl"); - } - MPages animeFromElement(List elements, bool hasNextPage) { List animeList = []; for (var element in elements) { @@ -209,7 +204,7 @@ class YoMovies extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ HeaderFilter( "Note: Only one selection at a time works, and it ignores text search"), @@ -340,6 +335,6 @@ class YoMovies extends MProvider { } } -YoMovies main() { - return YoMovies(); +YoMovies main(MSource source) { + return YoMovies(source: source); } diff --git a/anime/src/id/nimegami/nimegami.dart b/anime/src/id/nimegami/nimegami.dart index 02c1038..c020f78 100644 --- a/anime/src/id/nimegami/nimegami.dart +++ b/anime/src/id/nimegami/nimegami.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class NimeGami extends MProvider { - NimeGami(); + NimeGami({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client.get(Uri.parse("${source.baseUrl}/page/$page"))).body; List animeList = []; @@ -27,7 +29,7 @@ class NimeGami extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get(Uri.parse("${source.baseUrl}/page/$page"))).body; List animeList = []; @@ -48,8 +50,7 @@ class NimeGami extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future 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; @@ -70,7 +71,7 @@ class NimeGami extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final res = (await client.get(Uri.parse(url))).body; MManga anime = MManga(); final description = xpath(res, '//*[@id="Sinopsis"]/p/text()'); @@ -106,7 +107,7 @@ class NimeGami extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final resJson = json.decode(url); final urls = resJson["urls"]; List videos = []; @@ -176,6 +177,6 @@ class NimeGami extends MProvider { } } -NimeGami main() { - return NimeGami(); +NimeGami main(MSource source) { + return NimeGami(source: source); } diff --git a/anime/src/id/nimegami/source.dart b/anime/src/id/nimegami/source.dart index 3ddb2af..8f212ae 100644 --- a/anime/src/id/nimegami/source.dart +++ b/anime/src/id/nimegami/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get nimegami => _nimegami; -const _nimegamiVersion = "0.0.45"; +const _nimegamiVersion = "0.0.5"; const _nimegamiCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/id/nimegami/nimegami.dart"; Source _nimegami = Source( diff --git a/anime/src/id/oploverz/oploverz.dart b/anime/src/id/oploverz/oploverz.dart index c814cdb..48027e1 100644 --- a/anime/src/id/oploverz/oploverz.dart +++ b/anime/src/id/oploverz/oploverz.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class OploVerz extends MProvider { - OploVerz(); + OploVerz({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client.get(Uri.parse( "${source.baseUrl}/anime-list/page/$page/?order=popular"))) .body; @@ -15,7 +17,7 @@ class OploVerz extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get( Uri.parse("${source.baseUrl}/anime-list/page/$page/?order=latest"))) .body; @@ -23,8 +25,7 @@ class OploVerz extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final res = (await client.get( Uri.parse("${source.baseUrl}/anime-list/page/$page/?title=$query"))) .body; @@ -32,7 +33,7 @@ class OploVerz extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"ongoing": 0, "completed": 1} ]; @@ -67,7 +68,7 @@ class OploVerz extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> 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') @@ -147,6 +148,6 @@ class OploVerz extends MProvider { } } -OploVerz main() { - return OploVerz(); +OploVerz main(MSource source) { + return OploVerz(source: source); } diff --git a/anime/src/id/oploverz/source.dart b/anime/src/id/oploverz/source.dart index 49a2162..d5517fc 100644 --- a/anime/src/id/oploverz/source.dart +++ b/anime/src/id/oploverz/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get oploverz => _oploverz; -const _oploverzVersion = "0.0.35"; +const _oploverzVersion = "0.0.4"; const _oploverzCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/id/oploverz/oploverz.dart"; Source _oploverz = Source( diff --git a/anime/src/id/otakudesu/otakudesu.dart b/anime/src/id/otakudesu/otakudesu.dart index 042c9bf..89f6574 100644 --- a/anime/src/id/otakudesu/otakudesu.dart +++ b/anime/src/id/otakudesu/otakudesu.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class OtakuDesu extends MProvider { - OtakuDesu(); + OtakuDesu({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client .get(Uri.parse("${source.baseUrl}/complete-anime/page/$page"))) .body; @@ -15,7 +17,7 @@ class OtakuDesu extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client .get(Uri.parse("${source.baseUrl}/ongoing-anime/page/$page"))) .body; @@ -23,8 +25,7 @@ class OtakuDesu extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final res = (await client .get(Uri.parse("${source.baseUrl}/?s=$query&post_type=anime"))) .body; @@ -44,7 +45,7 @@ class OtakuDesu extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"Ongoing": 0, "Completed": 1} ]; @@ -85,7 +86,7 @@ class OtakuDesu extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { List videos = []; final res = (await client.get(Uri.parse(url))).body; final script = @@ -186,6 +187,6 @@ class OtakuDesu extends MProvider { } } -OtakuDesu main() { - return OtakuDesu(); +OtakuDesu main(MSource source) { + return OtakuDesu(source: source); } diff --git a/anime/src/id/otakudesu/source.dart b/anime/src/id/otakudesu/source.dart index 797b721..1ac9e21 100644 --- a/anime/src/id/otakudesu/source.dart +++ b/anime/src/id/otakudesu/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get otakudesu => _otakudesu; -const _otakudesuVersion = "0.0.4"; +const _otakudesuVersion = "0.0.45"; const _otakudesuCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/id/otakudesu/otakudesu.dart"; Source _otakudesu = Source( diff --git a/anime/src/it/animesaturn/animesaturn.dart b/anime/src/it/animesaturn/animesaturn.dart index 1853b7a..0ce788d 100644 --- a/anime/src/it/animesaturn/animesaturn.dart +++ b/anime/src/it/animesaturn/animesaturn.dart @@ -2,12 +2,14 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class AnimeSaturn extends MProvider { - AnimeSaturn(); + AnimeSaturn({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + Future getPopular(int page) async { final res = (await client .get(Uri.parse("${source.baseUrl}/animeincorso?page=$page"))) .body; @@ -34,7 +36,7 @@ class AnimeSaturn extends MProvider { } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { final res = (await client.get(Uri.parse("${source.baseUrl}/newest?page=$page"))) .body; @@ -59,8 +61,7 @@ class AnimeSaturn extends MProvider { } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = ""; @@ -141,7 +142,7 @@ class AnimeSaturn extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { final statusList = [ {"In corso": 0, "Finito": 1} ]; @@ -192,7 +193,7 @@ class AnimeSaturn extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = (await client.get(Uri.parse(url))).body; final urlVid = xpath(res, '//a[contains(@href,"/watch")]/@href').first; @@ -245,7 +246,7 @@ class AnimeSaturn extends MProvider { } @override - List getFilterList(MSource source) { + List getFilterList() { return [ HeaderFilter("Ricerca per titolo ignora i filtri e viceversa"), GroupFilter("GenreFilter", "Generi", [ @@ -313,7 +314,7 @@ class AnimeSaturn extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ ListPreference( key: "preferred_quality", @@ -353,6 +354,6 @@ class AnimeSaturn extends MProvider { } } -AnimeSaturn main() { - return AnimeSaturn(); +AnimeSaturn main(MSource source) { + return AnimeSaturn(source: source); } diff --git a/anime/src/it/animesaturn/source.dart b/anime/src/it/animesaturn/source.dart index ec19449..c7b318c 100644 --- a/anime/src/it/animesaturn/source.dart +++ b/anime/src/it/animesaturn/source.dart @@ -1,7 +1,7 @@ import '../../../../model/source.dart'; Source get animesaturn => _animesaturn; -const _animesaturnVersion = "0.0.25"; +const _animesaturnVersion = "0.0.3"; const _animesaturnCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/it/animesaturn/animesaturn.dart"; Source _animesaturn = Source( diff --git a/anime/src/sq/filma24/filma24.dart b/anime/src/sq/filma24/filma24.dart index 83e8fb9..e717b52 100644 --- a/anime/src/sq/filma24/filma24.dart +++ b/anime/src/sq/filma24/filma24.dart @@ -2,36 +2,37 @@ import 'package:mangayomi/bridge_lib.dart'; import 'dart:convert'; class Filma24 extends MProvider { - Filma24(); + Filma24({required this.source}); - final Client client = Client(); + MSource source; + + final Client client = Client(source); @override - Future getPopular(MSource source, int page) async { + String get baseUrl => getPreferenceValue(source.id, "pref_domain"); + + @override + Future getPopular(int page) async { String pageNu = page == 1 ? "" : "/page/$page/"; - final res = - (await client.get(Uri.parse("${preferenceBaseUrl(source.id)}$pageNu"))) - .body; + final res = (await client.get(Uri.parse("$baseUrl$pageNu"))).body; return animeFromRes(res); } @override - Future getLatestUpdates(MSource source, int page) async { + Future getLatestUpdates(int page) async { String pageNu = page == 1 ? "" : "page/$page/"; - final res = (await client.get( - Uri.parse("${preferenceBaseUrl(source.id)}/$pageNu?sort=trendy"))) - .body; + final res = + (await client.get(Uri.parse("$baseUrl/$pageNu?sort=trendy"))).body; return animeFromRes(res); } @override - Future search( - MSource source, String query, int page, FilterList filterList) async { + Future search(String query, int page, FilterList filterList) async { final filters = filterList.filters; String url = ""; String pageNu = page == 1 ? "" : "page/$page/"; if (query.isNotEmpty) { - url += "${preferenceBaseUrl(source.id)}/search/$query/"; + url += "$baseUrl/search/$query/"; } else { for (var filter in filters) { if (filter.type == "ReleaseFilter") { @@ -46,7 +47,7 @@ class Filma24 extends MProvider { } } } - url = "${preferenceBaseUrl(source.id)}$url"; + url = "$baseUrl$url"; } url += pageNu; @@ -56,7 +57,7 @@ class Filma24 extends MProvider { } @override - Future getDetail(MSource source, String url) async { + Future getDetail(String url) async { List? episodesList = []; if (!url.contains("seriale")) { MChapter episode = MChapter(); @@ -86,7 +87,7 @@ class Filma24 extends MProvider { } @override - Future> getVideoList(MSource source, String url) async { + Future> getVideoList(String url) async { final res = (await client.get(Uri.parse(url))).body; List videos = []; final serverUrls = xpath(res, '//*[@class="player"]/div[1]/a/@href'); @@ -117,7 +118,7 @@ class Filma24 extends MProvider { } @override - List getSourcePreferences(MSource source) { + List getSourcePreferences() { return [ EditTextPreference( key: "pref_domain", @@ -130,12 +131,8 @@ class Filma24 extends MProvider { ]; } - String preferenceBaseUrl(int sourceId) { - return getPreferenceValue(sourceId, "pref_domain"); - } - @override - List getFilterList(MSource source) { + List getFilterList() { return [ SelectFilter("ReleaseFilter", "Viti", 0, [ SelectFilterOption("