From 8c98a563ebc0a92195770bdb36bd8a5ec01952cc Mon Sep 17 00:00:00 2001 From: kodjomoustapha <107993382+kodjodevf@users.noreply.github.com> Date: Mon, 27 Nov 2023 15:08:51 +0100 Subject: [PATCH] added filter method --- anime/multisrc/zorotheme/sources.dart | 2 +- .../multisrc/zorotheme/zorotheme-v0.0.45.dart | 200 ---- .../multisrc/zorotheme/zorotheme-v0.0.5.dart | 432 +++++++ ...anime-v0.0.25.dart => okanime-v0.0.3.dart} | 3 +- anime/src/ar/okanime/source.dart | 2 +- anime/src/en/aniwave/aniwave-v0.0.1.dart | 242 ---- anime/src/en/aniwave/aniwave-v0.0.15.dart | 447 +++++++ anime/src/en/aniwave/source.dart | 2 +- anime/src/en/gogoanime/gogoanime-v0.0.35.dart | 165 --- anime/src/en/gogoanime/gogoanime-v0.0.4.dart | 1031 +++++++++++++++++ anime/src/en/gogoanime/source.dart | 4 +- ...kisskh-v0.0.3.dart => kisskh-v0.0.35.dart} | 3 +- anime/src/en/kisskh/source.dart | 2 +- ...a-v0.0.35.dart => animesultra-v0.0.4.dart} | 3 +- anime/src/fr/animesultra/source.dart | 2 +- ...anime-v0.0.35.dart => franime-v0.0.4.dart} | 3 +- anime/src/fr/franime/source.dart | 2 +- ...akufr-v0.0.35.dart => otakufr-v0.0.4.dart} | 3 +- anime/src/fr/otakufr/source.dart | 2 +- ...gami-v0.0.2.dart => nimegami-v0.0.25.dart} | 3 +- anime/src/id/nimegami/source.dart | 2 +- ...verz-v0.0.1.dart => oploverz-v0.0.15.dart} | 12 +- anime/src/id/oploverz/source.dart | 2 +- ...esu-v0.0.2.dart => otakudesu-v0.0.25.dart} | 3 +- anime/src/id/otakudesu/source.dart | 2 +- manga/multisrc/nepnep/nepnep-v0.0.4.dart | 32 +- 26 files changed, 1958 insertions(+), 648 deletions(-) delete mode 100644 anime/multisrc/zorotheme/zorotheme-v0.0.45.dart create mode 100644 anime/multisrc/zorotheme/zorotheme-v0.0.5.dart rename anime/src/ar/okanime/{okanime-v0.0.25.dart => okanime-v0.0.3.dart} (98%) delete mode 100644 anime/src/en/aniwave/aniwave-v0.0.1.dart create mode 100644 anime/src/en/aniwave/aniwave-v0.0.15.dart delete mode 100644 anime/src/en/gogoanime/gogoanime-v0.0.35.dart create mode 100644 anime/src/en/gogoanime/gogoanime-v0.0.4.dart rename anime/src/en/kisskh/{kisskh-v0.0.3.dart => kisskh-v0.0.35.dart} (97%) rename anime/src/fr/animesultra/{animesultra-v0.0.35.dart => animesultra-v0.0.4.dart} (98%) rename anime/src/fr/franime/{franime-v0.0.35.dart => franime-v0.0.4.dart} (99%) rename anime/src/fr/otakufr/{otakufr-v0.0.35.dart => otakufr-v0.0.4.dart} (98%) rename anime/src/id/nimegami/{nimegami-v0.0.2.dart => nimegami-v0.0.25.dart} (98%) rename anime/src/id/oploverz/{oploverz-v0.0.1.dart => oploverz-v0.0.15.dart} (93%) rename anime/src/id/otakudesu/{otakudesu-v0.0.2.dart => otakudesu-v0.0.25.dart} (98%) diff --git a/anime/multisrc/zorotheme/sources.dart b/anime/multisrc/zorotheme/sources.dart index 33f16130..80a15686 100644 --- a/anime/multisrc/zorotheme/sources.dart +++ b/anime/multisrc/zorotheme/sources.dart @@ -1,7 +1,7 @@ import '../../../model/source.dart'; import '../../../utils/utils.dart'; -const zorothemeVersion = "0.0.45"; +const zorothemeVersion = "0.0.5"; const zorothemeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/multisrc/zorotheme/zorotheme-v$zorothemeVersion.dart"; diff --git a/anime/multisrc/zorotheme/zorotheme-v0.0.45.dart b/anime/multisrc/zorotheme/zorotheme-v0.0.45.dart deleted file mode 100644 index 251e06ff..00000000 --- a/anime/multisrc/zorotheme/zorotheme-v0.0.45.dart +++ /dev/null @@ -1,200 +0,0 @@ -import 'package:mangayomi/bridge_lib.dart'; -import 'dart:convert'; - -class ZoroTheme extends MProvider { - ZoroTheme(); - - @override - Future getPopular(MSource source, int page) async { - final data = {"url": "${source.baseUrl}/most-popular?page=$page"}; - final res = await http('GET', json.encode(data)); - - return animeElementM(res); - } - - @override - Future getLatestUpdates(MSource source, int page) async { - final data = {"url": "${source.baseUrl}/recently-updated?page=$page"}; - final res = await http('GET', json.encode(data)); - - return animeElementM(res); - } - - @override - Future search(MSource source, String query, int page) async { - final data = {"url": "${source.baseUrl}/search?keyword=$query&page=$page"}; - final res = await http('GET', json.encode(data)); - - return animeElementM(res); - } - - @override - Future getDetail(MSource source, String url) async { - final statusList = [ - { - "Currently Airing": 0, - "Finished Airing": 1, - } - ]; - final data = {"url": "${source.baseUrl}$url"}; - final res = await http('GET', json.encode(data)); - MManga anime = MManga(); - final status = xpath(res, - '//*[@class="anisc-info"]/div[contains(text(),"Status:")]/span[2]/text()') - .first; - - anime.status = parseStatus(status, statusList); - anime.author = xpath(res, - '//*[@class="anisc-info"]/div[contains(text(),"Studios:")]/span/text()') - .first - .replaceAll("Studios:", ""); - anime.description = xpath(res, - '//*[@class="anisc-info"]/div[contains(text(),"Overview:")]/text()') - .first - .replaceAll("Overview:", ""); - final genre = xpath(res, - '//*[@class="anisc-info"]/div[contains(text(),"Genres:")]/a/text()'); - - anime.genre = genre; - final id = substringAfterLast(url, '-'); - - final urlEp = - "${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/list/$id"; - - final dataEp = { - "url": urlEp, - "headers": {"referer": url} - }; - final resEp = await http('GET', json.encode(dataEp)); - - final html = json.decode(resEp)["html"]; - - final epUrls = querySelectorAll(html, - selector: "a.ep-item", - typeElement: 3, - attributes: "href", - typeRegExp: 0); - final numbers = querySelectorAll(html, - selector: "a.ep-item", - typeElement: 3, - attributes: "data-number", - typeRegExp: 0); - - final titles = querySelectorAll(html, - selector: "a.ep-item", - typeElement: 3, - attributes: "title", - typeRegExp: 0); - - List episodes = []; - - for (var i = 0; i < titles.length; i++) { - final number = numbers[i]; - final title = titles[i]; - episodes.add("Episode $number: $title"); - } - List? episodesList = []; - for (var i = 0; i < episodes.length; i++) { - MChapter episode = MChapter(); - episode.name = episodes[i]; - episode.url = epUrls[i]; - episodesList.add(episode); - } - - anime.chapters = episodesList.reversed.toList(); - return anime; - } - - @override - Future> getVideoList(MSource source, String url) async { - final id = substringAfterLast(url, '?ep='); - - final datas = { - "url": - "${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/servers?episodeId=$id", - "headers": {"referer": "${source.baseUrl}/$url"} - }; - final res = await http('GET', json.encode(datas)); - final html = json.decode(res)["html"]; - - final names = querySelectorAll(html, - selector: "div.server-item", - typeElement: 0, - attributes: "", - typeRegExp: 0); - - final ids = querySelectorAll(html, - selector: "div.server-item", - typeElement: 3, - attributes: "data-id", - typeRegExp: 0); - - final subDubs = querySelectorAll(html, - selector: "div.server-item", - typeElement: 3, - attributes: "data-type", - typeRegExp: 0); - - List videos = []; - - for (var i = 0; i < names.length; i++) { - final name = names[i]; - final id = ids[i]; - final subDub = subDubs[i]; - final datasE = { - "url": - "${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/sources?id=$id", - "headers": {"referer": "${source.baseUrl}/$url"} - }; - - final resE = await http('GET', json.encode(datasE)); - String epUrl = substringBefore(substringAfter(resE, "\"link\":\""), "\""); - print(epUrl); - List a = []; - if (name.contains("Vidstreaming")) { - a = await rapidCloudExtractor(epUrl, "Vidstreaming - $subDub"); - } else if (name.contains("Vidcloud")) { - a = await rapidCloudExtractor(epUrl, "Vidcloud - $subDub"); - } else if (name.contains("StreamTape")) { - a = await streamTapeExtractor(epUrl, "StreamTape - $subDub"); - } - videos.addAll(a); - } - - return videos; - } - - MPages animeElementM(String res) { - List animeList = []; - - final urls = xpath( - res, '//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@href'); - - final names = xpath(res, - '//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@data-jname'); - - final images = xpath( - res, '//*[@class^="flw-item"]/div[@class="film-poster"]/img/@data-src'); - for (var i = 0; i < names.length; i++) { - MManga anime = MManga(); - anime.name = names[i]; - anime.imageUrl = images[i]; - anime.link = urls[i]; - animeList.add(anime); - } - final nextPage = - xpath(res, '//li[@class="page-item"]/a[@title="Next"]/@href', ""); - return MPages(animeList, !nextPage.isEmpty); - } - - String ajaxRoute(String baseUrl) { - if (baseUrl == "https://kaido.to") { - return ""; - } - return "/v2"; - } -} - -ZoroTheme main() { - return ZoroTheme(); -} diff --git a/anime/multisrc/zorotheme/zorotheme-v0.0.5.dart b/anime/multisrc/zorotheme/zorotheme-v0.0.5.dart new file mode 100644 index 00000000..a4571c21 --- /dev/null +++ b/anime/multisrc/zorotheme/zorotheme-v0.0.5.dart @@ -0,0 +1,432 @@ +import 'package:mangayomi/bridge_lib.dart'; +import 'dart:convert'; + +class ZoroTheme extends MProvider { + ZoroTheme(); + + @override + Future getPopular(MSource source, int page) async { + final data = {"url": "${source.baseUrl}/most-popular?page=$page"}; + final res = await http('GET', json.encode(data)); + + return animeElementM(res); + } + + @override + Future getLatestUpdates(MSource source, int page) async { + final data = {"url": "${source.baseUrl}/recently-updated?page=$page"}; + final res = await http('GET', json.encode(data)); + + return animeElementM(res); + } + + @override + Future search( + MSource source, String query, int page, FilterList filterList) async { + final filters = filterList.filters; + String url = "${source.baseUrl}/"; + + if (query.isEmpty) { + url += "filter?"; + } else { + url += "search?keyword=$query"; + } + + for (var filter in filters) { + if (filter.type == "TypeFilter") { + final type = filter.values[filter.state].value; + if (type.isNotEmpty) { + url += "${ll(url)}type=$type"; + } + } else if (filter.type == "StatusFilter") { + final status = filter.values[filter.state].value; + if (status.isNotEmpty) { + url += "${ll(url)}status=$status"; + } + } else if (filter.type == "RatedFilter") { + final rated = filter.values[filter.state].value; + if (rated.isNotEmpty) { + url += "${ll(url)}rated=$rated"; + } + } else if (filter.type == "ScoreFilter") { + final score = filter.values[filter.state].value; + if (score.isNotEmpty) { + url += "${ll(url)}score=$score"; + } + } else if (filter.type == "SeasonFilter") { + final season = filter.values[filter.state].value; + if (season.isNotEmpty) { + url += "${ll(url)}season=$season"; + } + } else if (filter.type == "LanguageFilter") { + final language = filter.values[filter.state].value; + if (language.isNotEmpty) { + url += "${ll(url)}language=$language"; + } + } else if (filter.type == "SortFilter") { + final sort = filter.values[filter.state].value; + if (sort.isNotEmpty) { + url += "${ll(url)}sort=$sort"; + } + } else if (filter.type == "StartYearFilter") { + final sy = filter.values[filter.state].value; + if (sy.isNotEmpty) { + url += "${ll(url)}sy=$sy"; + } + } else if (filter.type == "StartMonthFilter") { + final sm = filter.values[filter.state].value; + if (sm.isNotEmpty) { + url += "${ll(url)}sm=$sm"; + } + } else if (filter.type == "StartDayFilter") { + final sd = filter.values[filter.state].value; + if (sd.isNotEmpty) { + url += "${ll(url)}sd=$sd"; + } + } else if (filter.type == "EndYearFilter") { + final ey = filter.values[filter.state].value; + if (ey.isNotEmpty) { + url += "${ll(url)}sy=$ey"; + } + } else if (filter.type == "EndMonthFilter") { + final em = filter.values[filter.state].value; + if (em.isNotEmpty) { + url += "${ll(url)}sm=$em"; + } + } else if (filter.type == "EndDayFilter") { + final ed = filter.values[filter.state].value; + if (ed.isNotEmpty) { + url += "${ll(url)}sd=$ed"; + } + } else if (filter.type == "GenreFilter") { + final genre = (filter.state as List).where((e) => e.state).toList(); + if (genre.isNotEmpty) { + url += "${ll(url)}genre="; + for (var st in genre) { + url += "${st.value},"; + } + } + } + } + url += "${ll(url)}page=$page"; + final data = {"url": url}; + final res = await http('GET', json.encode(data)); + + return animeElementM(res); + } + + @override + Future getDetail(MSource source, String url) async { + final statusList = [ + { + "Currently Airing": 0, + "Finished Airing": 1, + } + ]; + final data = {"url": "${source.baseUrl}$url"}; + final res = await http('GET', json.encode(data)); + MManga anime = MManga(); + final status = xpath(res, + '//*[@class="anisc-info"]/div[contains(text(),"Status:")]/span[2]/text()') + .first; + + anime.status = parseStatus(status, statusList); + anime.author = xpath(res, + '//*[@class="anisc-info"]/div[contains(text(),"Studios:")]/span/text()') + .first + .replaceAll("Studios:", ""); + anime.description = xpath(res, + '//*[@class="anisc-info"]/div[contains(text(),"Overview:")]/text()') + .first + .replaceAll("Overview:", ""); + final genre = xpath(res, + '//*[@class="anisc-info"]/div[contains(text(),"Genres:")]/a/text()'); + + anime.genre = genre; + final id = substringAfterLast(url, '-'); + + final urlEp = + "${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/list/$id"; + + final dataEp = { + "url": urlEp, + "headers": {"referer": url} + }; + final resEp = await http('GET', json.encode(dataEp)); + + final html = json.decode(resEp)["html"]; + + final epUrls = querySelectorAll(html, + selector: "a.ep-item", + typeElement: 3, + attributes: "href", + typeRegExp: 0); + final numbers = querySelectorAll(html, + selector: "a.ep-item", + typeElement: 3, + attributes: "data-number", + typeRegExp: 0); + + final titles = querySelectorAll(html, + selector: "a.ep-item", + typeElement: 3, + attributes: "title", + typeRegExp: 0); + + List episodes = []; + + for (var i = 0; i < titles.length; i++) { + final number = numbers[i]; + final title = titles[i]; + episodes.add("Episode $number: $title"); + } + List? episodesList = []; + for (var i = 0; i < episodes.length; i++) { + MChapter episode = MChapter(); + episode.name = episodes[i]; + episode.url = epUrls[i]; + episodesList.add(episode); + } + + anime.chapters = episodesList.reversed.toList(); + return anime; + } + + @override + Future> getVideoList(MSource source, String url) async { + final id = substringAfterLast(url, '?ep='); + + final datas = { + "url": + "${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/servers?episodeId=$id", + "headers": {"referer": "${source.baseUrl}/$url"} + }; + final res = await http('GET', json.encode(datas)); + final html = json.decode(res)["html"]; + + final names = querySelectorAll(html, + selector: "div.server-item", + typeElement: 0, + attributes: "", + typeRegExp: 0); + + final ids = querySelectorAll(html, + selector: "div.server-item", + typeElement: 3, + attributes: "data-id", + typeRegExp: 0); + + final subDubs = querySelectorAll(html, + selector: "div.server-item", + typeElement: 3, + attributes: "data-type", + typeRegExp: 0); + + List videos = []; + + for (var i = 0; i < names.length; i++) { + final name = names[i]; + final id = ids[i]; + final subDub = subDubs[i]; + final datasE = { + "url": + "${source.baseUrl}/ajax${ajaxRoute('${source.baseUrl}')}/episode/sources?id=$id", + "headers": {"referer": "${source.baseUrl}/$url"} + }; + + final resE = await http('GET', json.encode(datasE)); + String epUrl = substringBefore(substringAfter(resE, "\"link\":\""), "\""); + print(epUrl); + List a = []; + if (name.contains("Vidstreaming")) { + a = await rapidCloudExtractor(epUrl, "Vidstreaming - $subDub"); + } else if (name.contains("Vidcloud")) { + a = await rapidCloudExtractor(epUrl, "Vidcloud - $subDub"); + } else if (name.contains("StreamTape")) { + a = await streamTapeExtractor(epUrl, "StreamTape - $subDub"); + } + videos.addAll(a); + } + + return videos; + } + + MPages animeElementM(String res) { + List animeList = []; + + final urls = xpath( + res, '//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@href'); + + final names = xpath(res, + '//*[@class^="flw-item"]/div[@class="film-detail"]/h3/a/@data-jname'); + + final images = xpath( + res, '//*[@class^="flw-item"]/div[@class="film-poster"]/img/@data-src'); + for (var i = 0; i < names.length; i++) { + MManga anime = MManga(); + anime.name = names[i]; + anime.imageUrl = images[i]; + anime.link = urls[i]; + animeList.add(anime); + } + final nextPage = + xpath(res, '//li[@class="page-item"]/a[@title="Next"]/@href', ""); + return MPages(animeList, !nextPage.isEmpty); + } + + String ajaxRoute(String baseUrl) { + if (baseUrl == "https://kaido.to") { + return ""; + } + return "/v2"; + } + + List yearList = [ + for (var i = 1917; i < 2024; i++) + SelectFilterOption(i.toString(), i.toString()), + SelectFilterOption("All", "") + ]; + List getFilterList() { + return [ + SelectFilter("TypeFilter", "Type", 0, [ + SelectFilterOption("All", ""), + SelectFilterOption("Movie", "1"), + SelectFilterOption("TV", "2"), + SelectFilterOption("OVA", "3"), + SelectFilterOption("ONA", "4"), + SelectFilterOption("Special", "5"), + SelectFilterOption("Music", "6") + ]), + SelectFilter("StatusFilter", "Status", 0, [ + SelectFilterOption("All", ""), + SelectFilterOption("Finished Airing", "1"), + SelectFilterOption("Currently Airing", "2"), + SelectFilterOption("Not yet aired", "3") + ]), + SelectFilter("RatedFilter", "Rated", 0, [ + SelectFilterOption("All", ""), + SelectFilterOption("G", "1"), + SelectFilterOption("PG", "2"), + SelectFilterOption("PG-13", "3"), + SelectFilterOption("R", "4"), + SelectFilterOption("R+", "5"), + SelectFilterOption("Rx", "6") + ]), + SelectFilter("ScoreFilter", "Score", 0, [ + SelectFilterOption("All", ""), + SelectFilterOption("(1) Appalling", "1"), + SelectFilterOption("(2) Horrible", "2"), + SelectFilterOption("(3) Very Bad", "3"), + SelectFilterOption("(4) Bad", "4"), + SelectFilterOption("(5) Average", "5"), + SelectFilterOption("(6) Fine", "6"), + SelectFilterOption("(7) Good", "7"), + SelectFilterOption("(8) Very Good", "8"), + SelectFilterOption("(9) Great", "9"), + SelectFilterOption("(10) Masterpiece", "10") + ]), + SelectFilter("SeasonFilter", "Season", 0, [ + SelectFilterOption("All", ""), + SelectFilterOption("Spring", "1"), + SelectFilterOption("Summer", "2"), + SelectFilterOption("Fall", "3"), + SelectFilterOption("Winter", "4") + ]), + SelectFilter("LanguageFilter", "Language", 0, [ + SelectFilterOption("All", ""), + SelectFilterOption("SUB", "1"), + SelectFilterOption("DUB", "2"), + SelectFilterOption("SUB & DUB", "3") + ]), + SelectFilter("SortFilter", "Sort by", 0, [ + SelectFilterOption("All", ""), + SelectFilterOption("Default", "default"), + SelectFilterOption("Recently Added", "recently_added"), + SelectFilterOption("Recently Updated", "recently_updated"), + SelectFilterOption("Score", "score"), + SelectFilterOption("Name A-Z", "name_az"), + SelectFilterOption("Released Date", "released_date"), + SelectFilterOption("Most Watched", "most_watched") + ]), + SelectFilter( + "StartYearFilter", "Start year", 0, yearList.reversed.toList()), + SelectFilter("StartMonthFilter", "Start month", 0, [ + SelectFilterOption("All", ""), + for (var i = 1; i < 13; i++) + SelectFilterOption(i.toString(), i.toString()) + ]), + SelectFilter("StartDayFilter", "Start day", 0, [ + SelectFilterOption("All", ""), + for (var i = 1; i < 32; i++) + SelectFilterOption(i.toString(), i.toString()), + ]), + SelectFilter("EndYearFilter", "End year", 0, yearList.reversed.toList()), + SelectFilter("EndmonthFilter", "End month", 0, [ + SelectFilterOption("All", ""), + for (var i = 1; i < 32; i++) + SelectFilterOption(i.toString(), i.toString()) + ]), + SelectFilter("EndDayFilter", "End day", 0, [ + SelectFilterOption("All", ""), + for (var i = 1; i < 32; i++) + SelectFilterOption(i.toString(), i.toString()) + ]), + GroupFilter("GenreFilter", "Genre", [ + CheckBoxFilter("Action", "1"), + CheckBoxFilter("Adventure", "2"), + CheckBoxFilter("Cars", "3"), + CheckBoxFilter("Comedy", "4"), + CheckBoxFilter("Dementia", "5"), + CheckBoxFilter("Demons", "6"), + CheckBoxFilter("Drama", "8"), + CheckBoxFilter("Ecchi", "9"), + CheckBoxFilter("Fantasy", "10"), + CheckBoxFilter("Game", "11"), + CheckBoxFilter("Harem", "35"), + CheckBoxFilter("Historical", "13"), + CheckBoxFilter("Horror", "14"), + CheckBoxFilter("Isekai", "44"), + CheckBoxFilter("Josei", "43"), + CheckBoxFilter("Kids", "15"), + CheckBoxFilter("Magic", "16"), + CheckBoxFilter("Martial Arts", "17"), + CheckBoxFilter("Mecha", "18"), + CheckBoxFilter("Military", "38"), + CheckBoxFilter("Music", "19"), + CheckBoxFilter("Mystery", "7"), + CheckBoxFilter("Parody", "20"), + CheckBoxFilter("Police", "39"), + CheckBoxFilter("Psychological", "40"), + CheckBoxFilter("Romance", "22"), + CheckBoxFilter("Samurai", "21"), + CheckBoxFilter("School", "23"), + CheckBoxFilter("Sci-Fi", "24"), + CheckBoxFilter("Seinen", "42"), + CheckBoxFilter("Shoujo", "25"), + CheckBoxFilter("Shoujo Ai", "26"), + CheckBoxFilter("Shounen", "27"), + CheckBoxFilter("Shounen Ai", "28"), + CheckBoxFilter("Slice of Life", "36"), + CheckBoxFilter("Space", "29"), + CheckBoxFilter("Sports", "30"), + CheckBoxFilter("Super Power", "31"), + CheckBoxFilter("Supernatural", "37"), + CheckBoxFilter("Thriller", "41"), + CheckBoxFilter("Vampire", "32"), + CheckBoxFilter("Yaoi", "33"), + CheckBoxFilter("Yuri", "34") + ]), + ]; + } + + String ll(String url) { + if (url.contains("?")) { + return "&"; + } + return "?"; + } +} + +ZoroTheme main() { + return ZoroTheme(); +} diff --git a/anime/src/ar/okanime/okanime-v0.0.25.dart b/anime/src/ar/okanime/okanime-v0.0.3.dart similarity index 98% rename from anime/src/ar/okanime/okanime-v0.0.25.dart rename to anime/src/ar/okanime/okanime-v0.0.3.dart index 585eb5d0..8b5fdf02 100644 --- a/anime/src/ar/okanime/okanime-v0.0.25.dart +++ b/anime/src/ar/okanime/okanime-v0.0.3.dart @@ -53,7 +53,8 @@ class OkAnime extends MProvider { } @override - Future search(MSource source, String query, int page) async { + Future search( + MSource source, String query, int page, FilterList filterList) async { String url = "${source.baseUrl}/search/?s=$query"; if (page > 1) { url += "&page=$page"; diff --git a/anime/src/ar/okanime/source.dart b/anime/src/ar/okanime/source.dart index 4377285e..6a2d6934 100644 --- a/anime/src/ar/okanime/source.dart +++ b/anime/src/ar/okanime/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get okanimeSource => _okanimeSource; -const okanimeVersion = "0.0.25"; +const okanimeVersion = "0.0.3"; const okanimeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/ar/okanime/okanime-v$okanimeVersion.dart"; Source _okanimeSource = Source( diff --git a/anime/src/en/aniwave/aniwave-v0.0.1.dart b/anime/src/en/aniwave/aniwave-v0.0.1.dart deleted file mode 100644 index 55029295..00000000 --- a/anime/src/en/aniwave/aniwave-v0.0.1.dart +++ /dev/null @@ -1,242 +0,0 @@ -import 'package:mangayomi/bridge_lib.dart'; -import 'dart:convert'; - -class Aniwave extends MProvider { - Aniwave(); - - @override - Future getPopular(MSource source, int page) async { - final data = {"url": "${source.baseUrl}/filter?sort=trending&page=$page"}; - final res = await http('GET', json.encode(data)); - return parseAnimeList(res); - } - - @override - Future getLatestUpdates(MSource source, int page) async { - final data = { - "url": "${source.baseUrl}/filter?sort=recently_updated&page=$page" - }; - final res = await http('GET', json.encode(data)); - return parseAnimeList(res); - } - - @override - Future search(MSource source, String query, int page) async { - final data = {"url": "${source.baseUrl}/filter?keyword=$query"}; - final res = await http('GET', json.encode(data)); - return parseAnimeList(res); - } - - @override - Future getDetail(MSource source, String url) async { - final statusList = [ - {"Releasing": 0, "Completed": 1} - ]; - final data = {"url": "${source.baseUrl}${url}"}; - final res = await http('GET', json.encode(data)); - MManga anime = MManga(); - final status = xpath(res, '//div[contains(text(),"Status")]/span/text()'); - if (status.isNotEmpty) { - anime.status = parseStatus(status.first, statusList); - } - final description = xpath(res, - '//*[contains(@class,"synopsis")]/div[@class="shorting"]/div[@class="content"]/text()'); - if (description.isNotEmpty) { - anime.description = description.first; - } - final author = xpath(res, '//div[contains(text(),"Studio")]/span/text()'); - if (author.isNotEmpty) { - anime.author = author.first; - } - - anime.genre = xpath(res, '//div[contains(text(),"Genre")]/span/a/text()'); - final id = querySelectorAll(res, - selector: "div[data-id]", - typeElement: 3, - attributes: "data-id", - typeRegExp: 0) - .first; - final encrypt = vrfEncrypt(id); - final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; - final dataEp = {"url": "${source.baseUrl}/ajax/episode/list/$id?$vrf"}; - final resEp = await http('GET', json.encode(dataEp)); - final html = json.decode(resEp)["result"]; - List? episodesList = []; - final epsHtml = querySelectorAll(html, - selector: "div.episodes ul > li", - typeElement: 2, - attributes: "", - typeRegExp: 0); - for (var epHtml in epsHtml) { - final title = xpath(epHtml, '//li/@title').isNotEmpty - ? xpath(epHtml, '//li/@title').first - : ""; - final ids = xpath(epHtml, '//a/@data-ids').first; - final sub = xpath(epHtml, '//a/@data-sub').first; - final dub = xpath(epHtml, '//a/@data-dub').first; - final softsub = title.toLowerCase().contains("softsub") ? "1" : ""; - final fillerEp = title.toLowerCase().contains("filler") ? "1" : ""; - final epNum = xpath(epHtml, '//a/@data-num').first; - String scanlator = ""; - if (sub == "1") { - scanlator += "Sub"; - } - if (softsub == "1") { - scanlator += ", Softsub"; - } - if (dub == "1") { - scanlator += ", Dub"; - } - if (fillerEp == "1") { - scanlator += ", • Filler Episode"; - } - MChapter episode = MChapter(); - episode.name = "Episode $epNum"; - episode.scanlator = scanlator; - episode.url = "$ids&epurl=$url/ep-$epNum"; - episodesList.add(episode); - } - - anime.chapters = episodesList.reversed.toList(); - return anime; - } - - @override - Future> getVideoList(MSource source, String url) async { - final ids = substringBefore(url, "&"); - final encrypt = vrfEncrypt(ids); - final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; - final res = await http('GET', - json.encode({"url": "${source.baseUrl}/ajax/server/list/$ids?$vrf"})); - final html = json.decode(res)["result"]; - final vidsHtml = querySelectorAll(html, - selector: "div.servers > div", - typeElement: 2, - attributes: "", - typeRegExp: 0); - List videos = []; - for (var vidHtml in vidsHtml) { - final type = xpath(vidHtml, '//div/@data-type').first; - final serversIds = xpath(vidHtml, '//li/@data-link-id'); - for (int i = 0; i < serversIds.length; i++) { - final serverId = serversIds[i]; - - final encrypt = vrfEncrypt(serverId); - final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; - final res = await http( - 'GET', - json.encode( - {"url": "${source.baseUrl}/ajax/server/$serverId?$vrf"})); - final status = json.decode(res)["status"]; - if (status == 200) { - List a = []; - final url = vrfDecrypt(json.decode(res)["result"]["url"]); - if (url.contains("mp4upload")) { - a = await mp4UploadExtractor(url, null, "", type); - } else if (url.contains("streamtape")) { - a = await streamTapeExtractor(url, "StreamTape - $type"); - } else if (url.contains("filemoon")) { - a = await filemoonExtractor(url, "", type); - } - videos.addAll(a); - } - } - } - - return videos; - } - - MPages parseAnimeList(String res) { - List animeList = []; - final urls = xpath(res, '//div[@class="item "]/div/div/div/a/@href'); - final names = xpath(res, '//div[@class="item "]/div/div/div/a/text()'); - final images = xpath(res, '//div[@class="item "]/div/div/a/img/@src'); - - for (var i = 0; i < names.length; i++) { - MManga anime = MManga(); - anime.name = names[i]; - anime.imageUrl = images[i]; - anime.link = urls[i]; - animeList.add(anime); - } - - return MPages(animeList, true); - } - - List rc4Encrypt(String key, List message) { - List _key = utf8.encode(key); - int _i = 0, _j = 0; - List _box = List.generate(256, (i) => i); - - int x = 0; - for (int i = 0; i < 256; i++) { - x = (x + _box[i] + _key[i % _key.length]) % 256; - var tmp = _box[i]; - _box[i] = _box[x]; - _box[x] = tmp; - } - - List out = []; - for (var char in message) { - _i = (_i + 1) % 256; - _j = (_j + _box[_i]) % 256; - - var tmp = _box[_i]; - _box[_i] = _box[_j]; - _box[_j] = tmp; - - final c = char ^ (_box[(_box[_i] + _box[_j]) % 256]); - out.add(c); - } - - return out; - } - - String vrfEncrypt(String input) { - final rc4 = rc4Encrypt("ysJhV6U27FVIjjuk", input.codeUnits); - final vrf = base64Url.encode(rc4); - final vrf1 = base64.encode(vrf.codeUnits); - List vrf2 = vrfShift(vrf1.codeUnits); - final vrf3 = base64.encode(vrf2); - return utf8.decode(rot13(vrf3.codeUnits)); - } - - String vrfDecrypt(String input) { - final decode = base64Url.decode(input); - final rc4 = rc4Encrypt("hlPeNwkncH0fq9so", decode); - return Uri.decodeComponent(utf8.decode(rc4)); - } - - List vrfShift(List vrf) { - var shifts = [-3, 3, -4, 2, -2, 5, 4, 5]; - for (var i = 0; i < vrf.length; i++) { - var shift = shifts[i % 8]; - vrf[i] = (vrf[i] + shift) & 0xFF; - } - return vrf; - } - - List rot13(List vrf) { - for (var i = 0; i < vrf.length; i++) { - var byte = vrf[i]; - if (byte >= 'A'.codeUnitAt(0) && byte <= 'Z'.codeUnitAt(0)) { - vrf[i] = (byte - 'A'.codeUnitAt(0) + 13) % 26 + 'A'.codeUnitAt(0); - } else if (byte >= 'a'.codeUnitAt(0) && byte <= 'z'.codeUnitAt(0)) { - vrf[i] = (byte - 'a'.codeUnitAt(0) + 13) % 26 + 'a'.codeUnitAt(0); - } - } - return vrf; - } -} - -Map getMirrorPref() { - return { - "aniwave.to": "https://aniwave.to", - "aniwave.bz": "https://aniwave.bz", - "aniwave.ws": "https://aniwave.ws", - }; -} - -Aniwave main() { - return Aniwave(); -} diff --git a/anime/src/en/aniwave/aniwave-v0.0.15.dart b/anime/src/en/aniwave/aniwave-v0.0.15.dart new file mode 100644 index 00000000..80656999 --- /dev/null +++ b/anime/src/en/aniwave/aniwave-v0.0.15.dart @@ -0,0 +1,447 @@ +import 'package:mangayomi/bridge_lib.dart'; +import 'dart:convert'; + +class Aniwave extends MProvider { + Aniwave(); + + @override + Future getPopular(MSource source, int page) async { + final data = {"url": "${source.baseUrl}/filter?sort=trending&page=$page"}; + final res = await http('GET', json.encode(data)); + return parseAnimeList(res); + } + + @override + Future getLatestUpdates(MSource source, int page) async { + final data = { + "url": "${source.baseUrl}/filter?sort=recently_updated&page=$page" + }; + final res = await http('GET', json.encode(data)); + return parseAnimeList(res); + } + + @override + Future search( + MSource source, String query, int page, FilterList filterList) async { + final filters = filterList.filters; + String url = "${source.baseUrl}/filter?keyword=$query"; + + for (var filter in filters) { + if (filter.type == "OrderFilter") { + final order = filter.values[filter.state].value; + url += "${ll(url)}sort=$order"; + } else if (filter.type == "GenreFilter") { + final genre = (filter.state as List).where((e) => e.state).toList(); + if (genre.isNotEmpty) { + for (var st in genre) { + url += "${ll(url)}genre[]=${st.value}"; + } + } + } else if (filter.type == "CountryFilter") { + final country = (filter.state as List).where((e) => e.state).toList(); + if (country.isNotEmpty) { + for (var st in country) { + url += "${ll(url)}country[]=${st.value}"; + } + } + } else if (filter.type == "SeasonFilter") { + final season = (filter.state as List).where((e) => e.state).toList(); + if (season.isNotEmpty) { + for (var st in season) { + url += "${ll(url)}season[]=${st.value}"; + } + } + } else if (filter.type == "YearFilter") { + final year = (filter.state as List).where((e) => e.state).toList(); + if (year.isNotEmpty) { + for (var st in year) { + url += "${ll(url)}year[]=${st.value}"; + } + } + } else if (filter.type == "TypeFilter") { + final type = (filter.state as List).where((e) => e.state).toList(); + if (type.isNotEmpty) { + for (var st in type) { + url += "${ll(url)}type[]=${st.value}"; + } + } + } else if (filter.type == "StatusFilter") { + final status = (filter.state as List).where((e) => e.state).toList(); + if (status.isNotEmpty) { + for (var st in status) { + url += "${ll(url)}status[]=${st.value}"; + } + } + } else if (filter.type == "LanguageFilter") { + final language = (filter.state as List).where((e) => e.state).toList(); + if (language.isNotEmpty) { + for (var st in language) { + url += "${ll(url)}language[]=${st.value}"; + } + } + } else if (filter.type == "RatingFilter") { + final rating = (filter.state as List).where((e) => e.state).toList(); + if (rating.isNotEmpty) { + for (var st in rating) { + url += "${ll(url)}rating[]=${st.value}"; + } + } + } + } + final data = {"url": "$url&page=$page"}; + final res = await http('GET', json.encode(data)); + return parseAnimeList(res); + } + + @override + Future getDetail(MSource source, String url) async { + final statusList = [ + {"Releasing": 0, "Completed": 1} + ]; + final data = {"url": "${source.baseUrl}${url}"}; + final res = await http('GET', json.encode(data)); + MManga anime = MManga(); + final status = xpath(res, '//div[contains(text(),"Status")]/span/text()'); + if (status.isNotEmpty) { + anime.status = parseStatus(status.first, statusList); + } + final description = xpath(res, + '//*[contains(@class,"synopsis")]/div[@class="shorting"]/div[@class="content"]/text()'); + if (description.isNotEmpty) { + anime.description = description.first; + } + final author = xpath(res, '//div[contains(text(),"Studio")]/span/text()'); + if (author.isNotEmpty) { + anime.author = author.first; + } + + anime.genre = xpath(res, '//div[contains(text(),"Genre")]/span/a/text()'); + final id = querySelectorAll(res, + selector: "div[data-id]", + typeElement: 3, + attributes: "data-id", + typeRegExp: 0) + .first; + final encrypt = vrfEncrypt(id); + final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; + final dataEp = {"url": "${source.baseUrl}/ajax/episode/list/$id?$vrf"}; + final resEp = await http('GET', json.encode(dataEp)); + final html = json.decode(resEp)["result"]; + List? episodesList = []; + final epsHtml = querySelectorAll(html, + selector: "div.episodes ul > li", + typeElement: 2, + attributes: "", + typeRegExp: 0); + for (var epHtml in epsHtml) { + final title = xpath(epHtml, '//li/@title').isNotEmpty + ? xpath(epHtml, '//li/@title').first + : ""; + final ids = xpath(epHtml, '//a/@data-ids').first; + final sub = xpath(epHtml, '//a/@data-sub').first; + final dub = xpath(epHtml, '//a/@data-dub').first; + final softsub = title.toLowerCase().contains("softsub") ? "1" : ""; + final fillerEp = title.toLowerCase().contains("filler") ? "1" : ""; + final epNum = xpath(epHtml, '//a/@data-num').first; + String scanlator = ""; + if (sub == "1") { + scanlator += "Sub"; + } + if (softsub == "1") { + scanlator += ", Softsub"; + } + if (dub == "1") { + scanlator += ", Dub"; + } + if (fillerEp == "1") { + scanlator += ", • Filler Episode"; + } + MChapter episode = MChapter(); + episode.name = "Episode $epNum"; + episode.scanlator = scanlator; + episode.url = "$ids&epurl=$url/ep-$epNum"; + episodesList.add(episode); + } + + anime.chapters = episodesList.reversed.toList(); + return anime; + } + + @override + Future> getVideoList(MSource source, String url) async { + final ids = substringBefore(url, "&"); + final encrypt = vrfEncrypt(ids); + final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; + final res = await http('GET', + json.encode({"url": "${source.baseUrl}/ajax/server/list/$ids?$vrf"})); + final html = json.decode(res)["result"]; + final vidsHtml = querySelectorAll(html, + selector: "div.servers > div", + typeElement: 2, + attributes: "", + typeRegExp: 0); + List videos = []; + for (var vidHtml in vidsHtml) { + final type = xpath(vidHtml, '//div/@data-type').first; + final serversIds = xpath(vidHtml, '//li/@data-link-id'); + for (int i = 0; i < serversIds.length; i++) { + final serverId = serversIds[i]; + + final encrypt = vrfEncrypt(serverId); + final vrf = "vrf=${Uri.encodeComponent(encrypt)}"; + final res = await http( + 'GET', + json.encode( + {"url": "${source.baseUrl}/ajax/server/$serverId?$vrf"})); + final status = json.decode(res)["status"]; + if (status == 200) { + List a = []; + final url = vrfDecrypt(json.decode(res)["result"]["url"]); + if (url.contains("mp4upload")) { + a = await mp4UploadExtractor(url, null, "", type); + } else if (url.contains("streamtape")) { + a = await streamTapeExtractor(url, "StreamTape - $type"); + } else if (url.contains("filemoon")) { + a = await filemoonExtractor(url, "", type); + } + videos.addAll(a); + } + } + } + + return videos; + } + + MPages parseAnimeList(String res) { + List animeList = []; + final urls = xpath(res, '//div[@class="item "]/div/div/div/a/@href'); + final names = xpath(res, '//div[@class="item "]/div/div/div/a/text()'); + final images = xpath(res, '//div[@class="item "]/div/div/a/img/@src'); + + for (var i = 0; i < names.length; i++) { + MManga anime = MManga(); + anime.name = names[i]; + anime.imageUrl = images[i]; + anime.link = urls[i]; + animeList.add(anime); + } + + return MPages(animeList, true); + } + + List rc4Encrypt(String key, List message) { + List _key = utf8.encode(key); + int _i = 0, _j = 0; + List _box = List.generate(256, (i) => i); + + int x = 0; + for (int i = 0; i < 256; i++) { + x = (x + _box[i] + _key[i % _key.length]) % 256; + var tmp = _box[i]; + _box[i] = _box[x]; + _box[x] = tmp; + } + + List out = []; + for (var char in message) { + _i = (_i + 1) % 256; + _j = (_j + _box[_i]) % 256; + + var tmp = _box[_i]; + _box[_i] = _box[_j]; + _box[_j] = tmp; + + final c = char ^ (_box[(_box[_i] + _box[_j]) % 256]); + out.add(c); + } + + return out; + } + + String vrfEncrypt(String input) { + final rc4 = rc4Encrypt("ysJhV6U27FVIjjuk", input.codeUnits); + final vrf = base64Url.encode(rc4); + final vrf1 = base64.encode(vrf.codeUnits); + List vrf2 = vrfShift(vrf1.codeUnits); + final vrf3 = base64.encode(vrf2); + return utf8.decode(rot13(vrf3.codeUnits)); + } + + String vrfDecrypt(String input) { + final decode = base64Url.decode(input); + final rc4 = rc4Encrypt("hlPeNwkncH0fq9so", decode); + return Uri.decodeComponent(utf8.decode(rc4)); + } + + List vrfShift(List vrf) { + var shifts = [-3, 3, -4, 2, -2, 5, 4, 5]; + for (var i = 0; i < vrf.length; i++) { + var shift = shifts[i % 8]; + vrf[i] = (vrf[i] + shift) & 0xFF; + } + return vrf; + } + + List rot13(List vrf) { + for (var i = 0; i < vrf.length; i++) { + var byte = vrf[i]; + if (byte >= 'A'.codeUnitAt(0) && byte <= 'Z'.codeUnitAt(0)) { + vrf[i] = (byte - 'A'.codeUnitAt(0) + 13) % 26 + 'A'.codeUnitAt(0); + } else if (byte >= 'a'.codeUnitAt(0) && byte <= 'z'.codeUnitAt(0)) { + vrf[i] = (byte - 'a'.codeUnitAt(0) + 13) % 26 + 'a'.codeUnitAt(0); + } + } + return vrf; + } + + List getFilterList() { + return [ + SelectFilter("OrderFilter", "Sort order", 0, [ + SelectFilterOption("Most relevance", "most_relevance"), + SelectFilterOption("Recently updated", "recently_updated"), + SelectFilterOption("Recently added", "recently_added"), + SelectFilterOption("Release date", "release_date"), + SelectFilterOption("Trending", "trending"), + SelectFilterOption("Name A-Z", "title_az"), + SelectFilterOption("Scores", "scores"), + SelectFilterOption("MAL scores", "mal_scores"), + SelectFilterOption("Most watched", "most_watched"), + SelectFilterOption("Most favourited", "most_favourited"), + SelectFilterOption("Number of episodes", "number_of_episodes"), + ]), + SeparatorFilter(), + GroupFilter("GenreFilter", "Genre", [ + CheckBoxFilter("Action", "1"), + CheckBoxFilter("Adventure", "2"), + CheckBoxFilter("Avant Garde", "2262888"), + CheckBoxFilter("Boys Love", "2262603"), + CheckBoxFilter("Comedy", "4"), + CheckBoxFilter("Demons", "4424081"), + CheckBoxFilter("Drama", "7"), + CheckBoxFilter("Ecchi", "8"), + CheckBoxFilter("Fantasy", "9"), + CheckBoxFilter("Girls Love", "2263743"), + CheckBoxFilter("Gourmet", "2263289"), + CheckBoxFilter("Harem", "11"), + CheckBoxFilter("Horror", "14"), + CheckBoxFilter("Isekai", "3457284"), + CheckBoxFilter("Iyashikei", "4398552"), + CheckBoxFilter("Josei", "15"), + CheckBoxFilter("Kids", "16"), + CheckBoxFilter("Magic", "4424082"), + CheckBoxFilter("Mahou Shoujo", "3457321"), + CheckBoxFilter("Martial Arts", "18"), + CheckBoxFilter("Mecha", "19"), + CheckBoxFilter("Military", "20"), + CheckBoxFilter("Music", "21"), + CheckBoxFilter("Mystery", "22"), + CheckBoxFilter("Parody", "23"), + CheckBoxFilter("Psychological", "25"), + CheckBoxFilter("Reverse Harem", "4398403"), + CheckBoxFilter("Romance", "26"), + CheckBoxFilter("School", "28"), + CheckBoxFilter("Sci-Fi", "29"), + CheckBoxFilter("Seinen", "30"), + CheckBoxFilter("Shoujo", "31"), + CheckBoxFilter("Shounen", "33"), + CheckBoxFilter("Slice of Life", "35"), + CheckBoxFilter("Space", "36"), + CheckBoxFilter("Sports", "37"), + CheckBoxFilter("Super Power", "38"), + CheckBoxFilter("Supernatural", "39"), + CheckBoxFilter("Suspense", "2262590"), + CheckBoxFilter("Thriller", "40"), + CheckBoxFilter("Vampire", "41") + ]), + GroupFilter("CountryFilter", "Country", [ + CheckBoxFilter("China", "120823"), + CheckBoxFilter("Japan", "120822") + ]), + GroupFilter("SeasonFilter", "Season", [ + CheckBoxFilter("Fall", "fall"), + CheckBoxFilter("Summer", "summer"), + CheckBoxFilter("Spring", "spring"), + CheckBoxFilter("Winter", "winter"), + CheckBoxFilter("Unknown", "unknown") + ]), + GroupFilter("YearFilter", "Year", [ + CheckBoxFilter("2023", "2023"), + CheckBoxFilter("2022", "2022"), + CheckBoxFilter("2021", "2021"), + CheckBoxFilter("2020", "2020"), + CheckBoxFilter("2019", "2019"), + CheckBoxFilter("2018", "2018"), + CheckBoxFilter("2017", "2017"), + CheckBoxFilter("2016", "2016"), + CheckBoxFilter("2015", "2015"), + CheckBoxFilter("2014", "2014"), + CheckBoxFilter("2013", "2013"), + CheckBoxFilter("2012", "2012"), + CheckBoxFilter("2011", "2011"), + CheckBoxFilter("2010", "2010"), + CheckBoxFilter("2009", "2009"), + CheckBoxFilter("2008", "2008"), + CheckBoxFilter("2007", "2007"), + CheckBoxFilter("2006", "2006"), + CheckBoxFilter("2005", "2005"), + CheckBoxFilter("2004", "2004"), + CheckBoxFilter("2003", "2003"), + CheckBoxFilter("2000s", "2000s"), + CheckBoxFilter("1990s", "1990s"), + CheckBoxFilter("1980s", "1980s"), + CheckBoxFilter("1970s", "1970s"), + CheckBoxFilter("1960s", "1960s"), + CheckBoxFilter("1950s", "1950s"), + CheckBoxFilter("1940s", "1940s"), + CheckBoxFilter("1930s", "1930s"), + CheckBoxFilter("1920s", "1920s"), + CheckBoxFilter("1910s", "1910s") + ]), + GroupFilter("TypeFilter", "Type", [ + CheckBoxFilter("Movie", "movie"), + CheckBoxFilter("TV", "tv"), + CheckBoxFilter("OVA", "ova"), + CheckBoxFilter("ONA", "ona"), + CheckBoxFilter("Special", "special"), + CheckBoxFilter("Music", "music") + ]), + GroupFilter("StatusFilter", "Status", [ + CheckBoxFilter("Not Yet Aired", "info"), + CheckBoxFilter("Releasing", "releasing"), + CheckBoxFilter("Completed", "completed") + ]), + GroupFilter("LanguageFilter", "Language", [ + CheckBoxFilter("Sub and Dub", "subdub"), + CheckBoxFilter("Sub", "sub"), + CheckBoxFilter("Dub", "dub") + ]), + GroupFilter("RatingFilter", "Rating", [ + CheckBoxFilter("G - All Ages", "g"), + CheckBoxFilter("PG - Children", "pg"), + CheckBoxFilter("PG 13 - Teens 13 and Older", "pg_13"), + CheckBoxFilter("R - 17+, Violence & Profanity", "r"), + CheckBoxFilter("R+ - Profanity & Mild Nudity", "r+"), + CheckBoxFilter("Rx - Hentai", "rx") + ]), + ]; + } + + String ll(String url) { + if (url.contains("?")) { + return "&"; + } + return "?"; + } +} + +Map getMirrorPref() { + return { + "aniwave.to": "https://aniwave.to", + "aniwave.bz": "https://aniwave.bz", + "aniwave.ws": "https://aniwave.ws", + }; +} + +Aniwave main() { + return Aniwave(); +} diff --git a/anime/src/en/aniwave/source.dart b/anime/src/en/aniwave/source.dart index 7ae0c8e6..59f257b4 100644 --- a/anime/src/en/aniwave/source.dart +++ b/anime/src/en/aniwave/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get aniwave => _aniwave; -const aniwaveVersion = "0.0.1"; +const aniwaveVersion = "0.0.15"; const aniwaveCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/en/aniwave/aniwave-v$aniwaveVersion.dart"; Source _aniwave = Source( diff --git a/anime/src/en/gogoanime/gogoanime-v0.0.35.dart b/anime/src/en/gogoanime/gogoanime-v0.0.35.dart deleted file mode 100644 index a6731e88..00000000 --- a/anime/src/en/gogoanime/gogoanime-v0.0.35.dart +++ /dev/null @@ -1,165 +0,0 @@ -import 'package:mangayomi/bridge_lib.dart'; -import 'dart:convert'; - -class GogoAnime extends MProvider { - GogoAnime(); - - @override - Future getPopular(MSource source, int page) async { - final data = {"url": "${source.baseUrl}/popular.html?page=$page"}; - final res = await http('GET', json.encode(data)); - - List animeList = []; - final urls = xpath(res, '//*[@class="img"]/a/@href'); - final names = xpath(res, '//*[@class="img"]/a/@title'); - final images = xpath(res, '//*[@class="img"]/a/img/@src'); - - for (var i = 0; i < names.length; i++) { - MManga anime = MManga(); - anime.name = names[i]; - anime.imageUrl = images[i]; - anime.link = urls[i]; - animeList.add(anime); - } - - return MPages(animeList, true); - } - - @override - Future getLatestUpdates(MSource source, int page) async { - final data = { - "url": - "https://ajax.gogo-load.com/ajax/page-recent-release-ongoing.html?page=$page&type=1" - }; - final res = await http('GET', json.encode(data)); - - List animeList = []; - final urls = - xpath(res, '//*[@class="added_series_body popular"]/ul/li/a[1]/@href'); - final names = xpath( - res, '//*[//*[@class="added_series_body popular"]/ul/li/a[1]/@title'); - List images = []; - List imagess = xpath(res, - '//*[//*[@class="added_series_body popular"]/ul/li/a/div[@class="thumbnail-popular"]/@style'); - for (var url in imagess) { - images.add(url.replaceAll("background: url('", "").replaceAll("');", "")); - } - - for (var i = 0; i < names.length; i++) { - MManga anime = MManga(); - anime.name = names[i]; - anime.imageUrl = images[i]; - anime.link = urls[i]; - animeList.add(anime); - } - - return MPages(animeList, true); - } - - @override - Future search(MSource source, String query, int page) async { - final data = { - "url": "${source.baseUrl}/search.html?keyword=$query&page=$page" - }; - final res = await http('GET', json.encode(data)); - - List animeList = []; - final urls = xpath(res, '//*[@class="img"]/a/@href'); - final names = xpath(res, '//*[@class="img"]/a/@title'); - final images = xpath(res, '//*[@class="img"]/a/img/@src'); - - for (var i = 0; i < names.length; i++) { - MManga anime = MManga(); - anime.name = names[i]; - anime.imageUrl = images[i]; - anime.link = urls[i]; - animeList.add(anime); - } - - return MPages(animeList, true); - } - - @override - Future getDetail(MSource source, String url) async { - final statusList = [ - { - "Ongoing": 0, - "Completed": 1, - } - ]; - final data = {"url": "${source.baseUrl}$url"}; - final res = await http('GET', json.encode(data)); - MManga anime = MManga(); - final status = xpath( - res, '//*[@class="anime_info_body_bg"]/p[@class="type"][5]/text()') - .first - .replaceAll("Status: ", ""); - anime.description = xpath( - res, '//*[@class="anime_info_body_bg"]/p[@class="type"][2]/text()') - .first - .replaceAll("Plot Summary: ", ""); - anime.status = parseStatus(status, statusList); - anime.genre = xpath( - res, '//*[@class="anime_info_body_bg"]/p[@class="type"][3]/text()') - .first - .replaceAll("Genre: ", "") - .split(","); - - final id = xpath(res, '//*[@id="movie_id"]/@value').first; - final urlEp = - "https://ajax.gogo-load.com/ajax/load-list-episode?ep_start=0&ep_end=4000&id=$id"; - final dataEp = {"url": urlEp}; - final resEp = await http('GET', json.encode(dataEp)); - - final epUrls = xpath(resEp, '//*[@id="episode_related"]/li/a/@href'); - final names = xpath( - resEp, '//*[@id="episode_related"]/li/a/div[@class="name"]/text()'); - List episodes = []; - - for (var a in names) { - episodes.add("Episode ${substringAfterLast(a, ' ')}"); - } - List? episodesList = []; - for (var i = 0; i < episodes.length; i++) { - MChapter episode = MChapter(); - episode.name = episodes[i]; - episode.url = epUrls[i]; - episodesList.add(episode); - } - - anime.chapters = episodesList; - return anime; - } - - @override - Future> getVideoList(MSource source, String url) async { - final datas = {"url": "${source.baseUrl}$url"}; - - final res = await http('GET', json.encode(datas)); - final serverUrls = - xpath(res, '//*[@class="anime_muti_link"]/ul/li/a/@data-video'); - final classNames = xpath(res, '//*[@class="anime_muti_link"]/ul/li/@class'); - List videos = []; - for (var i = 0; i < classNames.length; i++) { - final name = classNames[i]; - final url = serverUrls[i]; - List a = []; - if (name.contains("anime")) { - a = await gogoCdnExtractor(url); - } else if (name.contains("vidcdn")) { - a = await gogoCdnExtractor(url); - } else if (name.contains("doodstream")) { - a = await doodExtractor(url); - } else if (name.contains("mp4upload")) { - a = await mp4UploadExtractor(url, null, "", ""); - } else if (name.contains("streamsb")) {} - videos.addAll(a); - } - - return videos; - } -} - -GogoAnime main() { - return GogoAnime(); -} diff --git a/anime/src/en/gogoanime/gogoanime-v0.0.4.dart b/anime/src/en/gogoanime/gogoanime-v0.0.4.dart new file mode 100644 index 00000000..dc0ba8dd --- /dev/null +++ b/anime/src/en/gogoanime/gogoanime-v0.0.4.dart @@ -0,0 +1,1031 @@ +import 'package:mangayomi/bridge_lib.dart'; +import 'dart:convert'; + +class GogoAnime extends MProvider { + GogoAnime(); + + @override + Future getPopular(MSource source, int page) async { + final data = {"url": "${source.baseUrl}/popular.html?page=$page"}; + final res = await http('GET', json.encode(data)); + + List animeList = []; + final urls = xpath(res, '//*[@class="img"]/a/@href'); + final names = xpath(res, '//*[@class="img"]/a/@title'); + final images = xpath(res, '//*[@class="img"]/a/img/@src'); + + for (var i = 0; i < names.length; i++) { + MManga anime = MManga(); + anime.name = names[i]; + anime.imageUrl = images[i]; + anime.link = urls[i]; + animeList.add(anime); + } + + return MPages(animeList, true); + } + + @override + Future getLatestUpdates(MSource source, int page) async { + final data = { + "url": + "https://ajax.gogo-load.com/ajax/page-recent-release-ongoing.html?page=$page&type=1" + }; + final res = await http('GET', json.encode(data)); + + List animeList = []; + final urls = + xpath(res, '//*[@class="added_series_body popular"]/ul/li/a[1]/@href'); + final names = xpath( + res, '//*[//*[@class="added_series_body popular"]/ul/li/a[1]/@title'); + List images = []; + List imagess = xpath(res, + '//*[//*[@class="added_series_body popular"]/ul/li/a/div[@class="thumbnail-popular"]/@style'); + for (var url in imagess) { + images.add(url.replaceAll("background: url('", "").replaceAll("');", "")); + } + + for (var i = 0; i < names.length; i++) { + MManga anime = MManga(); + anime.name = names[i]; + anime.imageUrl = images[i]; + anime.link = urls[i]; + animeList.add(anime); + } + + return MPages(animeList, true); + } + + @override + Future search( + MSource source, String query, int page, FilterList filterList) async { + final filters = filterList.filters; + String filterStr = ""; + String url = ""; + + String genre = ""; + String recent = ""; + String season = ""; + + for (var filter in filters) { + if (filter.type == "SortFilter") { + final sort = filter.values[filter.state].value; + filterStr += "&sort=$sort"; + } else if (filter.type == "GenreFilter") { + final genre = (filter.state as List).where((e) => e.state).toList(); + if (genre.isNotEmpty) { + for (var st in genre) { + filterStr += "&genre[]=${st.value}"; + } + } + } else if (filter.type == "CountryFilter") { + final country = (filter.state as List).where((e) => e.state).toList(); + if (country.isNotEmpty) { + for (var st in country) { + filterStr += "&country[]=${st.value}"; + } + } + } else if (filter.type == "SeasonFilter") { + final season = (filter.state as List).where((e) => e.state).toList(); + if (season.isNotEmpty) { + for (var st in season) { + filterStr += "&season[]=${st.value}"; + } + } + } else if (filter.type == "YearFilter") { + final year = (filter.state as List).where((e) => e.state).toList(); + if (year.isNotEmpty) { + for (var st in year) { + filterStr += "&year[]=${st.value}"; + } + } + } else if (filter.type == "TypeFilter") { + final type = (filter.state as List).where((e) => e.state).toList(); + if (type.isNotEmpty) { + for (var st in type) { + filterStr += "&type[]=${st.value}"; + } + } + } else if (filter.type == "StatusFilter") { + final status = (filter.state as List).where((e) => e.state).toList(); + if (status.isNotEmpty) { + for (var st in status) { + filterStr += "&status[]=${st.value}"; + } + } + } else if (filter.type == "LanguageFilter") { + final language = (filter.state as List).where((e) => e.state).toList(); + if (language.isNotEmpty) { + for (var st in language) { + filterStr += "&language[]=${st.value}"; + } + } + } + if (filter.type == "GenreIFilter") { + genre = filter.values[filter.state].value; + } else if (filter.type == "RecentFilter") { + recent = filter.values[filter.state].value; + } else if (filter.type == "SeasonIFilter") { + season = filter.values[filter.state].value; + } + } + if (genre.isNotEmpty) { + url = "${source.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 = "${source.baseUrl}/$season?page=$page"; + } else { + url = "${source.baseUrl}/filter.html?keyword=$query$filterStr&page=$page"; + } + + final data = {"url": url}; + final res = await http('GET', json.encode(data)); + + List animeList = []; + final urls = xpath(res, '//*[@class="img"]/a/@href'); + final names = xpath(res, '//*[@class="img"]/a/@title'); + final images = xpath(res, '//*[@class="img"]/a/img/@src'); + + for (var i = 0; i < names.length; i++) { + MManga anime = MManga(); + anime.name = names[i]; + anime.imageUrl = images[i]; + anime.link = urls[i]; + animeList.add(anime); + } + + return MPages(animeList, true); + } + + @override + Future getDetail(MSource source, String url) async { + final statusList = [ + { + "Ongoing": 0, + "Completed": 1, + } + ]; + final data = {"url": "${source.baseUrl}$url"}; + final res = await http('GET', json.encode(data)); + MManga anime = MManga(); + final status = xpath( + res, '//*[@class="anime_info_body_bg"]/p[@class="type"][5]/text()') + .first + .replaceAll("Status: ", ""); + anime.description = xpath( + res, '//*[@class="anime_info_body_bg"]/p[@class="type"][2]/text()') + .first + .replaceAll("Plot Summary: ", ""); + anime.status = parseStatus(status, statusList); + anime.genre = xpath( + res, '//*[@class="anime_info_body_bg"]/p[@class="type"][3]/text()') + .first + .replaceAll("Genre: ", "") + .split(","); + + final id = xpath(res, '//*[@id="movie_id"]/@value').first; + final urlEp = + "https://ajax.gogo-load.com/ajax/load-list-episode?ep_start=0&ep_end=4000&id=$id"; + final dataEp = {"url": urlEp}; + final resEp = await http('GET', json.encode(dataEp)); + + final epUrls = xpath(resEp, '//*[@id="episode_related"]/li/a/@href'); + final names = xpath( + resEp, '//*[@id="episode_related"]/li/a/div[@class="name"]/text()'); + List episodes = []; + + for (var a in names) { + episodes.add("Episode ${substringAfterLast(a, ' ')}"); + } + List? episodesList = []; + for (var i = 0; i < episodes.length; i++) { + MChapter episode = MChapter(); + episode.name = episodes[i]; + episode.url = epUrls[i]; + episodesList.add(episode); + } + + anime.chapters = episodesList; + return anime; + } + + @override + Future> getVideoList(MSource source, String url) async { + final datas = {"url": "${source.baseUrl}$url"}; + + final res = await http('GET', json.encode(datas)); + final serverUrls = + xpath(res, '//*[@class="anime_muti_link"]/ul/li/a/@data-video'); + final serverNames = + xpath(res, '//*[@class="anime_muti_link"]/ul/li/@class'); + List videos = []; + for (var i = 0; i < serverNames.length; i++) { + final name = serverNames[i]; + final url = serverUrls[i]; + List a = []; + if (name.contains("anime")) { + a = await gogoCdnExtractor(url); + } else if (name.contains("vidcdn")) { + a = await gogoCdnExtractor(url); + } else if (name.contains("doodstream")) { + a = await doodExtractor(url); + } else if (name.contains("mp4upload")) { + a = await mp4UploadExtractor(url, null, "", ""); + } else if (name.contains("filelions")) { + a = await streamWishExtractor(url, "FileLions"); + } else if (name.contains("streamwish")) { + a = await streamWishExtractor(url, "StreamWish"); + } + videos.addAll(a); + } + + return videos; + } + + List getFilterList() { + return [ + HeaderFilter("Advanced search"), + GroupFilter("GenreFilter", "Genre", [ + { + "type": "CheckBox", + "filter": {"name": "Action", "value": "action"} + }, + { + "type": "CheckBox", + "filter": {"name": "Adult Cast", "value": "adult-cast"} + }, + { + "type": "CheckBox", + "filter": {"name": "Adventure", "value": "adventure"} + }, + { + "type": "CheckBox", + "filter": {"name": "Anthropomorphic", "value": "anthropomorphic"} + }, + { + "type": "CheckBox", + "filter": {"name": "Avant Garde", "value": "avant-garde"} + }, + { + "type": "CheckBox", + "filter": {"name": "Boys Love", "value": "shounen-ai"} + }, + { + "type": "CheckBox", + "filter": {"name": "Cars", "value": "cars"} + }, + { + "type": "CheckBox", + "filter": {"name": "CGDCT", "value": "cgdct"} + }, + { + "type": "CheckBox", + "filter": {"name": "Childcare", "value": "childcare"} + }, + { + "type": "CheckBox", + "filter": {"name": "Comedy", "value": "comedy"} + }, + { + "type": "CheckBox", + "filter": {"name": "Comic", "value": "comic"} + }, + { + "type": "CheckBox", + "filter": {"name": "Crime", "value": "crime"} + }, + { + "type": "CheckBox", + "filter": {"name": "Crossdressing", "value": "crossdressing"} + }, + { + "type": "CheckBox", + "filter": {"name": "Delinquents", "value": "delinquents"} + }, + { + "type": "CheckBox", + "filter": {"name": "Dementia", "value": "dementia"} + }, + { + "type": "CheckBox", + "filter": {"name": "Demons", "value": "demons"} + }, + { + "type": "CheckBox", + "filter": {"name": "Detective", "value": "detective"} + }, + { + "type": "CheckBox", + "filter": {"name": "Drama", "value": "drama"} + }, + { + "type": "CheckBox", + "filter": {"name": "Dub", "value": "dub"} + }, + { + "type": "CheckBox", + "filter": {"name": "Ecchi", "value": "ecchi"} + }, + { + "type": "CheckBox", + "filter": {"name": "Erotica", "value": "erotica"} + }, + { + "type": "CheckBox", + "filter": {"name": "Family", "value": "family"} + }, + { + "type": "CheckBox", + "filter": {"name": "Fantasy", "value": "fantasy"} + }, + { + "type": "CheckBox", + "filter": {"name": "Gag Humor", "value": "gag-humor"} + }, + { + "type": "CheckBox", + "filter": {"name": "Game", "value": "game"} + }, + { + "type": "CheckBox", + "filter": {"name": "Gender Bender", "value": "gender-bender"} + }, + { + "type": "CheckBox", + "filter": {"name": "Gore", "value": "gore"} + }, + { + "type": "CheckBox", + "filter": {"name": "Gourmet", "value": "gourmet"} + }, + { + "type": "CheckBox", + "filter": {"name": "Harem", "value": "harem"} + }, + { + "type": "CheckBox", + "filter": {"name": "Hentai", "value": "hentai"} + }, + { + "type": "CheckBox", + "filter": {"name": "High Stakes Game", "value": "high-stakes-game"} + }, + { + "type": "CheckBox", + "filter": {"name": "Historical", "value": "historical"} + }, + { + "type": "CheckBox", + "filter": {"name": "Horror", "value": "horror"} + }, + { + "type": "CheckBox", + "filter": {"name": "Isekai", "value": "isekai"} + }, + { + "type": "CheckBox", + "filter": {"name": "Iyashikei", "value": "iyashikei"} + }, + { + "type": "CheckBox", + "filter": {"name": "Josei", "value": "josei"} + }, + { + "type": "CheckBox", + "filter": {"name": "Kids", "value": "kids"} + }, + { + "type": "CheckBox", + "filter": {"name": "Magic", "value": "magic"} + }, + { + "type": "CheckBox", + "filter": {"name": "Magical Sex Shift", "value": "magical-sex-shift"} + }, + { + "type": "CheckBox", + "filter": {"name": "Mahou Shoujo", "value": "mahou-shoujo"} + }, + { + "type": "CheckBox", + "filter": {"name": "Martial Arts", "value": "martial-arts"} + }, + { + "type": "CheckBox", + "filter": {"name": "Mecha", "value": "mecha"} + }, + { + "type": "CheckBox", + "filter": {"name": "Medical", "value": "medical"} + }, + { + "type": "CheckBox", + "filter": {"name": "Military", "value": "military"} + }, + { + "type": "CheckBox", + "filter": {"name": "Music", "value": "music"} + }, + { + "type": "CheckBox", + "filter": {"name": "Mystery", "value": "mystery"} + }, + { + "type": "CheckBox", + "filter": {"name": "Mythology", "value": "mythology"} + }, + { + "type": "CheckBox", + "filter": {"name": "Organized Crime", "value": "organized-crime"} + }, + { + "type": "CheckBox", + "filter": {"name": "Parody", "value": "parody"} + }, + { + "type": "CheckBox", + "filter": {"name": "Performing Arts", "value": "performing-arts"} + }, + { + "type": "CheckBox", + "filter": {"name": "Pets", "value": "pets"} + }, + { + "type": "CheckBox", + "filter": {"name": "Police", "value": "police"} + }, + { + "type": "CheckBox", + "filter": {"name": "Psychological", "value": "psychological"} + }, + { + "type": "CheckBox", + "filter": {"name": "Racing", "value": "racing"} + }, + { + "type": "CheckBox", + "filter": {"name": "Reincarnation", "value": "reincarnation"} + }, + { + "type": "CheckBox", + "filter": {"name": "Romance", "value": "romance"} + }, + { + "type": "CheckBox", + "filter": {"name": "Romantic Subtext", "value": "romantic-subtext"} + }, + { + "type": "CheckBox", + "filter": {"name": "Samurai", "value": "samurai"} + }, + { + "type": "CheckBox", + "filter": {"name": "School", "value": "school"} + }, + { + "type": "CheckBox", + "filter": {"name": "Sci-Fi", "value": "sci-fi"} + }, + { + "type": "CheckBox", + "filter": {"name": "Seinen", "value": "seinen"} + }, + { + "type": "CheckBox", + "filter": {"name": "Shoujo", "value": "shoujo"} + }, + { + "type": "CheckBox", + "filter": {"name": "Shoujo Ai", "value": "shoujo-ai"} + }, + { + "type": "CheckBox", + "filter": {"name": "Shounen", "value": "shounen"} + }, + { + "type": "CheckBox", + "filter": {"name": "Showbiz", "value": "showbiz"} + }, + { + "type": "CheckBox", + "filter": {"name": "Slice of Life", "value": "slice-of-life"} + }, + { + "type": "CheckBox", + "filter": {"name": "Space", "value": "space"} + }, + { + "type": "CheckBox", + "filter": {"name": "Sports", "value": "sports"} + }, + { + "type": "CheckBox", + "filter": {"name": "Strategy Game", "value": "strategy-game"} + }, + { + "type": "CheckBox", + "filter": {"name": "Super Power", "value": "super-power"} + }, + { + "type": "CheckBox", + "filter": {"name": "Supernatural", "value": "supernatural"} + }, + { + "type": "CheckBox", + "filter": {"name": "Survival", "value": "survival"} + }, + { + "type": "CheckBox", + "filter": {"name": "Suspense", "value": "suspense"} + }, + { + "type": "CheckBox", + "filter": {"name": "Team Sports", "value": "team-sports"} + }, + { + "type": "CheckBox", + "filter": {"name": "Thriller", "value": "thriller"} + }, + { + "type": "CheckBox", + "filter": {"name": "Time Travel", "value": "time-travel"} + }, + { + "type": "CheckBox", + "filter": {"name": "Vampire", "value": "vampire"} + }, + { + "type": "CheckBox", + "filter": {"name": "Visual Arts", "value": "visual-arts"} + }, + { + "type": "CheckBox", + "filter": {"name": "Work Life", "value": "work-life"} + }, + { + "type": "CheckBox", + "filter": {"name": "Workplace", "value": "workplace"} + }, + { + "type": "CheckBox", + "filter": {"name": "Yaoi", "value": "yaoi"} + }, + { + "type": "CheckBox", + "filter": {"name": "Yuri", "value": "yuri"} + } + ]), + GroupFilter("CountryFilter", "Country", + [CheckBoxFilter("China", "5"), CheckBoxFilter("Japan", "2")]), + GroupFilter("SeasonFilter", "Season", [ + CheckBoxFilter("Fall", "fall"), + CheckBoxFilter("Summer", "summer"), + CheckBoxFilter("Spring", "spring"), + CheckBoxFilter("Winter", "winter"), + ]), + GroupFilter("YearFilter", "Year", [ + CheckBoxFilter("2023", "2023"), + CheckBoxFilter("2022", "2022"), + CheckBoxFilter("2021", "2021"), + CheckBoxFilter("2020", "2020"), + CheckBoxFilter("2019", "2019"), + CheckBoxFilter("2018", "2018"), + CheckBoxFilter("2017", "2017"), + CheckBoxFilter("2016", "2016"), + CheckBoxFilter("2015", "2015"), + CheckBoxFilter("2014", "2014"), + CheckBoxFilter("2013", "2013"), + CheckBoxFilter("2012", "2012"), + CheckBoxFilter("2011", "2011"), + CheckBoxFilter("2010", "2010"), + CheckBoxFilter("2009", "2009"), + CheckBoxFilter("2008", "2008"), + CheckBoxFilter("2007", "2007"), + CheckBoxFilter("2006", "2006"), + CheckBoxFilter("2005", "2005"), + CheckBoxFilter("2004", "2004"), + CheckBoxFilter("2003", "2003"), + CheckBoxFilter("2002", "2002"), + CheckBoxFilter("2001", "2001"), + CheckBoxFilter("2000", "2000"), + CheckBoxFilter("1999", "1999"), + ]), + GroupFilter("LanguageFilter", "Language", [ + CheckBoxFilter("Sub & Dub", "subdub"), + CheckBoxFilter("Sub", "sub"), + CheckBoxFilter("Dub", "dub"), + ]), + GroupFilter("TypeFilter", "Type", [ + CheckBoxFilter("Movie", "3"), + CheckBoxFilter("TV", "1"), + CheckBoxFilter("OVA", "26"), + CheckBoxFilter("ONA", "30"), + CheckBoxFilter("Special", "2"), + CheckBoxFilter("Music", "32"), + ]), + GroupFilter("StatusFilter", "Status", [ + CheckBoxFilter("Not Yet Aired", "Upcoming"), + CheckBoxFilter("Ongoing", "Ongoing"), + CheckBoxFilter("Completed", "Completed") + ]), + SelectFilter("SortFilter", "Sort by", 0, [ + SelectFilterOption("Name A-Z", "title_az"), + SelectFilterOption("Recently updated", "recently_updated"), + SelectFilterOption("Recently added", "recently_added"), + SelectFilterOption("Release date", "release_date") + ]), + SeparatorFilter(), + HeaderFilter("Select sub-page"), + HeaderFilter("Note: Ignores search & other filters"), + SelectFilter("GenreIFilter", "Genre", 0, [ + { + "type": "SelectOption", + "filter": {"name": "", "value": ""} + }, + { + "type": "SelectOption", + "filter": {"name": "Action", "value": "action"} + }, + { + "type": "SelectOption", + "filter": {"name": "Adult Cast", "value": "adult-cast"} + }, + { + "type": "SelectOption", + "filter": {"name": "Adventure", "value": "adventure"} + }, + { + "type": "SelectOption", + "filter": {"name": "Anthropomorphic", "value": "anthropomorphic"} + }, + { + "type": "SelectOption", + "filter": {"name": "Avant Garde", "value": "avant-garde"} + }, + { + "type": "SelectOption", + "filter": {"name": "Boys Love", "value": "shounen-ai"} + }, + { + "type": "SelectOption", + "filter": {"name": "Cars", "value": "cars"} + }, + { + "type": "SelectOption", + "filter": {"name": "CGDCT", "value": "cgdct"} + }, + { + "type": "SelectOption", + "filter": {"name": "Childcare", "value": "childcare"} + }, + { + "type": "SelectOption", + "filter": {"name": "Comedy", "value": "comedy"} + }, + { + "type": "SelectOption", + "filter": {"name": "Comic", "value": "comic"} + }, + { + "type": "SelectOption", + "filter": {"name": "Crime", "value": "crime"} + }, + { + "type": "SelectOption", + "filter": {"name": "Crossdressing", "value": "crossdressing"} + }, + { + "type": "SelectOption", + "filter": {"name": "Delinquents", "value": "delinquents"} + }, + { + "type": "SelectOption", + "filter": {"name": "Dementia", "value": "dementia"} + }, + { + "type": "SelectOption", + "filter": {"name": "Demons", "value": "demons"} + }, + { + "type": "SelectOption", + "filter": {"name": "Detective", "value": "detective"} + }, + { + "type": "SelectOption", + "filter": {"name": "Drama", "value": "drama"} + }, + { + "type": "SelectOption", + "filter": {"name": "Dub", "value": "dub"} + }, + { + "type": "SelectOption", + "filter": {"name": "Ecchi", "value": "ecchi"} + }, + { + "type": "SelectOption", + "filter": {"name": "Erotica", "value": "erotica"} + }, + { + "type": "SelectOption", + "filter": {"name": "Family", "value": "family"} + }, + { + "type": "SelectOption", + "filter": {"name": "Fantasy", "value": "fantasy"} + }, + { + "type": "SelectOption", + "filter": {"name": "Gag Humor", "value": "gag-humor"} + }, + { + "type": "SelectOption", + "filter": {"name": "Game", "value": "game"} + }, + { + "type": "SelectOption", + "filter": {"name": "Gender Bender", "value": "gender-bender"} + }, + { + "type": "SelectOption", + "filter": {"name": "Gore", "value": "gore"} + }, + { + "type": "SelectOption", + "filter": {"name": "Gourmet", "value": "gourmet"} + }, + { + "type": "SelectOption", + "filter": {"name": "Harem", "value": "harem"} + }, + { + "type": "SelectOption", + "filter": {"name": "Hentai", "value": "hentai"} + }, + { + "type": "SelectOption", + "filter": {"name": "High Stakes Game", "value": "high-stakes-game"} + }, + { + "type": "SelectOption", + "filter": {"name": "Historical", "value": "historical"} + }, + { + "type": "SelectOption", + "filter": {"name": "Horror", "value": "horror"} + }, + { + "type": "SelectOption", + "filter": {"name": "Isekai", "value": "isekai"} + }, + { + "type": "SelectOption", + "filter": {"name": "Iyashikei", "value": "iyashikei"} + }, + { + "type": "SelectOption", + "filter": {"name": "Josei", "value": "josei"} + }, + { + "type": "SelectOption", + "filter": {"name": "Kids", "value": "kids"} + }, + { + "type": "SelectOption", + "filter": {"name": "Magic", "value": "magic"} + }, + { + "type": "SelectOption", + "filter": {"name": "Magical Sex Shift", "value": "magical-sex-shift"} + }, + { + "type": "SelectOption", + "filter": {"name": "Mahou Shoujo", "value": "mahou-shoujo"} + }, + { + "type": "SelectOption", + "filter": {"name": "Martial Arts", "value": "martial-arts"} + }, + { + "type": "SelectOption", + "filter": {"name": "Mecha", "value": "mecha"} + }, + { + "type": "SelectOption", + "filter": {"name": "Medical", "value": "medical"} + }, + { + "type": "SelectOption", + "filter": {"name": "Military", "value": "military"} + }, + { + "type": "SelectOption", + "filter": {"name": "Music", "value": "music"} + }, + { + "type": "SelectOption", + "filter": {"name": "Mystery", "value": "mystery"} + }, + { + "type": "SelectOption", + "filter": {"name": "Mythology", "value": "mythology"} + }, + { + "type": "SelectOption", + "filter": {"name": "Organized Crime", "value": "organized-crime"} + }, + { + "type": "SelectOption", + "filter": {"name": "Parody", "value": "parody"} + }, + { + "type": "SelectOption", + "filter": {"name": "Performing Arts", "value": "performing-arts"} + }, + { + "type": "SelectOption", + "filter": {"name": "Pets", "value": "pets"} + }, + { + "type": "SelectOption", + "filter": {"name": "Police", "value": "police"} + }, + { + "type": "SelectOption", + "filter": {"name": "Psychological", "value": "psychological"} + }, + { + "type": "SelectOption", + "filter": {"name": "Racing", "value": "racing"} + }, + { + "type": "SelectOption", + "filter": {"name": "Reincarnation", "value": "reincarnation"} + }, + { + "type": "SelectOption", + "filter": {"name": "Romance", "value": "romance"} + }, + { + "type": "SelectOption", + "filter": {"name": "Romantic Subtext", "value": "romantic-subtext"} + }, + { + "type": "SelectOption", + "filter": {"name": "Samurai", "value": "samurai"} + }, + { + "type": "SelectOption", + "filter": {"name": "School", "value": "school"} + }, + { + "type": "SelectOption", + "filter": {"name": "Sci-Fi", "value": "sci-fi"} + }, + { + "type": "SelectOption", + "filter": {"name": "Seinen", "value": "seinen"} + }, + { + "type": "SelectOption", + "filter": {"name": "Shoujo", "value": "shoujo"} + }, + { + "type": "SelectOption", + "filter": {"name": "Shoujo Ai", "value": "shoujo-ai"} + }, + { + "type": "SelectOption", + "filter": {"name": "Shounen", "value": "shounen"} + }, + { + "type": "SelectOption", + "filter": {"name": "Showbiz", "value": "showbiz"} + }, + { + "type": "SelectOption", + "filter": {"name": "Slice of Life", "value": "slice-of-life"} + }, + { + "type": "SelectOption", + "filter": {"name": "Space", "value": "space"} + }, + { + "type": "SelectOption", + "filter": {"name": "Sports", "value": "sports"} + }, + { + "type": "SelectOption", + "filter": {"name": "Strategy Game", "value": "strategy-game"} + }, + { + "type": "SelectOption", + "filter": {"name": "Super Power", "value": "super-power"} + }, + { + "type": "SelectOption", + "filter": {"name": "Supernatural", "value": "supernatural"} + }, + { + "type": "SelectOption", + "filter": {"name": "Survival", "value": "survival"} + }, + { + "type": "SelectOption", + "filter": {"name": "Suspense", "value": "suspense"} + }, + { + "type": "SelectOption", + "filter": {"name": "Team Sports", "value": "team-sports"} + }, + { + "type": "SelectOption", + "filter": {"name": "Thriller", "value": "thriller"} + }, + { + "type": "SelectOption", + "filter": {"name": "Time Travel", "value": "time-travel"} + }, + { + "type": "SelectOption", + "filter": {"name": "Vampire", "value": "vampire"} + }, + { + "type": "SelectOption", + "filter": {"name": "Visual Arts", "value": "visual-arts"} + }, + { + "type": "SelectOption", + "filter": {"name": "Work Life", "value": "work-life"} + }, + { + "type": "SelectOption", + "filter": {"name": "Workplace", "value": "workplace"} + }, + { + "type": "SelectOption", + "filter": {"name": "Yaoi", "value": "yaoi"} + }, + { + "type": "SelectOption", + "filter": {"name": "Yuri", "value": "yuri"} + } + ]), + SelectFilter("RecentFilter", "Recent", 0, [ + SelectFilterOption("", ""), + SelectFilterOption("Recent Release", "1"), + SelectFilterOption("Recent Dub", "2"), + SelectFilterOption("Recent Chinese", "3") + ]), + SelectFilter("SeasonIFilter", "Season", 0, [ + SelectFilterOption("", ""), + SelectFilterOption("Latest season", "new-season.html"), + SelectFilterOption("Summer 2023", "sub-category/summer-2023-anime"), + SelectFilterOption("Spring 2023", "sub-category/spring-2023-anime"), + SelectFilterOption("Winter 2023", "sub-category/winter-2023-anime"), + SelectFilterOption("Fall 2022", "sub-category/fall-2022-anime"), + SelectFilterOption("Summer 2022", "sub-category/summer-2022-anime"), + SelectFilterOption("Spring 2022", "sub-category/spring-2022-anime"), + SelectFilterOption("Winter 2022", "sub-category/winter-2022-anime"), + SelectFilterOption("Fall 2021", "sub-category/fall-2021-anime"), + SelectFilterOption("Summer 2021", "sub-category/summer-2021-anime"), + SelectFilterOption("Spring 2021", "sub-category/spring-2021-anime"), + SelectFilterOption("Winter 2021", "sub-category/winter-2021-anime"), + SelectFilterOption("Fall 2020", "sub-category/fall-2020-anime"), + SelectFilterOption("Summer 2020", "sub-category/summer-2020-anime"), + SelectFilterOption("Spring 2020", "sub-category/spring-2020-anime"), + SelectFilterOption("Winter 2020", "sub-category/winter-2020-anime"), + SelectFilterOption("Fall 2019", "sub-category/fall-2019-anime"), + SelectFilterOption("Summer 2019", "sub-category/summer-2019-anime"), + SelectFilterOption("Spring 2019", "sub-category/spring-2019-anime"), + SelectFilterOption("Winter 2019", "sub-category/winter-2019-anime"), + SelectFilterOption("Fall 2018", "sub-category/fall-2018-anime"), + SelectFilterOption("Summer 2018", "sub-category/summer-2018-anime"), + SelectFilterOption("Spring 2018", "sub-category/spring-2018-anime"), + SelectFilterOption("Winter 2018", "sub-category/winter-2018-anime"), + SelectFilterOption("Fall 2017", "sub-category/fall-2017-anime"), + SelectFilterOption("Summer 2017", "sub-category/summer-2017-anime"), + SelectFilterOption("Spring 2017", "sub-category/spring-2017-anime"), + SelectFilterOption("Winter 2017", "sub-category/winter-2017-anime"), + SelectFilterOption("Fall 2016", "sub-category/fall-2016-anime"), + SelectFilterOption("Summer 2016", "sub-category/summer-2016-anime"), + SelectFilterOption("Spring 2016", "sub-category/spring-2016-anime"), + SelectFilterOption("Winter 2016", "sub-category/winter-2016-anime"), + SelectFilterOption("Fall 2015", "sub-category/fall-2015-anime"), + SelectFilterOption("Summer 2015", "sub-category/summer-2015-anime"), + SelectFilterOption("Spring 2015", "sub-category/spring-2015-anime"), + SelectFilterOption("Winter 2015", "sub-category/winter-2015-anime"), + SelectFilterOption("Fall 2014", "sub-category/fall-2014-anime"), + SelectFilterOption("Summer 2014", "sub-category/summer-2014-anime"), + SelectFilterOption("Spring 2014", "sub-category/spring-2014-anime"), + SelectFilterOption("Winter 2014", "sub-category/winter-2014-anime") + ]), + ]; + } +} + +GogoAnime main() { + return GogoAnime(); +} diff --git a/anime/src/en/gogoanime/source.dart b/anime/src/en/gogoanime/source.dart index f375e6b8..88ef15c7 100644 --- a/anime/src/en/gogoanime/source.dart +++ b/anime/src/en/gogoanime/source.dart @@ -2,12 +2,12 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get gogoanimeSource => _gogoanimeSource; -const gogoanimeVersion = "0.0.35"; +const gogoanimeVersion = "0.0.4"; const gogoanimeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/en/gogoanime/gogoanime-v$gogoanimeVersion.dart"; Source _gogoanimeSource = Source( name: "Gogoanime", - baseUrl: "https://gogoanime.tel", + baseUrl: "https://gogoanime3.net", lang: "en", typeSource: "single", iconUrl: getIconUrl("gogoanime", "en"), diff --git a/anime/src/en/kisskh/kisskh-v0.0.3.dart b/anime/src/en/kisskh/kisskh-v0.0.35.dart similarity index 97% rename from anime/src/en/kisskh/kisskh-v0.0.3.dart rename to anime/src/en/kisskh/kisskh-v0.0.35.dart index 2362f09c..8eadfa3f 100644 --- a/anime/src/en/kisskh/kisskh-v0.0.3.dart +++ b/anime/src/en/kisskh/kisskh-v0.0.35.dart @@ -57,7 +57,8 @@ class KissKh extends MProvider { } @override - Future search(MSource source, String query, int page) async { + Future search( + MSource source, String query, int page, FilterList filterList) async { final data = { "url": "${source.baseUrl}/api/DramaList/Search?q=$query&type=0" }; diff --git a/anime/src/en/kisskh/source.dart b/anime/src/en/kisskh/source.dart index 04801528..079ccc11 100644 --- a/anime/src/en/kisskh/source.dart +++ b/anime/src/en/kisskh/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get kisskhSource => _kisskhSource; -const kisskhVersion = "0.0.3"; +const kisskhVersion = "0.0.35"; const kisskhSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/en/kisskh/kisskh-v$kisskhVersion.dart"; Source _kisskhSource = Source( diff --git a/anime/src/fr/animesultra/animesultra-v0.0.35.dart b/anime/src/fr/animesultra/animesultra-v0.0.4.dart similarity index 98% rename from anime/src/fr/animesultra/animesultra-v0.0.35.dart rename to anime/src/fr/animesultra/animesultra-v0.0.4.dart index eff595f1..b4c3b89e 100644 --- a/anime/src/fr/animesultra/animesultra-v0.0.35.dart +++ b/anime/src/fr/animesultra/animesultra-v0.0.4.dart @@ -53,7 +53,8 @@ class AnimesUltra extends MProvider { } @override - Future search(MSource source, String query, int page) async { + Future search( + MSource source, String query, int page, FilterList filterList) async { final data = {"url": "${source.baseUrl}/"}; final res = await http('GET', json.encode(data)); diff --git a/anime/src/fr/animesultra/source.dart b/anime/src/fr/animesultra/source.dart index 9f6dd51a..d4c4d0cd 100644 --- a/anime/src/fr/animesultra/source.dart +++ b/anime/src/fr/animesultra/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get animesultraSource => _animesultraSource; -const animesultraVersion = "0.0.35"; +const animesultraVersion = "0.0.4"; const animesultraSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/fr/animesultra/animesultra-v$animesultraVersion.dart"; Source _animesultraSource = Source( diff --git a/anime/src/fr/franime/franime-v0.0.35.dart b/anime/src/fr/franime/franime-v0.0.4.dart similarity index 99% rename from anime/src/fr/franime/franime-v0.0.35.dart rename to anime/src/fr/franime/franime-v0.0.4.dart index 0174b04c..9aedeb81 100644 --- a/anime/src/fr/franime/franime-v0.0.35.dart +++ b/anime/src/fr/franime/franime-v0.0.4.dart @@ -24,7 +24,8 @@ class FrAnime extends MProvider { } @override - Future search(MSource source, String query, int page) async { + Future search( + MSource source, String query, int page, FilterList filterList) async { final res = await dataBase(); return animeSeachFetch(res, query); diff --git a/anime/src/fr/franime/source.dart b/anime/src/fr/franime/source.dart index a0030b38..0643414b 100644 --- a/anime/src/fr/franime/source.dart +++ b/anime/src/fr/franime/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get franimeSource => _franimeSource; -const franimeVersion = "0.0.35"; +const franimeVersion = "0.0.4"; const franimeSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/fr/franime/franime-v$franimeVersion.dart"; Source _franimeSource = Source( diff --git a/anime/src/fr/otakufr/otakufr-v0.0.35.dart b/anime/src/fr/otakufr/otakufr-v0.0.4.dart similarity index 98% rename from anime/src/fr/otakufr/otakufr-v0.0.35.dart rename to anime/src/fr/otakufr/otakufr-v0.0.4.dart index bf5853e8..5e0d0cc3 100644 --- a/anime/src/fr/otakufr/otakufr-v0.0.35.dart +++ b/anime/src/fr/otakufr/otakufr-v0.0.4.dart @@ -71,7 +71,8 @@ class OtakuFr extends MProvider { } @override - Future search(MSource source, String query, int page) async { + Future search( + MSource source, String query, int page, FilterList filterList) async { final data = { "url": "${source.baseUrl}/toute-la-liste-affiches/page/$page/?q=$query" }; diff --git a/anime/src/fr/otakufr/source.dart b/anime/src/fr/otakufr/source.dart index 5c45aca1..c9495929 100644 --- a/anime/src/fr/otakufr/source.dart +++ b/anime/src/fr/otakufr/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get otakufr => _otakufr; -const otakufrVersion = "0.0.35"; +const otakufrVersion = "0.0.4"; const otakufrCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/fr/otakufr/otakufr-v$otakufrVersion.dart"; Source _otakufr = Source( diff --git a/anime/src/id/nimegami/nimegami-v0.0.2.dart b/anime/src/id/nimegami/nimegami-v0.0.25.dart similarity index 98% rename from anime/src/id/nimegami/nimegami-v0.0.2.dart rename to anime/src/id/nimegami/nimegami-v0.0.25.dart index ebf36fbf..61bc269e 100644 --- a/anime/src/id/nimegami/nimegami-v0.0.2.dart +++ b/anime/src/id/nimegami/nimegami-v0.0.25.dart @@ -46,7 +46,8 @@ class NimeGami extends MProvider { } @override - Future search(MSource source, String query, int page) async { + Future search( + MSource source, String query, int page, FilterList filterList) async { final data = { "url": "${source.baseUrl}/page/$page/?s=$query&post_type=post" }; diff --git a/anime/src/id/nimegami/source.dart b/anime/src/id/nimegami/source.dart index 02224d21..afe74542 100644 --- a/anime/src/id/nimegami/source.dart +++ b/anime/src/id/nimegami/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get nimegami => _nimegami; -const nimegamiVersion = "0.0.2"; +const nimegamiVersion = "0.0.25"; const nimegamiCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/id/nimegami/nimegami-v$nimegamiVersion.dart"; Source _nimegami = Source( diff --git a/anime/src/id/oploverz/oploverz-v0.0.1.dart b/anime/src/id/oploverz/oploverz-v0.0.15.dart similarity index 93% rename from anime/src/id/oploverz/oploverz-v0.0.1.dart rename to anime/src/id/oploverz/oploverz-v0.0.15.dart index 4884749b..d2e00156 100644 --- a/anime/src/id/oploverz/oploverz-v0.0.1.dart +++ b/anime/src/id/oploverz/oploverz-v0.0.15.dart @@ -23,7 +23,8 @@ class OploVerz extends MProvider { } @override - Future search(MSource source, String query, int page) async { + Future search( + MSource source, String query, int page, FilterList filterList) async { final data = { "url": "${source.baseUrl}/anime-list/page/$page/?title=$query" }; @@ -95,15 +96,14 @@ class OploVerz extends MProvider { })); final playerLink = xpath(ress, '//iframe[@class="playeriframe"]/@src').first; - print(playerLink); final resPlayer = await http('GET', json.encode({"url": playerLink})); var resJson = substringBefore(substringAfter(resPlayer, "= "), "<"); - var streams = json.decode(resJson)["streams"] as List; + var streams = + json.decode(getMapValue(resJson, "streams", encode: true)) as List; List videos = []; for (var stream in streams) { - print(stream["play_url"]); - final videoUrl = stream["play_url"]; - final quality = getQuality(stream["format_id"]); + final videoUrl = getMapValue(stream, "play_url"); + final quality = getQuality(getMapValue(stream, "format_id")); MVideo video = MVideo(); video diff --git a/anime/src/id/oploverz/source.dart b/anime/src/id/oploverz/source.dart index 8a43fbd3..8b184b9e 100644 --- a/anime/src/id/oploverz/source.dart +++ b/anime/src/id/oploverz/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get oploverz => _oploverz; -const oploverzVersion = "0.0.1"; +const oploverzVersion = "0.0.15"; const oploverzCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/id/oploverz/oploverz-v$oploverzVersion.dart"; Source _oploverz = Source( diff --git a/anime/src/id/otakudesu/otakudesu-v0.0.2.dart b/anime/src/id/otakudesu/otakudesu-v0.0.25.dart similarity index 98% rename from anime/src/id/otakudesu/otakudesu-v0.0.2.dart rename to anime/src/id/otakudesu/otakudesu-v0.0.25.dart index 3e811601..66e36dc8 100644 --- a/anime/src/id/otakudesu/otakudesu-v0.0.2.dart +++ b/anime/src/id/otakudesu/otakudesu-v0.0.25.dart @@ -19,7 +19,8 @@ class OtakuDesu extends MProvider { } @override - Future search(MSource source, String query, int page) async { + Future search( + MSource source, String query, int page, FilterList filterList) async { final data = {"url": "${source.baseUrl}/?s=$query&post_type=anime"}; final res = await http('GET', json.encode(data)); List animeList = []; diff --git a/anime/src/id/otakudesu/source.dart b/anime/src/id/otakudesu/source.dart index 7c47291a..4c30ad29 100644 --- a/anime/src/id/otakudesu/source.dart +++ b/anime/src/id/otakudesu/source.dart @@ -2,7 +2,7 @@ import '../../../../model/source.dart'; import '../../../../utils/utils.dart'; Source get otakudesu => _otakudesu; -const otakudesuVersion = "0.0.2"; +const otakudesuVersion = "0.0.25"; const otakudesuCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/id/otakudesu/otakudesu-v$otakudesuVersion.dart"; Source _otakudesu = Source( diff --git a/manga/multisrc/nepnep/nepnep-v0.0.4.dart b/manga/multisrc/nepnep/nepnep-v0.0.4.dart index 4e203c1b..524dd4aa 100644 --- a/manga/multisrc/nepnep/nepnep-v0.0.4.dart +++ b/manga/multisrc/nepnep/nepnep-v0.0.4.dart @@ -60,39 +60,39 @@ class NepNep extends MProvider { if (filter.type == "ScanStatusFilter") { if (filter.state != 0) { queryRes = queryRes.where((e) { - final name = getMapValue(json.encode(e), 'ss'); - return name.toLowerCase().contains( + final value = getMapValue(json.encode(e), 'ss'); + return value.toLowerCase().contains( (filter.values[filter.state].value as String).toLowerCase()); }).toList(); } } else if (filter.type == "PublishStatusFilter") { if (filter.state != 0) { queryRes = queryRes.where((e) { - final name = getMapValue(json.encode(e), 'ps'); - return name.toLowerCase().contains( + final value = getMapValue(json.encode(e), 'ps'); + return value.toLowerCase().contains( (filter.values[filter.state].value as String).toLowerCase()); }).toList(); } } else if (filter.type == "TypeFilter") { if (filter.state != 0) { queryRes = queryRes.where((e) { - final name = getMapValue(json.encode(e), 't'); - return name.toLowerCase().contains( + final value = getMapValue(json.encode(e), 't'); + return value.toLowerCase().contains( (filter.values[filter.state].value as String).toLowerCase()); }).toList(); } } else if (filter.type == "TranslationFilter") { if (filter.state != 0) { queryRes = queryRes.where((e) { - final name = getMapValue(json.encode(e), 'o'); - return name.toLowerCase().contains("yes"); + final value = getMapValue(json.encode(e), 'o'); + return value.toLowerCase().contains("yes"); }).toList(); } } else if (filter.type == "YearFilter") { if (filter.state.isNotEmpty) { queryRes = queryRes.where((e) { - final name = getMapValue(json.encode(e), 'y'); - return name + final value = getMapValue(json.encode(e), 'y'); + return value .toLowerCase() .contains((filter.name as String).toLowerCase()); }).toList(); @@ -100,8 +100,8 @@ class NepNep extends MProvider { } else if (filter.type == "AuthorFilter") { if (filter.state.isNotEmpty) { queryRes = queryRes.where((e) { - final name = getMapValue(json.encode(e), 'a'); - return name + final value = getMapValue(json.encode(e), 'a'); + return value .toLowerCase() .contains((filter.name as String).toLowerCase()); }).toList(); @@ -116,8 +116,8 @@ class NepNep extends MProvider { if (included.isNotEmpty) { for (var val in included) { queryRes = queryRes.where((e) { - final name = getMapValue(json.encode(e), 'g'); - return name + final value = getMapValue(json.encode(e), 'g'); + return value .toLowerCase() .contains((val.value as String).toLowerCase()); }).toList(); @@ -126,8 +126,8 @@ class NepNep extends MProvider { if (excluded.isNotEmpty) { for (var val in excluded) { queryRes = queryRes.where((e) { - final name = getMapValue(json.encode(e), 'g'); - return !(name + final value = getMapValue(json.encode(e), 'g'); + return !(value .toLowerCase() .contains((val.value as String).toLowerCase())); }).toList();