Comick: refactor code (#17364)

- fix filters not resetting
- add origination to genres
This commit is contained in:
AwkwardPeak7 2023-08-03 22:35:06 +05:00 committed by GitHub
parent 17f4a332d6
commit 11eb5915ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 169 additions and 185 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'Comick' extName = 'Comick'
pkgNameSuffix = 'all.comickfun' pkgNameSuffix = 'all.comickfun'
extClass = '.ComickFunFactory' extClass = '.ComickFunFactory'
extVersionCode = 32 extVersionCode = 33
isNsfw = true isNsfw = true
} }

View File

@ -133,41 +133,31 @@ abstract class ComickFun(
} }
} }
is GenreFilter -> { is GenreFilter -> {
it.state.filter { (it as TriState).isIncluded() }.forEach { it.state.filter { it.isIncluded() }.forEach {
addQueryParameter( addQueryParameter("genres", it.value)
"genres",
(it as TriState).value,
)
} }
it.state.filter { (it as TriState).isExcluded() }.forEach { it.state.filter { it.isExcluded() }.forEach {
addQueryParameter( addQueryParameter("excludes", it.value)
"excludes",
(it as TriState).value,
)
} }
} }
is DemographicFilter -> { is DemographicFilter -> {
it.state.filter { (it as CheckBox).state }.forEach { it.state.filter { it.isIncluded() }.forEach {
addQueryParameter( addQueryParameter("demographic", it.value)
"demographic",
(it as CheckBox).value,
)
} }
} }
is TypeFilter -> { is TypeFilter -> {
it.state.filter { (it as CheckBox).state }.forEach { it.state.filter { it.state }.forEach {
addQueryParameter( addQueryParameter("country", it.value)
"country",
(it as CheckBox).value,
)
} }
} }
is SortFilter -> { is SortFilter -> {
addQueryParameter("sort", it.getValue()) addQueryParameter("sort", it.getValue())
} }
is StatusFilter -> { is StatusFilter -> {
addQueryParameter("status", it.getValue()) if (it.state > 0) {
addQueryParameter("status", it.getValue())
}
} }
is CreatedAtFilter -> { is CreatedAtFilter -> {
if (it.state > 0) { if (it.state > 0) {

View File

@ -9,30 +9,30 @@ import kotlinx.serialization.Serializable
data class SearchManga( data class SearchManga(
val hid: String, val hid: String,
val title: String, val title: String,
val md_covers: List<MDcovers>, @SerialName("md_covers") val mdCovers: List<MDcovers> = emptyList(),
val cover_url: String? = null, @SerialName("cover_url") val cover: String? = null,
) { ) {
fun toSManga() = SManga.create().apply { fun toSManga() = SManga.create().apply {
// appennding # at end as part of migration from slug to hid // appending # at end as part of migration from slug to hid
url = "/comic/$hid#" url = "/comic/$hid#"
title = this@SearchManga.title title = this@SearchManga.title
thumbnail_url = parseCover(cover_url, md_covers) thumbnail_url = parseCover(cover, mdCovers)
} }
} }
@Serializable @Serializable
data class Manga( data class Manga(
val comic: Comic, val comic: Comic,
val artists: List<Artist> = emptyList(), val artists: List<Name> = emptyList(),
val authors: List<Author> = emptyList(), val authors: List<Name> = emptyList(),
val genres: List<Genre> = emptyList(), val genres: List<Name> = emptyList(),
) { ) {
fun toSManga() = SManga.create().apply { fun toSManga() = SManga.create().apply {
// appennding # at end as part of migration from slug to hid // appennding # at end as part of migration from slug to hid
url = "/comic/${comic.hid}#" url = "/comic/${comic.hid}#"
title = comic.title title = comic.title
description = comic.desc.beautifyDescription() description = comic.desc?.beautifyDescription()
if (comic.altTitles.isNotEmpty()) { if (comic.altTitles.isNotEmpty()) {
if (description.isNullOrEmpty()) { if (description.isNullOrEmpty()) {
description = "Alternative Titles:\n" description = "Alternative Titles:\n"
@ -44,11 +44,12 @@ data class Manga(
title.title?.let { "$it" } title.title?.let { "$it" }
}.joinToString("\n") }.joinToString("\n")
} }
status = comic.status.parseStatus(comic.translation_completed) status = comic.status.parseStatus(comic.translationComplete)
thumbnail_url = parseCover(comic.cover_url, comic.md_covers) thumbnail_url = parseCover(comic.cover, comic.mdCovers)
artist = artists.joinToString { it.name.trim() } artist = artists.joinToString { it.name.trim() }
author = authors.joinToString { it.name.trim() } author = authors.joinToString { it.name.trim() }
genre = genres.joinToString { it.name.trim() } genre = (listOfNotNull(comic.origination) + genres)
.joinToString { it.name.trim() }
} }
} }
@ -56,13 +57,21 @@ data class Manga(
data class Comic( data class Comic(
val hid: String, val hid: String,
val title: String, val title: String,
@SerialName("md_titles") val altTitles: List<MDtitles>, val country: String? = null,
val desc: String = "N/A", @SerialName("md_titles") val altTitles: List<Title> = emptyList(),
val status: Int = 0, val desc: String? = null,
val translation_completed: Boolean = true, val status: Int? = 0,
val md_covers: List<MDcovers>, @SerialName("translation_completed") val translationComplete: Boolean? = true,
val cover_url: String? = null, @SerialName("md_covers") val mdCovers: List<MDcovers> = emptyList(),
) @SerialName("cover_url") val cover: String? = null,
) {
val origination = when (country) {
"jp" -> Name("Manga")
"kr" -> Name("Manhwa")
"cn" -> Name("Manhua")
else -> null
}
}
@Serializable @Serializable
data class MDcovers( data class MDcovers(
@ -70,25 +79,12 @@ data class MDcovers(
) )
@Serializable @Serializable
data class MDtitles( data class Title(
val title: String?, val title: String?,
) )
@Serializable @Serializable
data class Artist( data class Name(
val name: String,
val slug: String,
)
@Serializable
data class Author(
val name: String,
val slug: String,
)
@Serializable
data class Genre(
val slug: String,
val name: String, val name: String,
) )
@ -103,16 +99,16 @@ data class Chapter(
val hid: String, val hid: String,
val lang: String, val lang: String,
val title: String = "", val title: String = "",
val created_at: String = "", @SerialName("created_at") val createdAt: String = "",
val chap: String = "", val chap: String = "",
val vol: String = "", val vol: String = "",
val group_name: List<String> = emptyList(), @SerialName("group_name") val groups: List<String> = emptyList(),
) { ) {
fun toSChapter(mangaUrl: String) = SChapter.create().apply { fun toSChapter(mangaUrl: String) = SChapter.create().apply {
url = "$mangaUrl/$hid-chapter-$chap-$lang" url = "$mangaUrl/$hid-chapter-$chap-$lang"
name = beautifyChapterName(vol, chap, title) name = beautifyChapterName(vol, chap, title)
date_upload = created_at.parseDate() date_upload = createdAt.parseDate()
scanlator = group_name.joinToString().takeUnless { it.isBlank() } ?: "Unknown" scanlator = groups.joinToString().takeUnless { it.isBlank() } ?: "Unknown"
} }
} }

View File

@ -20,154 +20,151 @@ fun getFilters(): FilterList {
ToYearFilter("To"), ToYearFilter("To"),
Filter.Header("Separate tags with commas"), Filter.Header("Separate tags with commas"),
TagFilter("Tags"), TagFilter("Tags"),
) )
} }
/** Filters **/ /** Filters **/
internal class GenreFilter(name: String, genreList: List<TriState>) : Group(name, genreList) internal class GenreFilter(name: String, genreList: List<Pair<String, String>>) :
Filter.Group<TriFilter>(name, genreList.map { TriFilter(it.first, it.second) })
internal class TagFilter(name: String) : Text(name) internal class TagFilter(name: String) : TextFilter(name)
internal class DemographicFilter(name: String, demographicList: List<CheckBox>) : internal class DemographicFilter(name: String, demographicList: List<Pair<String, String>>) :
Group(name, demographicList) Filter.Group<TriFilter>(name, demographicList.map { TriFilter(it.first, it.second) })
internal class TypeFilter(name: String, typeList: List<CheckBox>) : internal class TypeFilter(name: String, typeList: List<Pair<String, String>>) :
Group(name, typeList) Filter.Group<CheckBoxFilter>(name, typeList.map { CheckBoxFilter(it.first, it.second) })
internal class CompletedFilter(name: String) : CheckBox(name) internal class CompletedFilter(name: String) : CheckBoxFilter(name)
internal class CreatedAtFilter(name: String, createdAtList: Array<Pair<String, String>>) : internal class CreatedAtFilter(name: String, createdAtList: List<Pair<String, String>>) :
Select(name, createdAtList) SelectFilter(name, createdAtList)
internal class MinimumFilter(name: String) : Text(name) internal class MinimumFilter(name: String) : TextFilter(name)
internal class FromYearFilter(name: String) : Text(name) internal class FromYearFilter(name: String) : TextFilter(name)
internal class ToYearFilter(name: String) : Text(name) internal class ToYearFilter(name: String) : TextFilter(name)
internal class SortFilter(name: String, sortList: Array<Pair<String, String>>, state: Int = 0) : internal class SortFilter(name: String, sortList: List<Pair<String, String>>, state: Int = 0) :
Select(name, sortList, state) SelectFilter(name, sortList, state)
internal class StatusFilter(name: String, statusList: Array<Pair<String, String>>, state: Int = 0) : internal class StatusFilter(name: String, statusList: List<Pair<String, String>>, state: Int = 0) :
Select(name, statusList, state) SelectFilter(name, statusList, state)
/** Generics **/ /** Generics **/
internal open class Group(name: String, values: List<Any>) : internal open class TriFilter(name: String, val value: String) : Filter.TriState(name)
Filter.Group<Any>(name, values)
internal open class TriState(name: String, val value: String) : Filter.TriState(name) internal open class TextFilter(name: String) : Filter.Text(name)
internal open class Text(name: String) : Filter.Text(name) internal open class CheckBoxFilter(name: String, val value: String = "") : Filter.CheckBox(name)
internal open class CheckBox(name: String, val value: String = "") : Filter.CheckBox(name) internal open class SelectFilter(name: String, private val vals: List<Pair<String, String>>, state: Int = 0) :
internal open class Select(name: String, private val vals: Array<Pair<String, String>>, state: Int = 0) :
Filter.Select<String>(name, vals.map { it.first }.toTypedArray(), state) { Filter.Select<String>(name, vals.map { it.first }.toTypedArray(), state) {
fun getValue() = vals[state].second fun getValue() = vals[state].second
} }
/** Filters Data **/ /** Filters Data **/
private val getGenresList: List<TriState> = listOf( private val getGenresList: List<Pair<String, String>> = listOf(
TriState("4-Koma", "4-koma"), Pair("4-Koma", "4-koma"),
TriState("Action", "action"), Pair("Action", "action"),
TriState("Adaptation", "adaptation"), Pair("Adaptation", "adaptation"),
TriState("Adult", "adult"), Pair("Adult", "adult"),
TriState("Adventure", "adventure"), Pair("Adventure", "adventure"),
TriState("Aliens", "aliens"), Pair("Aliens", "aliens"),
TriState("Animals", "animals"), Pair("Animals", "animals"),
TriState("Anthology", "anthology"), Pair("Anthology", "anthology"),
TriState("Award Winning", "award-winning"), Pair("Award Winning", "award-winning"),
TriState("Comedy", "comedy"), Pair("Comedy", "comedy"),
TriState("Cooking", "cooking"), Pair("Cooking", "cooking"),
TriState("Crime", "crime"), Pair("Crime", "crime"),
TriState("Crossdressing", "crossdressing"), Pair("Crossdressing", "crossdressing"),
TriState("Delinquents", "delinquents"), Pair("Delinquents", "delinquents"),
TriState("Demons", "demons"), Pair("Demons", "demons"),
TriState("Doujinshi", "doujinshi"), Pair("Doujinshi", "doujinshi"),
TriState("Drama", "drama"), Pair("Drama", "drama"),
TriState("Ecchi", "ecchi"), Pair("Ecchi", "ecchi"),
TriState("Fan Colored", "fan-colored"), Pair("Fan Colored", "fan-colored"),
TriState("Fantasy", "fantasy"), Pair("Fantasy", "fantasy"),
TriState("Full Color", "full-color"), Pair("Full Color", "full-color"),
TriState("Gender Bender", "gender-bender"), Pair("Gender Bender", "gender-bender"),
TriState("Genderswap", "genderswap"), Pair("Genderswap", "genderswap"),
TriState("Ghosts", "ghosts"), Pair("Ghosts", "ghosts"),
TriState("Gore", "gore"), Pair("Gore", "gore"),
TriState("Gyaru", "gyaru"), Pair("Gyaru", "gyaru"),
TriState("Harem", "harem"), Pair("Harem", "harem"),
TriState("Historical", "historical"), Pair("Historical", "historical"),
TriState("Horror", "horror"), Pair("Horror", "horror"),
TriState("Incest", "incest"), Pair("Incest", "incest"),
TriState("Isekai", "isekai"), Pair("Isekai", "isekai"),
TriState("Loli", "loli"), Pair("Loli", "loli"),
TriState("Long Strip", "long-strip"), Pair("Long Strip", "long-strip"),
TriState("Mafia", "mafia"), Pair("Mafia", "mafia"),
TriState("Magic", "magic"), Pair("Magic", "magic"),
TriState("Magical Girls", "magical-girls"), Pair("Magical Girls", "magical-girls"),
TriState("Martial Arts", "martial-arts"), Pair("Martial Arts", "martial-arts"),
TriState("Mature", "mature"), Pair("Mature", "mature"),
TriState("Mecha", "mecha"), Pair("Mecha", "mecha"),
TriState("Medical", "medical"), Pair("Medical", "medical"),
TriState("Military", "military"), Pair("Military", "military"),
TriState("Monster Girls", "monster-girls"), Pair("Monster Girls", "monster-girls"),
TriState("Monsters", "monsters"), Pair("Monsters", "monsters"),
TriState("Music", "music"), Pair("Music", "music"),
TriState("Mystery", "mystery"), Pair("Mystery", "mystery"),
TriState("Ninja", "ninja"), Pair("Ninja", "ninja"),
TriState("Office Workers", "office-workers"), Pair("Office Workers", "office-workers"),
TriState("Official Colored", "official-colored"), Pair("Official Colored", "official-colored"),
TriState("Oneshot", "oneshot"), Pair("Oneshot", "oneshot"),
TriState("Philosophical", "philosophical"), Pair("Philosophical", "philosophical"),
TriState("Police", "police"), Pair("Police", "police"),
TriState("Post-Apocalyptic", "post-apocalyptic"), Pair("Post-Apocalyptic", "post-apocalyptic"),
TriState("Psychological", "psychological"), Pair("Psychological", "psychological"),
TriState("Reincarnation", "reincarnation"), Pair("Reincarnation", "reincarnation"),
TriState("Reverse Harem", "reverse-harem"), Pair("Reverse Harem", "reverse-harem"),
TriState("Romance", "romance"), Pair("Romance", "romance"),
TriState("Samurai", "samurai"), Pair("Samurai", "samurai"),
TriState("School Life", "school-life"), Pair("School Life", "school-life"),
TriState("Sci-Fi", "sci-fi"), Pair("Sci-Fi", "sci-fi"),
TriState("Sexual Violence", "sexual-violence"), Pair("Sexual Violence", "sexual-violence"),
TriState("Shota", "shota"), Pair("Shota", "shota"),
TriState("Shoujo Ai", "shoujo-ai"), Pair("Shoujo Ai", "shoujo-ai"),
TriState("Shounen Ai", "shounen-ai"), Pair("Shounen Ai", "shounen-ai"),
TriState("Slice of Life", "slice-of-life"), Pair("Slice of Life", "slice-of-life"),
TriState("Smut", "smut"), Pair("Smut", "smut"),
TriState("Sports", "sports"), Pair("Sports", "sports"),
TriState("Superhero", "superhero"), Pair("Superhero", "superhero"),
TriState("Supernatural", "supernatural"), Pair("Supernatural", "supernatural"),
TriState("Survival", "survival"), Pair("Survival", "survival"),
TriState("Thriller", "thriller"), Pair("Thriller", "thriller"),
TriState("Time Travel", "time-travel"), Pair("Time Travel", "time-travel"),
TriState("Traditional Games", "traditional-games"), Pair("Traditional Games", "traditional-games"),
TriState("Tragedy", "tragedy"), Pair("Tragedy", "tragedy"),
TriState("User Created", "user-created"), Pair("User Created", "user-created"),
TriState("Vampires", "vampires"), Pair("Vampires", "vampires"),
TriState("Video Games", "video-games"), Pair("Video Games", "video-games"),
TriState("Villainess", "villainess"), Pair("Villainess", "villainess"),
TriState("Virtual Reality", "virtual-reality"), Pair("Virtual Reality", "virtual-reality"),
TriState("Web Comic", "web-comic"), Pair("Web Comic", "web-comic"),
TriState("Wuxia", "wuxia"), Pair("Wuxia", "wuxia"),
TriState("Yaoi", "yaoi"), Pair("Yaoi", "yaoi"),
TriState("Yuri", "yuri"), Pair("Yuri", "yuri"),
TriState("Zombies", "zombies"), Pair("Zombies", "zombies"),
) )
private val getDemographicList: List<CheckBox> = listOf( private val getDemographicList: List<Pair<String, String>> = listOf(
CheckBox("Shounen", "1"), Pair("Shounen", "1"),
CheckBox("Shoujo", "2"), Pair("Shoujo", "2"),
CheckBox("Seinen", "3"), Pair("Seinen", "3"),
CheckBox("Josei", "4"), Pair("Josei", "4"),
) )
private val getTypeList: List<CheckBox> = listOf( private val getTypeList: List<Pair<String, String>> = listOf(
CheckBox("Manga", "jp"), Pair("Manga", "jp"),
CheckBox("Manhwa", "kr"), Pair("Manhwa", "kr"),
CheckBox("Manhua", "cn"), Pair("Manhua", "cn"),
) )
private val getCreatedAtList: Array<Pair<String, String>> = arrayOf( private val getCreatedAtList: List<Pair<String, String>> = listOf(
Pair("", ""), Pair("", ""),
Pair("3 days", "3"), Pair("3 days", "3"),
Pair("7 days", "7"), Pair("7 days", "7"),
@ -177,7 +174,8 @@ private val getCreatedAtList: Array<Pair<String, String>> = arrayOf(
Pair("1 year", "365"), Pair("1 year", "365"),
) )
private val getSortsList: Array<Pair<String, String>> = arrayOf( private val getSortsList: List<Pair<String, String>> = listOf(
Pair("Most popular", "follow"),
Pair("Most follows", "user_follow_count"), Pair("Most follows", "user_follow_count"),
Pair("Most views", "view"), Pair("Most views", "view"),
Pair("High rating", "rating"), Pair("High rating", "rating"),
@ -185,7 +183,7 @@ private val getSortsList: Array<Pair<String, String>> = arrayOf(
Pair("Newest", "created_at"), Pair("Newest", "created_at"),
) )
private val getStatusList: Array<Pair<String, String>> = arrayOf( private val getStatusList: List<Pair<String, String>> = listOf(
Pair("All", "0"), Pair("All", "0"),
Pair("Ongoing", "1"), Pair("Ongoing", "1"),
Pair("Completed", "2"), Pair("Completed", "2"),

View File

@ -18,11 +18,11 @@ internal fun String.beautifyDescription(): String {
.trim() .trim()
} }
internal fun Int.parseStatus(translationComplete: Boolean): Int { internal fun Int?.parseStatus(translationComplete: Boolean?): Int {
return when (this) { return when (this) {
1 -> SManga.ONGOING 1 -> SManga.ONGOING
2 -> { 2 -> {
if (translationComplete) { if (translationComplete == true) {
SManga.COMPLETED SManga.COMPLETED
} else { } else {
SManga.PUBLISHING_FINISHED SManga.PUBLISHING_FINISHED
@ -34,11 +34,11 @@ internal fun Int.parseStatus(translationComplete: Boolean): Int {
} }
} }
internal fun parseCover(thumbnailUrl: String?, mdCovers: List<MDcovers>): String { internal fun parseCover(thumbnailUrl: String?, mdCovers: List<MDcovers>): String? {
val b2key = runCatching { mdCovers.first().b2key } val b2key = mdCovers.firstOrNull()?.b2key
.getOrNull() ?: "" ?: return thumbnailUrl
return "$thumbnailUrl#$b2key" return thumbnailUrl?.let { "$it#$b2key" }
} }
internal fun thumbnailIntercept(chain: Interceptor.Chain): Response { internal fun thumbnailIntercept(chain: Interceptor.Chain): Response {