From 6ab5743f66207068c2d4027647b11f3aa1345e77 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Wed, 16 Mar 2022 13:08:26 +0200 Subject: [PATCH] Change configuration behavior --- .../kotatsu/parsers/MangaLoaderContext.kt | 1 + .../koitharu/kotatsu/parsers/MangaParser.kt | 31 +++---- .../kotatsu/parsers/MangaSourceConfig.kt | 6 -- .../kotatsu/parsers/config/ConfigKey.kt | 13 +++ .../parsers/config/MangaSourceConfig.kt | 6 ++ .../kotatsu/parsers/model/Constants.kt | 3 + .../koitharu/kotatsu/parsers/model/Manga.kt | 91 +++++++++++++++++-- .../kotatsu/parsers/model/MangaChapter.kt | 34 ++++++- .../kotatsu/parsers/model/MangaPage.kt | 29 +++++- .../kotatsu/parsers/model/MangaTag.kt | 25 ++++- .../kotatsu/parsers/site/AnibelParser.kt | 11 ++- .../kotatsu/parsers/site/BatoToParser.kt | 12 ++- .../kotatsu/parsers/site/ChanParser.kt | 5 +- .../kotatsu/parsers/site/ComickFunParser.kt | 7 +- .../kotatsu/parsers/site/DesuMeParser.kt | 10 +- .../kotatsu/parsers/site/ExHentaiParser.kt | 15 +-- .../kotatsu/parsers/site/GroupleParser.kt | 5 +- .../kotatsu/parsers/site/HenChanParser.kt | 6 +- .../kotatsu/parsers/site/HentaiLibParser.kt | 8 +- .../kotatsu/parsers/site/MangaChanParser.kt | 6 +- .../kotatsu/parsers/site/MangaDexParser.kt | 16 ++-- .../kotatsu/parsers/site/MangaLibParser.kt | 16 ++-- .../kotatsu/parsers/site/MangaOwlParser.kt | 14 +-- .../kotatsu/parsers/site/MangaTownParser.kt | 10 +- .../kotatsu/parsers/site/MangareadParser.kt | 9 +- .../kotatsu/parsers/site/MintMangaParser.kt | 6 +- .../kotatsu/parsers/site/NineMangaParser.kt | 12 ++- .../kotatsu/parsers/site/NudeMoonParser.kt | 10 +- .../kotatsu/parsers/site/ReadmangaParser.kt | 6 +- .../kotatsu/parsers/site/RemangaParser.kt | 13 ++- .../kotatsu/parsers/site/SelfMangaParser.kt | 6 +- .../kotatsu/parsers/site/YaoiChanParser.kt | 6 +- .../kotatsu/parsers/InMemoryCookieJar.kt | 2 +- .../kotatsu/parsers/MangaLoaderContextMock.kt | 1 + .../kotatsu/parsers/SourceConfigMock.kt | 7 +- 35 files changed, 325 insertions(+), 133 deletions(-) delete mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/MangaSourceConfig.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/config/MangaSourceConfig.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/model/Constants.kt diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaLoaderContext.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaLoaderContext.kt index ccb9e931..cd93b6d8 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaLoaderContext.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaLoaderContext.kt @@ -5,6 +5,7 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.toRequestBody import org.json.JSONObject import org.jsoup.HttpStatusException +import org.koitharu.kotatsu.parsers.config.MangaSourceConfig import org.koitharu.kotatsu.parsers.exception.GraphQLException import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.await diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParser.kt index 84b40d4f..9793f162 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaParser.kt @@ -1,19 +1,18 @@ package org.koitharu.kotatsu.parsers +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* -abstract class MangaParser { +abstract class MangaParser(val source: MangaSource) { protected abstract val context: MangaLoaderContext - abstract val source: MangaSource - abstract val sortOrders: Set - abstract val defaultDomain: String + val config by lazy { context.getConfig(source) } - protected val config by lazy { context.getConfig(source) } + protected abstract val configKeyDomain: ConfigKey.Domain abstract suspend fun getList( offset: Int, @@ -32,10 +31,14 @@ abstract class MangaParser { open fun getFaviconUrl() = "https://${getDomain()}/favicon.ico" + open fun onCreateConfig(keys: MutableCollection>) { + keys.add(configKeyDomain) + } + /* Utils */ - protected fun getDomain(): String { - return config.getDomain(defaultDomain) + fun getDomain(): String { + return config[configKeyDomain] } protected fun generateUid(url: String): Long { @@ -60,25 +63,19 @@ abstract class MangaParser { protected fun String.withDomain(subdomain: String? = null) = when { this.startsWith("//") -> buildString { - append("http") - if (config.isSslEnabled(true)) { - append('s') - } + append("https") append(":") append(this@withDomain) } this.startsWith("/") -> buildString { - append("http") - if (config.isSslEnabled(true)) { - append('s') - } + append("https") append("://") if (subdomain != null) { append(subdomain) append('.') - append(config.getDomain(defaultDomain).removePrefix("www.")) + append(getDomain().removePrefix("www.")) } else { - append(config.getDomain(defaultDomain)) + append(getDomain()) } append(this@withDomain) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaSourceConfig.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaSourceConfig.kt deleted file mode 100644 index 41d0bdde..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/MangaSourceConfig.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.koitharu.kotatsu.parsers - -interface MangaSourceConfig { - fun getDomain(defaultValue: String): String - fun isSslEnabled(defaultValue: Boolean): Boolean -} \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt new file mode 100644 index 00000000..c6c623d1 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.config + +sealed class ConfigKey( + val key: String, +) { + + abstract val defaultValue: T + + class Domain( + override val defaultValue: String, + val presetValues: Array?, + ) : ConfigKey("domain") +} \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/config/MangaSourceConfig.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/config/MangaSourceConfig.kt new file mode 100644 index 00000000..fe8e4590 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/config/MangaSourceConfig.kt @@ -0,0 +1,6 @@ +package org.koitharu.kotatsu.parsers.config + +interface MangaSourceConfig { + + operator fun get(key: ConfigKey): T +} \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/Constants.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/Constants.kt new file mode 100644 index 00000000..1e790de1 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/Constants.kt @@ -0,0 +1,3 @@ +package org.koitharu.kotatsu.parsers.model + +internal const val RATING_UNKNOWN = -1f \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/Manga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/Manga.kt index fff0cd77..a7ee5bea 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/Manga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/Manga.kt @@ -1,25 +1,98 @@ package org.koitharu.kotatsu.parsers.model -data class Manga( +class Manga( val id: Long, val title: String, - val altTitle: String? = null, + val altTitle: String?, val url: String, // relative url for internal use val publicUrl: String, - val rating: Float = NO_RATING, // normalized value [0..1] or -1 - val isNsfw: Boolean = false, + val rating: Float, // normalized value [0..1] or -1 + val isNsfw: Boolean, val coverUrl: String, + val tags: Set, + val state: MangaState?, + val author: String?, val largeCoverUrl: String? = null, val description: String? = null, // HTML - val tags: Set = emptySet(), - val state: MangaState? = null, - val author: String? = null, val chapters: List? = null, val source: MangaSource, ) { - companion object { + val hasRating: Boolean + get() = rating in 0f..1f - const val NO_RATING = -1f + internal fun copy( + title: String = this.title, + altTitle: String? = this.altTitle, + publicUrl: String = this.publicUrl, + rating: Float = this.rating, + isNsfw: Boolean = this.isNsfw, + coverUrl: String = this.coverUrl, + tags: Set = this.tags, + state: MangaState? = this.state, + author: String? = this.author, + largeCoverUrl: String? = this.largeCoverUrl, + description: String? = this.description, + chapters: List? = this.chapters, + ) = Manga( + id = id, + title = title, + altTitle = altTitle, + url = url, + publicUrl = publicUrl, + rating = rating, + isNsfw = isNsfw, + coverUrl = coverUrl, + tags = tags, + state = state, + author = author, + largeCoverUrl = largeCoverUrl, + description = description, + chapters = chapters, + source = source, + ) + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Manga + + if (id != other.id) return false + if (title != other.title) return false + if (altTitle != other.altTitle) return false + if (url != other.url) return false + if (publicUrl != other.publicUrl) return false + if (rating != other.rating) return false + if (isNsfw != other.isNsfw) return false + if (coverUrl != other.coverUrl) return false + if (tags != other.tags) return false + if (state != other.state) return false + if (author != other.author) return false + if (largeCoverUrl != other.largeCoverUrl) return false + if (description != other.description) return false + if (chapters != other.chapters) return false + if (source != other.source) return false + + return true + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + title.hashCode() + result = 31 * result + (altTitle?.hashCode() ?: 0) + result = 31 * result + url.hashCode() + result = 31 * result + publicUrl.hashCode() + result = 31 * result + rating.hashCode() + result = 31 * result + isNsfw.hashCode() + result = 31 * result + coverUrl.hashCode() + result = 31 * result + tags.hashCode() + result = 31 * result + (state?.hashCode() ?: 0) + result = 31 * result + (author?.hashCode() ?: 0) + result = 31 * result + (largeCoverUrl?.hashCode() ?: 0) + result = 31 * result + (description?.hashCode() ?: 0) + result = 31 * result + (chapters?.hashCode() ?: 0) + result = 31 * result + source.hashCode() + return result } } \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaChapter.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaChapter.kt index 896bfeb2..98ef4cf9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaChapter.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaChapter.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.parsers.model -data class MangaChapter( +class MangaChapter( val id: Long, val name: String, val number: Int, @@ -14,4 +14,36 @@ data class MangaChapter( override fun compareTo(other: MangaChapter): Int { return number.compareTo(other.number) } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as MangaChapter + + if (id != other.id) return false + if (name != other.name) return false + if (number != other.number) return false + if (url != other.url) return false + if (scanlator != other.scanlator) return false + if (uploadDate != other.uploadDate) return false + if (branch != other.branch) return false + if (source != other.source) return false + + return true + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + name.hashCode() + result = 31 * result + number + result = 31 * result + url.hashCode() + result = 31 * result + (scanlator?.hashCode() ?: 0) + result = 31 * result + uploadDate.hashCode() + result = 31 * result + (branch?.hashCode() ?: 0) + result = 31 * result + source.hashCode() + return result + } + + } \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaPage.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaPage.kt index 357078de..77de7783 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaPage.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaPage.kt @@ -1,9 +1,34 @@ package org.koitharu.kotatsu.parsers.model -data class MangaPage( +class MangaPage( val id: Long, val url: String, val referer: String, val preview: String?, val source: MangaSource, -) \ No newline at end of file +) { + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as MangaPage + + if (id != other.id) return false + if (url != other.url) return false + if (referer != other.referer) return false + if (preview != other.preview) return false + if (source != other.source) return false + + return true + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + url.hashCode() + result = 31 * result + referer.hashCode() + result = 31 * result + (preview?.hashCode() ?: 0) + result = 31 * result + source.hashCode() + return result + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaTag.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaTag.kt index 065fc1b7..f42252c9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaTag.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/model/MangaTag.kt @@ -1,7 +1,28 @@ package org.koitharu.kotatsu.parsers.model -data class MangaTag( +class MangaTag( val title: String, val key: String, val source: MangaSource, -) \ No newline at end of file +) { + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as MangaTag + + if (title != other.title) return false + if (key != other.key) return false + if (source != other.source) return false + + return true + } + + override fun hashCode(): Int { + var result = title.hashCode() + result = 31 * result + key.hashCode() + result = 31 * result + source.hashCode() + return result + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/AnibelParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/AnibelParser.kt index 4f274828..a5dc9628 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/AnibelParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/AnibelParser.kt @@ -5,17 +5,16 @@ import org.json.JSONArray import org.json.JSONObject import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.json.mapJSON import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed import org.koitharu.kotatsu.parsers.util.json.stringIterator import java.util.* -internal class AnibelParser(override val context: MangaLoaderContext) : MangaParser() { +internal class AnibelParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.ANIBEL) { - override val source = MangaSource.ANIBEL - - override val defaultDomain = "anibel.net" + override val configKeyDomain = ConfigKey.Domain("anibel.net", null) override val sortOrders: Set = EnumSet.of( SortOrder.NEWEST, @@ -73,6 +72,7 @@ internal class AnibelParser(override val context: MangaLoaderContext) : MangaPar .withDomain("cdn") + "?width=200&height=280", altTitle = title.getString("alt").takeUnless(String::isEmpty), author = null, + isNsfw = false, rating = jo.getDouble("rating").toFloat() / 10f, url = href, publicUrl = "https://${getDomain()}/$href", @@ -213,7 +213,8 @@ internal class AnibelParser(override val context: MangaLoaderContext) : MangaPar .withDomain("cdn") + "?width=200&height=280", altTitle = title.getString("en").takeUnless(String::isEmpty), author = null, - rating = Manga.NO_RATING, + isNsfw = false, + rating = RATING_UNKNOWN, url = href, publicUrl = "https://${getDomain()}/$href", tags = emptySet(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/BatoToParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/BatoToParser.kt index 17e625fb..c0c18d14 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/BatoToParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/BatoToParser.kt @@ -6,6 +6,7 @@ import org.json.JSONObject import org.jsoup.nodes.Element import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* import java.nio.charset.StandardCharsets @@ -18,9 +19,7 @@ import javax.crypto.spec.SecretKeySpec private const val PAGE_SIZE = 60 private const val PAGE_SIZE_SEARCH = 20 -internal class BatoToParser(override val context: MangaLoaderContext) : MangaParser() { - - override val source = MangaSource.BATOTO +internal class BatoToParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.BATOTO) { override val sortOrders: Set = EnumSet.of( SortOrder.NEWEST, @@ -29,7 +28,10 @@ internal class BatoToParser(override val context: MangaLoaderContext) : MangaPar SortOrder.ALPHABETICAL, ) - override val defaultDomain: String = "bato.to" + override val configKeyDomain = ConfigKey.Domain( + "bato.to", + arrayOf("bato.to", "mto.to", "mangatoto.com", "battwo.com", "batotwo.com", "comiko.net", "batotoo.com"), + ) override suspend fun getList( offset: Int, @@ -193,7 +195,7 @@ internal class BatoToParser(override val context: MangaLoaderContext) : MangaPar altTitle = div.selectFirst(".item-alias")?.text()?.takeUnless { it == title }, url = href, publicUrl = a.absUrl("href"), - rating = Manga.NO_RATING, + rating = RATING_UNKNOWN, isNsfw = false, coverUrl = div.selectFirst("img[src]")?.absUrl("src").orEmpty(), largeCoverUrl = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ChanParser.kt index e044434d..4113e3eb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ChanParser.kt @@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* -internal abstract class ChanParser : MangaParser() { +internal abstract class ChanParser(source: MangaSource) : MangaParser(source) { override val sortOrders: Set = EnumSet.of( SortOrder.NEWEST, @@ -64,6 +64,9 @@ internal abstract class ChanParser : MangaParser() { ) } }.getOrNull().orEmpty(), + rating = RATING_UNKNOWN, + state = null, + isNsfw = false, source = source, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ComickFunParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ComickFunParser.kt index bfe479ed..5028c0ff 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ComickFunParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ComickFunParser.kt @@ -6,6 +6,7 @@ import org.json.JSONArray import org.json.JSONObject import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.json.JSONIterator @@ -22,10 +23,10 @@ import java.util.* private const val PAGE_SIZE = 20 private const val CHAPTERS_LIMIT = 99999 -internal class ComickFunParser(override val context: MangaLoaderContext) : MangaParser() { +internal class ComickFunParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.COMICK_FUN) { + + override val configKeyDomain = ConfigKey.Domain("comick.fun", null) - override val defaultDomain = "comick.fun" - override val source = MangaSource.COMICK_FUN override val sortOrders: Set = EnumSet.of( SortOrder.POPULARITY, SortOrder.UPDATED, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/DesuMeParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/DesuMeParser.kt index 11d524d9..9ba61469 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/DesuMeParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/DesuMeParser.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* @@ -10,11 +11,9 @@ import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed import org.koitharu.kotatsu.parsers.util.json.mapJSONToSet import java.util.* -internal class DesuMeParser(override val context: MangaLoaderContext) : MangaParser() { +internal class DesuMeParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.DESUME) { - override val source = MangaSource.DESUME - - override val defaultDomain = "desu.me" + override val configKeyDomain = ConfigKey.Domain("desu.me", null) override val sortOrders: Set = EnumSet.of( SortOrder.UPDATED, @@ -71,6 +70,9 @@ internal class DesuMeParser(override val context: MangaLoaderContext) : MangaPar }, rating = jo.getDouble("score").toFloat().coerceIn(0f, 1f), id = generateUid(id), + isNsfw = false, + tags = emptySet(), + author = null, description = jo.getString("description"), ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ExHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ExHentaiParser.kt index abfb9bd7..02216820 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ExHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ExHentaiParser.kt @@ -4,6 +4,7 @@ import org.jsoup.nodes.Element import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParserAuthProvider +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -14,16 +15,16 @@ import kotlin.math.pow private const val DOMAIN_UNAUTHORIZED = "e-hentai.org" private const val DOMAIN_AUTHORIZED = "exhentai.org" -internal class ExHentaiParser(override val context: MangaLoaderContext) : MangaParser(), MangaParserAuthProvider { - - override val source = MangaSource.EXHENTAI +internal class ExHentaiParser( + override val context: MangaLoaderContext, +) : MangaParser(MangaSource.EXHENTAI), MangaParserAuthProvider { override val sortOrders: Set = Collections.singleton( SortOrder.NEWEST, ) - override val defaultDomain: String - get() = if (isAuthorized) DOMAIN_AUTHORIZED else DOMAIN_UNAUTHORIZED + override val configKeyDomain: ConfigKey.Domain + get() = ConfigKey.Domain(if (isAuthorized) DOMAIN_AUTHORIZED else DOMAIN_UNAUTHORIZED, null) override val authUrl: String get() = "https://${getDomain()}/bounce_login.php" @@ -118,7 +119,7 @@ internal class ExHentaiParser(override val context: MangaLoaderContext) : MangaP altTitle = null, url = href, publicUrl = a.absUrl("href"), - rating = td2.selectFirst("div.ir")?.parseRating() ?: Manga.NO_RATING, + rating = td2.selectFirst("div.ir")?.parseRating() ?: RATING_UNKNOWN, isNsfw = true, coverUrl = td1.selectFirst("img")?.absUrl("src").orEmpty(), tags = setOfNotNull(mainTag), @@ -239,7 +240,7 @@ internal class ExHentaiParser(override val context: MangaLoaderContext) : MangaP p1 += 8 } (80 - p1) / 80f - }.getOrDefault(Manga.NO_RATING) + }.getOrDefault(RATING_UNKNOWN) } private fun String.cleanupTitle(): String { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/GroupleParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/GroupleParser.kt index 459748e4..75e1595c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/GroupleParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/GroupleParser.kt @@ -14,7 +14,7 @@ private const val PAGE_SIZE = 70 private const val PAGE_SIZE_SEARCH = 50 private const val NSFW_ALERT = "сексуальные сцены" -internal abstract class GroupleParser : MangaParser() { +internal abstract class GroupleParser(source: MangaSource) : MangaParser(source) { private val headers = Headers.Builder() .add("User-Agent", "readmangafun") @@ -91,8 +91,9 @@ internal abstract class GroupleParser : MangaParser() { ?.substringBefore(' ') ?.toFloatOrNull() ?.div(10f) - }.getOrNull() ?: Manga.NO_RATING, + }.getOrNull() ?: RATING_UNKNOWN, author = tileInfo?.selectFirst("a.person-link")?.text(), + isNsfw = false, tags = runCatching { tileInfo?.select("a.element-link") ?.mapToSet { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HenChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HenChanParser.kt index 22474d49..c19a6236 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HenChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HenChanParser.kt @@ -1,16 +1,16 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.mapToSet import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.toTitleCase -internal class HenChanParser(override val context: MangaLoaderContext) : ChanParser() { +internal class HenChanParser(override val context: MangaLoaderContext) : ChanParser(MangaSource.HENCHAN) { - override val defaultDomain = "hentaichan.live" - override val source = MangaSource.HENCHAN + override val configKeyDomain = ConfigKey.Domain("hentaichan.live", null) override suspend fun getList( offset: Int, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HentaiLibParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HentaiLibParser.kt index f3aab2c6..2181d142 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HentaiLibParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/HentaiLibParser.kt @@ -2,13 +2,11 @@ package org.koitharu.kotatsu.parsers.site import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource -internal class HentaiLibParser(context: MangaLoaderContext) : MangaLibParser(context) { - - override val defaultDomain = "hentailib.me" - - override val source = MangaSource.HENTAILIB +internal class HentaiLibParser(context: MangaLoaderContext) : MangaLibParser(context, MangaSource.HENTAILIB) { + override val configKeyDomain = ConfigKey.Domain("hentailib.me", null) override fun isNsfw(doc: Document) = true } \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaChanParser.kt index 7beac176..ac5a2918 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaChanParser.kt @@ -1,10 +1,10 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource -internal class MangaChanParser(override val context: MangaLoaderContext) : ChanParser() { +internal class MangaChanParser(override val context: MangaLoaderContext) : ChanParser(MangaSource.MANGACHAN) { - override val defaultDomain = "manga-chan.me" - override val source = MangaSource.MANGACHAN + override val configKeyDomain = ConfigKey.Domain("manga-chan.me", null) } \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaDexParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaDexParser.kt index fef31b39..fe107df3 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaDexParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaDexParser.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.coroutineScope import org.json.JSONObject import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.json.* @@ -16,10 +17,9 @@ private const val CONTENT_RATING = "contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic" private const val LOCALE_FALLBACK = "en" -internal class MangaDexParser(override val context: MangaLoaderContext) : MangaParser() { +internal class MangaDexParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGADEX) { - override val source = MangaSource.MANGADEX - override val defaultDomain = "mangadex.org" + override val configKeyDomain = ConfigKey.Domain("mangadex.org", null) override val sortOrders: EnumSet = EnumSet.of( SortOrder.UPDATED, @@ -86,7 +86,7 @@ internal class MangaDexParser(override val context: MangaLoaderContext) : MangaP altTitle = attrs.optJSONObject("altTitles")?.selectByLocale(), url = id, publicUrl = "https://$domain/title/$id", - rating = Manga.NO_RATING, + rating = RATING_UNKNOWN, isNsfw = attrs.getStringOrNull("contentRating") == "erotica", coverUrl = cover?.plus(".256.jpg").orEmpty(), largeCoverUrl = cover, @@ -114,7 +114,7 @@ internal class MangaDexParser(override val context: MangaLoaderContext) : MangaP } } - override suspend fun getDetails(manga: Manga): Manga = coroutineScope { + override suspend fun getDetails(manga: Manga): Manga = coroutineScope { val domain = getDomain() val attrsDeferred = async { context.httpGet( @@ -169,11 +169,11 @@ internal class MangaDexParser(override val context: MangaLoaderContext) : MangaP override suspend fun getPages(chapter: MangaChapter): List { val domain = getDomain() - val chapter = context.httpGet("https://api.$domain/at-home/server/${chapter.url}?forcePort443=false") + val chapterJson = context.httpGet("https://api.$domain/at-home/server/${chapter.url}?forcePort443=false") .parseJson() .getJSONObject("chapter") - val pages = chapter.getJSONArray("data") - val prefix = "https://uploads.$domain/data/${chapter.getString("hash")}/" + val pages = chapterJson.getJSONArray("data") + val prefix = "https://uploads.$domain/data/${chapterJson.getString("hash")}/" val referer = "https://$domain/" return List(pages.length()) { i -> val url = prefix + pages.getString(i) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaLibParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaLibParser.kt index a7acf379..ac51b868 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaLibParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaLibParser.kt @@ -7,6 +7,7 @@ import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParserAuthProvider +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -17,11 +18,12 @@ import org.koitharu.kotatsu.parsers.util.json.mapJSON import java.text.SimpleDateFormat import java.util.* -internal open class MangaLibParser(override val context: MangaLoaderContext) : MangaParser(), MangaParserAuthProvider { +internal open class MangaLibParser( + override val context: MangaLoaderContext, + source: MangaSource = MangaSource.MANGALIB, +) : MangaParser(source), MangaParserAuthProvider { - override val defaultDomain = "mangalib.me" - - override val source = MangaSource.MANGALIB + override val configKeyDomain = ConfigKey.Domain("mangalib.me", null) override val authUrl: String get() = "https://${getDomain()}/login" @@ -69,11 +71,12 @@ internal open class MangaLibParser(override val context: MangaLoaderContext) : M coverUrl = a.absUrl("data-src"), altTitle = null, author = null, - rating = Manga.NO_RATING, + rating = RATING_UNKNOWN, url = href, publicUrl = href.inContextOf(a), tags = emptySet(), state = null, + isNsfw = false, source = source, ) } @@ -269,8 +272,9 @@ internal open class MangaLibParser(override val context: MangaLoaderContext) : M author = null, tags = emptySet(), rating = jo.getString("rate_avg") - .toFloatOrNull()?.div(5f) ?: Manga.NO_RATING, + .toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN, state = null, + isNsfw = false, source = source, coverUrl = covers.getString("thumbnail"), largeCoverUrl = covers.getString("default"), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaOwlParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaOwlParser.kt index 6098b62d..7dc78705 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaOwlParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaOwlParser.kt @@ -2,17 +2,16 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* -internal class MangaOwlParser(override val context: MangaLoaderContext) : MangaParser() { +internal class MangaOwlParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGAOWL) { - override val source = MangaSource.MANGAOWL - - override val defaultDomain = "mangaowls.com" + override val configKeyDomain = ConfigKey.Domain("mangaowls.com", null) override val sortOrders: Set = EnumSet.of( SortOrder.POPULARITY, @@ -62,8 +61,11 @@ internal class MangaOwlParser(override val context: MangaLoaderContext) : MangaP ?.text() ?.toFloatOrNull() ?.div(10f) - }.getOrNull() ?: Manga.NO_RATING, + }.getOrNull() ?: RATING_UNKNOWN, url = href, + isNsfw = false, + tags = emptySet(), + state = null, publicUrl = href.withDomain(), source = source, ) @@ -79,7 +81,7 @@ internal class MangaOwlParser(override val context: MangaLoaderContext) : MangaP val trElement = doc.getElementsByTag("script").find { trRegex.find(it.data()) != null } ?: parseFailed("Oops, tr not found") val tr = trRegex.find(trElement.data())!!.groups[1]!!.value - val s = context.encodeBase64(defaultDomain.toByteArray()) + val s = context.encodeBase64(getDomain().toByteArray()) return manga.copy( description = info.selectFirst(".description")?.html(), largeCoverUrl = info.select("img").first()?.let { img -> diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaTownParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaTownParser.kt index e0a0eb1e..7ed922f9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaTownParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangaTownParser.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* @@ -9,11 +10,9 @@ import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* -internal class MangaTownParser(override val context: MangaLoaderContext) : MangaParser() { +internal class MangaTownParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGATOWN) { - override val source = MangaSource.MANGATOWN - - override val defaultDomain = "www.mangatown.com" + override val configKeyDomain = ConfigKey.Domain("www.mangatown.com", null) override val sortOrders: Set = EnumSet.of( SortOrder.ALPHABETICAL, @@ -69,7 +68,7 @@ internal class MangaTownParser(override val context: MangaLoaderContext) : Manga source = MangaSource.MANGATOWN, altTitle = null, rating = li.selectFirst("p.score")?.selectFirst("b") - ?.ownText()?.toFloatOrNull()?.div(5f) ?: Manga.NO_RATING, + ?.ownText()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN, author = views.findText { x -> x.startsWith("Author:") }?.substringAfter(':') ?.trim(), state = when (status) { @@ -85,6 +84,7 @@ internal class MangaTownParser(override val context: MangaLoaderContext) : Manga ) }.orEmpty(), url = href, + isNsfw = false, publicUrl = href.inContextOf(a), ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangareadParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangareadParser.kt index 61124071..393bd793 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangareadParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MangareadParser.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* @@ -11,11 +12,9 @@ import java.util.* private const val PAGE_SIZE = 12 -internal class MangareadParser(override val context: MangaLoaderContext) : MangaParser() { +internal class MangareadParser(override val context: MangaLoaderContext) : MangaParser(MangaSource.MANGAREAD) { - override val source = MangaSource.MANGAREAD - - override val defaultDomain = "www.mangaread.org" + override val configKeyDomain = ConfigKey.Domain("www.mangaread.org", null) override val sortOrders: Set = EnumSet.of( SortOrder.UPDATED, @@ -56,6 +55,7 @@ internal class MangareadParser(override val context: MangaLoaderContext) : Manga publicUrl = href.inContextOf(div), coverUrl = div.selectFirst("img")?.absUrl("data-src").orEmpty(), title = summary?.selectFirst("h3")?.text().orEmpty(), + altTitle = null, rating = div.selectFirst("span.total_votes")?.ownText() ?.toFloatOrNull()?.div(5f) ?: -1f, tags = summary?.selectFirst(".mg_genres")?.select("a")?.mapToSet { a -> @@ -75,6 +75,7 @@ internal class MangareadParser(override val context: MangaLoaderContext) : Manga else -> null }, source = MangaSource.MANGAREAD, + isNsfw = false, ) } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MintMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MintMangaParser.kt index 00e9a03d..7145c5d9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MintMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/MintMangaParser.kt @@ -1,10 +1,10 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource -internal class MintMangaParser(override val context: MangaLoaderContext) : GroupleParser() { +internal class MintMangaParser(override val context: MangaLoaderContext) : GroupleParser(MangaSource.MINTMANGA) { - override val source = MangaSource.MINTMANGA - override val defaultDomain: String = "mintmanga.live" + override val configKeyDomain = ConfigKey.Domain("mintmanga.live", null) } \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NineMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NineMangaParser.kt index 3b4325f7..6f4c97f9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NineMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NineMangaParser.kt @@ -4,6 +4,7 @@ import okhttp3.Headers import okhttp3.HttpUrl.Companion.toHttpUrl import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* @@ -14,9 +15,11 @@ private const val PAGE_SIZE = 26 internal abstract class NineMangaParser( final override val context: MangaLoaderContext, - final override val source: MangaSource, - final override val defaultDomain: String, -) : MangaParser() { + source: MangaSource, + defaultDomain: String, +) : MangaParser(source) { + + override val configKeyDomain = ConfigKey.Domain(defaultDomain, null) init { context.cookieJar.insertCookies(getDomain(), "ninemanga_template_desk=yes") @@ -77,8 +80,9 @@ internal abstract class NineMangaParser( title = dd?.selectFirst("a.bookname")?.text()?.toCamelCase().orEmpty(), altTitle = null, coverUrl = node.selectFirst("img")?.absUrl("src").orEmpty(), - rating = Manga.NO_RATING, + rating = RATING_UNKNOWN, author = null, + isNsfw = false, tags = emptySet(), state = null, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NudeMoonParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NudeMoonParser.kt index 2a712fa6..c148254a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NudeMoonParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/NudeMoonParser.kt @@ -4,6 +4,7 @@ import androidx.collection.SparseArrayCompat import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParserAuthProvider +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* @@ -12,10 +13,11 @@ import java.text.SimpleDateFormat import java.util.* import java.util.regex.Pattern -internal class NudeMoonParser(override val context: MangaLoaderContext) : MangaParser(), MangaParserAuthProvider { +internal class NudeMoonParser( + override val context: MangaLoaderContext, +) : MangaParser(MangaSource.NUDEMOON), MangaParserAuthProvider { - override val source = MangaSource.NUDEMOON - override val defaultDomain = "nude-moon.net" + override val configKeyDomain = ConfigKey.Domain("nude-moon.net", null) override val authUrl: String get() = "https://${getDomain()}/index.php" @@ -89,7 +91,7 @@ internal class NudeMoonParser(override val context: MangaLoaderContext) : MangaP }.orEmpty(), source = source, publicUrl = a.absUrl("href"), - rating = Manga.NO_RATING, + rating = RATING_UNKNOWN, isNsfw = true, description = row.selectFirst("div.description")?.html(), state = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ReadmangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ReadmangaParser.kt index 94eb4f74..9bb47051 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ReadmangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ReadmangaParser.kt @@ -1,10 +1,10 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource -internal class ReadmangaParser(override val context: MangaLoaderContext) : GroupleParser() { +internal class ReadmangaParser(override val context: MangaLoaderContext) : GroupleParser(MangaSource.READMANGA_RU) { - override val defaultDomain = "readmanga.io" - override val source = MangaSource.READMANGA_RU + override val configKeyDomain = ConfigKey.Domain("readmanga.io", null) } \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/RemangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/RemangaParser.kt index 332bf0d2..d5286443 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/RemangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/RemangaParser.kt @@ -7,6 +7,7 @@ import org.json.JSONObject import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaParserAuthProvider +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* @@ -23,11 +24,11 @@ private const val PAGE_SIZE = 30 private const val STATUS_ONGOING = 1 private const val STATUS_FINISHED = 0 -internal class RemangaParser(override val context: MangaLoaderContext) : MangaParser(), MangaParserAuthProvider { +internal class RemangaParser( + override val context: MangaLoaderContext, +) : MangaParser(MangaSource.REMANGA), MangaParserAuthProvider { - override val source = MangaSource.REMANGA - - override val defaultDomain = "remanga.org" + override val configKeyDomain = ConfigKey.Domain("remanga.org", null) override val authUrl: String get() = "https://${getDomain()}/user/login" @@ -85,10 +86,12 @@ internal class RemangaParser(override val context: MangaLoaderContext) : MangaPa publicUrl = "https://$domain$url", title = jo.getString("rus_name"), altTitle = jo.getString("en_name"), - rating = jo.getString("avg_rating").toFloatOrNull()?.div(10f) ?: Manga.NO_RATING, + rating = jo.getString("avg_rating").toFloatOrNull()?.div(10f) ?: RATING_UNKNOWN, coverUrl = "https://api.$domain${img.getString("mid")}", largeCoverUrl = "https://api.$domain${img.getString("high")}", author = null, + isNsfw = false, + state = null, tags = jo.optJSONArray("genres")?.mapJSONToSet { g -> MangaTag( title = g.getString("name").toTitleCase(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/SelfMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/SelfMangaParser.kt index 40d1a611..c485aa1d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/SelfMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/SelfMangaParser.kt @@ -1,10 +1,10 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource -internal class SelfMangaParser(override val context: MangaLoaderContext) : GroupleParser() { +internal class SelfMangaParser(override val context: MangaLoaderContext) : GroupleParser(MangaSource.SELFMANGA) { - override val defaultDomain = "selfmanga.live" - override val source = MangaSource.SELFMANGA + override val configKeyDomain = ConfigKey.Domain("selfmanga.live", null) } \ No newline at end of file diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/YaoiChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/YaoiChanParser.kt index 1faf378f..3fec897e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/YaoiChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/YaoiChanParser.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.parsers.site import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaChapter @@ -8,10 +9,9 @@ import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.relUrl -internal class YaoiChanParser(override val context: MangaLoaderContext) : ChanParser() { +internal class YaoiChanParser(override val context: MangaLoaderContext) : ChanParser(MangaSource.YAOICHAN) { - override val source = MangaSource.YAOICHAN - override val defaultDomain = "yaoi-chan.me" + override val configKeyDomain = ConfigKey.Domain("yaoi-chan.me", null) override suspend fun getDetails(manga: Manga): Manga { val doc = context.httpGet(manga.url.withDomain()).parseHtml() diff --git a/src/test/kotlin/org/koitharu/kotatsu/parsers/InMemoryCookieJar.kt b/src/test/kotlin/org/koitharu/kotatsu/parsers/InMemoryCookieJar.kt index 34c16f54..c88efb9f 100644 --- a/src/test/kotlin/org/koitharu/kotatsu/parsers/InMemoryCookieJar.kt +++ b/src/test/kotlin/org/koitharu/kotatsu/parsers/InMemoryCookieJar.kt @@ -32,7 +32,7 @@ class InMemoryCookieJar : CookieJar { if (line.isBlank() || line.startsWith("# ")) { continue } - val (host, includeSubdomains, path, secure, expire, name, value) = line.split(Regex("\\s+")) + val (host, _, path, secure, expire, name, value) = line.split(Regex("\\s+")) val domain = host.removePrefix("#HttpOnly_").trimStart('.') val httpOnly = host.startsWith("#HttpOnly_") val cookie = Cookie.Builder() diff --git a/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaLoaderContextMock.kt b/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaLoaderContextMock.kt index d2696b22..dfb7f22e 100644 --- a/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaLoaderContextMock.kt +++ b/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaLoaderContextMock.kt @@ -4,6 +4,7 @@ import com.koushikdutta.quack.QuackContext import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response +import org.koitharu.kotatsu.parsers.config.MangaSourceConfig import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.await import java.util.concurrent.TimeUnit diff --git a/src/test/kotlin/org/koitharu/kotatsu/parsers/SourceConfigMock.kt b/src/test/kotlin/org/koitharu/kotatsu/parsers/SourceConfigMock.kt index 701791d1..1141c009 100644 --- a/src/test/kotlin/org/koitharu/kotatsu/parsers/SourceConfigMock.kt +++ b/src/test/kotlin/org/koitharu/kotatsu/parsers/SourceConfigMock.kt @@ -1,8 +1,9 @@ package org.koitharu.kotatsu.parsers -internal class SourceConfigMock : MangaSourceConfig { +import org.koitharu.kotatsu.parsers.config.ConfigKey +import org.koitharu.kotatsu.parsers.config.MangaSourceConfig - override fun getDomain(defaultValue: String): String = defaultValue +internal class SourceConfigMock : MangaSourceConfig { - override fun isSslEnabled(defaultValue: Boolean): Boolean = defaultValue + override fun get(key: ConfigKey): T = key.defaultValue } \ No newline at end of file