diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/CuuTruyenParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/CuuTruyenParser.kt index 361d0343..46a06f7b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/CuuTruyenParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/CuuTruyenParser.kt @@ -178,7 +178,7 @@ internal class CuuTruyenParser(context: MangaLoaderContext) : manga.copy( title = title, altTitles = json.optJSONArray("titles")?.mapJSONToSet { it.getString("name") }?.minus(title).orEmpty(), - contentRating = if (json.getBooleanOrDefault("is_nsfw", manga.isNsfw)) { + contentRating = if (json.getBooleanOrDefault("is_nsfw", false)) { ContentRating.ADULT } else { ContentRating.SAFE diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenHentai18.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenHentai18.kt index 12d25ee0..f68db43c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenHentai18.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenHentai18.kt @@ -121,10 +121,10 @@ internal class TruyenHentai18(context: MangaLoaderContext): } } - private fun parseNextList(doc: Document): List { // need to clean code, very slow response + private fun parseNextList(doc: Document): List { val script = doc.select("script").firstOrNull { it.data().contains("response") } ?: throw Exception("Không tìm thấy script chứa dữ liệu manga") - + val scriptContent = script.data() val cleanedScript = scriptContent .replace("self.__next_f.push([1,", "") @@ -134,57 +134,25 @@ internal class TruyenHentai18(context: MangaLoaderContext): .replace("\\\\\",", ",") .replace("\\\"", "\"") .replace("\\\\", "\\") - .replace("\\n", "") - .replace("\\t", "") - .replace("\\r", "") - + .replace("[\\n\\r\\t]", "") + val responseStart = cleanedScript.indexOf("{\"response\":") if (responseStart == -1) throw Exception("Không tìm thấy object 'response' trong script") - - var bracketCount = 0 - var i = responseStart - var jsonStr = "" - - while (i < cleanedScript.length) { - val c = cleanedScript[i] - when (c) { - '{' -> bracketCount++ - '}' -> bracketCount-- - } - jsonStr += c - if (bracketCount == 0 && jsonStr.isNotEmpty()) break - i++ - } + val jsonStr = extractJsonString(cleanedScript, responseStart) val responseObj = org.json.JSONObject(jsonStr) val dataArray = responseObj.getJSONObject("response").optJSONArray("data") ?: throw Exception("Không tìm thấy trường 'data' trong object 'response'") return (0 until dataArray.length()).map { idx -> val item = dataArray.getJSONObject(idx) - val genres = item.optJSONArray("genres")?.let { genresArray -> - (0 until genresArray.length()).mapNotNull { gIdx -> - val genreItem = genresArray.optJSONObject(gIdx) ?: return@mapNotNull null - MangaTag( - key = genreItem.optString("slug"), - title = genreItem.optString("name"), - source = source - ) - }.toSet() - } ?: emptySet() - - val authors = item.optJSONArray("authors")?.let { authorsArray -> - (0 until authorsArray.length()).mapNotNull { aIdx -> - authorsArray.optJSONObject(aIdx)?.optString("name") - }.toSet() - } ?: emptySet() + val genres = extractGenres(item) + val authors = extractAuthors(item) Manga( id = item.getLong("id"), title = item.getString("title"), - altTitles = setOfNotNull( - item.optString("official_name").takeIf { it.isNotBlank() } - ), + altTitles = setOfNotNull(item.optString("official_name").takeIf { it.isNotBlank() }), url = item.getString("slug"), publicUrl = item.getString("slug").toAbsoluteUrl(domain), rating = RATING_UNKNOWN, @@ -277,4 +245,42 @@ internal class TruyenHentai18(context: MangaLoaderContext): else -> SimpleDateFormat("dd/MM/yyyy", Locale.US).parse(date)?.time ?: 0L } } -} + + private fun extractJsonString(script: String, responseStart: Int): String { + val stringBuilder = StringBuilder() + var bracketCount = 0 + var i = responseStart + + while (i < script.length) { + val c = script[i] + stringBuilder.append(c) + if (c == '{') bracketCount++ + if (c == '}') bracketCount-- + if (bracketCount == 0) break + i++ + } + return stringBuilder.toString() + } + + private fun extractGenres(item: JSONObject): Set { + return item.optJSONArray("genres")?.let { genresArray -> + (0 until genresArray.length()).mapNotNull { gIdx -> + genresArray.optJSONObject(gIdx)?.let { genreItem -> + MangaTag( + key = genreItem.optString("slug"), + title = genreItem.optString("name"), + source = source + ) + } + }.toSet() + } ?: emptySet() + } + + private fun extractAuthors(item: JSONObject): Set { + return item.optJSONArray("authors")?.let { authorsArray -> + (0 until authorsArray.length()).mapNotNull { aIdx -> + authorsArray.optJSONObject(aIdx)?.optString("name") + }.toSet() + } ?: emptySet() + } +} \ No newline at end of file