diff --git a/dart/anime/src/all/nyaa/nyaa.dart b/dart/anime/src/all/nyaa/nyaa.dart index 4083052b..ef21fcb8 100644 --- a/dart/anime/src/all/nyaa/nyaa.dart +++ b/dart/anime/src/all/nyaa/nyaa.dart @@ -9,23 +9,21 @@ class Nyaa extends MProvider { @override Future getPopular(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; + final res = (await client.get( + Uri.parse( + "${getBaseUrl()}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=&s=downloads&o=desc&p=$page", + ), + )).body; return parseAnimeList(res); } @override Future getLatestUpdates(int page) async { - final res = - (await client.get( - Uri.parse( - "${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=$page", - ), - )).body; + final res = (await client.get( + Uri.parse( + "${getBaseUrl()}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=$page", + ), + )).body; return parseAnimeList(res); } @@ -34,7 +32,7 @@ class Nyaa extends MProvider { final filters = filterList.filters; String url = ""; url = - "${source.baseUrl}/?f=0&c=${getPreferenceValue(source.id, "preferred_categorie_page")}&q=${query.replaceAll(" ", "+")}&p=$page"; + "${getBaseUrl()}/?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}"; @@ -46,22 +44,68 @@ class Nyaa extends MProvider { return parseAnimeList(res); } + String extractPanelBody(MDocument document) { + final panelBody = document.selectFirst('.panel-body'); + if (panelBody == null) return ""; + + final rows = panelBody.select('.row'); + + final Map info = {}; + for (var row in rows) { + final labels = row.select('.col-md-1'); + for (var label in labels) { + final key = label.text.replaceAll(":", "").trim(); + final valueDiv = label.nextElementSibling; + if (valueDiv == null) continue; + + final links = valueDiv.select('a'); + String value; + if (links.isNotEmpty) { + value = links.map((a) => a.text.trim()).join(' - '); + } else { + value = valueDiv.text.trim(); + } + + info[key] = value; + } + } + + final buffer = StringBuffer(); + buffer.writeln("Torrent Info:\n"); + info.forEach((k, v) { + buffer.writeln("${k.padRight(11)}: $v"); + }); + if (getPreferenceValue(source.id, "torrent_description_visible")) { + buffer.writeln("\n\n"); + buffer.writeln("Torrent Description: \n"); + buffer.writeln( + document + .select("#torrent-description") + .map((e) => e.text.trim()) + .join("\n\n"), + ); + } + + return buffer.toString(); + } + @override Future getDetail(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]; + + anime.description = extractPanelBody(document); + + List chapters = []; + chapters.add( + MChapter( + name: "Torrent", + url: "${getBaseUrl()}/download/${substringAfterLast(url, '/')}.torrent", + ), + ); + anime.chapters = chapters; + return anime; } @@ -100,9 +144,36 @@ class Nyaa extends MProvider { entries: ["Anime", "Live Action"], entryValues: ["1_0", "4_0"], ), + SwitchPreferenceCompat( + key: "torrent_description_visible", + title: "Display Torrent Description", + summary: + "Enable to show the full torrent description in the details view.", + value: false, + ), + EditTextPreference( + key: "domain_url", + title: 'Edit URL', + summary: "", + value: source.baseUrl, + dialogTitle: "URL", + dialogMessage: "", + ), ]; } + String getBaseUrl() { + final baseUrl = getPreferenceValue(source.id, "domain_url")?.trim(); + + if (baseUrl == null || baseUrl.isEmpty) { + return source.baseUrl; + } + + return baseUrl.endsWith("/") + ? baseUrl.substring(0, baseUrl.length - 1) + : baseUrl; + } + MPages parseAnimeList(String res) { List animeList = []; final document = parseHtml(res); @@ -113,28 +184,26 @@ class Nyaa extends MProvider { for (var value in values) { MManga anime = MManga(); anime.imageUrl = - "${source.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; + "${getBaseUrl()}${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 = - "${source.baseUrl}${getUrlWithoutDomain(firstElement.getHref)}"; + "${getBaseUrl()}${getUrlWithoutDomain(firstElement.getHref)}"; anime.name = firstElement.attr("title"); animeList.add(anime); } - final hasNextPage = - xpath( - res, - '//ul[@class="pagination"]/li[contains(text(),"»")]/a/@href', - ).isNotEmpty; + final hasNextPage = xpath( + res, + '//ul[@class="pagination"]/li[contains(text(),"»")]/a/@href', + ).isNotEmpty; return MPages(animeList, hasNextPage); } diff --git a/dart/anime/src/all/nyaa/source.dart b/dart/anime/src/all/nyaa/source.dart index e48e5501..59168bfe 100644 --- a/dart/anime/src/all/nyaa/source.dart +++ b/dart/anime/src/all/nyaa/source.dart @@ -1,6 +1,6 @@ import '../../../../../model/source.dart'; -const _nyaaVersion = "0.0.3"; +const _nyaaVersion = "0.0.4"; const _nyaaSourceCodeUrl = "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/dart/anime/src/all/nyaa/nyaa.dart";