From ced337481fc1adb236bc9581e4c32e8bd323b333 Mon Sep 17 00:00:00 2001 From: kodjomoustapha <107993382+kodjodevf@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:27:47 +0100 Subject: [PATCH] New source: AnimeToast (DE) --- anime/source_generator.dart | 4 +- anime/src/de/animetoast/animetoast.dart | 234 ++++++++++++++++++++++++ anime/src/de/animetoast/icon.png | Bin 0 -> 5171 bytes anime/src/de/animetoast/source.dart | 16 ++ 4 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 anime/src/de/animetoast/animetoast.dart create mode 100644 anime/src/de/animetoast/icon.png create mode 100644 anime/src/de/animetoast/source.dart diff --git a/anime/source_generator.dart b/anime/source_generator.dart index 386735ff..521a8e25 100644 --- a/anime/source_generator.dart +++ b/anime/source_generator.dart @@ -10,6 +10,7 @@ import 'src/all/nyaa/source.dart'; import 'src/all/yomiroll/source.dart'; import 'src/ar/okanime/source.dart'; import 'src/de/aniflix/source.dart'; +import 'src/de/animetoast/source.dart'; import 'src/en/animepahe/source.dart'; import 'src/en/aniwave/source.dart'; import 'src/en/dramacool/source.dart'; @@ -54,7 +55,8 @@ void main() { ...animeworldindiaSourcesList, nyaaSource, yomirollSource, - animepaheSource + animepaheSource, + animetoast ]; final List> jsonList = _sourcesList.map((source) => source.toJson()).toList(); diff --git a/anime/src/de/animetoast/animetoast.dart b/anime/src/de/animetoast/animetoast.dart new file mode 100644 index 00000000..0be52f54 --- /dev/null +++ b/anime/src/de/animetoast/animetoast.dart @@ -0,0 +1,234 @@ +import 'package:mangayomi/bridge_lib.dart'; + +class AnimeToast extends MProvider { + AnimeToast({required this.source}); + + MSource source; + + final Client client = Client(source); + + @override + bool get supportsLatest => false; + + @override + String get baseUrl => source.baseUrl; + + @override + Future getPopular(int page) async { + final res = (await client.get(Uri.parse(baseUrl))).body; + final document = parseHtml(res); + final elements = document.select("div.row div.col-md-4 div.video-item"); + List animeList = []; + for (var element in elements) { + MManga anime = MManga(); + anime.name = element.selectFirst("div.item-thumbnail a").attr("title"); + anime.link = getUrlWithoutDomain( + element.selectFirst("div.item-thumbnail a").attr("href")); + anime.imageUrl = + element.selectFirst("div.item-thumbnail a img").attr("src"); + animeList.add(anime); + } + return MPages(animeList, false); + } + + @override + Future search(String query, int page, FilterList filterList) async { + final res = + (await client.get(Uri.parse("$baseUrl/page/$page/?s=$query"))).body; + final document = parseHtml(res); + final elements = document.select("div.item-thumbnail a[href]"); + List animeList = []; + for (var element in elements) { + MManga anime = MManga(); + anime.name = element.attr("title"); + anime.link = getUrlWithoutDomain(element.attr("href")); + anime.imageUrl = element.selectFirst("a img").attr("src"); + animeList.add(anime); + } + return MPages( + animeList, document.selectFirst("li.next a")?.attr("href") != null); + } + + @override + Future getDetail(String url) async { + MManga anime = MManga(); + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; + final document = parseHtml(res); + anime.imageUrl = document.selectFirst(".item-content p img").attr("src"); + anime.genre = + (document.xpathFirst('//p[contains(text(),"Genre:")]/text()') ?? "") + .replaceAll("Genre:", "") + .split(","); + anime.description = document.selectFirst("div.item-content div + p").text; + final categoryTag = document.xpath('//*[@rel="category tag"]/text()'); + if (categoryTag.isNotEmpty) { + if (categoryTag.contains("Airing")) { + anime.status = MStatus.ongoing; + } else { + anime.status = MStatus.completed; + } + } + List? episodesList = []; + if (categoryTag.contains("Serie")) { + List elements = []; + if (document.selectFirst("#multi_link_tab0")?.attr("id") != null) { + elements = document.select("#multi_link_tab0"); + } else { + elements = document.select("#multi_link_tab1"); + } + for (var element in elements) { + final episodeElement = element.selectFirst("div.tab-pane a"); + final epT = episodeElement.text; + if (epT.contains(":") || epT.contains("-")) { + final url = episodeElement.attr("href"); + final document = parseHtml((await client.get(Uri.parse(url))).body); + final nUrl = document.selectFirst("#player-embed a").attr("href"); + final nDoc = parseHtml((await client.get(Uri.parse(nUrl))).body); + final nEpEl = nDoc.select("div.tab-pane a"); + for (var epElement in nEpEl) { + MChapter ep = MChapter(); + ep.name = epElement.text; + ep.url = getUrlWithoutDomain(epElement.attr("href")); + episodesList.add(ep); + } + } else { + final episodeElements = element.select("div.tab-pane a"); + for (var epElement in episodeElements) { + MChapter ep = MChapter(); + ep.name = epElement.text; + ep.url = getUrlWithoutDomain(epElement.attr("href")); + episodesList.add(ep); + } + } + } + } else { + MChapter ep = MChapter(); + ep.name = document.selectFirst("h1.light-title")?.text ?? "Film"; + ep.url = getUrlWithoutDomain( + document.selectFirst("link[rel=canonical]").attr("href")); + episodesList.add(ep); + } + anime.chapters = episodesList.reversed.toList(); + return anime; + } + + List preferenceHosterSelection() { + return getPreferenceValue(source.id, "hoster_selection"); + } + + @override + Future> getVideoList(String url) async { + final res = (await client.get(Uri.parse("$baseUrl$url"))).body; + final document = parseHtml(res); + final fEp = document.selectFirst("div.tab-pane"); + List videos = []; + List ep = []; + int epcu = 100; + + if (fEp.text.contains(":") || fEp.text.contains("-")) { + final tx = document.select("div.tab-pane"); + + for (var e in tx) { + final sUrl = e.selectFirst("a").attr("href"); + final doc = parseHtml((await client.get(Uri.parse(sUrl))).body); + final nUrl = doc.selectFirst("#player-embed a").attr("href"); + final nDoc = parseHtml((await client.get(Uri.parse(nUrl))).body); + epcu = int.tryParse(substringAfter( + document.selectFirst("div.tab-pane a.current-link")?.text ?? "", + "Ep.")) ?? + 100; + ep = nDoc.select("div.tab-pane a"); + } + } else { + epcu = int.tryParse(substringAfter( + document.selectFirst("div.tab-pane a.current-link")?.text ?? "", + "Ep.")) ?? + 100; + ep = document.select("div.tab-pane a"); + } + final hosterSelection = preferenceHosterSelection(); + for (var e in ep) { + if (int.tryParse(substringAfter(e.text, "Ep.")) == epcu) { + final epUrl = e.attr("href"); + final newdoc = parseHtml((await client.get(Uri.parse(epUrl))).body); + final elements = newdoc.select("#player-embed"); + for (var element in elements) { + final link = element.selectFirst("a").getHref ?? ""; + if (link.contains("https://voe.sx") && + hosterSelection.contains("voe")) { + videos.addAll(await voeExtractor(link, "Voe")); + } + } + for (var element in elements) { + List a = []; + final link = element.selectFirst("iframe").getSrc ?? ""; + if ((link.contains("https://dood") || + link.contains("https://ds2play") || + link.contains("https://d0")) && + hosterSelection.contains("dood")) { + a = await doodExtractor(link, "DoodStream"); + } else if (link.contains("filemoon") && + hosterSelection.contains("filemoon")) { + a = await filemoonExtractor(link, "", ""); + } else if (link.contains("mp4upload") && + hosterSelection.contains("mp4upload")) { + a = await mp4UploadExtractor(url, null, "", ""); + } + videos.addAll(a); + } + } + } + return sortVideos(videos); + } + + List sortVideos(List videos) { + String server = getPreferenceValue(source.id, "preferred_hoster"); + + videos.sort((MVideo a, MVideo b) { + int qualityMatchA = 0; + if (a.quality.toLowerCase().contains(server)) { + qualityMatchA = 1; + } + int qualityMatchB = 0; + if (b.quality.toLowerCase().contains(server)) { + qualityMatchB = 1; + } + if (qualityMatchA != qualityMatchB) { + return qualityMatchB - qualityMatchA; + } + + final regex = RegExp(r'(\d+)p'); + final matchA = regex.firstMatch(a.quality); + final matchB = regex.firstMatch(b.quality); + final int qualityNumA = int.tryParse(matchA?.group(1) ?? '0') ?? 0; + final int qualityNumB = int.tryParse(matchB?.group(1) ?? '0') ?? 0; + return qualityNumB - qualityNumA; + }); + + return videos; + } + + @override + List getSourcePreferences() { + return [ + ListPreference( + key: "preferred_hoster", + title: "Standard-Hoster", + summary: "", + valueIndex: 0, + entries: ["Voe", "DoodStream", "Filemoon", "Mp4upload"], + entryValues: ["voe", "doodStream", "filemoon", "mp4upload"]), + MultiSelectListPreference( + key: "hoster_selection", + title: "Hoster auswählen", + summary: "", + entries: ["Voe", "DoodStream", "Filemoon", "Mp4upload"], + entryValues: ["voe", "dood", "filemoon", "mp4upload"], + values: ["voe", "dood", "filemoon", "mp4upload"]), + ]; + } +} + +AnimeToast main(MSource source) { + return AnimeToast(source: source); +} diff --git a/anime/src/de/animetoast/icon.png b/anime/src/de/animetoast/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..172ddf3b39ffbf9a567165659797927a0715c81e GIT binary patch literal 5171 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 _animetoast; +const _animetoastVersion = "0.0.1"; +const _animetoastCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/de/animetoast/animetoast.dart"; +Source _animetoast = Source( + name: "AnimeToast", + baseUrl: "https://animetoast.cc", + lang: "de", + typeSource: "single", + iconUrl: + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/de/animetoast/icon.png", + sourceCodeUrl: _animetoastCodeUrl, + version: _animetoastVersion, + isManga: false);