diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt index 49422e65..45c86648 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt @@ -29,4 +29,9 @@ sealed class ConfigKey( class SplitByTranslations( override val defaultValue: Boolean, ) : ConfigKey("split_translations") + + class PreferredImageServer( + val presetValues: Map, + override val defaultValue: String?, + ) : ConfigKey("img_server") } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/MangaWorld.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/MangaWorld.kt index c9ca68cf..797e7450 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/MangaWorld.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/MangaWorld.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.parsers.site.it +import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser @@ -9,15 +10,20 @@ import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* -@MangaSourceParser("MANGAWORLD", "mangaworld.ac", "it") +@MangaSourceParser("MANGAWORLD", "MangaWorld", "it") internal class MangaWorld( context: MangaLoaderContext, ) : PagedMangaParser(context, MangaSource.MANGAWORLD, pageSize = 16) { override val availableSortOrders: Set = - EnumSet.of(SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.NEWEST, SortOrder.ALPHABETICAL_DESC) + EnumSet.of(SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.NEWEST, SortOrder.ALPHABETICAL_DESC, SortOrder.UPDATED) + + override val defaultSortOrder: SortOrder + get() = SortOrder.ALPHABETICAL override val configKeyDomain = ConfigKey.Domain("mangaworld.ac") + override val availableStates: Set = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED, MangaState.PAUSED) + override val isMultipleTagsSupported = true override suspend fun getListPage( @@ -36,6 +42,8 @@ internal class MangaWorld( } is MangaListFilter.Advanced -> { + if(filter.tags.isEmpty() && filter.states.isEmpty() && filter.sortOrder == SortOrder.UPDATED) return parseMangaList(webClient.httpGet("https://$domain/?page=$page").parseHtml()) + if (filter.tags.isNotEmpty()) { filter.tags.joinTo(this, "&") { it.key.substringAfter("archive?") } } @@ -61,6 +69,10 @@ internal class MangaWorld( append("&page=$page") } val doc = webClient.httpGet(url).parseHtml() + return parseMangaList(doc) + } + + private fun parseMangaList(doc: Document): List { return doc.select(".comics-grid .entry").map { div -> val href = div.selectFirstOrThrow("a.thumb").attrAsRelativeUrl("href") val tags = div.select(".genres a[href*=/archive?genre=]") @@ -89,15 +101,26 @@ internal class MangaWorld( } } + override suspend fun getAvailableTags(): Set { val doc = webClient.httpGet("https://$domain/").parseHtml() - return doc.select("div[aria-labelledby=genresDropdown] a").mapNotNullToSet { + val genres = doc.select("div[aria-labelledby=genresDropdown] a").mapNotNullToSet { + MangaTag( + key = it.attr("href"), + title = it.text().toTitleCase(sourceLocale), + source = source, + ) + } + + val types = doc.select("div[aria-labelledby=typesDropdown] a").mapNotNullToSet { MangaTag( key = it.attr("href"), title = it.text().toTitleCase(sourceLocale), source = source, ) } + + return genres + types } override suspend fun getDetails(manga: Manga): Manga { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt index d5afad35..b81aa404 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt @@ -37,6 +37,18 @@ internal abstract class LibSocialParser( 5, MangaState.ABANDONED, ) private val imageServers = SuspendLazy(::fetchServers) + private val splitTranslationsKey = ConfigKey.SplitByTranslations(true) + private val preferredServerKey = ConfigKey.PreferredImageServer( + presetValues = mapOf( + null to null, + SERVER_MAIN to "Первый", + SERVER_SECONDARY to "Второй", + SERVER_COMPRESS to "Сжатия", + SERVER_DOWNLOAD to "Загрузки", + SERVER_CROP to "Обрезки", + ), + defaultValue = null, + ) override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { val urlBuilder = urlBuilder("api") @@ -75,7 +87,7 @@ internal abstract class LibSocialParser( SortOrder.NEWEST -> "created_at" SortOrder.ALPHABETICAL, SortOrder.ALPHABETICAL_DESC, - -> "rus_name" + -> "rus_name" }, ) urlBuilder.addQueryParameter( @@ -86,7 +98,7 @@ internal abstract class LibSocialParser( SortOrder.RATING, SortOrder.NEWEST, SortOrder.ALPHABETICAL_DESC, - -> "desc" + -> "desc" SortOrder.ALPHABETICAL -> "asc" }, @@ -132,10 +144,7 @@ internal abstract class LibSocialParser( } val servers = imageServers.get() val json = pages.await() - val primaryServer = - checkNotNull(servers[SERVER_MAIN] ?: servers[SERVER_DOWNLOAD] ?: servers[SERVER_SECONDARY]) { - "No available images servers" - } + val primaryServer = getPrimaryImageServer(servers) json.getJSONArray("pages").mapJSON { jo -> val url = jo.getString("url") MangaPage( @@ -167,6 +176,12 @@ internal abstract class LibSocialParser( } } + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(splitTranslationsKey) + keys.add(preferredServerKey) + } + private fun parseManga(jo: JSONObject): Manga { val cover = jo.getJSONObject("cover") return Manga( @@ -187,6 +202,16 @@ internal abstract class LibSocialParser( ) } + private fun getPrimaryImageServer(servers: ScatterMap): String { + val preferred = config[preferredServerKey] + if (preferred != null) { + servers[preferred]?.let { return it } + } + return checkNotNull(servers[SERVER_MAIN] ?: servers[SERVER_DOWNLOAD] ?: servers[SERVER_SECONDARY]) { + "No available images servers" + } + } + private suspend fun fetchChapters(manga: Manga): List { val url = urlBuilder("api") .addPathSegment("api") @@ -197,6 +222,7 @@ internal abstract class LibSocialParser( val json = webClient.httpGet(url).parseJson().getJSONArray("data") val builder = ChaptersListBuilder(json.length()) val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US) + val useBranching = config[splitTranslationsKey] for (i in 0 until json.length()) { val jo = json.getJSONObject(i) val volume = jo.getIntOrDefault("volume", 0) @@ -219,7 +245,7 @@ internal abstract class LibSocialParser( url = "${manga.url}/chapter?number=$numberString&volume=$volume", scanlator = team, uploadDate = dateFormat.tryParse(bjo.getStringOrNull("created_at")), - branch = team, + branch = if (useBranching) team else null, source = source, ) }