Update WPComics multisrc (#1146)

* NetTruyen/NhatTruyen: add filter, fix searching, update genres

* Add Filter to Nhattruyen by moving FilterList to WPComics
* Fix searching Nettruyen/Nhattruyen with filter Genre on
* Fix searching Nhattruyen when filter status=Completed
* Update Nettruyen/Nhattruyen genres list

* XoxoComics: support fillter by genre & status

* XoxoComics: add Filter header

* XoxoComics: fix URL query when filtering

* tweak replace search path method

---------

Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>
This commit is contained in:
Cuong M. Tran 2024-02-14 01:45:46 +07:00 committed by Draff
parent b3668dfe11
commit 93d1700373
5 changed files with 230 additions and 24 deletions

View File

@ -1,21 +1,67 @@
package eu.kanade.tachiyomi.extension.vi.nettruyen package eu.kanade.tachiyomi.extension.vi.nettruyen
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import okhttp3.Headers
import okhttp3.Request
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
class NetTruyen : WPComics("NetTruyen", "https://www.nettruyenss.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) { class NetTruyen : WPComics("NetTruyen", "https://www.nettruyenss.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
override fun headersBuilder(): Headers.Builder = Headers.Builder() override fun String.replaceSearchPath() = replace("/$searchPath?status=2&", "/truyen-full?")
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build())
override fun getFilterList(): FilterList { override fun getGenreList(): Array<Pair<String?, String>> = arrayOf(
return FilterList( null to "Tất cả",
StatusFilter(getStatusList()), "action-95" to "Action",
GenreFilter(getGenreList()), "truong-thanh" to "Adult",
"adventure" to "Adventure",
"anime" to "Anime",
"chuyen-sinh-2131" to "Chuyển Sinh",
"comedy-99" to "Comedy",
"comic" to "Comic",
"cooking-101" to "Cooking",
"co-dai-207" to "Cổ Đại",
"doujinshi" to "Doujinshi",
"drama-103" to "Drama",
"dam-my" to "Đam Mỹ",
"ecchi-104" to "Ecchi",
"fantasy-1050" to "Fantasy",
"gender-bender-106" to "Gender Bender",
"harem-107" to "Harem",
"historical" to "Historical",
"horror" to "Horror",
"josei" to "Josei",
"live-action" to "Live action",
"manga-112" to "Manga",
"manhua" to "Manhua",
"manhwa-11400" to "Manhwa",
"martial-arts" to "Martial Arts",
"mature" to "Mature",
"mecha-117" to "Mecha",
"mystery" to "Mystery",
"ngon-tinh" to "Ngôn Tình",
"one-shot" to "One shot",
"psychological" to "Psychological",
"romance-121" to "Romance",
"school-life" to "School Life",
"sci-fi" to "Sci-fi",
"seinen" to "Seinen",
"shoujo" to "Shoujo",
"shoujo-ai-126" to "Shoujo Ai",
"shounen-127" to "Shounen",
"shounen-ai" to "Shounen Ai",
"slice-of-life" to "Slice of Life",
"smut" to "Smut",
"soft-yaoi" to "Soft Yaoi",
"soft-yuri" to "Soft Yuri",
"sports" to "Sports",
"supernatural" to "Supernatural",
"tap-chi-truyen-tranh" to "Tạp chí truyện tranh",
"thieu-nhi" to "Thiếu Nhi",
"tragedy-136" to "Tragedy",
"trinh-tham" to "Trinh Thám",
"truyen-scan" to "Truyện scan",
"truyen-mau-214" to "Truyện Màu",
"viet-nam" to "Việt Nam",
"webtoon-140" to "Webtoon",
"xuyen-khong-205" to "Xuyên Không",
"16" to "16+",
) )
} }
}

View File

@ -1,16 +1,67 @@
package eu.kanade.tachiyomi.extension.vi.nhattruyen package eu.kanade.tachiyomi.extension.vi.nhattruyen
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import okhttp3.Headers
import okhttp3.Request
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
class NhatTruyen : WPComics("NhatTruyen", "https://nhattruyento.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) { class NhatTruyen : WPComics("NhatTruyen", "https://nhattruyento.com", "vi", SimpleDateFormat("dd/MM/yy", Locale.getDefault()), null) {
override fun headersBuilder(): Headers.Builder = Headers.Builder() override val searchPath = "the-loai"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/the-loai?keyword=$query&page=$page", headers)
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", baseUrl).build()) override fun getGenreList(): Array<Pair<String?, String>> = arrayOf(
null to "Tất cả",
"action" to "Action",
"adult" to "Adult",
"adventure" to "Adventure",
"anime" to "Anime",
"chuyen-sinh" to "Chuyển Sinh",
"comedy" to "Comedy",
"comic" to "Comic",
"cooking" to "Cooking",
"co-dai" to "Cổ Đại",
"doujinshi" to "Doujinshi",
"drama" to "Drama",
"dam-my" to "Đam Mỹ",
"ecchi" to "Ecchi",
"fantasy" to "Fantasy",
"gender-bender" to "Gender Bender",
"harem" to "Harem",
"historical" to "Historical",
"horror" to "Horror",
"josei" to "Josei",
"live-action" to "Live action",
"manga-241" to "Manga",
"manhua" to "Manhua",
"manhwa-2431" to "Manhwa",
"martial-arts" to "Martial Arts",
"mature" to "Mature",
"mecha" to "Mecha",
"mystery" to "Mystery",
"ngon-tinh" to "Ngôn Tình",
"one-shot" to "One shot",
"psychological" to "Psychological",
"romance" to "Romance",
"school-life" to "School Life",
"sci-fi" to "Sci-fi",
"seinen" to "Seinen",
"shoujo" to "Shoujo",
"shoujo-ai" to "Shoujo Ai",
"shounen" to "Shounen",
"shounen-ai" to "Shounen Ai",
"slice-of-life" to "Slice of Life",
"smut" to "Smut",
"soft-yaoi" to "Soft Yaoi",
"soft-yuri" to "Soft Yuri",
"sports" to "Sports",
"supernatural" to "Supernatural",
"tap-chi-truyen-tranh" to "Tạp chí truyện tranh",
"thieu-nhi" to "Thiếu Nhi",
"tragedy" to "Tragedy",
"trinh-tham" to "Trinh Thám",
"truyen-scan" to "Truyện scan",
"truyen-mau" to "Truyện Màu",
"viet-nam" to "Việt Nam",
"webtoon" to "Webtoon",
"xuyen-khong" to "Xuyên Không",
"16" to "16+",
)
} }

View File

@ -2,10 +2,12 @@ package eu.kanade.tachiyomi.extension.en.xoxocomics
import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics import eu.kanade.tachiyomi.multisrc.wpcomics.WPComics
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -14,6 +16,7 @@ import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
class XoxoComics : WPComics("XOXO Comics", "https://xoxocomic.com", "en", SimpleDateFormat("MM/dd/yyyy", Locale.US), null) { class XoxoComics : WPComics("XOXO Comics", "https://xoxocomic.com", "en", SimpleDateFormat("MM/dd/yyyy", Locale.US), null) {
override val searchPath = "search-comic"
override val popularPath = "hot-comic" override val popularPath = "hot-comic"
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/comic-update?page=$page", headers) override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/comic-update?page=$page", headers)
override fun latestUpdatesSelector() = "li.row" override fun latestUpdatesSelector() = "li.row"
@ -26,8 +29,36 @@ class XoxoComics : WPComics("XOXO Comics", "https://xoxocomic.com", "en", Simple
thumbnail_url = element.select("img").attr("data-original") thumbnail_url = element.select("img").attr("data-original")
} }
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return GET("$baseUrl/search-comic?keyword=$query&page=$page", headers) val filterList = filters.let { if (it.isEmpty()) getFilterList() else it }
return if (query.isNotEmpty() || filterList.isEmpty()) {
// Search won't work together with filter
return GET("$baseUrl/$searchPath?keyword=$query&page=$page", headers)
} else {
val url = baseUrl.toHttpUrl().newBuilder()
var genreFilter: UriPartFilter? = null
var statusFilter: UriPartFilter? = null
filterList.forEach { filter ->
when (filter) {
is GenreFilter -> genreFilter = filter
is StatusFilter -> statusFilter = filter
else -> {}
}
}
// Genre filter must come before status filter
genreFilter?.toUriPart()?.let { url.addPathSegment(it) }
statusFilter?.toUriPart()?.let { url.addPathSegment(it) }
url.apply {
addQueryParameter("page", page.toString())
addQueryParameter("sort", "0")
}
GET(url.toString(), headers)
}
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
@ -52,4 +83,73 @@ class XoxoComics : WPComics("XOXO Comics", "https://xoxocomic.com", "en", Simple
} }
override fun pageListRequest(chapter: SChapter): Request = GET(baseUrl + "${chapter.url}/all") override fun pageListRequest(chapter: SChapter): Request = GET(baseUrl + "${chapter.url}/all")
override fun getStatusList(): Array<Pair<String?, String>> = arrayOf(
Pair(null, "All"),
Pair("ongoing", "Ongoing"),
Pair("completed", "Completed"),
)
override fun getGenreList(): Array<Pair<String?, String>> = arrayOf(
null to "All",
"marvel-comic" to "Marvel",
"dc-comics-comic" to "DC Comics",
"dark-horse-comic" to "Dark Horse",
"action-comic" to "Action",
"adventure-comic" to "Adventure",
"anthology-comic" to "Anthology",
"anthropomorphic-comic" to "Anthropomorphic",
"biography-comic" to "Biography",
"children-comic" to "Children",
"comedy-comic" to "Comedy",
"crime-comic" to "Crime",
"drama-comic" to "Drama",
"family-comic" to "Family",
"fantasy-comic" to "Fantasy",
"fighting-comic" to "Fighting",
"graphic-novels-comic" to "Graphic Novels",
"historical-comic" to "Historical",
"horror-comic" to "Horror",
"leading-ladies-comic" to "Leading Ladies",
"lgbtq-comic" to "LGBTQ",
"literature-comic" to "Literature",
"manga-comic" to "Manga",
"martial-arts-comic" to "Martial Arts",
"military-comic" to "Military",
"mini-series-comic" to "Mini-Series",
"movies-tv-comic" to "Movies &amp; TV",
"music-comic" to "Music",
"mystery-comic" to "Mystery",
"mythology-comic" to "Mythology",
"personal-comic" to "Personal",
"political-comic" to "Political",
"post-apocalyptic-comic" to "Post-Apocalyptic",
"psychological-comic" to "Psychological",
"pulp-comic" to "Pulp",
"religious-comic" to "Religious",
"robots-comic" to "Robots",
"romance-comic" to "Romance",
"school-life-comic" to "School Life",
"sci-fi-comic" to "Sci-Fi",
"slice-of-life-comic" to "Slice of Life",
"sport-comic" to "Sport",
"spy-comic" to "Spy",
"superhero-comic" to "Superhero",
"supernatural-comic" to "Supernatural",
"suspense-comic" to "Suspense",
"teen-comic" to "Teen",
"thriller-comic" to "Thriller",
"vampires-comic" to "Vampires",
"video-games-comic" to "Video Games",
"war-comic" to "War",
"western-comic" to "Western",
"zombies-comic" to "Zombies",
)
override fun getFilterList(): FilterList {
return FilterList(
Filter.Header("Search query won't use Genre/Status filter"),
StatusFilter(getStatusList()),
GenreFilter(getGenreList()),
)
}
} }

View File

@ -73,6 +73,8 @@ abstract class WPComics(
protected open val searchPath = "tim-truyen" protected open val searchPath = "tim-truyen"
protected open fun String.replaceSearchPath() = this
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val filterList = filters.let { if (it.isEmpty()) getFilterList() else it } val filterList = filters.let { if (it.isEmpty()) getFilterList() else it }
return if (filterList.isEmpty()) { return if (filterList.isEmpty()) {
@ -94,7 +96,7 @@ abstract class WPComics(
addQueryParameter("sort", "0") addQueryParameter("sort", "0")
} }
GET(url.toString().replace("/tim-truyen?status=2&", "/truyen-full?"), headers) GET(url.toString().replaceSearchPath(), headers)
} }
} }
@ -288,6 +290,13 @@ abstract class WPComics(
"xuyen-khong" to "Xuyên Không", "xuyen-khong" to "Xuyên Không",
) )
override fun getFilterList(): FilterList {
return FilterList(
StatusFilter(getStatusList()),
GenreFilter(getGenreList()),
)
}
protected open class UriPartFilter(displayName: String, val vals: Array<Pair<String?, String>>) : protected open class UriPartFilter(displayName: String, val vals: Array<Pair<String?, String>>) :
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray()) { Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray()) {
fun toUriPart() = vals[state].first fun toUriPart() = vals[state].first

View File

@ -9,7 +9,7 @@ class WPComicsGenerator : ThemeSourceGenerator {
override val themeClass = "WPComics" override val themeClass = "WPComics"
override val baseVersionCode: Int = 3 override val baseVersionCode: Int = 4
override val sources = listOf( override val sources = listOf(
SingleLang("NetTruyen", "https://www.nettruyenss.com", "vi", overrideVersionCode = 22), SingleLang("NetTruyen", "https://www.nettruyenss.com", "vi", overrideVersionCode = 22),