From 6c1e55053c67f14c564efd3ba5ae7b571cee88c3 Mon Sep 17 00:00:00 2001 From: Cuong-Tran Date: Thu, 20 Feb 2025 21:45:30 +0700 Subject: [PATCH] Madara: Expose genresList (#7674) * Madara: Allow ext to preload with a list of genres Help with fork like SY which allows saving search * fix extensions * update the fetchSearchManga to using HttpUrlBuilder --- lib-multisrc/madara/build.gradle.kts | 2 +- .../tachiyomi/multisrc/madara/Madara.kt | 27 ++++++++++--- .../extension/en/gourmetscans/GourmetScans.kt | 16 ++++---- .../extension/en/manga18fx/Manga18fx.kt | 17 ++++---- .../en/manhwahentaime/ManhwahentaiMe.kt | 38 ++++++------------ .../extension/en/manycomic/ManyComic.kt | 29 +++----------- .../extension/en/manytoon/ManyToon.kt | 39 ++++++------------- .../extension/es/leermanga/LeerManga.kt | 5 +-- .../tachiyomi/extension/id/mgkomik/MGKomik.kt | 30 +++----------- .../extension/id/pojokmanga/PojokManga.kt | 2 +- 10 files changed, 74 insertions(+), 131 deletions(-) diff --git a/lib-multisrc/madara/build.gradle.kts b/lib-multisrc/madara/build.gradle.kts index 8255bf3e7..d96dd889d 100644 --- a/lib-multisrc/madara/build.gradle.kts +++ b/lib-multisrc/madara/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("lib-multisrc") } -baseVersionCode = 39 +baseVersionCode = 40 dependencies { api(project(":lib:cryptoaes")) diff --git a/lib-multisrc/madara/src/eu/kanade/tachiyomi/multisrc/madara/Madara.kt b/lib-multisrc/madara/src/eu/kanade/tachiyomi/multisrc/madara/Madara.kt index 074512f36..00a019ce5 100644 --- a/lib-multisrc/madara/src/eu/kanade/tachiyomi/multisrc/madara/Madara.kt +++ b/lib-multisrc/madara/src/eu/kanade/tachiyomi/multisrc/madara/Madara.kt @@ -82,7 +82,12 @@ abstract class Madara( /** * Automatically fetched genres from the source to be used in the filters. */ - private var genresList: List = emptyList() + protected open var genresList: List = emptyList() + + /** + * Whether genres have been fetched + */ + private var genresFetched: Boolean = false /** * Inner variable to control how much tries the genres request was called. @@ -237,11 +242,14 @@ abstract class Madara( override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { if (query.startsWith(URL_SEARCH_PREFIX)) { - val mangaUrl = "/$mangaSubString/${query.substringAfter(URL_SEARCH_PREFIX)}/" - return client.newCall(GET("$baseUrl$mangaUrl", headers)) + val mangaUrl = baseUrl.toHttpUrl().newBuilder().apply { + addPathSegment(mangaSubString) + addPathSegment(query.substringAfter(URL_SEARCH_PREFIX)) + }.build() + return client.newCall(GET(mangaUrl, headers)) .asObservableSuccess().map { response -> val manga = mangaDetailsParse(response).apply { - url = mangaUrl + setUrlWithoutDomain(mangaUrl.toString()) } MangasPage(listOf(manga), false) @@ -1069,10 +1077,17 @@ abstract class Madara( * Fetch the genres from the source to be used in the filters. */ protected fun fetchGenres() { - if (fetchGenres && fetchGenresAttempts < 3 && genresList.isEmpty()) { + if (fetchGenres && fetchGenresAttempts < 3 && !genresFetched) { try { - genresList = client.newCall(genresRequest()).execute() + client.newCall(genresRequest()).execute() .use { parseGenres(it.asJsoup()) } + .also { + genresFetched = true + } + .takeIf { it.isNotEmpty() } + ?.also { + genresList = it + } } catch (_: Exception) { } finally { fetchGenresAttempts++ diff --git a/src/en/gourmetscans/src/eu/kanade/tachiyomi/extension/en/gourmetscans/GourmetScans.kt b/src/en/gourmetscans/src/eu/kanade/tachiyomi/extension/en/gourmetscans/GourmetScans.kt index 657a736f0..84239f371 100644 --- a/src/en/gourmetscans/src/eu/kanade/tachiyomi/extension/en/gourmetscans/GourmetScans.kt +++ b/src/en/gourmetscans/src/eu/kanade/tachiyomi/extension/en/gourmetscans/GourmetScans.kt @@ -61,24 +61,22 @@ class GourmetScans : Madara( override fun genresRequest(): Request = GET("$baseUrl/$mangaSubString", headers) override fun parseGenres(document: Document): List { - genresList = document.select("div.row.genres ul li a") + return document.select("div.row.genres ul li a") .orEmpty() .map { li -> - Pair( + Genre( li.text(), li.attr("href").split("/").last { it.isNotBlank() }, ) } - - return emptyList() } - private var genresList: List> = emptyList() - - class GenreFilter(vals: List>) : - UriPartFilter("Genre", vals.toTypedArray()) + class GenreFilter(vals: List) : + UriPartFilter("Genre", vals.map { Pair(it.name, it.id) }.toTypedArray()) override fun getFilterList(): FilterList { + launchIO { fetchGenres() } + val filters = buildList(4) { add(YearFilter(intl["year_filter_title"])) add( @@ -93,7 +91,7 @@ class GourmetScans : Madara( if (genresList.isEmpty()) { add(Filter.Header(intl["genre_missing_warning"])) } else { - add(GenreFilter(listOf(Pair("", "")) + genresList)) } } diff --git a/src/en/manga18fx/src/eu/kanade/tachiyomi/extension/en/manga18fx/Manga18fx.kt b/src/en/manga18fx/src/eu/kanade/tachiyomi/extension/en/manga18fx/Manga18fx.kt index 87c54b9ea..3e8112f91 100644 --- a/src/en/manga18fx/src/eu/kanade/tachiyomi/extension/en/manga18fx/Manga18fx.kt +++ b/src/en/manga18fx/src/eu/kanade/tachiyomi/extension/en/manga18fx/Manga18fx.kt @@ -68,7 +68,7 @@ class Manga18fx : Madara( if (query.isEmpty()) { filters.forEach { filter -> if (filter is GenreFilter) { - return GET(filter.vals[filter.state].second, headers) + return GET(filter.vals[filter.state].id, headers) } } return latestUpdatesRequest(page) @@ -94,23 +94,22 @@ class Manga18fx : Madara( override fun chapterDateSelector() = "span.chapter-time" - class GenreFilter(val vals: List>) : - Filter.Select("Genre", vals.map { it.first }.toTypedArray()) + class GenreFilter(val vals: List) : + Filter.Select("Genre", vals.map { it.name }.toTypedArray()) private fun loadGenres(document: Document) { genresList = document.select(".header-bottom li a").map { val href = it.attr("href") val url = if (href.startsWith("http")) href else "$baseUrl/$href" - Pair(it.text(), url) + Genre(it.text(), url) } } - private var genresList: List> = emptyList() - private var hardCodedTypes: List> = listOf( - Pair("Manhwa", "$baseUrl/manga-genre/manhwa"), - Pair("Manhua", "$baseUrl/manga-genre/manhua"), - Pair("Raw", "$baseUrl/manga-genre/raw"), + private var hardCodedTypes: List = listOf( + Genre("Manhwa", "$baseUrl/manga-genre/manhwa"), + Genre("Manhua", "$baseUrl/manga-genre/manhua"), + Genre("Raw", "$baseUrl/manga-genre/raw"), ) override fun getFilterList(): FilterList { diff --git a/src/en/manhwahentaime/src/eu/kanade/tachiyomi/extension/en/manhwahentaime/ManhwahentaiMe.kt b/src/en/manhwahentaime/src/eu/kanade/tachiyomi/extension/en/manhwahentaime/ManhwahentaiMe.kt index 8d5408062..0e712d028 100644 --- a/src/en/manhwahentaime/src/eu/kanade/tachiyomi/extension/en/manhwahentaime/ManhwahentaiMe.kt +++ b/src/en/manhwahentaime/src/eu/kanade/tachiyomi/extension/en/manhwahentaime/ManhwahentaiMe.kt @@ -104,35 +104,22 @@ class ManhwahentaiMe : Madara("Manhwahentai.me", "https://manhwahentai.me", "en" intl["order_by_filter_new"] to "new-manga", ) - private var genresList: List> = emptyList() - private var fetchGenresAttempts: Int = 0 - - private fun fetchGenresMe() { - if (fetchGenres && fetchGenresAttempts < 3 && genresList.isEmpty()) { - try { - genresList = client.newCall(genresRequest()).execute() - .use { parseGenresMe(it.asJsoup()) } - } catch (_: Exception) { - } finally { - fetchGenresAttempts++ - } - } - } - - private fun parseGenresMe(document: Document): List> { + override fun parseGenres(document: Document): List { return document.selectFirst("div.genres") ?.select("a") .orEmpty() .map { a -> - a.ownText() to - a.attr("href").substringBeforeLast("/").substringAfterLast("/") + Genre( + a.ownText(), + a.attr("href").substringBeforeLast("/").substringAfterLast("/"), + ) }.let { - listOf(("All" to "all")) + it + listOf(Genre("All", "all")) + it } } override fun getFilterList(): FilterList { - launchIO { fetchGenresMe() } + launchIO { fetchGenres() } val filters = mutableListOf( Filter.Header("All filters except the orderby filter are incompatible with each other"), @@ -145,17 +132,16 @@ class ManhwahentaiMe : Madara("Manhwahentai.me", "https://manhwahentai.me", "en" ), ) - if (genresList.isNotEmpty()) { - filters += listOf( + filters += if (genresList.isNotEmpty()) { + listOf( Filter.Separator(), - Filter.Header(intl["genre_filter_header"]), GenreConditionFilter( title = intl["genre_filter_title"], - options = genresList, + options = genresList.map { it.name to it.id }, ), ) - } else if (fetchGenres) { - filters += listOf( + } else { + listOf( Filter.Separator(), Filter.Header(intl["genre_missing_warning"]), ) diff --git a/src/en/manycomic/src/eu/kanade/tachiyomi/extension/en/manycomic/ManyComic.kt b/src/en/manycomic/src/eu/kanade/tachiyomi/extension/en/manycomic/ManyComic.kt index b6dd40d20..e66168486 100644 --- a/src/en/manycomic/src/eu/kanade/tachiyomi/extension/en/manycomic/ManyComic.kt +++ b/src/en/manycomic/src/eu/kanade/tachiyomi/extension/en/manycomic/ManyComic.kt @@ -5,7 +5,6 @@ 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.util.asJsoup import okhttp3.FormBody import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Request @@ -67,7 +66,7 @@ class ManyComic : Madara("ManyComic", "https://manycomic.com", "en") { override fun searchMangaSelector() = popularMangaSelector() override fun getFilterList(): FilterList { - launchIO { fetchGenres_() } + launchIO { fetchGenres() } val filters: MutableList> = mutableListOf( OrderByFilter( @@ -77,18 +76,18 @@ class ManyComic : Madara("ManyComic", "https://manycomic.com", "en") { ), ) - if (genresList.isNotEmpty()) { - filters += listOf( + filters += if (genresList.isNotEmpty()) { + listOf( Filter.Separator(), Filter.Header("Genre filter is ignored when searching by title"), GenreFilter( title = intl["genre_filter_title"], - options = genresList, + options = listOf(Genre("", "")) + genresList, state = 0, ), ) - } else if (fetchGenres) { - filters += listOf( + } else { + listOf( Filter.Separator(), Filter.Header(intl["genre_missing_warning"]), ) @@ -106,22 +105,6 @@ class ManyComic : Madara("ManyComic", "https://manycomic.com", "en") { intl["order_by_filter_new"] to "new-manga", ) - private var genresList: List = emptyList() - private var fetchGenresAttempts: Int = 0 - - private fun fetchGenres_() { - if (fetchGenres && fetchGenresAttempts < 3 && genresList.isEmpty()) { - try { - genresList = listOf(Genre("", "")) + - client.newCall(genresRequest()).execute() - .use { parseGenres(it.asJsoup()) } - } catch (_: Exception) { - } finally { - fetchGenresAttempts++ - } - } - } - private class GenreFilter(title: String, options: List, state: Int = 0) : UriPartFilter(title, options.map { Pair(it.name, it.id) }.toTypedArray(), state) } diff --git a/src/en/manytoon/src/eu/kanade/tachiyomi/extension/en/manytoon/ManyToon.kt b/src/en/manytoon/src/eu/kanade/tachiyomi/extension/en/manytoon/ManyToon.kt index bc6876ed9..4a56371c2 100644 --- a/src/en/manytoon/src/eu/kanade/tachiyomi/extension/en/manytoon/ManyToon.kt +++ b/src/en/manytoon/src/eu/kanade/tachiyomi/extension/en/manytoon/ManyToon.kt @@ -5,7 +5,6 @@ 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.util.asJsoup import okhttp3.FormBody import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Request @@ -94,35 +93,22 @@ class ManyToon : Madara("ManyToon", "https://manytoon.com", "en") { intl["order_by_filter_new"] to "new-manga", ) - private var genresList: List> = emptyList() - private var fetchGenresAttempts: Int = 0 - - private fun fetchGenresMe() { - if (fetchGenres && fetchGenresAttempts < 3 && genresList.isEmpty()) { - try { - genresList = client.newCall(genresRequest()).execute() - .use { parseGenresMe(it.asJsoup()) } - } catch (_: Exception) { - } finally { - fetchGenresAttempts++ - } - } - } - - private fun parseGenresMe(document: Document): List> { + override fun parseGenres(document: Document): List { return document.selectFirst("div.genres") ?.select("a") .orEmpty() .map { a -> - a.ownText() to - a.attr("href").substringBeforeLast("/").substringAfterLast("/") + Genre( + a.ownText(), + a.attr("href").substringBeforeLast("/").substringAfterLast("/"), + ) }.let { - listOf(("All" to "all")) + it + listOf(Genre("All", "all")) + it } } override fun getFilterList(): FilterList { - launchIO { fetchGenresMe() } + launchIO { fetchGenres() } val filters = mutableListOf( Filter.Header("All filters except the orderby filter are incompatible with each other"), @@ -135,17 +121,16 @@ class ManyToon : Madara("ManyToon", "https://manytoon.com", "en") { ), ) - if (genresList.isNotEmpty()) { - filters += listOf( + filters += if (genresList.isNotEmpty()) { + listOf( Filter.Separator(), - Filter.Header(intl["genre_filter_header"]), GenreConditionFilter( title = intl["genre_filter_title"], - options = genresList, + options = genresList.map { it.name to it.id }, ), ) - } else if (fetchGenres) { - filters += listOf( + } else { + listOf( Filter.Separator(), Filter.Header(intl["genre_missing_warning"]), ) diff --git a/src/es/leermanga/src/eu/kanade/tachiyomi/extension/es/leermanga/LeerManga.kt b/src/es/leermanga/src/eu/kanade/tachiyomi/extension/es/leermanga/LeerManga.kt index 355108198..3fe896036 100644 --- a/src/es/leermanga/src/eu/kanade/tachiyomi/extension/es/leermanga/LeerManga.kt +++ b/src/es/leermanga/src/eu/kanade/tachiyomi/extension/es/leermanga/LeerManga.kt @@ -80,19 +80,16 @@ class LeerManga : Madara( // =============================== Filters =============================== - private var genresList: List = emptyList() - override fun getFilterList(): FilterList { val filters = mutableListOf>() if (genresList.isNotEmpty()) { filters += listOf( - Filter.Header(intl["genre_filter_header"]), GenreGroup( displayName = intl["genre_filter_title"], genres = genresList, ), ) - } else if (fetchGenres) { + } else { filters += Filter.Header(intl["genre_missing_warning"]) } return FilterList(filters) diff --git a/src/id/mgkomik/src/eu/kanade/tachiyomi/extension/id/mgkomik/MGKomik.kt b/src/id/mgkomik/src/eu/kanade/tachiyomi/extension/id/mgkomik/MGKomik.kt index 48923d001..4606c640d 100644 --- a/src/id/mgkomik/src/eu/kanade/tachiyomi/extension/id/mgkomik/MGKomik.kt +++ b/src/id/mgkomik/src/eu/kanade/tachiyomi/extension/id/mgkomik/MGKomik.kt @@ -5,7 +5,6 @@ import eu.kanade.tachiyomi.network.GET 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.util.asJsoup import okhttp3.Request import org.jsoup.nodes.Document import java.text.SimpleDateFormat @@ -84,26 +83,21 @@ class MGKomik : Madara( // ================================ Filters ================================ - private var genresList: List = emptyList() - - override val fetchGenres = false - override fun getFilterList(): FilterList { - launchIO { fetchGenresOption() } + launchIO { fetchGenres() } val filters = super.getFilterList().list.toMutableList() - if (genresList.isNotEmpty()) { - filters += listOf( + filters += if (genresList.isNotEmpty()) { + listOf( Filter.Separator(), - Filter.Header(intl["genre_filter_header"]), GenreContentFilter( title = intl["genre_filter_title"], options = genresList.map { it.name to it.id }, ), ) - } else if (fetchGenres) { - filters += listOf( + } else { + listOf( Filter.Separator(), Filter.Header(intl["genre_missing_warning"]), ) @@ -119,20 +113,6 @@ class MGKomik : Madara( override fun genresRequest() = GET("$baseUrl/$mangaSubString", headers) - private var fetchGenresAttempts: Int = 0 - - fun fetchGenresOption() { - if (fetchGenresAttempts < 3 && genresList.isEmpty()) { - try { - genresList = client.newCall(genresRequest()).execute() - .use { parseGenres(it.asJsoup()) } - } catch (_: Exception) { - } finally { - fetchGenresAttempts++ - } - } - } - override fun parseGenres(document: Document): List { val genres = mutableListOf() genres += Genre("All", "") diff --git a/src/id/pojokmanga/src/eu/kanade/tachiyomi/extension/id/pojokmanga/PojokManga.kt b/src/id/pojokmanga/src/eu/kanade/tachiyomi/extension/id/pojokmanga/PojokManga.kt index 246f09f59..02a09b47c 100644 --- a/src/id/pojokmanga/src/eu/kanade/tachiyomi/extension/id/pojokmanga/PojokManga.kt +++ b/src/id/pojokmanga/src/eu/kanade/tachiyomi/extension/id/pojokmanga/PojokManga.kt @@ -83,7 +83,7 @@ class PojokManga : Madara("Pojok Manga", "https://pojokmanga.info", "id", Simple override val mangaDetailsSelectorTag = "#toNotBeUsed" - protected class ProjectFilter : UriPartFilter( + private class ProjectFilter : UriPartFilter( "Filter Project", arrayOf( Pair("Show all manga", ""),