HentaiVN.su: Small fixes, remove broken annotation

master
dragonx943 7 months ago
parent 8908031eee
commit ac977a6cbb
No known key found for this signature in database
GPG Key ID: 48DD99A2C5421C1C

@ -1,11 +1,9 @@
package org.koitharu.kotatsu.parsers.site.vi package org.koitharu.kotatsu.parsers.site.vi
import androidx.collection.ArrayMap
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import org.koitharu.kotatsu.parsers.Broken
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
@ -15,17 +13,18 @@ import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.*
import org.koitharu.kotatsu.parsers.util.json.* import org.koitharu.kotatsu.parsers.util.json.*
import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@Broken("Need some tests + Clean code")
@MangaSourceParser("HENTAIVNSU", "HentaiVN.su", "vi", type = ContentType.HENTAI) @MangaSourceParser("HENTAIVNSU", "HentaiVN.su", "vi", type = ContentType.HENTAI)
internal class HentaiVnSU(context: MangaLoaderContext) : internal class HentaiVnSU(context: MangaLoaderContext) :
PagedMangaParser(context, MangaParserSource.HENTAIVNSU, 24), MangaParserAuthProvider { PagedMangaParser(context, MangaParserSource.HENTAIVNSU, 24), MangaParserAuthProvider {
override val configKeyDomain = ConfigKey.Domain("hentaivn.su") override val configKeyDomain = ConfigKey.Domain("hentaivn.su")
private val placeHolderUrl: String
get() = "https://$domain/placeholder-error.webp"
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) { override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys) super.onCreateConfig(keys)
keys.remove(userAgentKey) keys.remove(userAgentKey)
@ -61,12 +60,12 @@ internal class HentaiVnSU(context: MangaLoaderContext) :
) )
override val filterCapabilities: MangaListFilterCapabilities = MangaListFilterCapabilities( override val filterCapabilities: MangaListFilterCapabilities = MangaListFilterCapabilities(
isSearchSupported = true,
isMultipleTagsSupported = true, isMultipleTagsSupported = true,
isSearchSupported = true
) )
override suspend fun getFilterOptions(): MangaListFilterOptions = MangaListFilterOptions( override suspend fun getFilterOptions(): MangaListFilterOptions = MangaListFilterOptions(
availableTags = getOrCreateTagMap().values.toSet() availableTags = fetchTags(),
) )
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> { override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
@ -91,7 +90,6 @@ internal class HentaiVnSU(context: MangaLoaderContext) :
} }
} }
addQueryParameter("page", page.toString()) addQueryParameter("page", page.toString())
addQueryParameter("limit", page.toString())
build() build()
} }
@ -110,7 +108,8 @@ internal class HentaiVnSU(context: MangaLoaderContext) :
title = jo.getString("title"), title = jo.getString("title"),
url = "/manga/$id", url = "/manga/$id",
publicUrl = "/manga/$id".toAbsoluteUrl(domain), publicUrl = "/manga/$id".toAbsoluteUrl(domain),
coverUrl = jo.getString("coverUrl").toAbsoluteUrl(domain), coverUrl = jo.getString("coverUrl").toAbsoluteUrl(domain)
.takeIf { it.isNotEmpty() } ?: placeHolderUrl,
authors = setOfNotNull(jo.getStringOrNull("authors")), authors = setOfNotNull(jo.getStringOrNull("authors")),
tags = jo.optJSONArray("genres")?.mapJSONToSet { genreJo -> tags = jo.optJSONArray("genres")?.mapJSONToSet { genreJo ->
MangaTag(genreJo.getString("name"), genreJo.getString("id"), source) MangaTag(genreJo.getString("name"), genreJo.getString("id"), source)
@ -126,13 +125,8 @@ internal class HentaiVnSU(context: MangaLoaderContext) :
override suspend fun getDetails(manga: Manga): Manga = coroutineScope { override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
val mangaId = manga.url.substringAfterLast('/') val mangaId = manga.url.substringAfterLast('/')
val detailsDeferred = async { val detailsJson = webClient.httpGet("/api/manga/$mangaId".toAbsoluteUrl(domain)).parseJson()
webClient.httpGet("/api/manga/$mangaId".toAbsoluteUrl(domain)).parseJson() val chapters = async { fetchChapters(mangaId) }.await()
}
val chaptersDeferred = async { fetchChapters(mangaId) }
val detailsJson = detailsDeferred.await()
val chapters = chaptersDeferred.await()
manga.copy( manga.copy(
altTitles = detailsJson.optJSONArray("alternativeTitles")?.asTypedList<String>()?.toSet() ?: emptySet(), altTitles = detailsJson.optJSONArray("alternativeTitles")?.asTypedList<String>()?.toSet() ?: emptySet(),
@ -141,7 +135,7 @@ internal class HentaiVnSU(context: MangaLoaderContext) :
tags = detailsJson.optJSONArray("genres")?.mapJSONToSet { genreJo -> tags = detailsJson.optJSONArray("genres")?.mapJSONToSet { genreJo ->
MangaTag(genreJo.getString("name"), genreJo.getString("id"), source) MangaTag(genreJo.getString("name"), genreJo.getString("id"), source)
} ?: emptySet(), } ?: emptySet(),
chapters = chapters.map { it.copy(scanlator = detailsJson.optJSONObject("uploader")?.optString("name")) } chapters = chapters.map { it.copy(scanlator = detailsJson.optJSONObject("uploader")?.optString("name")) },
) )
} }
@ -159,31 +153,33 @@ internal class HentaiVnSU(context: MangaLoaderContext) :
volume = 0, volume = 0,
branch = null branch = null
) )
} }.takeIf { it.isNotEmpty() } ?: emptyList()
} }
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> { override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val chapterId = chapter.url.substringAfterLast('/') val chapterId = chapter.url.substringAfterLast('/')
val apiUrl = "/api/chapter/$chapterId".toAbsoluteUrl(domain) val apiUrl = "/api/chapter/$chapterId".toAbsoluteUrl(domain)
val chapterData = webClient.httpGet(apiUrl).parseJson() val chapterData = webClient.httpGet(apiUrl).parseJson()
return chapterData.getJSONArray("pages").asTypedList<String>().map { imageUrl -> return chapterData.getJSONArray("pages").asTypedList<String>().map { imageUrl ->
MangaPage(id = generateUid(imageUrl), url = imageUrl.toAbsoluteUrl(domain), source = source, preview = null) MangaPage(
id = generateUid(imageUrl),
url = imageUrl.toAbsoluteUrl(domain),
preview = null,
source = source,
)
} }
} }
private suspend fun getOrCreateTagMap(): Map<String, MangaTag> { private suspend fun fetchTags(): Set<MangaTag> {
val apiUrl = "/api/tag/genre".toAbsoluteUrl(domain) val url = "/api/tag/genre".toAbsoluteUrl(domain)
val genres = webClient.httpGet(apiUrl).parseJsonArray() val response = webClient.httpGet(url).parseJsonArray()
return response.mapJSONToSet { jo ->
val tagMap = ArrayMap<String, MangaTag>(genres.length()) MangaTag(
for (i in 0 until genres.length()) { title = jo.getString("name").toTitleCase(sourceLocale),
val genre = genres.getJSONObject(i) key = jo.getLong("id").toString(),
val name = genre.getString("name") source = source,
val id = genre.getString("id") )
tagMap[name] = MangaTag(title = name, key = id, source = source)
} }
return tagMap
} }
private fun parseDate(dateStr: String?): Long? { private fun parseDate(dateStr: String?): Long? {
@ -193,12 +189,12 @@ internal class HentaiVnSU(context: MangaLoaderContext) :
return try { return try {
sdf.parse(dateStr)?.time sdf.parse(dateStr)?.time
} catch (_: ParseException) { } catch (_: Exception) {
try { try {
val simplerSdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US) val simplerSdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)
.apply { timeZone = TimeZone.getTimeZone("UTC") } .apply { timeZone = TimeZone.getTimeZone("UTC") }
simplerSdf.parse(dateStr)?.time simplerSdf.parse(dateStr)?.time
} catch (_: ParseException) { null } } catch (_: Exception) { null }
} }
} }
} }

Loading…
Cancel
Save