|
|
|
@ -18,6 +18,7 @@ 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.getStringOrNull
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.mapJSON
|
|
|
|
import org.koitharu.kotatsu.parsers.util.json.mapJSON
|
|
|
|
|
|
|
|
import org.koitharu.kotatsu.parsers.util.suspendlazy.suspendLazy
|
|
|
|
import java.nio.ByteBuffer
|
|
|
|
import java.nio.ByteBuffer
|
|
|
|
import java.nio.ByteOrder
|
|
|
|
import java.nio.ByteOrder
|
|
|
|
import java.security.MessageDigest
|
|
|
|
import java.security.MessageDigest
|
|
|
|
@ -387,7 +388,7 @@ internal class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context
|
|
|
|
return nozomi
|
|
|
|
return nozomi
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private val galleriesIndexVersion = SuspendLazy {
|
|
|
|
private val galleriesIndexVersion = suspendLazy {
|
|
|
|
webClient.httpGet("$ltnBaseUrl/galleriesindex/version?_=${System.currentTimeMillis()}").parseRaw()
|
|
|
|
webClient.httpGet("$ltnBaseUrl/galleriesindex/version?_=${System.currentTimeMillis()}").parseRaw()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -480,14 +481,14 @@ internal class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context
|
|
|
|
title = doc.selectFirstOrThrow("h1").text(),
|
|
|
|
title = doc.selectFirstOrThrow("h1").text(),
|
|
|
|
url = id.toString(),
|
|
|
|
url = id.toString(),
|
|
|
|
coverUrl =
|
|
|
|
coverUrl =
|
|
|
|
"https:" +
|
|
|
|
"https:" +
|
|
|
|
doc.selectFirstOrThrow("picture > source")
|
|
|
|
doc.selectFirstOrThrow("picture > source")
|
|
|
|
.attr("data-srcset")
|
|
|
|
.attr("data-srcset")
|
|
|
|
.substringBefore(" "),
|
|
|
|
.substringBefore(" "),
|
|
|
|
publicUrl =
|
|
|
|
publicUrl =
|
|
|
|
doc.selectFirstOrThrow("h1 > a")
|
|
|
|
doc.selectFirstOrThrow("h1 > a")
|
|
|
|
.attrAsRelativeUrl("href")
|
|
|
|
.attrAsRelativeUrl("href")
|
|
|
|
.toAbsoluteUrl(domain),
|
|
|
|
.toAbsoluteUrl(domain),
|
|
|
|
author = null,
|
|
|
|
author = null,
|
|
|
|
tags = emptySet(),
|
|
|
|
tags = emptySet(),
|
|
|
|
isNsfw = true,
|
|
|
|
isNsfw = true,
|
|
|
|
@ -510,37 +511,37 @@ internal class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context
|
|
|
|
return manga.copy(
|
|
|
|
return manga.copy(
|
|
|
|
title = json.getString("title"),
|
|
|
|
title = json.getString("title"),
|
|
|
|
largeCoverUrl =
|
|
|
|
largeCoverUrl =
|
|
|
|
json.getJSONArray("files").getJSONObject(0).let {
|
|
|
|
json.getJSONArray("files").getJSONObject(0).let {
|
|
|
|
val hash = it.getString("hash")
|
|
|
|
val hash = it.getString("hash")
|
|
|
|
val commonId = commonImageId()
|
|
|
|
val commonId = commonImageId()
|
|
|
|
val imageId = imageIdFromHash(hash)
|
|
|
|
val imageId = imageIdFromHash(hash)
|
|
|
|
val subDomain = 'a' + subdomainOffset(imageId)
|
|
|
|
val subDomain = 'a' + subdomainOffset(imageId)
|
|
|
|
|
|
|
|
|
|
|
|
"https://${getDomain("${subDomain}a")}/webp/$commonId$imageId/$hash.webp"
|
|
|
|
"https://${getDomain("${subDomain}a")}/webp/$commonId$imageId/$hash.webp"
|
|
|
|
},
|
|
|
|
},
|
|
|
|
author =
|
|
|
|
author =
|
|
|
|
json.optJSONArray("artists")
|
|
|
|
json.optJSONArray("artists")
|
|
|
|
?.mapJSON { it.getString("artist").toCamelCase() }
|
|
|
|
?.mapJSON { it.getString("artist").toCamelCase() }
|
|
|
|
?.joinToString(),
|
|
|
|
?.joinToString(),
|
|
|
|
publicUrl = json.getString("galleryurl").toAbsoluteUrl(domain),
|
|
|
|
publicUrl = json.getString("galleryurl").toAbsoluteUrl(domain),
|
|
|
|
tags =
|
|
|
|
tags =
|
|
|
|
buildSet {
|
|
|
|
buildSet {
|
|
|
|
json.optJSONArray("characters")
|
|
|
|
json.optJSONArray("characters")
|
|
|
|
?.mapToTags("character")
|
|
|
|
?.mapToTags("character")
|
|
|
|
?.let(::addAll)
|
|
|
|
?.let(::addAll)
|
|
|
|
json.optJSONArray("tags")
|
|
|
|
json.optJSONArray("tags")
|
|
|
|
?.mapToTags("tag")
|
|
|
|
?.mapToTags("tag")
|
|
|
|
?.let(::addAll)
|
|
|
|
?.let(::addAll)
|
|
|
|
json.optJSONArray("artists")
|
|
|
|
json.optJSONArray("artists")
|
|
|
|
?.mapToTags("artist")
|
|
|
|
?.mapToTags("artist")
|
|
|
|
?.let(::addAll)
|
|
|
|
?.let(::addAll)
|
|
|
|
json.optJSONArray("parodys")
|
|
|
|
json.optJSONArray("parodys")
|
|
|
|
?.mapToTags("parody")
|
|
|
|
?.mapToTags("parody")
|
|
|
|
?.let(::addAll)
|
|
|
|
?.let(::addAll)
|
|
|
|
json.optJSONArray("groups")
|
|
|
|
json.optJSONArray("groups")
|
|
|
|
?.mapToTags("group")
|
|
|
|
?.mapToTags("group")
|
|
|
|
?.let(::addAll)
|
|
|
|
?.let(::addAll)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
chapters = listOf(
|
|
|
|
chapters = listOf(
|
|
|
|
MangaChapter(
|
|
|
|
MangaChapter(
|
|
|
|
id = generateUid(manga.url),
|
|
|
|
id = generateUid(manga.url),
|
|
|
|
@ -564,15 +565,15 @@ internal class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context
|
|
|
|
mapJSON {
|
|
|
|
mapJSON {
|
|
|
|
MangaTag(
|
|
|
|
MangaTag(
|
|
|
|
title =
|
|
|
|
title =
|
|
|
|
it.getString(key).toCamelCase().let { title ->
|
|
|
|
it.getString(key).toCamelCase().let { title ->
|
|
|
|
if (it.getStringOrNull("female")?.toIntOrNull() == 1) {
|
|
|
|
if (it.getStringOrNull("female")?.toIntOrNull() == 1) {
|
|
|
|
"$title ♀"
|
|
|
|
"$title ♀"
|
|
|
|
} else if (it.getStringOrNull("male")?.toIntOrNull() == 1) {
|
|
|
|
} else if (it.getStringOrNull("male")?.toIntOrNull() == 1) {
|
|
|
|
"$title ♂"
|
|
|
|
"$title ♂"
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
title
|
|
|
|
title
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
key = it.getString("url").tagUrlToTag(),
|
|
|
|
key = it.getString("url").tagUrlToTag(),
|
|
|
|
source = source,
|
|
|
|
source = source,
|
|
|
|
).let(tags::add)
|
|
|
|
).let(tags::add)
|
|
|
|
|