From bb0449b7ce9b2981373982f1129a2bd9aab50068 Mon Sep 17 00:00:00 2001 From: Needye Date: Thu, 26 Sep 2024 01:37:05 +0200 Subject: [PATCH 1/2] Add AniZone Source --- dart/anime/src/fr/AniZone/AniZone.dart | 479 +++++++++++++++++++++++++ dart/anime/src/fr/AniZone/icon.png | Bin 0 -> 26313 bytes dart/anime/src/fr/AniZone/source.dart | 16 + 3 files changed, 495 insertions(+) create mode 100644 dart/anime/src/fr/AniZone/AniZone.dart create mode 100644 dart/anime/src/fr/AniZone/icon.png create mode 100644 dart/anime/src/fr/AniZone/source.dart diff --git a/dart/anime/src/fr/AniZone/AniZone.dart b/dart/anime/src/fr/AniZone/AniZone.dart new file mode 100644 index 00000000..d2ff08df --- /dev/null +++ b/dart/anime/src/fr/AniZone/AniZone.dart @@ -0,0 +1,479 @@ +import 'package:mangayomi/bridge_lib.dart'; +import 'dart:convert'; + +class AniZone extends MProvider { + AniZone({required this.source}); + + final MSource source; + final Client client = Client(source); + + @override + bool get supportsLatest => true; + + @override + Map get headers => {}; + + // Constants for the xpath + static const String urlXpath = + '//*[contains(@class,"flw-item item-qtip")]/div[@class="film-poster"]/a/@href'; + static const String nameXpath = + '//*[contains(@class,"flw-item item-qtip")]/div[@class="film-detail"]/h3/text()'; + static const String imageXpath = + '//*[contains(@class,"flw-item item-qtip")]/div[@class="film-poster"]/img/@data-src'; + + // Methods for fetching the manga list (popular, latest & search) + Future _getMangaList(String url) async { + final doc = (await client.get(Uri.parse(url))).body; + List animeList = []; + + final urls = xpath(doc, urlXpath); + final names = xpath(doc, nameXpath); + final images = xpath(doc, imageXpath); + + if (urls.isEmpty || names.isEmpty || images.isEmpty) { + return MPages([], false); + } + + 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, urls.isNotEmpty); + } + + @override + Future getPopular(int page) async { + return _getMangaList("${source.baseUrl}/most-popular/?page=$page"); + } + + @override + Future getLatestUpdates(int page) async { + return _getMangaList("${source.baseUrl}/recently-added/?page=$page"); + } + + @override + Future search(String query, int page, FilterList filterList) async { + List animeList = []; + String baseUrl = "${source.baseUrl}/filter?keyword=$query"; + + Map> filterMap = { + "type": [], + "status": [], + "season": [], + "lang": [], + "genre": [] + }; + + // Regroupement des filtres avec une logique générique + final filterHandlers = { + "TypeFilter": "type", + "LanguageFilter": "lang", + "SaisonFilter": "season", + "StatusFilter": "status", + "GenreFilter": "genre" + }; + + for (var filter in filterList.filters) { + if (filterHandlers.containsKey(filter.type)) { + var key = filterHandlers[filter.type]!; + for (var stateItem in filter.state as List) { + if (stateItem.state == true) { + filterMap[key]?.add(stateItem.value as String); + } + } + } + } + + //add filters to the url dynamically + for (var entry in filterMap.entries) { + List values = entry.value; + if (values.isNotEmpty) { + baseUrl += '&${entry.key}=${values.join("%2C")}'; + } + } + + return _getMangaList("$baseUrl&page=$page"); + } + + Future getDetail(String url) async { + MManga anime = MManga(); + try { + final doc = (await client.get(Uri.parse(url))).body; + final description = xpath(doc, '//p[contains(@class,"short")]/text()'); + anime.description = description.isNotEmpty ? description.first : ""; + + final statusList = xpath(doc, + '//div[contains(@class,"col2")]//div[contains(@class,"item")]//div[contains(@class,"item-content")]/text()'); + if (statusList.isNotEmpty) { + if (statusList[0] == "Terminer") { + anime.status = MStatus.completed; + } else if (statusList[0] == "En cours") { + anime.status = MStatus.ongoing; + } else { + anime.status = MStatus.unknown; + } + } else { + anime.status = MStatus.unknown; + } + + anime.genre = xpath(doc, + '//div[contains(@class,"item")]//div[contains(@class,"item-content")]//a[contains(@href,"genre")]/text()'); + + final regex = RegExp(r'(\d+)$'); + final match = regex.firstMatch(url); + + if (match == null) { + throw Exception('Numéro de l\'épisode non trouvé dans l\'URL.'); + } + + final res = (await client.get(Uri.parse( + "${source.baseUrl}/ajax/episode/list/${match.group(1)}"))) + .body; + + final titles = xpath(res.replaceAll(r'\', ' '), + '//div[contains(@class,"ss-list")]//a/@title'); + final urls = xpath(res.replaceAll(r'\', ' '), + '//div[contains(@class,"ss-list")]//a/@href'); + + List episodesList = []; + + // Associer chaque titre à son URL et récupérer les vidéos + for (int i = 0; i < titles.length; i++) { + MChapter episode = MChapter(); + episode.name = titles[i]; + + List> videoList = []; + + final videoMatch = regex.firstMatch(urls[i]); + if (videoMatch == null) { + throw Exception( + 'Numéro de l\'épisode non trouvé dans l\'URL pour les vidéos.'); + } + + final videoRes = (await client.get( + Uri.parse( + "${source.baseUrl}/ajax/episode/servers?episodeId=${videoMatch.group(1)}"), + headers: {'Referer': "${source.baseUrl}/${urls[i]}"}, + )) + .body; + + final lang = xpath(videoRes.replaceAll(r'\', ''), + '//div[contains(@class,"item server-item")]/@data-type'); + final links = xpath(videoRes.replaceAll(r'\', ''), + '//div[contains(@class,"item server-item")]/@data-id'); + final name_players = xpath(videoRes.replaceAll(r'\', ''), + '//div[contains(@class,"item server-item")]/text()'); + + for (int j = 0; j < links.length; j++) { + // schema of players https://v1.animesz.xyz/ajax/episode/servers?episodeId=(id_episode) + // schema or url https://v1.animesz.xyz/ajax/episode/sources?id=(player_id)&epid=(id_episode) + if (name_players.isNotEmpty && name_players[j] == "sibnet") { + final playerUrl = + "https://video.sibnet.ru/shell.php?videoid=${links[j]}"; + videoList.add({"lang": lang[j], "player": playerUrl}); + } else if (name_players.isNotEmpty && name_players[j] == "sendvid") { + final playerUrl = "https://sendvid.com/embed/${links[j]}"; + videoList.add({"lang": lang[j], "player": playerUrl}); + } else if (name_players.isNotEmpty && name_players[j] == "VidCDN") { + final playerUrl = + "https://r.vidcdn.xyz/v1/api/get_sources/${links[j].replaceFirst(RegExp(r'vidcdn$'), '')}"; + videoList.add({"lang": lang[j], "player": playerUrl}); + } else if (name_players.isNotEmpty && name_players[j] == "Voe") { + final playerUrl = "https://voe.sx/e/${links[j]}"; + videoList.add({"lang": lang[j], "player": playerUrl}); + } else if (name_players.isNotEmpty && name_players[j] == "Fmoon") { + final playerUrl = "https://filemoon.sx/e/${links[j]}&data-realid=${links[j]}&epid=${videoMatch.group(1)}"; + videoList.add({"lang": lang[j], "player": playerUrl}); + } + } + episode.url = json.encode(videoList); + episodesList.add(episode); + } + + anime.chapters = episodesList.reversed.toList(); + + return anime; + } catch (e) { + throw Exception('Erreur lors de la récupération des détails: $e'); + } + } + + @override + Future> getVideoList(String url) async { + final players = json.decode(url); + List videos = []; + for (var player in players) { + String lang = (player["lang"] as String).toUpperCase(); + String playerUrl = player["player"]; + List a = []; + if (playerUrl.contains("sendvid")) { + a = await sendVidExtractorr(playerUrl, "$lang "); + } else if (playerUrl.contains("sibnet.ru")) { + a = await sibnetExtractor(playerUrl, lang); + } else if (playerUrl.contains("voe.sx")) { + a = await voeExtractor(playerUrl, lang); + } else if (playerUrl.contains("vidcdn")) { + a = await vidcdnExtractor(playerUrl, lang); + } else if (playerUrl.contains("filemoon")) { + a = await filemoonExtractor(playerUrl, lang,""); + } + videos.addAll(a); + } + + return sortVideos(videos, source.id); + } + + @override + Future> getPageList(String url) async { + // TODO: implement + } + + @override + List getFilterList() { + return [ + GroupFilter("TypeFilter", "Type", [ + CheckBoxFilter("Film", "1"), + CheckBoxFilter("Anime", "2"), + CheckBoxFilter("OVA", "3"), + CheckBoxFilter("ONA", "4"), + CheckBoxFilter("Special", "5"), + CheckBoxFilter("Music", "6"), + ]), + GroupFilter("LanguageFilter", "Langue", [ + CheckBoxFilter("VF", "3"), + CheckBoxFilter("VOSTFR", "4"), + CheckBoxFilter("Multicc", "2"), + CheckBoxFilter("EN", "1"), + ]), + GroupFilter("SaisonFilter", "Saison", [ + CheckBoxFilter("Printemps", "1"), + CheckBoxFilter("Été", "2"), + CheckBoxFilter("Automne", "3"), + CheckBoxFilter("Hiver", "4"), + ]), + GroupFilter("StatusFilter", "Statut", [ + CheckBoxFilter("Terminés", "1"), + CheckBoxFilter("En cours", "2"), + CheckBoxFilter("Pas encore diffusés", "3"), + ]), + GroupFilter("GenreFilter", "Genre", [ + CheckBoxFilter("Action", "1"), + CheckBoxFilter("Aventure", "2"), + CheckBoxFilter("Voitures", "3"), + CheckBoxFilter("Comédie", "4"), + CheckBoxFilter("Démence", "5"), + CheckBoxFilter("Démons", "6"), + CheckBoxFilter("Drame", "8"), + CheckBoxFilter("Ecchi", "9"), + CheckBoxFilter("Fantastique", "10"), + CheckBoxFilter("Jeu", "11"), + CheckBoxFilter("Harem", "35"), + CheckBoxFilter("Historique", "13"), + CheckBoxFilter("Horreur", "14"), + CheckBoxFilter("Isekai", "44"), + CheckBoxFilter("Josei", "43"), + CheckBoxFilter("Enfants", "25"), + CheckBoxFilter("Magie", "16"), + CheckBoxFilter("Arts martiaux", "17"), + CheckBoxFilter("Mecha", "18"), + CheckBoxFilter("Militaire", "38"), + CheckBoxFilter("Musique", "19"), + CheckBoxFilter("Mystère", "7"), + CheckBoxFilter("Parodie", "20"), + CheckBoxFilter("Police", "39"), + CheckBoxFilter("Psychologique", "40"), + CheckBoxFilter("Romance", "22"), + CheckBoxFilter("Samouraï", "21"), + CheckBoxFilter("École", "23"), + CheckBoxFilter("Science-Fiction", "24"), + CheckBoxFilter("Seinen", "42"), + CheckBoxFilter("Shoujo Ai", "26"), + CheckBoxFilter("Shoujo", "25"), + CheckBoxFilter("Shounen Ai", "28"), + CheckBoxFilter("Tranche de vie", "36"), + CheckBoxFilter("Shounen", "27"), + CheckBoxFilter("Espace", "29"), + CheckBoxFilter("Sports", "30"), + CheckBoxFilter("Super Pouvoir", "31"), + CheckBoxFilter("Surnaturel", "37"), + CheckBoxFilter("Vampire", "32"), + CheckBoxFilter("Yaoi", "33"), + CheckBoxFilter("Yuri", "34"), + ]) + ]; + } + + @override + List getSourcePreferences() { + return [ + ListPreference( + key: "preferred_quality", + title: "Qualité préférée", + summary: "", + valueIndex: 0, + entries: ["1080p", "720p", "480p", "360p"], + entryValues: ["1080", "720", "480", "360"]), + ListPreference( + key: "voices_preference", + title: "Préférence des voix", + summary: "", + valueIndex: 0, + entries: ["Préférer VOSTFR", "Préférer VF"], + entryValues: ["vostfr", "vf"]), + ]; + } + + List sortVideos(List videos, int sourceId) { + String quality = getPreferenceValue(sourceId, "preferred_quality"); + String voice = getPreferenceValue(sourceId, "voices_preference"); + + videos.sort((MVideo a, MVideo b) { + int qualityMatchA = 0; + if (a.quality.contains(quality) && + a.quality.toLowerCase().contains(voice)) { + qualityMatchA = 1; + } + int qualityMatchB = 0; + if (b.quality.contains(quality) && + b.quality.toLowerCase().contains(voice)) { + 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; + } + + Future> sendVidExtractorr(String url, String prefix) async { + final res = (await client.get(Uri.parse(url))).body; + final document = parseHtml(res); + final masterUrl = document.selectFirst("source#video_source")?.attr("src"); + print(masterUrl); + if (masterUrl == null) return []; + final masterHeaders = { + "Accept": "*/*", + "Host": Uri.parse(masterUrl).host, + "Origin": "https://${Uri.parse(url).host}", + "Referer": "https://${Uri.parse(url).host}/", + }; + List videos = []; + if (masterUrl.contains(".m3u8")) { + final masterPlaylistRes = (await client.get(Uri.parse(masterUrl))).body; + + for (var it in substringAfter(masterPlaylistRes, "#EXT-X-STREAM-INF:") + .split("#EXT-X-STREAM-INF:")) { + final quality = + "${substringBefore(substringBefore(substringAfter(substringAfter(it, "RESOLUTION="), "x"), ","), "\n")}p"; + + String videoUrl = substringBefore(substringAfter(it, "\n"), "\n"); + + if (!videoUrl.startsWith("http")) { + videoUrl = + "${masterUrl.split("/").sublist(0, masterUrl.split("/").length - 1).join("/")}/$videoUrl"; + } + final videoHeaders = { + "Accept": "*/*", + "Host": Uri.parse(videoUrl).host, + "Origin": "https://${Uri.parse(url).host}", + "Referer": "https://${Uri.parse(url).host}/", + }; + var video = MVideo(); + video + ..url = videoUrl + ..originalUrl = videoUrl + ..quality = prefix + "Sendvid:$quality" + ..headers = videoHeaders; + videos.add(video); + } + } else { + var video = MVideo(); + video + ..url = masterUrl + ..originalUrl = masterUrl + ..quality = prefix + "Sendvid:default" + ..headers = masterHeaders; + videos.add(video); + } + + return videos; + } + + Future> vidcdnExtractor(String url, String prefix) async { + final res = await client.get(Uri.parse(url)); + if (res.statusCode != 200) { + print("Erreur lors de la récupération de la page : ${res.statusCode}"); + return []; + } + final jsonResponse = jsonDecode(res.body); + + String masterUrl = jsonResponse['sources'][0]['file'] ?? ''; + final quality = jsonResponse['quality'] ?? ''; + + List videos = []; + + final masterPlaylistRes = await client.get(Uri.parse(masterUrl)); + if (masterPlaylistRes.statusCode != 200) { + print( + "Error lors de la récupération de la playlist M3U8 : ${masterPlaylistRes.statusCode}"); + return []; + } + + final masterPlaylistBody = masterPlaylistRes.body; + + final playlistLines = masterPlaylistBody.split("\n"); + + for (int i = 0; i < playlistLines.length; i++) { + final line = playlistLines[i]; + if (line.startsWith("#EXT-X-STREAM-INF")) { + final resolutionLine = line.split("RESOLUTION=").last; + final resolution = resolutionLine.split(",").first; + final width = int.parse(resolution.split("x").first); + final height = int.parse(resolution.split("x").last); + + String videoQuality; + if (height >= 1080) { + videoQuality = "1080p"; + } else if (height >= 720) { + videoQuality = "720p"; + } else if (height >= 480) { + videoQuality = "480p"; + } else if (height >= 360) { + videoQuality = "360p"; + } else { + videoQuality = "${height}p"; + } + + String videoUrl = playlistLines[i + 1].trim(); + + if (!videoUrl.startsWith("http")) { + videoUrl = + "${masterUrl.substring(0, masterUrl.lastIndexOf('/'))}/$videoUrl"; + } + + var video = MVideo(); + video + ..url = masterUrl + ..originalUrl = masterUrl + ..quality = "$prefix VidCDN:$videoQuality"; + videos.add(video); + } + } + return videos; + } +} + +AniZone main(MSource source) { + return AniZone(source: source); +} diff --git a/dart/anime/src/fr/AniZone/icon.png b/dart/anime/src/fr/AniZone/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..32debc92558373dd9fbcca5cd9fdddbf7e413c9a GIT binary patch literal 26313 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 _AniZoneSource; +const _AniZoneVersion = "0.0.1"; +const _AniZoneSourceCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/AniZone/AniZone.dart"; +Source _AniZoneSource = Source( + name: "AniZone", + baseUrl: "https://v1.animesz.xyz", + lang: "fr", + typeSource: "single", + iconUrl: + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/AniZone/icon.png", + sourceCodeUrl: _AniZoneSourceCodeUrl, + version: _AniZoneVersion, + isManga: false); \ No newline at end of file From 13839b5ef65444ed2ba8b60d233e1a23a32f2962 Mon Sep 17 00:00:00 2001 From: kodjomoustapha <101261721+kodjomoustapha@users.noreply.github.com> Date: Thu, 26 Sep 2024 09:18:49 +0100 Subject: [PATCH 2/2] fix --- dart/anime/anime_source_list.dart | 3 ++- dart/anime/src/fr/AniZone/AniZone.dart | 6 +++--- dart/anime/src/fr/AniZone/source.dart | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/dart/anime/anime_source_list.dart b/dart/anime/anime_source_list.dart index e582dc61..df2b238f 100644 --- a/dart/anime/anime_source_list.dart +++ b/dart/anime/anime_source_list.dart @@ -10,6 +10,7 @@ import 'src/en/animepahe/source.dart'; import 'src/en/dramacool/source.dart'; import 'src/en/gogoanime/source.dart'; import 'src/en/nineanimetv/source.dart'; +import 'src/fr/anizone/source.dart'; import 'src/fr/animesama/source.dart'; import 'src/hi/yomovies/source.dart'; import 'src/en/kisskh/source.dart'; @@ -50,5 +51,5 @@ List dartAnimesourceList = [ animepaheSource, animetoast, animesvision, - diziwatchSource + diziwatchSource,aniZoneSource ]; diff --git a/dart/anime/src/fr/AniZone/AniZone.dart b/dart/anime/src/fr/AniZone/AniZone.dart index d2ff08df..ed9e4377 100644 --- a/dart/anime/src/fr/AniZone/AniZone.dart +++ b/dart/anime/src/fr/AniZone/AniZone.dart @@ -57,7 +57,6 @@ class AniZone extends MProvider { @override Future search(String query, int page, FilterList filterList) async { - List animeList = []; String baseUrl = "${source.baseUrl}/filter?keyword=$query"; Map> filterMap = { @@ -186,7 +185,8 @@ class AniZone extends MProvider { final playerUrl = "https://voe.sx/e/${links[j]}"; videoList.add({"lang": lang[j], "player": playerUrl}); } else if (name_players.isNotEmpty && name_players[j] == "Fmoon") { - final playerUrl = "https://filemoon.sx/e/${links[j]}&data-realid=${links[j]}&epid=${videoMatch.group(1)}"; + final playerUrl = + "https://filemoon.sx/e/${links[j]}&data-realid=${links[j]}&epid=${videoMatch.group(1)}"; videoList.add({"lang": lang[j], "player": playerUrl}); } } @@ -219,7 +219,7 @@ class AniZone extends MProvider { } else if (playerUrl.contains("vidcdn")) { a = await vidcdnExtractor(playerUrl, lang); } else if (playerUrl.contains("filemoon")) { - a = await filemoonExtractor(playerUrl, lang,""); + a = await filemoonExtractor(playerUrl, lang, ""); } videos.addAll(a); } diff --git a/dart/anime/src/fr/AniZone/source.dart b/dart/anime/src/fr/AniZone/source.dart index bee5066b..482f6e2a 100644 --- a/dart/anime/src/fr/AniZone/source.dart +++ b/dart/anime/src/fr/AniZone/source.dart @@ -1,16 +1,16 @@ import '../../../../../model/source.dart'; -Source get _AniZoneSource => _AniZoneSource; -const _AniZoneVersion = "0.0.1"; -const _AniZoneSourceCodeUrl = - "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/AniZone/AniZone.dart"; -Source _AniZoneSource = Source( - name: "AniZone", +Source get aniZoneSource => _aniZoneSource; +const _aniZoneVersion = "0.0.1"; +const _aniZoneSourceCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/anizone.dart"; +Source _aniZoneSource = Source( + name: "aniZone", baseUrl: "https://v1.animesz.xyz", lang: "fr", typeSource: "single", iconUrl: - "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/AniZone/icon.png", - sourceCodeUrl: _AniZoneSourceCodeUrl, - version: _AniZoneVersion, - isManga: false); \ No newline at end of file + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/fr/anizone/icon.png", + sourceCodeUrl: _aniZoneSourceCodeUrl, + version: _aniZoneVersion, + isManga: false);