From e00fef7c78c3deebc2ffa418b0d089248f1d3c63 Mon Sep 17 00:00:00 2001 From: kodjomoustapha <107993382+kodjodevf@users.noreply.github.com> Date: Tue, 1 Aug 2023 22:51:04 +0100 Subject: [PATCH] new source : otakufr (FR) --- anime/src/fr/otakufr/otakufr-v0.0.1.dart | 226 +++++++++++++++++++++++ anime/src/fr/otakufr/source.dart | 16 ++ 2 files changed, 242 insertions(+) create mode 100644 anime/src/fr/otakufr/otakufr-v0.0.1.dart create mode 100644 anime/src/fr/otakufr/source.dart diff --git a/anime/src/fr/otakufr/otakufr-v0.0.1.dart b/anime/src/fr/otakufr/otakufr-v0.0.1.dart new file mode 100644 index 00000000..92d21bac --- /dev/null +++ b/anime/src/fr/otakufr/otakufr-v0.0.1.dart @@ -0,0 +1,226 @@ +import 'dart:convert'; +import 'package:bridge_lib/bridge_lib.dart'; + +getPopularAnime(MangaModel anime) async { + final data = { + "url": "${anime.baseUrl}/toute-la-liste-affiches/page/${anime.page}/?q=.", + "headers": null, + "sourceId": anime.sourceId + }; + final res = await MBridge.http(json.encode(data), 0); + if (res.isEmpty) { + return anime; + } + + anime.urls = MBridge.xpath( + res, '//*[@class="list"]/article/div/div/figure/a/@href', '._') + .split('._'); + + anime.names = MBridge.xpath( + res, '//*[@class="list"]/article/div/div/figure/a/img/@title', '._') + .split('._'); + anime.images = MBridge.xpath( + res, '//*[@class="list"]/article/div/div/figure/a/img/@src', '._') + .split('._'); + final nextPage = MBridge.xpath(res, '//a[@class="next page-link"]/@href', ''); + if (nextPage.isEmpty) { + anime.hasNextPage = false; + } else { + anime.hasNextPage = true; + } + return anime; +} + +getLatestUpdatesAnime(MangaModel anime) async { + final data = { + "url": "${anime.baseUrl}/page/${anime.page}/", + "headers": null, + "sourceId": anime.sourceId + }; + final res = await MBridge.http(json.encode(data), 0); + if (res.isEmpty) { + return anime; + } + + anime.urls = + MBridge.xpath(res, '//*[@class="episode"]/div/a/@href', '._').split('._'); + List namess = + MBridge.xpath(res, '//*[@class="episode"]/div/a/text()', '._') + .split('._'); + List names = []; + for (var name in MBridge.listParse(namess, 0)) { + names.add(MBridge.regExp( + name, + r'(?<=\bS\d\s*|)\d{2}\s*(?=\b(Vostfr|vostfr|VF|Vf|vf|\(VF\)|\(vf\)|\(Vf\)|\(Vostfr\)\b))?', + '', + 0, + 0) + .replaceAll(' vostfr', '') + .replaceAll(' Vostfr', '') + .replaceAll(' VF', '') + .replaceAll(' Vf', '') + .replaceAll(' vf', '') + .replaceAll(' (VF)', '') + .replaceAll(' (vf)', '') + .replaceAll(' (vf)', '') + .replaceAll(' (Vf)', '') + .replaceAll(' (Vostfr)', '')); + } + anime.names = names; + anime.images = + MBridge.xpath(res, '//*[@class="episode"]/div/figure/a/img/@src', '._') + .split('._'); + final nextPage = MBridge.xpath(res, '//a[@class="next page-link"]/@href', ''); + if (nextPage.isEmpty) { + anime.hasNextPage = false; + } else { + anime.hasNextPage = true; + } + return anime; +} + +getAnimeDetail(MangaModel anime) async { + final statusList = [ + { + "En cours": 0, + "Terminé": 1, + } + ]; + final url = anime.link; + final data = {"url": url, "headers": null}; + String res = await MBridge.http(json.encode(data), 0); + if (res.isEmpty) { + return anime; + } + + final originalUrl = MBridge.xpath(res, + '//*[@class="breadcrumb"]/li[@class="breadcrumb-item"][2]/a/@href', ''); + if (originalUrl.isEmpty) { + } else { + final newData = {"url": originalUrl, "headers": null}; + res = await MBridge.http(json.encode(newData), 0); + if (res.isEmpty) { + return anime; + } + } + anime.description = + MBridge.xpath(res, '//*[@class="episode fz-sm synop"]/p/text()', '') + .replaceAll("Synopsis:", ""); + final status = MBridge.xpath( + res, + '//*[@class="list-unstyled"]/li[contains(text(),"Statut")]/text()', + '') + .replaceAll("Statut: ", ""); + anime.status = MBridge.parseStatus(status, statusList); + anime.genre = MBridge.xpath( + res, + '//*[@class="list-unstyled"]/li[contains(text(),"Genre")]/ul/li/a/text()', + '._') + .split('._'); + + anime.urls = + MBridge.xpath(res, '//*[@class="list-episodes list-group"]/a/@href', '._') + .split("._"); + List dates = MBridge.xpath( + res, '//*[@class="list-episodes list-group"]/a/span/text()', '._') + .split("._"); + List names = MBridge.xpath( + res, '//*[@class="list-episodes list-group"]/a/text()', '._') + .split("._"); + + List episodes = []; + for (var i = 0; i < names.length; i++) { + final date = MBridge.listParse(dates, 0)[i]; + final name = MBridge.listParse(names, 0)[i]; + episodes.add( + "Episode ${MBridge.regExp(name.replaceAll(date, ""), r".* (\d*) [VvfF]{1,1}", '', 1, 1)}"); + } + print(episodes); + anime.names = episodes; + anime.chaptersDateUploads = MBridge.listParse( + MBridge.listParseDateTime(dates, "dd MMMM yyyy", "fr"), 0); + return anime; +} + +searchAnime(MangaModel anime) async { + final data = { + "url": + "${anime.baseUrl}/toute-la-liste-affiches/page/${anime.page}/?q=${anime.query}", + "headers": null, + "sourceId": anime.sourceId + }; + final res = await MBridge.http(json.encode(data), 0); + if (res.isEmpty) { + return anime; + } + + anime.urls = MBridge.xpath( + res, '//*[@class="list"]/article/div/div/figure/a/@href', '._') + .split('._'); + + anime.names = MBridge.xpath( + res, '//*[@class="list"]/article/div/div/figure/a/img/@title', '._') + .split('._'); + anime.images = MBridge.xpath( + res, '//*[@class="list"]/article/div/div/figure/a/img/@src', '._') + .split('._'); + final nextPage = MBridge.xpath(res, '//a[@class="next page-link"]/@href', ''); + if (nextPage.isEmpty) { + anime.hasNextPage = false; + } else { + anime.hasNextPage = true; + } + return anime; +} + +getVideoList(MangaModel anime) async { + final datas = { + "url": anime.link, + "headers": null, + "sourceId": anime.sourceId + }; + + final res = await MBridge.http(json.encode(datas), 0); + + if (res.isEmpty) { + return []; + } + final servers = + MBridge.xpath(res, '//*[@id="nav-tabContent"]/div/iframe/@src', ".-") + .split(".-"); + List videos = []; + for (var url in MBridge.listParse(servers, 0)) { + final datasServer = { + "url": fixUrl(url), + "headers": {"X-Requested-With": "XMLHttpRequest"}, + "sourceId": anime.sourceId + }; + + final resServer = await MBridge.http(json.encode(datasServer), 0); + final serverUrl = + fixUrl(MBridge.regExp(resServer, r"data-url='([^']+)'", '', 1, 1)); + List a = []; + if (serverUrl.contains("https://streamwish")) { + a = await MBridge.streamWishExtractor(serverUrl, "StreamWish"); + } else if (serverUrl.contains("sibnet")) { + a = await MBridge.sibnetExtractor(serverUrl); + } else if (serverUrl.contains("dooood")) { + a = await MBridge.doodExtractor(serverUrl); + } else if (serverUrl.contains("https://voe.sx")) { + a = await MBridge.voeExtractor(serverUrl, null); + } else if (serverUrl.contains("https://ok.ru")) { + a = await MBridge.okruExtractor( + serverUrl, + ); + } + for (var vi in a) { + videos.add(vi); + } + } + + return videos; +} + +String fixUrl(String url) { + return MBridge.regExp(url, r"^(?:(?:https?:)?//|www\.)", 'https://', 0, 0); +} diff --git a/anime/src/fr/otakufr/source.dart b/anime/src/fr/otakufr/source.dart new file mode 100644 index 00000000..8dde2bff --- /dev/null +++ b/anime/src/fr/otakufr/source.dart @@ -0,0 +1,16 @@ +import '../../../../model/source.dart'; + +Source get otakufr => _otakufr; +const otakufrVersion = "0.0.13"; +const otakufrCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/anime/src/fr/otakufr/otakufr-v$otakufrVersion.dart"; +Source _otakufr = Source( + name: "otakufr", + baseUrl: "https://otakufr.co", + lang: "fr", + typeSource: "single", + iconUrl: '', + sourceCodeUrl: otakufrCodeUrl, + version: otakufrVersion, + isManga: false, + isFullData: false);