From 68399a43e580ae14e8a7eaee997469e5e1879ada Mon Sep 17 00:00:00 2001 From: kodjomoustapha <107993382+kodjodevf@users.noreply.github.com> Date: Mon, 29 Jan 2024 10:25:49 +0100 Subject: [PATCH] New source: Nyaa (ALL) --- anime/source_generator.dart | 4 +- anime/src/all/nyaa/icon.png | Bin 0 -> 3187 bytes anime/src/all/nyaa/nyaa.dart | 126 +++++++++++++++++++++++++++++++++ anime/src/all/nyaa/source.dart | 20 ++++++ 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 anime/src/all/nyaa/icon.png create mode 100644 anime/src/all/nyaa/nyaa.dart create mode 100644 anime/src/all/nyaa/source.dart diff --git a/anime/source_generator.dart b/anime/source_generator.dart index 7caa06d6..54e0c764 100644 --- a/anime/source_generator.dart +++ b/anime/source_generator.dart @@ -6,6 +6,7 @@ import 'multisrc/datalifeengine/sources.dart'; import 'multisrc/dopeflix/sources.dart'; import 'multisrc/zorotheme/sources.dart'; import 'src/all/animeworldindia/sources.dart'; +import 'src/all/nyaa/source.dart'; import 'src/ar/okanime/source.dart'; import 'src/de/aniflix/source.dart'; import 'src/en/aniwave/source.dart'; @@ -48,7 +49,8 @@ void main() { animesamaSource, nineanimetv, aniflix, - ...animeworldindiaSourcesList + ...animeworldindiaSourcesList, + nyaaSource ]; final List> jsonList = _sourcesList.map((source) => source.toJson()).toList(); diff --git a/anime/src/all/nyaa/icon.png b/anime/src/all/nyaa/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b57dba5f8a55647122a8b6f046ccc72e8177105a GIT binary patch literal 3187 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 getPopular(MSource source, int page) async { + final res = (await client.get(Uri.parse( + "${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=&s=downloads&o=desc&p=$page"))) + .body; + return parseAnimeList(res, source.baseUrl); + } + + @override + Future getLatestUpdates(MSource source, int page) async { + final res = (await client.get(Uri.parse( + "${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=$page"))) + .body; + return parseAnimeList(res, source.baseUrl); + } + + @override + Future search( + MSource source, String query, int page, FilterList filterList) async { + final filters = filterList.filters; + String url = ""; + url = + "${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=${query.replaceAll(" ", "+")}&p=$page"; + for (var filter in filters) { + if (filter.type == "SortFilter") { + url += "${ll(url)}s=${filter.values[filter.state.index].value}"; + final asc = filter.state.ascending ? "&o=asc" : "&o=desc"; + url += "${ll(url)}$asc"; + } + } + final res = (await client.get(Uri.parse(url))).body; + return parseAnimeList(res, source.baseUrl); + } + + @override + Future getDetail(MSource source, String url) async { + MManga anime = MManga(); + final res = (await client.get(Uri.parse(url))).body; + final document = parseHtml(res); + String description = + (document.xpathFirst('//div[@class="panel-body"]/text()') ?? "") + .replaceAll("\n", ""); + description += + "\n\n${(document.xpathFirst('//div[@class="panel panel-default"]/text()') ?? "").trim().replaceAll("\n", "")}"; + anime.description = description; + MChapter ep = MChapter(); + ep.name = "Torrent"; + ep.url = + "${source.baseUrl}/download/${substringAfterLast(url, '/')}.torrent"; + anime.chapters = [ep]; + return anime; + } + + @override + List getFilterList(MSource source) { + return [ + SortFilter("SortFilter", "Sort by", SortState(0, true), [ + SelectFilterOption("None", ""), + SelectFilterOption("Size", "size"), + SelectFilterOption("Date", "id"), + SelectFilterOption("Seeders", "seeders"), + SelectFilterOption("Leechers", "leechers"), + SelectFilterOption("Download", "downloads") + ]) + ]; + } + + @override + List getSourcePreferences(MSource source) { + return [ + ListPreference( + key: "preferred_categorie_page", + title: "Preferred categorie page", + summary: "", + valueIndex: 0, + entries: ["Anime", "Live Action"], + entryValues: ["1_0", "4_0"]), + ]; + } + + MPages parseAnimeList(String res, String baseUrl) { + List animeList = []; + final document = parseHtml(res); + + final values = document + .select("body > div > div.table-responsive > table > tbody > tr"); + for (var value in values) { + MManga anime = MManga(); + anime.imageUrl = + "$baseUrl${getUrlWithoutDomain(value.selectFirst("td:nth-child(1) > a > img").getSrc)}"; + MElement firstElement = value + .select("td > a") + .where((MElement e) => + e.outerHtml.contains("/view/") && + !e.outerHtml.contains("#comments")) + .toList() + .first; + anime.link = "$baseUrl${getUrlWithoutDomain(firstElement.getHref)}"; + anime.name = firstElement.attr("title"); + animeList.add(anime); + } + + final hasNextPage = + xpath(res, '//ul[@class="pagination"]/li[contains(text(),"ยป")]/a/@href') + .isNotEmpty; + return MPages(animeList, hasNextPage); + } + + String ll(String url) { + if (url.contains("?")) { + return "&"; + } + return "?"; + } +} + +Nyaa main() { + return Nyaa(); +} diff --git a/anime/src/all/nyaa/source.dart b/anime/src/all/nyaa/source.dart new file mode 100644 index 00000000..6f15a2d5 --- /dev/null +++ b/anime/src/all/nyaa/source.dart @@ -0,0 +1,20 @@ +import '../../../../model/source.dart'; + +const _nyaaVersion = "0.0.1"; +const _nyaaSourceCodeUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/all/nyaa/nyaa.dart"; + +String _iconUrl = + "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/anime/src/all/nyaa/icon.png"; + +Source get nyaaSource => _nyaaSource; +Source _nyaaSource = Source( + name: 'Nyaa', + baseUrl: "https://nyaa.si", + lang: "all", + typeSource: "torrent", + iconUrl: _iconUrl, + version: _nyaaVersion, + isManga: false, + appMinVerReq: "0.1.65", + sourceCodeUrl: _nyaaSourceCodeUrl);