MyReadingManga: Improve search query with more filters

master
dragonx943 7 months ago
parent 8a18df148d
commit 7cb069d108
No known key found for this signature in database
GPG Key ID: 48DD99A2C5421C1C

@ -15,7 +15,7 @@ jobs:
- name: Set up enviroment 🔧 - name: Set up enviroment 🔧
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with: with:
java-version: '17' java-version: '21'
distribution: 'temurin' distribution: 'temurin'
- name: Set up Gradle 📦 - name: Set up Gradle 📦

@ -19,7 +19,7 @@ jobs:
- name: Set up enviroment 🔧 - name: Set up enviroment 🔧
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
with: with:
java-version: '17' java-version: '21'
distribution: 'temurin' distribution: 'temurin'
- name: Set up Gradle 📦 - name: Set up Gradle 📦

@ -1,8 +1,8 @@
package org.koitharu.kotatsu.parsers.site.all package org.koitharu.kotatsu.parsers.site.all
import okhttp3.Headers
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import org.koitharu.kotatsu.parsers.Broken
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.config.ConfigKey
@ -23,34 +23,39 @@ import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl
import org.koitharu.kotatsu.parsers.util.generateUid import org.koitharu.kotatsu.parsers.util.generateUid
import org.koitharu.kotatsu.parsers.util.mapToSet import org.koitharu.kotatsu.parsers.util.mapToSet
import org.koitharu.kotatsu.parsers.util.oneOrThrowIfMany
import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.parseHtml
import org.koitharu.kotatsu.parsers.util.splitByWhitespace
import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
import org.koitharu.kotatsu.parsers.util.urlEncoded
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.EnumSet import java.util.EnumSet
import java.util.Locale import java.util.Locale
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlin.collections.joinToString
@Broken("Need to rewrite getListPage")
@MangaSourceParser("MYREADINGMANGA", "MyReadingManga", type = ContentType.HENTAI) @MangaSourceParser("MYREADINGMANGA", "MyReadingManga", type = ContentType.HENTAI)
internal class MyReadingManga(context: MangaLoaderContext) : internal class MyReadingManga(context: MangaLoaderContext) :
PagedMangaParser(context, MangaParserSource.MYREADINGMANGA, 18) { PagedMangaParser(context, MangaParserSource.MYREADINGMANGA, 18) {
override val configKeyDomain = ConfigKey.Domain("myreadingmanga.info") override val configKeyDomain = ConfigKey.Domain("myreadingmanga.info")
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) { override fun getRequestHeaders(): Headers = Headers.Builder()
super.onCreateConfig(keys) .add("User-Agent", "Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36")
keys.add(userAgentKey) .add("X-Requested-With", randomString((1..20).random()))
} .build()
override val filterCapabilities: MangaListFilterCapabilities override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities( get() = MangaListFilterCapabilities(
isSearchSupported = true, isSearchSupported = true,
isSearchWithFiltersSupported = true,
isMultipleTagsSupported = true,
isOriginalLocaleSupported = true, isOriginalLocaleSupported = true,
) )
override val availableSortOrders: Set<SortOrder> = EnumSet.of( override val availableSortOrders: Set<SortOrder> = EnumSet.of(
SortOrder.UPDATED, SortOrder.RELEVANCE,
SortOrder.NEWEST,
SortOrder.NEWEST_ASC,
) )
override suspend fun getFilterOptions() = MangaListFilterOptions( override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -58,6 +63,8 @@ internal class MyReadingManga(context: MangaLoaderContext) :
availableStates = EnumSet.of( availableStates = EnumSet.of(
MangaState.ONGOING, MangaState.ONGOING,
MangaState.FINISHED, MangaState.FINISHED,
MangaState.PAUSED,
MangaState.ABANDONED,
), ),
availableContentRating = EnumSet.of(ContentRating.ADULT), availableContentRating = EnumSet.of(ContentRating.ADULT),
availableLocales = setOf( availableLocales = setOf(
@ -102,6 +109,8 @@ internal class MyReadingManga(context: MangaLoaderContext) :
private fun getLanguageSlug(locale: Locale?): String? { private fun getLanguageSlug(locale: Locale?): String? {
return when { return when {
locale?.language == "en" -> "english"
locale?.language == "ja" -> "japanese"
locale?.language == "fr" -> "french" locale?.language == "fr" -> "french"
locale?.language == "ja" -> "jp" locale?.language == "ja" -> "jp"
locale?.language == "zh" && locale.country == "TW" -> "traditional-chinese" locale?.language == "zh" && locale.country == "TW" -> "traditional-chinese"
@ -141,74 +150,52 @@ internal class MyReadingManga(context: MangaLoaderContext) :
} }
} }
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> { override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString { val url = buildString {
append("https://") append("https://")
append(domain) append(domain)
// Add language path if specified, need to fix
val langSlug = getLanguageSlug(filter.locale)
if (langSlug != null) {
append("/lang/")
append(langSlug)
}
when {
!filter.query.isNullOrEmpty() -> {
// Search with language: /lang/french/page/2/?s=example
if (page > 1) { if (page > 1) {
append("/page/") append("/page/")
append(page) append(page)
} }
append("/?s=")
append(filter.query.urlEncoded()) append("/?ep_sort=")
when (order) {
SortOrder.NEWEST -> append("date")
SortOrder.NEWEST_ASC -> append("date_asc")
else -> append("")
} }
filter.tags.isNotEmpty() -> { if (!filter.query.isNullOrEmpty()) {
// Genre filtering doesn't work with language, so we ignore language for genre append("&s=")
if (langSlug == null) { append(filter.query.splitByWhitespace().joinToString(separator = "+"))
append("/genre/")
append(filter.tags.first().key)
append("/page/")
append(page)
append("/")
} else {
// If both language and genre are selected, just use language
append("/page/")
append(page)
append("/")
} }
val langSlug = getLanguageSlug(filter.locale)
if (langSlug != null) {
append("&ep_filter_lang=")
append(langSlug)
} }
filter.states.isNotEmpty() -> { if (filter.states.isNotEmpty()) {
// Status filtering doesn't work with language either append("&ep_filter_status=")
if (langSlug == null) { filter.states.oneOrThrowIfMany()?.let {
append("/status/")
append( append(
when (filter.states.first()) { when (it) {
MangaState.ONGOING -> "ongoing" MangaState.ONGOING -> "ongoing"
MangaState.FINISHED -> "completed" MangaState.FINISHED -> "completed"
else -> "ongoing" MangaState.PAUSED -> "hiatus"
}, MangaState.ABANDONED -> "dropped"
else -> ""
}
) )
append("/page/")
append(page)
append("/")
} else {
// If both language and status are selected, just use language
append("/page/")
append(page)
append("/")
} }
} }
else -> { if (filter.tags.isNotEmpty()) {
// Regular browsing with or without language append("&ep_filter_genre=")
append("/page/") append(filter.tags.joinToString(",") { it.key })
append(page)
append("/")
}
} }
} }
@ -302,6 +289,8 @@ internal class MyReadingManga(context: MangaLoaderContext) :
val state = when (doc.select("a[href*=status]").firstOrNull()?.text()) { val state = when (doc.select("a[href*=status]").firstOrNull()?.text()) {
"Ongoing" -> MangaState.ONGOING "Ongoing" -> MangaState.ONGOING
"Completed" -> MangaState.FINISHED "Completed" -> MangaState.FINISHED
"Hiatus" -> MangaState.PAUSED
"Dropped" -> MangaState.ABANDONED
else -> null else -> null
} }
@ -449,5 +438,10 @@ internal class MyReadingManga(context: MangaLoaderContext) :
0L 0L
} }
} }
private fun randomString(length: Int): String {
val charPool = ('a'..'z') + ('A'..'Z')
return List(length) { charPool.random() }.joinToString("")
}
} }

Loading…
Cancel
Save