From dc3135aedeebf70eaabebe6b7c699953180bbb81 Mon Sep 17 00:00:00 2001 From: Secozzi <49240133+Secozzi@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:46:47 +0000 Subject: [PATCH] Move mangasect to liliana theme (#2534) * fix page request + move mangasect to liliana * remove unused file * Update src/en/mangasect/build.gradle --- lib-multisrc/liliana/build.gradle.kts | 2 +- .../tachiyomi/multisrc/liliana/Liliana.kt | 1 + .../en/comickiba/ManhuagoldFilters.kt | 142 ----------- src/en/mangasect/build.gradle | 4 +- .../extension/en/mangasect/MangaSect.kt | 239 +----------------- .../en/mangasect/MangaSectFilters.kt | 167 ------------ .../extension/ja/mangakoma/MangaKoma.kt | 15 +- 7 files changed, 14 insertions(+), 556 deletions(-) delete mode 100644 src/en/comickiba/src/eu/kanade/tachiyomi/extension/en/comickiba/ManhuagoldFilters.kt delete mode 100644 src/en/mangasect/src/eu/kanade/tachiyomi/extension/en/mangasect/MangaSectFilters.kt diff --git a/lib-multisrc/liliana/build.gradle.kts b/lib-multisrc/liliana/build.gradle.kts index 9dce2478c..e2f11e9c1 100644 --- a/lib-multisrc/liliana/build.gradle.kts +++ b/lib-multisrc/liliana/build.gradle.kts @@ -2,4 +2,4 @@ plugins { id("lib-multisrc") } -baseVersionCode = 2 +baseVersionCode = 3 diff --git a/lib-multisrc/liliana/src/eu/kanade/tachiyomi/multisrc/liliana/Liliana.kt b/lib-multisrc/liliana/src/eu/kanade/tachiyomi/multisrc/liliana/Liliana.kt index 760934ec7..cc5c8ef4d 100644 --- a/lib-multisrc/liliana/src/eu/kanade/tachiyomi/multisrc/liliana/Liliana.kt +++ b/lib-multisrc/liliana/src/eu/kanade/tachiyomi/multisrc/liliana/Liliana.kt @@ -342,6 +342,7 @@ abstract class Liliana( val imgHeaders = headersBuilder().apply { add("Accept", "image/avif,image/webp,*/*") add("Host", page.imageUrl!!.toHttpUrl().host) + removeAll("Referer") }.build() return GET(page.imageUrl!!, imgHeaders) } diff --git a/src/en/comickiba/src/eu/kanade/tachiyomi/extension/en/comickiba/ManhuagoldFilters.kt b/src/en/comickiba/src/eu/kanade/tachiyomi/extension/en/comickiba/ManhuagoldFilters.kt deleted file mode 100644 index f8dccbc81..000000000 --- a/src/en/comickiba/src/eu/kanade/tachiyomi/extension/en/comickiba/ManhuagoldFilters.kt +++ /dev/null @@ -1,142 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.comickiba - -import eu.kanade.tachiyomi.source.model.Filter - -object Note : Filter.Header("NOTE: Ignored if using text search!") - -sealed class Select( - name: String, - val param: String, - values: Array, -) : Filter.Select(name, values) { - open val selection: String - get() = if (state == 0) "" else state.toString() -} - -class StatusFilter( - values: Array = statuses.keys.toTypedArray(), -) : Select("Status", "status", values) { - override val selection: String - get() = statuses[values[state]]!! - - companion object { - private val statuses = mapOf( - "All" to "", - "Completed" to "completed", - "OnGoing" to "on-going", - "On-Hold" to "on-hold", - "Canceled" to "canceled", - ) - } -} - -class SortFilter( - values: Array = orders.keys.toTypedArray(), -) : Select("Sort", "sort", values) { - override val selection: String - get() = orders[values[state]]!! - - companion object { - private val orders = mapOf( - "Default" to "default", - "Latest Updated" to "latest-updated", - "Most Viewed" to "views", - "Most Viewed Month" to "views_month", - "Most Viewed Week" to "views_week", - "Most Viewed Day" to "views_day", - "Score" to "score", - "Name A-Z" to "az", - "Name Z-A" to "za", - "The highest chapter count" to "chapters", - "Newest" to "new", - "Oldest" to "old", - ) - } -} - -class Genre(name: String, val id: String) : Filter.CheckBox(name) - -class GenresFilter( - values: List = genres, -) : Filter.Group("Genres", values) { - val param = "genres" - - val selection: String - get() = state.filter { it.state }.joinToString(",") { it.id } - - companion object { - private val genres: List - get() = listOf( - Genre("Action", "37"), - Genre("Adaptation", "19"), - Genre("Adult", "5310"), - Genre("Adventure", "38"), - Genre("Aliens", "5436"), - Genre("Animals", "1552"), - Genre("Award Winning", "39"), - Genre("Comedy", "202"), - Genre("Comic", "287"), - Genre("Cooking", "277"), - Genre("Crime", "2723"), - Genre("Delinquents", "4438"), - Genre("Demons", "379"), - Genre("Drama", "3"), - Genre("Ecchi", "17"), - Genre("Fantasy", "197"), - Genre("Full Color", "13"), - Genre("Gender Bender", "221"), - Genre("Genderswap", "2290"), - Genre("Ghosts", "2866"), - Genre("Gore", "42"), - Genre("Harem", "222"), - Genre("Historical", "4"), - Genre("Horror", "5"), - Genre("Isekai", "259"), - Genre("Josei", "292"), - Genre("Loli", "5449"), - Genre("Long Strip", "7"), - Genre("Magic", "272"), - Genre("Manhwa", "266"), - Genre("Martial Arts", "40"), - Genre("Mature", "5311"), - Genre("Mecha", "2830"), - Genre("Medical", "1598"), - Genre("Military", "43"), - Genre("Monster Girls", "2307"), - Genre("Monsters", "298"), - Genre("Music", "3182"), - Genre("Mystery", "6"), - Genre("Office Workers", "14"), - Genre("Official Colored", "1046"), - Genre("Philosophical", "2776"), - Genre("Post-Apocalyptic", "1059"), - Genre("Psychological", "493"), - Genre("Reincarnation", "204"), - Genre("Reverse", "280"), - Genre("Reverse Harem", "199"), - Genre("Romance", "186"), - Genre("School Life", "601"), - Genre("Sci-Fi", "1845"), - Genre("Sexual Violence", "731"), - Genre("Shoujo", "254"), - Genre("Slice of Life", "10"), - Genre("Sports", "4066"), - Genre("Superhero", "481"), - Genre("Supernatural", "198"), - Genre("Survival", "44"), - Genre("Thriller", "1058"), - Genre("Time Travel", "299"), - Genre("Tragedy", "41"), - Genre("Video Games", "1846"), - Genre("Villainess", "278"), - Genre("Virtual Reality", "1847"), - Genre("Web Comic", "12"), - Genre("Webtoon", "279"), - Genre("Webtoons", "267"), - Genre("Wuxia", "203"), - Genre("Yaoi", "18"), - Genre("Yuri", "11"), - Genre("Zombies", "1060"), - ) - } -} diff --git a/src/en/mangasect/build.gradle b/src/en/mangasect/build.gradle index d2402b2ec..95a9a9975 100644 --- a/src/en/mangasect/build.gradle +++ b/src/en/mangasect/build.gradle @@ -1,7 +1,9 @@ ext { extName = 'Manga Sect' extClass = '.MangaSect' - extVersionCode = 1 + themePkg = 'liliana' + baseUrl = 'https://mangasect.net' + overrideVersionCode = 0 } apply from: "$rootDir/common.gradle" diff --git a/src/en/mangasect/src/eu/kanade/tachiyomi/extension/en/mangasect/MangaSect.kt b/src/en/mangasect/src/eu/kanade/tachiyomi/extension/en/mangasect/MangaSect.kt index 8803f71ad..6282eee4d 100644 --- a/src/en/mangasect/src/eu/kanade/tachiyomi/extension/en/mangasect/MangaSect.kt +++ b/src/en/mangasect/src/eu/kanade/tachiyomi/extension/en/mangasect/MangaSect.kt @@ -1,238 +1,15 @@ package eu.kanade.tachiyomi.extension.en.mangasect -import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.multisrc.liliana.Liliana import eu.kanade.tachiyomi.network.interceptor.rateLimit -import eu.kanade.tachiyomi.source.model.Filter -import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.MangasPage -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 kotlinx.serialization.Serializable -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.json.Json -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response -import org.jsoup.Jsoup -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import uy.kohesive.injekt.injectLazy -class MangaSect : ParsedHttpSource() { - - override val name = "Manga Sect" - - override val baseUrl = "https://mangasect.com" - - override val lang = "en" - - override val supportsLatest = true - - private val json: Json by injectLazy() - - override val client: OkHttpClient = network.cloudflareClient.newBuilder() +class MangaSect : Liliana( + "Manga Sect", + "https://mangasect.net", + "en", + usesPostSearch = true, +) { + override val client = super.client.newBuilder() .rateLimit(1) .build() - - override fun headersBuilder() = super.headersBuilder() - .add("Referer", "$baseUrl/") - - // Popular - - override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/ranking/week/$page", headers) - - override fun popularMangaSelector(): String = "div#main div.grid > div" - - override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply { - thumbnail_url = element.selectFirst("img")?.imgAttr() - element.selectFirst(".text-center a")!!.run { - title = text().trim() - setUrlWithoutDomain(attr("href")) - } - } - - override fun popularMangaNextPageSelector(): String = ".blog-pager > span.pagecurrent + span" - - // Latest - - override fun latestUpdatesRequest(page: Int): Request = - GET("$baseUrl/all-manga/$page/?sort=1", headers) - - override fun latestUpdatesParse(response: Response): MangasPage = popularMangaParse(response) - - override fun latestUpdatesSelector(): String = - throw UnsupportedOperationException() - - override fun latestUpdatesFromElement(element: Element): SManga = - throw UnsupportedOperationException() - - override fun latestUpdatesNextPageSelector(): String = - throw UnsupportedOperationException() - - // Search - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val url = baseUrl.toHttpUrl().newBuilder().apply { - if (query.isNotBlank()) { - addPathSegment("search") - addQueryParameter("keyword", query) - } else { - addPathSegment("filter") - filters.forEach { filter -> - when (filter) { - is GenreFilter -> { - if (filter.checked.isNotEmpty()) { - addQueryParameter("genres", filter.checked.joinToString(",")) - } - } - is StatusFilter -> { - if (filter.selected.isNotBlank()) { - addQueryParameter("status", filter.selected) - } - } - is SortFilter -> { - addQueryParameter("sort", filter.selected) - } - is ChapterCountFilter -> { - addQueryParameter("chapter_count", filter.selected) - } - is GenderFilter -> { - addQueryParameter("sex", filter.selected) - } - else -> {} - } - } - } - - addPathSegment(page.toString()) - addPathSegment("") - } - - return GET(url.build(), headers) - } - - override fun searchMangaParse(response: Response): MangasPage = popularMangaParse(response) - - override fun searchMangaSelector(): String = - throw UnsupportedOperationException() - - override fun searchMangaFromElement(element: Element): SManga = - throw UnsupportedOperationException() - - override fun searchMangaNextPageSelector(): String = - throw UnsupportedOperationException() - - // Filters - - override fun getFilterList(): FilterList = FilterList( - Filter.Header("Ignored when using text search"), - Filter.Separator(), - GenreFilter(), - ChapterCountFilter(), - GenderFilter(), - StatusFilter(), - SortFilter(), - ) - - // Details - - override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply { - description = document.selectFirst("div#syn-target")?.text() - thumbnail_url = document.selectFirst(".a1 > figure img")?.imgAttr() - title = document.selectFirst(".a2 header h1")?.text()?.trim() ?: "N/A" - genre = document.select(".a2 div > a[rel='tag'].label").joinToString(", ") { it.text() } - - document.selectFirst(".a1 > aside")?.run { - author = select("div:contains(Authors) > span a") - .joinToString(", ") { it.text().trim() } - .takeUnless { it.isBlank() || it.equals("Updating", true) } - status = selectFirst("div:contains(Status) > span")?.text().let(::parseStatus) - } - } - - private fun parseStatus(status: String?): Int = when { - status.equals("ongoing", true) -> SManga.ONGOING - status.equals("completed", true) -> SManga.COMPLETED - status.equals("on-hold", true) -> SManga.ON_HIATUS - status.equals("canceled", true) -> SManga.CANCELLED - else -> SManga.UNKNOWN - } - - // Chapters - - override fun chapterListSelector() = "ul > li.chapter" - - override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply { - element.selectFirst("time[datetime]")?.also { - date_upload = it.attr("datetime").toLongOrNull()?.let { it * 1000L } ?: 0L - } - element.selectFirst("a")!!.run { - text().trim().also { - name = it - chapter_number = it.substringAfter("hapter ").toFloatOrNull() ?: 0F - } - setUrlWithoutDomain(attr("href")) - } - } - - // Pages - - override fun pageListRequest(chapter: SChapter): Request { - val pageHeaders = headersBuilder().apply { - add("Accept", "application/json, text/javascript, */*; q=0.01") - add("Host", baseUrl.toHttpUrl().host) - add("Referer", baseUrl + chapter.url) - add("X-Requested-With", "XMLHttpRequest") - }.build() - - val id = chapter.url.split("/").last() - return GET("$baseUrl/ajax/image/list/chap/$id", pageHeaders) - } - - @Serializable - data class PageListResponseDto(val html: String) - - override fun pageListParse(response: Response): List { - val data = response.parseAs().html - return pageListParse( - Jsoup.parseBodyFragment( - data, - response.request.header("Referer")!!, - ), - ) - } - - override fun pageListParse(document: Document): List { - return document.select("div.separator").map { page -> - val index = page.attr("data-index").toInt() - val url = page.selectFirst("a")!!.attr("abs:href") - Page(index, document.location(), url) - }.sortedBy { it.index } - } - - override fun imageUrlParse(document: Document) = "" - - override fun imageRequest(page: Page): Request { - val imgHeaders = headersBuilder().apply { - add("Accept", "image/avif,image/webp,*/*") - add("Host", page.imageUrl!!.toHttpUrl().host) - }.build() - return GET(page.imageUrl!!, imgHeaders) - } - - // Utilities - - // From mangathemesia - private fun Element.imgAttr(): String = when { - hasAttr("data-lazy-src") -> attr("abs:data-lazy-src") - hasAttr("data-src") -> attr("abs:data-src") - else -> attr("abs:src") - } - - private inline fun Response.parseAs(): T { - return json.decodeFromString(body.string()) - } } diff --git a/src/en/mangasect/src/eu/kanade/tachiyomi/extension/en/mangasect/MangaSectFilters.kt b/src/en/mangasect/src/eu/kanade/tachiyomi/extension/en/mangasect/MangaSectFilters.kt deleted file mode 100644 index 92fbaa4fc..000000000 --- a/src/en/mangasect/src/eu/kanade/tachiyomi/extension/en/mangasect/MangaSectFilters.kt +++ /dev/null @@ -1,167 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.mangasect - -import eu.kanade.tachiyomi.source.model.Filter - -abstract class SelectFilter( - name: String, - private val options: List>, -) : Filter.Select( - name, - options.map { it.first }.toTypedArray(), -) { - val selected get() = options[state].second -} - -class CheckBoxFilter( - name: String, - val value: String, -) : Filter.CheckBox(name) - -class ChapterCountFilter : SelectFilter("Chapter count", chapterCount) { - companion object { - private val chapterCount = listOf( - Pair(">= 0", "0"), - Pair(">= 10", "10"), - Pair(">= 30", "30"), - Pair(">= 50", "50"), - Pair(">= 100", "100"), - Pair(">= 200", "200"), - Pair(">= 300", "300"), - Pair(">= 400", "400"), - Pair(">= 500", "500"), - ) - } -} - -class GenderFilter : SelectFilter("Manga Gender", gender) { - companion object { - private val gender = listOf( - Pair("All", "All"), - Pair("Boy", "Boy"), - Pair("Girl", "Girl"), - ) - } -} - -class StatusFilter : SelectFilter("Status", status) { - companion object { - private val status = listOf( - Pair("All", ""), - Pair("Completed", "completed"), - Pair("OnGoing", "on-going"), - Pair("On-Hold", "on-hold"), - Pair("Canceled", "canceled"), - ) - } -} - -class SortFilter : SelectFilter("Sort", sort) { - companion object { - private val sort = listOf( - Pair("Default", "default"), - Pair("Latest Updated", "latest-updated"), - Pair("Most Viewed", "most-viewd"), - Pair("Score", "score"), - Pair("Name A-Z", "az"), - Pair("Name Z-A", "za"), - Pair("Newest", "new"), - Pair("Oldest", "old"), - ) - } -} - -class GenreFilter : Filter.Group( - "Genre", - genres.map { CheckBoxFilter(it.first, it.second) }, -) { - val checked get() = state.filter { it.state }.map { it.value } - - companion object { - private val genres = listOf( - Pair("Action", "29"), - Pair("Adaptation", "66"), - Pair("Adult", "108"), - Pair("Adventure", "33"), - Pair("Aliens", "2326"), - Pair("Animals", "199"), - Pair("Comedy", "35"), - Pair("Comic", "109"), - Pair("Cooking", "26"), - Pair("Crime", "274"), - Pair("Delinquents", "234"), - Pair("Demons", "136"), - Pair("Drama", "39"), - Pair("Dungeons", "204"), - Pair("Ecchi", "54"), - Pair("Fantasy", "30"), - Pair("Full Color", "27"), - Pair("Genderswap", "1441"), - Pair("Genius MC", "209"), - Pair("Ghosts", "1527"), - Pair("Gore", "1678"), - Pair("Harem", "43"), - Pair("Historical", "49"), - Pair("Horror", "69"), - Pair("Incest", "1189"), - Pair("Isekai", "40"), - Pair("Loli", "198"), - Pair("Long Strip", "233"), - Pair("Magic", "212"), - Pair("Magical Girls", "1676"), - Pair("Manhua", "58"), - Pair("Manhwa", "80"), - Pair("Martial Arts", "32"), - Pair("Mature", "34"), - Pair("Mecha", "70"), - Pair("Medical", "2113"), - Pair("Military", "1531"), - Pair("Monster", "218"), - Pair("Monster Girls", "201"), - Pair("Monsters", "63"), - Pair("Murim", "208"), - Pair("Music", "412"), - Pair("Mystery", "31"), - Pair("One shot", "155"), - Pair("Overpowered", "206"), - Pair("Police", "275"), - Pair("Post-Apocalyptic", "197"), - Pair("Psychological", "36"), - Pair("Rebirth", "1435"), - Pair("Recarnation", "67"), - Pair("Regression", "205"), - Pair("Reincarnation", "64"), - Pair("Return", "1454"), - Pair("Returner", "211"), - Pair("Revenge", "219"), - Pair("Romance", "37"), - Pair("School Life", "44"), - Pair("Sci fi", "42"), - Pair("Sci-fi", "216"), - Pair("Seinen", "52"), - Pair("Sexual Violence", "2325"), - Pair("Shota", "2327"), - Pair("Shoujo", "92"), - Pair("Shounen", "38"), - Pair("Shounen ai", "103"), - Pair("Slice of Life", "68"), - Pair("Super power", "213"), - Pair("Superhero", "1630"), - Pair("Supernatural", "41"), - Pair("Survival", "463"), - Pair("System", "203"), - Pair("Thriller", "462"), - Pair("Time travel", "65"), - Pair("tower", "207"), - Pair("Tragedy", "51"), - Pair("Transmigration", "217"), - Pair("Uncategorized", "55"), - Pair("Vampires", "200"), - Pair("Video Games", "1606"), - Pair("Virtual Reality", "757"), - Pair("Web comic", "98"), - Pair("Webtoons", "77"), - Pair("Wuxia", "202"), - Pair("Zombies", "464"), - ) - } -} diff --git a/src/ja/mangakoma/src/eu/kanade/tachiyomi/extension/ja/mangakoma/MangaKoma.kt b/src/ja/mangakoma/src/eu/kanade/tachiyomi/extension/ja/mangakoma/MangaKoma.kt index 165a75dfb..ead00e195 100644 --- a/src/ja/mangakoma/src/eu/kanade/tachiyomi/extension/ja/mangakoma/MangaKoma.kt +++ b/src/ja/mangakoma/src/eu/kanade/tachiyomi/extension/ja/mangakoma/MangaKoma.kt @@ -1,18 +1,5 @@ package eu.kanade.tachiyomi.extension.ja.mangakoma import eu.kanade.tachiyomi.multisrc.liliana.Liliana -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.Page -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.Request -class MangaKoma : Liliana("Manga Koma", "https://mangakoma01.net", "ja") { - override fun imageRequest(page: Page): Request { - val imgHeaders = headersBuilder().apply { - add("Accept", "image/avif,image/webp,*/*") - add("Host", page.imageUrl!!.toHttpUrl().host) - removeAll("Referer") - }.build() - return GET(page.imageUrl!!, imgHeaders) - } -} +class MangaKoma : Liliana("Manga Koma", "https://mangakoma01.net", "ja")