From f076c8095ac59e15c287f1f93dc126c2f86704e9 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 21 Apr 2025 12:22:08 +0300 Subject: [PATCH] Misc parsers fixes --- .../parsers/site/fr/PhenixscansParser.kt | 19 +++++++++---------- .../kotatsu/parsers/site/ru/ComXParser.kt | 17 +++++++++-------- .../kotatsu/parsers/site/ru/RemangaParser.kt | 2 +- .../kotatsu/parsers/site/vi/CMangaParser.kt | 9 ++++++--- .../kotatsu/parsers/site/vi/GocTruyenTranh.kt | 7 ++++--- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/PhenixscansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/PhenixscansParser.kt index d560a843..0044f986 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/PhenixscansParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/PhenixscansParser.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.parsers.site.fr -import kotlinx.coroutines.* +import kotlinx.coroutines.coroutineScope import org.json.JSONArray import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser @@ -115,14 +115,13 @@ internal class PhenixscansParser(context: MangaLoaderContext) : private fun parseMangaList(json: JSONArray): List { return json.mapJSON { j -> val slug = j.getString("slug") - val urlManga = "https://$domain/manga/$slug" Manga( id = generateUid(j.getString("_id")), title = j.getString("title"), altTitles = emptySet(), - url = urlManga, - publicUrl = urlManga, - rating = j.getFloatOrDefault("averageRating", RATING_UNKNOWN) / 10f, + url = slug, + publicUrl = "https://$domain/manga/$slug", + rating = j.getFloatOrDefault("averageRating", RATING_UNKNOWN * 10f) / 10f, contentRating = null, description = j.getStringOrNull("synopsis"), coverUrl = "https://cdn.phenix-scans.com/?url=https://api.phenix-scans.com/" + j.getString("coverImage") + "&output=webp&w=400&ll", @@ -142,7 +141,7 @@ internal class PhenixscansParser(context: MangaLoaderContext) : private val dateFormat = SimpleDateFormat("d MMM yyyy", sourceLocale) override suspend fun getDetails(manga: Manga): Manga = coroutineScope { - val mangaUrl = manga.url.toAbsoluteUrl(domain) + val mangaUrl = "https://$domain/manga/${manga.url}" val doc = webClient.httpGet(mangaUrl).parseHtml() manga.copy( @@ -156,8 +155,8 @@ internal class PhenixscansParser(context: MangaLoaderContext) : chapters = doc.select(" div.project__chapters a.project__chapter") .mapChapters(reversed = true) { i, a -> val href = a.attrAsRelativeUrl("href") - val name = a.selectFirst(".project__chapter-title")?.text().orEmpty() - val dateText = a.selectFirst(".project__chapter-date")?.text().orEmpty() + val name = a.selectFirst(".project__chapter-title")?.textOrNull() + val dateText = a.selectFirst(".project__chapter-date")?.textOrNull() MangaChapter( id = generateUid(href), title = name, @@ -180,7 +179,7 @@ internal class PhenixscansParser(context: MangaLoaderContext) : val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select("div.chapter-images img.chapter-image").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, @@ -196,7 +195,7 @@ internal class PhenixscansParser(context: MangaLoaderContext) : return json.mapJSONToSet { MangaTag( key = it.getString("_id"), - title = it.getString("name"), + title = it.getString("name").toTitleCase(sourceLocale), source = source, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/ComXParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/ComXParser.kt index 385a94a6..a1c5eac6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/ComXParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/ComXParser.kt @@ -10,6 +10,7 @@ import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.json.getFloatOrDefault +import org.koitharu.kotatsu.parsers.util.json.getIntOrDefault import org.koitharu.kotatsu.parsers.util.json.getStringOrNull import org.koitharu.kotatsu.parsers.util.suspendlazy.getOrNull import org.koitharu.kotatsu.parsers.util.suspendlazy.suspendLazy @@ -23,7 +24,7 @@ internal class ComXParser(context: MangaLoaderContext) : override val configKeyDomain = ConfigKey.Domain("com-x.life") private val availableTags = suspendLazy(initializer = ::fetchTags) - private val cdnImageUrl = "img.com-x.life/comix/" + private val cdnImageUrl = "img.com-x.life/comix/" override fun onCreateConfig(keys: MutableCollection>) { super.onCreateConfig(keys) @@ -86,12 +87,12 @@ internal class ComXParser(context: MangaLoaderContext) : Manga( id = generateUid(href), url = href, - publicUrl = a.attr("href"), + publicUrl = a.attrAsAbsoluteUrl("href"), title = titleElement.text(), altTitles = emptySet(), authors = emptySet(), description = null, - tags = emptySet(), + tags = emptySet(), rating = RATING_UNKNOWN, state = null, coverUrl = img?.attrAsAbsoluteUrlOrNull("data-src"), @@ -115,13 +116,13 @@ internal class ComXParser(context: MangaLoaderContext) : val jsonData = JSONObject(scriptData) val chaptersJson = jsonData.getJSONArray("chapters") val newsId = jsonData.getLong("news_id") - + val chapters = List(chaptersJson.length()) { i -> val chapter = chaptersJson.getJSONObject(i) val chapterId = chapter.getLong("id") - + MangaChapter( - id = generateUid("$newsId/$chapterId"), + id = generateUid("$newsId/$chapterId"), url = "/reader/$newsId/$chapterId", number = chapter.getFloatOrDefault("posi", 0f), title = decodeText(chapter.getStringOrNull("title")), @@ -129,7 +130,7 @@ internal class ComXParser(context: MangaLoaderContext) : source = source, scanlator = null, branch = null, - volume = chapter.optInt("volume", 0) + volume = chapter.getIntOrDefault("volume", 0), ) }.reversed() @@ -179,7 +180,7 @@ internal class ComXParser(context: MangaLoaderContext) : ?: throw ParseException("Image data not found", chapter.url) return data.map { imageUrl -> - val finalUrl = "https://" + cdnImageUrl + imageUrl + val finalUrl = "https://$cdnImageUrl$imageUrl" MangaPage( id = generateUid(imageUrl), url = finalUrl, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/RemangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/RemangaParser.kt index 0e6553f8..43c33668 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/RemangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/RemangaParser.kt @@ -141,7 +141,7 @@ internal class RemangaParser( val content = try { data.getJSONObject("content") } catch (e: JSONException) { - throw ParseException(data.optString("msg"), manga.publicUrl, e) + throw ParseException(data.getStringOrNull("msg"), manga.publicUrl, e) } val branchId = content.getJSONArray("branches").optJSONObject(0) ?.getLong("id") ?: throw ParseException("No branches found", manga.publicUrl) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/CMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/CMangaParser.kt index b6a3138c..27c70317 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/CMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/CMangaParser.kt @@ -147,9 +147,12 @@ internal class CMangaParser(context: MangaLoaderContext) : return mangaList.mapJSONNotNull { jo -> val info = jo.parseJson("info") val slug = info.getStringOrNull("url") ?: return@mapJSONNotNull null - val id = info.optLong("id").takeIf { it != 0L } ?: return@mapJSONNotNull null + val id = info.getLongOrDefault("id", 0L) + if (id == 0L) { + return@mapJSONNotNull null + } val relativeUrl = "/album/$slug-$id" - val title = info.optString("name").replace("\\", "") + val title = info.getString("name").replace("\\", "") val altTitle = info.optJSONArray("name_other")?.asTypedList()?.map { it.replace("\\", "") } Manga( @@ -201,7 +204,7 @@ internal class CMangaParser(context: MangaLoaderContext) : private suspend fun getTags(): Map { val tagList = webClient.httpGet("assets/json/album_tags_image.json".toAbsoluteUrl(domain)).parseJson() .getJSONObject("list") - val tags = ArrayMap() + val tags = ArrayMap(tagList.length()) for (key in tagList.keys()) { val jo = tagList.getJSONObject(key) val name = jo.getString("name") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/GocTruyenTranh.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/GocTruyenTranh.kt index ea7ec862..b39905c1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/GocTruyenTranh.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/GocTruyenTranh.kt @@ -8,6 +8,7 @@ import org.koitharu.kotatsu.parsers.core.LegacyPagedMangaParser import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.util.* +import org.koitharu.kotatsu.parsers.util.json.getStringOrNull import java.util.* @MangaSourceParser("GOCTRUYENTRANH", "Góc Truyện Tranh", "vi") @@ -150,11 +151,11 @@ internal class GocTruyenTranh(context: MangaLoaderContext) : url = "/$slug", publicUrl = mangaUrl, title = item.getString("name"), - altTitles = setOfNotNull(item.optString("origin_name")?.takeUnless { it == "null" || it.isEmpty() }), - description = item.optString("content"), + altTitles = setOfNotNull(item.getStringOrNull("origin_name")?.takeUnless { it == "null" }), + description = item.getStringOrNull("content"), rating = RATING_UNKNOWN, contentRating = if (checkNsfw || isNsfwSource) ContentRating.ADULT else null, - coverUrl = item.optString("thumbnail"), + coverUrl = item.getStringOrNull("thumbnail"), tags = tags, state = when (item.optString("status")) { "0" -> MangaState.ONGOING