[ExHentai] Pages preview support

master
Koitharu 1 year ago
parent db0782c61a
commit cc437b8cd4
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -13,6 +13,7 @@ import org.jsoup.nodes.Element
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.bitmap.Rect
import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.core.LegacyPagedMangaParser
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
@ -258,7 +259,7 @@ internal class ExHentaiParser(
MangaPage(
id = generateUid(url),
url = url,
preview = null,
preview = a.children().firstOrNull()?.extractPreview(),
source = source,
)
}
@ -318,6 +319,22 @@ internal class ExHentaiParser(
)
}
}
val imageRect = response.request.url.fragment?.split(',')
if (imageRect != null && imageRect.size == 4) {
// rect: top,left,right,bottom
return context.redrawImageResponse(response) { bitmap ->
val srcRect = Rect(
left = imageRect[0].toInt(),
top = imageRect[1].toInt(),
right = imageRect[2].toInt(),
bottom = imageRect[3].toInt(),
)
val dstRect = Rect(0, 0, srcRect.width, srcRect.height)
val result = context.createBitmap(dstRect.width, dstRect.height)
result.drawBitmap(bitmap, srcRect, dstRect)
result
}
}
return response
}
@ -394,6 +411,22 @@ internal class ExHentaiParser(
return result
}
private fun Element.extractPreview(): String? {
val bg = backgroundOrNull() ?: return null
return buildString {
append(bg.url)
append('#')
// rect: left,top,right,bottom
append(bg.left)
append(',')
append(bg.top)
append(',')
append(bg.right)
append(',')
append(bg.bottom)
}
}
private fun getNextTimestamp(root: Element): Long {
return root.getElementById("unext")
?.attrAsAbsoluteUrlOrNull("href")

@ -0,0 +1,52 @@
package org.koitharu.kotatsu.core.parser
import org.jsoup.nodes.Element
import org.koitharu.kotatsu.parsers.util.attrOrNull
import org.koitharu.kotatsu.parsers.util.nullIfEmpty
import org.koitharu.kotatsu.parsers.util.splitByWhitespace
/**
* Utility class for parsing the `background` property of css
*/
public class CSSBackground private constructor(
public val url: String,
public val left: Int,
public val top: Int,
public val width: Int,
public val height: Int,
) {
public val right: Int
get() = left + width
public val bottom: Int
get() = top + height
internal companion object {
fun parse(element: Element): CSSBackground? {
val style = element.attrOrNull("style") ?: return null
val attrs = style.split(';').associate {
val trimmed = it.trim()
trimmed.substringBefore(':') to trimmed.substringAfter(':', "")
}
val width = attrs["width"]?.toPx() ?: return null
val height = attrs["height"]?.toPx() ?: return null
val bg = attrs["background"]?.substringAfter("url")?.splitByWhitespace() ?: return null
val url = bg.firstOrNull()?.removeSurrounding("(", ")")?.nullIfEmpty() ?: return null
val x = bg.getOrNull(1)?.toPx() ?: 0
val y = bg.getOrNull(2)?.toPx() ?: 0
return CSSBackground(
url = url,
left = -x,
top = y,
width = width,
height = height,
)
}
private fun String.toPx(): Int? {
return removeSuffix("px").toIntOrNull()
}
}
}

@ -7,6 +7,7 @@ import org.jsoup.nodes.Element
import org.jsoup.select.Elements
import org.jsoup.select.QueryParser
import org.jsoup.select.Selector
import org.koitharu.kotatsu.core.parser.CSSBackground
import org.koitharu.kotatsu.parsers.InternalParsersApi
import org.koitharu.kotatsu.parsers.exception.ParseException
import kotlin.contracts.contract
@ -189,6 +190,8 @@ public fun Element.requireSrc(): String = parseNotNull(src()) {
"Image src not found"
}
public fun Element.backgroundOrNull(): CSSBackground? = CSSBackground.parse(this)
public fun Element.metaValue(itemprop: String): String? = getElementsByAttributeValue("itemprop", itemprop)
.firstNotNullOfOrNull { element ->
element.attrOrNull("content")

Loading…
Cancel
Save