From d59870fa843b38d384aec0e10af694bc2c3068c4 Mon Sep 17 00:00:00 2001 From: antonycaporossi <38634189+antonycaporossi@users.noreply.github.com> Date: Sat, 12 Dec 2020 01:02:47 +0100 Subject: [PATCH] Fix #5095 and #5082 (#5100) Fix #5095 and #5082 --- src/en/manhwamanga/build.gradle | 2 +- .../extension/en/manhwamanga/ManhwaManga.kt | 187 ++++++++++++------ src/zh/jinmantiantang/build.gradle | 2 +- .../zh/jinmantiantang/Jinmantiantang.kt | 2 +- 4 files changed, 128 insertions(+), 65 deletions(-) diff --git a/src/en/manhwamanga/build.gradle b/src/en/manhwamanga/build.gradle index bd2f1858f..8e5d2a21b 100644 --- a/src/en/manhwamanga/build.gradle +++ b/src/en/manhwamanga/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'ManhwaManga.net' pkgNameSuffix = 'en.manhwamanga' extClass = '.ManhwaManga' - extVersionCode = 1 + extVersionCode = 2 libVersion = '1.2' containsNsfw = true } diff --git a/src/en/manhwamanga/src/eu/kanade/tachiyomi/extension/en/manhwamanga/ManhwaManga.kt b/src/en/manhwamanga/src/eu/kanade/tachiyomi/extension/en/manhwamanga/ManhwaManga.kt index 7d511dcd9..011e4798c 100644 --- a/src/en/manhwamanga/src/eu/kanade/tachiyomi/extension/en/manhwamanga/ManhwaManga.kt +++ b/src/en/manhwamanga/src/eu/kanade/tachiyomi/extension/en/manhwamanga/ManhwaManga.kt @@ -2,92 +2,99 @@ package eu.kanade.tachiyomi.extension.en.manhwamanga import eu.kanade.tachiyomi.annotations.Nsfw import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST +import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.ParsedHttpSource +import eu.kanade.tachiyomi.util.asJsoup import okhttp3.HttpUrl -import okhttp3.OkHttpClient import okhttp3.Request +import okhttp3.RequestBody +import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element @Nsfw class ManhwaManga : ParsedHttpSource() { - override val name = "ManhwaManga.net" - override val baseUrl = "https://manhwamanga.net" - override val lang = "en" - override val supportsLatest = true - override val client: OkHttpClient = network.cloudflareClient + override fun popularMangaSelector() = ".home-truyendecu" + override fun latestUpdatesSelector() = popularMangaSelector() + override fun searchMangaSelector() = popularMangaSelector() + override fun chapterListSelector() = "#list-chapter > div.row > div > ul > li:nth-child(n)" - // Popular + override fun popularMangaNextPageSelector() = "li.active+li a[data-page]" + override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() + override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun popularMangaRequest(page: Int): Request { - return GET("$baseUrl/most-views", headers) + return GET("$baseUrl/most-views/page/$page", headers) } - override fun popularMangaSelector() = searchMangaSelector() - - override fun popularMangaFromElement(element: Element): SManga { - - val manga = SManga.create() - - manga.setUrlWithoutDomain(element.select("a").attr("href")) - manga.title = element.select("a").attr("title") - manga.thumbnail_url = element.select("a img").attr("src") - - return manga - } - - override fun popularMangaNextPageSelector(): Nothing? = null - - // Latest override fun latestUpdatesRequest(page: Int): Request { - return GET("$baseUrl/latest-updates", headers) + return GET("$baseUrl/latest-updates/page/$page", headers) } - override fun latestUpdatesSelector() = searchMangaSelector() - - override fun latestUpdatesFromElement(element: Element): SManga { - - val manga = SManga.create() - - manga.setUrlWithoutDomain(element.select("a").attr("href")) - manga.title = element.select("a").attr("title") - manga.thumbnail_url = element.select("a img").attr("src") - return manga - } - - override fun latestUpdatesNextPageSelector(): Nothing? = null - - // Search override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val url = HttpUrl.parse("$baseUrl/?s=$query")?.newBuilder() - return GET(url.toString(), headers) + return if (query.isNotBlank()) { + GET("$baseUrl/s?s=$query", headers) + } else { + val url = HttpUrl.parse("$baseUrl/category/")!!.newBuilder() + filters.forEach { filter -> + when (filter) { + + is GenreFilter -> url.addPathSegment(filter.toUriPart()) + } + } + url.addPathSegment("page") + url.addPathSegment("$page") + GET(url.toString(), headers) + } } - - override fun searchMangaSelector() = "div.col-xs-12.col-sm-12.col-md-9.col-truyen-main > div:nth-child(1) > div > div:nth-child(2) > div:nth-child(n)" - - override fun searchMangaFromElement(element: Element): SManga { + override fun popularMangaFromElement(element: Element): SManga { val manga = SManga.create() - manga.setUrlWithoutDomain(element.select("a").attr("href")) manga.title = element.select("a").attr("title") manga.thumbnail_url = element.select("a img").attr("src") return manga } + override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element) + override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) - override fun searchMangaNextPageSelector(): Nothing? = null + protected fun getXhrChapters(mangaId: String): Document { + val xhrHeaders = headersBuilder().add("Content-Type: application/x-www-form-urlencoded; charset=UTF-8") + .build() + val body = RequestBody.create(null, "action=tw_ajax&type=list_chap&id=$mangaId") + return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, body)).execute().asJsoup() + } + + override fun chapterListParse(response: Response): List { + val document = response.asJsoup() + val dataIdSelector = "input[id^=id_post]" + + return getXhrChapters(document.select(dataIdSelector).attr("value")).select("option").map { chapterFromElement(it) }.reversed() + } + + override fun chapterFromElement(element: Element): SChapter { + val chapter = SChapter.create() + element.let { urlElement -> + chapter.setUrlWithoutDomain(urlElement.attr("value")) + chapter.name = urlElement.text() + } + chapter.date_upload = 0 + + return chapter + } override fun mangaDetailsParse(document: Document) = SManga.create().apply { - title = document.select("div.col-xs-12.col-sm-8.col-md-8.desc > h3").text() + title = document.select("h3.title").text() description = document.select("div.desc-text > p").text() thumbnail_url = document.select("div.books > div > img").attr("src") author = document.select("div.info > div:nth-child(1) > a").attr("title") @@ -101,23 +108,79 @@ class ManhwaManga : ParsedHttpSource() { } } - override fun chapterListSelector() = "#list-chapter > div.row > div > ul > li:nth-child(n)" - - override fun chapterFromElement(element: Element): SChapter { - val chapter = SChapter.create() - - chapter.setUrlWithoutDomain(element.select("a").attr("href")) - chapter.name = element.select("a").attr("title") - - return chapter - } - - // Pages override fun pageListParse(document: Document): List = mutableListOf().apply { - document.select("#content-fiximg > p:nth-child(n) img").forEachIndexed { index, element -> + document.select(".chapter_beta_content p img").forEachIndexed { index, element -> add(Page(index, "", element.attr("src"))) } } + override fun imageUrlRequest(page: Page) = throw Exception("Not used") override fun imageUrlParse(document: Document) = throw Exception("Not used") + + override fun getFilterList() = FilterList( + Filter.Header("NOTE: Ignored if using text search!"), + Filter.Separator(), + GenreFilter(getGenreList()) + ) + class GenreFilter(vals: Array>) : UriPartFilter("Category", vals) + + private fun getGenreList() = arrayOf( + Pair("All", ""), + Pair("Action", "action"), + Pair("Adult", "adult"), + Pair("Adventure", "adventure"), + Pair("BL", "bl"), + Pair("Comedy", "comedy"), + Pair("Comic", "comic"), + Pair("Crime", "crime"), + Pair("Detective", "detective"), + Pair("Drama", "drama"), + Pair("Ecchi", "ecchi"), + Pair("Fantasy", "fantasy"), + Pair("Gender bender", "gender-bender"), + Pair("GL", "gl"), + Pair("Gossip", "gossip"), + Pair("Harem", "harem"), + Pair("HentaiVN.Net", "hentaivn"), + Pair("Historical", "historical"), + Pair("HoiHentai.Com", "hoihentai-com"), + Pair("Horror", "horror"), + Pair("Incest", "incest"), + Pair("Isekai", "isekai"), + Pair("Manhua", "manhua"), + Pair("Martial arts", "martial-arts"), + Pair("Mature", "mature"), + Pair("Mecha", "mecha"), + Pair("Medical", "medical"), + Pair("Monster/Tentacle", "monster-tentacle"), + Pair("Mystery", "mystery"), + Pair("Novel", "novel"), + Pair("Office Life", "office-life"), + Pair("One shot", "one-shot"), + Pair("Psychological", "psychological"), + Pair("Revenge", "revenge"), + Pair("Romance", "romance"), + Pair("School Life", "school-life"), + Pair("Sci Fi", "sci-fi"), + Pair("Seinen", "seinen"), + Pair("Shoujo", "shoujo"), + Pair("Shounen", "shounen"), + Pair("Slice of Life", "slice-of-life"), + Pair("Smut", "smut"), + Pair("Sports", "sports"), + Pair("Supernatural", "supernatural"), + Pair("Teenager", "teenager"), + Pair("Thriller", "thriller"), + Pair("Time Travel", "time-travel"), + Pair("Tragedy", "tragedy"), + Pair("Uncensored", "uncensored"), + Pair("Vampire", "vampire"), + Pair("Webtoon", "webtoon"), + Pair("Yaoi", "yaoi"), + Pair("Yuri", "yuri") + ) + open class UriPartFilter(displayName: String, private val vals: Array>) : + Filter.Select(displayName, vals.map { it.first }.toTypedArray()) { + fun toUriPart() = vals[state].second + } } diff --git a/src/zh/jinmantiantang/build.gradle b/src/zh/jinmantiantang/build.gradle index 8bfce0e34..e65a4c461 100644 --- a/src/zh/jinmantiantang/build.gradle +++ b/src/zh/jinmantiantang/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'Jinmantiantang' pkgNameSuffix = 'zh.jinmantiantang' extClass = '.Jinmantiantang' - extVersionCode = 7 + extVersionCode = 8 libVersion = '1.2' containsNsfw = true } diff --git a/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt b/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt index 939d77cbe..7cf903660 100644 --- a/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt +++ b/src/zh/jinmantiantang/src/eu/kanade/tachiyomi/extension/zh/jinmantiantang/Jinmantiantang.kt @@ -175,7 +175,7 @@ class Jinmantiantang : ParsedHttpSource() { // When the index passed by the "selectDetailsStatusAndGenre(document: Document, index: Int)" index is 1, // it will definitely return a String type of 0, 1 or 2. This warning can be ignored status = selectDetailsStatusAndGenre(document, 1).trim().toInt() - description = document.select("div.p-t-5.p-b-5")[7].text().removePrefix("敘述:") + description = document.select("#intro-block .p-t-5.p-b-5").text().substringAfter("敘述:").trim() } // 查询作者信息