From 3ff9e69585ec9103d6ea77f48f4dc6ca9f946490 Mon Sep 17 00:00:00 2001 From: Zakhar Timoshenko Date: Tue, 4 Jun 2024 00:14:39 +0300 Subject: [PATCH] [MangaOVH] Removal (closes #824) --- .../kotatsu/parsers/site/ru/MangaOvhParser.kt | 254 ------------------ 1 file changed, 254 deletions(-) delete mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/MangaOvhParser.kt diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/MangaOvhParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/MangaOvhParser.kt deleted file mode 100644 index 1fe4dcfd..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/MangaOvhParser.kt +++ /dev/null @@ -1,254 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.ru - -import androidx.collection.ArrayMap -import kotlinx.coroutines.async -import kotlinx.coroutines.coroutineScope -import org.json.JSONObject -import org.koitharu.kotatsu.parsers.InternalParsersApi -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.PagedMangaParser -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.* -import java.text.SimpleDateFormat -import java.util.* - -@MangaSourceParser("MANGA_OVH", "МангаОВХ", "ru") -class MangaOvhParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.MANGA_OVH, pageSize = 20) { - - override val availableSortOrders: Set = EnumSet.of( - SortOrder.POPULARITY, - SortOrder.RATING, - SortOrder.UPDATED, - SortOrder.NEWEST, - ) - - @InternalParsersApi - override val configKeyDomain = ConfigKey.Domain("manga.ovh") - - override val isTagsExclusionSupported = true - - override val availableStates: Set = EnumSet.of( - MangaState.UPCOMING, - MangaState.PAUSED, - MangaState.ONGOING, - MangaState.FINISHED, - ) - - override val availableContentRating: Set = EnumSet.allOf(ContentRating::class.java) - - init { - paginator.firstPage = 0 - searchPaginator.firstPage = 0 - } - - override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { - val url = urlBuilder("api") - .addPathSegment("v2") - .addPathSegment("books") - .addQueryParameter("page", page.toString()) - .addQueryParameter("size", pageSize.toString()) - .addQueryParameter("type", "COMIC") - when (filter) { - is MangaListFilter.Advanced -> { - url.addQueryParameter( - "sort", - when (filter.sortOrder) { - SortOrder.UPDATED -> "updatedAt,desc" - SortOrder.POPULARITY -> "viewsCount,desc" - SortOrder.RATING -> "likesCount,desc" - SortOrder.NEWEST -> "createdAt,desc" - SortOrder.ALPHABETICAL, - SortOrder.ALPHABETICAL_DESC, - -> throw IllegalArgumentException("Unsupported ${filter.sortOrder}") - }, - ) - if (filter.tags.isNotEmpty()) { - url.addQueryParameter("labelsInclude", filter.tags.joinToString(",") { it.key }) - } - if (filter.tagsExclude.isNotEmpty()) { - url.addQueryParameter("labelsExclude", filter.tags.joinToString(",") { it.key }) - } - if (filter.states.isNotEmpty()) { - url.addQueryParameter( - "status", - filter.states.joinToString(",") { - when (it) { - MangaState.ONGOING -> "ONGOING" - MangaState.FINISHED -> "DONE" - MangaState.ABANDONED -> "" - MangaState.PAUSED -> "FROZEN" - MangaState.UPCOMING -> "ANNOUNCE" - } - }, - ) - } - if (filter.contentRating.isNotEmpty()) { - url.addQueryParameter( - "contentStatus", - filter.contentRating.joinToString(",") { - when (it) { - ContentRating.SAFE -> "SAFE" - ContentRating.SUGGESTIVE -> "UNSAFE,EROTIC" - ContentRating.ADULT -> "PORNOGRAPHIC" - } - }, - ) - } - } - - is MangaListFilter.Search -> { - url.addQueryParameter("search", filter.query) - } - - null -> Unit - } - val ja = webClient.httpGet(url.build()).parseJsonArray() - return ja.mapJSON { jo -> jo.toManga() } - } - - override suspend fun getDetails(manga: Manga): Manga = coroutineScope { - val chaptersDeferred = async { getChapters(manga.url) } - val url = urlBuilder("api") - .addPathSegment("v2") - .addPathSegment("books") - .addPathSegment(manga.url) - val jo = webClient.httpGet(url.build()).parseJson() - Manga( - id = generateUid(jo.getString("id")), - title = jo.getJSONObject("name").getString("ru"), - altTitle = jo.getJSONObject("name").getStringOrNull("en"), - url = jo.getString("id"), - publicUrl = "https://$domain/manga/${jo.getString("slug")}", - rating = jo.getFloatOrDefault("averageRating", -10f) / 10f, - isNsfw = jo.getStringOrNull("contentStatus").isNsfw(), - coverUrl = jo.getString("poster"), - tags = jo.getJSONArray("labels").mapJSONToSet { it.toMangaTag() }, - state = jo.getStringOrNull("status")?.toMangaState(), - author = jo.getJSONArray("relations").toJSONList().firstNotNullOfOrNull { - if (it.getStringOrNull("type") == "AUTHOR") { - it.getJSONObject("publisher").getStringOrNull("name") - } else { - null - } - }, - source = source, - largeCoverUrl = null, - description = jo.getString("description").nl2br(), - chapters = chaptersDeferred.await(), - ) - } - - override suspend fun getPages(chapter: MangaChapter): List { - val url = urlBuilder("api") - .addPathSegment("v2") - .addPathSegment("chapters") - .addPathSegment(chapter.url) - val json = webClient.httpGet(url.build()).parseJson() - return json.getJSONArray("pages").mapJSON { jo -> - MangaPage( - id = generateUid(jo.getString("id")), - url = jo.getString("image"), - preview = null, - source = source, - ) - } - } - - override suspend fun getAvailableTags(): Set { - val url = urlBuilder("api") - .addPathSegment("label") - val json = webClient.httpGet(url.build()).parseJson() - return json.getJSONArray("content").mapJSONToSet { jo -> - MangaTag( - title = jo.getJSONObject("name").getString("ru").toTitleCase(sourceLocale), - key = jo.getString("slug"), - source = source, - ) - } - } - - override suspend fun getRelatedManga(seed: Manga): List { - val url = urlBuilder("api") - .addPathSegment("book") - .addPathSegment(seed.url) - .addPathSegment("related") - val ja = webClient.httpGet(url.build()).parseJsonArray() - return ja.mapJSON { jo -> jo.toManga() } - } - - override suspend fun getPageUrl(page: MangaPage): String = page.url - - private suspend fun getChapters(mangaId: String): List { - val url = urlBuilder("api") - .addPathSegment("v2") - .addPathSegment("chapters") - .addQueryParameter("bookId", mangaId) - val ja = webClient.httpGet(url.build()).parseJsonArray() - val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'", Locale.ROOT) - val branches = ArrayMap() - return ja.mapJSON { jo -> - val number = jo.getFloatOrDefault("number", 0f) - val volume = jo.getIntOrDefault("volume", 0) - val branchId = jo.getString("branchId") - MangaChapter( - id = generateUid(jo.getString("id")), - name = jo.getStringOrNull("name") ?: buildString { - if (volume > 0) append("Том ").append(volume).append(' ') - if (number > 0) append("Глава ").append(number) else append("Без имени") - }, - number = number, - volume = volume, - url = jo.getString("id"), - scanlator = null, - uploadDate = dateFormat.tryParse(jo.getString("createdAt")), - branch = branches.getOrPut(branchId) { getBranchName(branchId) }, - source = source, - ) - }.reversed() - } - - private suspend fun getBranchName(id: String): String? = runCatchingCancellable { - val url = urlBuilder("api") - .addPathSegment("branch") - .addPathSegment(id) - val json = webClient.httpGet(url.build()).parseJson() - json.getJSONArray("publishers").mapJSONToSet { it.getStringOrNull("name") }.firstOrNull() - }.getOrElse { - id.substringBefore('-') - } - - private fun String.toMangaState() = when (this.uppercase(Locale.ROOT)) { - "DONE" -> MangaState.FINISHED - "ONGOING" -> MangaState.ONGOING - "FROZEN" -> MangaState.PAUSED - "ANNOUNCE" -> MangaState.UPCOMING - else -> null - } - - private fun String?.isNsfw() = this.equals("EROTIC", ignoreCase = true) || - this.equals("PORNOGRAPHIC", ignoreCase = true) - - private fun JSONObject.toMangaTag() = MangaTag( - title = getString("name").toTitleCase(sourceLocale), - key = getString("slug"), - source = source, - ) - - private fun JSONObject.toManga() = Manga( - id = generateUid(getString("id")), - title = getJSONObject("name").getString("ru"), - altTitle = getJSONObject("name").getStringOrNull("en"), - url = getString("id"), - publicUrl = "https://$domain/manga/${getString("slug")}", - rating = getFloatOrDefault("averageRating", -10f) / 10f, - isNsfw = getStringOrNull("contentStatus").isNsfw(), - coverUrl = getString("poster"), - tags = setOf(), - state = getStringOrNull("status")?.toMangaState(), - author = null, - source = source, - ) -}