Revert "Store pToken in GalleryPreview and refine parser" (#2390)

This commit is contained in:
renovate[bot] authored and GitHub committed 2025-06-05 07:17:26 +00:00
1 parent d4b152e7c0
commit 5b8d3a2824
7 files changed
+67 -42

No files matched your search

@@ -15,31 +15,26 @@
*/
package com.hippo.ehviewer.client.data
import com.hippo.ehviewer.client.getThumbKey
import com.hippo.ehviewer.client.getV2PreviewKey
import com.hippo.ehviewer.client.keyToUrl
sealed interface GalleryPreview {
val url: String
val imageKey: String
val position: Int
val pToken: String
}
data class V1GalleryPreview(
override val url: String,
override val imageKey: String,
override val position: Int,
override val pToken: String,
) : GalleryPreview {
override val imageKey get() = getThumbKey(url)
override val url get() = keyToUrl(imageKey)
}
data class V2GalleryPreview(
override val url: String,
override val imageKey: String,
override val position: Int,
override val pToken: String,
val offsetX: Int,
val clipWidth: Int,
val clipHeight: Int,
) : GalleryPreview {
override val imageKey get() = getV2PreviewKey(url)
}
) : GalleryPreview
@@ -17,6 +17,7 @@ package com.hippo.ehviewer.client.parser
import arrow.core.Either
import arrow.core.getOrElse
import arrow.core.unzip
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhFilter
@@ -39,6 +40,7 @@ import com.hippo.ehviewer.client.exception.OffensiveException
import com.hippo.ehviewer.client.exception.ParseException
import com.hippo.ehviewer.client.exception.PiningException
import com.hippo.ehviewer.client.getThumbKey
import com.hippo.ehviewer.client.getV2PreviewKey
import com.hippo.ehviewer.util.toEpochMillis
import com.hippo.ehviewer.util.toFloatOrDefault
import com.hippo.ehviewer.util.toIntOrDefault
@@ -55,21 +57,25 @@ import org.jsoup.select.NodeTraversor
object GalleryDetailParser {
private val PATTERN_ERROR = Regex("<div class=\"d\">\n<p>([^<]+)</p>")
private val PATTERN_DETAIL =
Regex("var gid = (\\d+);\\s+var token = \"([a-f0-9]+)\";\\s+var apiuid = ([\\-\\d]+);\\s+var apikey = \"([a-f0-9]+)\";")
private val PATTERN_DETAIL = Regex(
"var gid = (\\d+);.+?var token = \"([a-f0-9]+)\";.+?var apiuid = ([\\-\\d]+);.+?var apikey = \"([a-f0-9]+)\";",
RegexOption.DOT_MATCHES_ALL,
)
private val PATTERN_TORRENT =
Regex("<a[^<>]*onclick=\"return popUp\\('([^']+)'[^)]+\\)\">Torrent Download \\((\\d+)\\)</a>")
private val PATTERN_ARCHIVE =
Regex("<a[^<>]*onclick=\"return popUp\\('([^']+)'[^)]+\\)\">Archive Download</a>")
private val PATTERN_COVER = Regex("(\\d+)\\D+(\\d+)[^(]+\\(([^)]+)")
private val PATTERN_COVER = Regex("width:(\\d+)px; height:(\\d+)px.+?url\\((.+?)\\)")
private val PATTERN_PAGES =
Regex("<tr><td[^<>]*>Length:</td><td[^<>]*>([\\d,]+) pages</td></tr>")
private val PATTERN_NEWER_DATE = Regex(", added ([^<]+)<br />")
private val PATTERN_PREVIEW_PAGES =
Regex("<td[^>]+><a[^>]+>([\\d,]+)</a></td><td[^>]+>(?:<a[^>]+>)?&gt;(?:</a>)?</td>")
private val PATTERN_NEWER_DATE = Regex(", added (.+?)<br />")
private val PATTERN_FAVORITE_SLOT =
Regex("/fav\\.png\\); background-position:0px -(\\d+)px")
Regex("/fav.png\\); background-position:0px -(\\d+)px")
private val EMPTY_GALLERY_COMMENT_LIST = GalleryCommentList(emptyList(), false)
private val PreviewRegex =
Regex("<a href=\"https[^s]+s/([0-9a-f]{10})/\\d+-(\\d+)\"(?:[^\"]+\"){3}\\D+(\\d+)\\D+(\\d+)[^(]+\\(([^)]+)\\)(?: -(\\d+))?")
Regex("<a href=\"([^\"]+)\">(?:<div>)?<div title=\"Page (\\d+)(?:[^\"]+\"){2}\\D+(\\d+)\\D+(\\d+)[^(]+\\(([^)]+)\\)(?: -(\\d+))?")
// dd MMMM yyyy, HH:mm
private val WEB_COMMENT_DATE_FORMAT = LocalDateTime.Format {
@@ -101,7 +107,7 @@ object GalleryDetailParser {
val galleryDetail = GalleryDetail(
tagGroups = parseTagGroups(document),
comments = parseComments(document),
previewList = parsePreviewList(body),
previewList = parsePreviewList(body).first,
)
parseDetail(galleryDetail, document, body)
@@ -409,25 +415,35 @@ object GalleryDetailParser {
EMPTY_GALLERY_COMMENT_LIST
}
/**
* Parse preview pages with regular expressions
*/
fun parsePreviewPages(body: String): Int = PATTERN_PREVIEW_PAGES.find(body)?.groupValues?.get(1)?.toIntOrNull()
?: throw ParseException("Parse preview page count error")
/**
* Parse pages with regular expressions
*/
fun parsePages(body: String): Int = PATTERN_PAGES.find(body)?.groupValues?.get(1)?.toIntOrNull()
?: throw ParseException("Parse pages error")
fun parsePreviewList(body: String) = PreviewRegex.findAll(body).map {
val pToken = it.groupValues[1]
fun parsePreviewList(body: String) = PreviewRegex.findAll(body).unzip {
val pageUrl = it.groupValues[1]
val position = it.groupValues[2].toInt() - 1
val url = it.groupValues[5]
val offset = it.groupValues[6]
if (offset.isEmpty()) {
V1GalleryPreview(url, position, pToken)
val imageKey = getThumbKey(url)
V1GalleryPreview(imageKey, position)
} else {
val imageKey = getV2PreviewKey(url)
val width = it.groupValues[3].toInt()
val height = it.groupValues[4].toInt()
V2GalleryPreview(url, position, pToken, offset.toInt(), width, height)
}
}.toList().apply {
if (isEmpty()) throw ParseException("Parse preview list error")
V2GalleryPreview(url, imageKey, position, offset.toInt(), width, height)
} to pageUrl
}.run {
first.toList().apply {
if (isEmpty()) throw ParseException("Parse preview list error")
} to second.toList()
}
}
@@ -30,11 +30,10 @@ fun ImageRequest.Builder.ehUrl(info: GalleryInfo) = apply {
// Load in original size so the memory cache can be reused for preload requests
fun ImageRequest.Builder.ehPreview(preview: GalleryPreview) = apply {
with(preview) {
val key = imageKey
data(url)
size(SizeResolver.ORIGINAL)
memoryCacheKey(key)
diskCacheKey(key)
memoryCacheKey(imageKey)
diskCacheKey(imageKey)
}
}
@@ -10,15 +10,15 @@ fun Path.readLegacySpiderInfo() = read {
fun readInt() = read().toInt()
fun readLong() = read().toLong()
read() // Skip version, we assert it's v2
read() // Skip startPage
repeat(2) { read() } // We assert that only info v2
val gid = readLong()
val token = read()
read() // Skip mode
read() // Skip previewPages
read()
val previewPages = readInt()
val previewPerPage = readInt()
val pages = readInt()
SpiderInfo(gid, token, pages, previewPerPage = previewPerPage).apply {
val pages = read().toInt()
val pTokenMap = hashMapOf<Int, String>()
SpiderInfo(gid, token, pages, pTokenMap, previewPages, previewPerPage).apply {
runCatching {
while (true) {
val line = read()
@@ -27,6 +27,8 @@ class SpiderInfo(
val pTokenMap: MutableMap<Int, String> = hashMapOf(),
var previewPages: Int = -1,
var previewPerPage: Int = -1,
)
@@ -34,7 +34,9 @@ import com.hippo.ehviewer.client.exception.QuotaExceededException
import com.hippo.ehviewer.client.fetchUsingAsText
import com.hippo.ehviewer.client.parser.GalleryDetailParser.parsePages
import com.hippo.ehviewer.client.parser.GalleryDetailParser.parsePreviewList
import com.hippo.ehviewer.client.parser.GalleryDetailParser.parsePreviewPages
import com.hippo.ehviewer.client.parser.GalleryMultiPageViewerPTokenParser
import com.hippo.ehviewer.client.parser.GalleryPageUrlParser
import com.hippo.ehviewer.util.displayString
import com.hippo.files.find
import eu.kanade.tachiyomi.util.system.logcat
@@ -319,14 +321,20 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
?: readFromCache(galleryInfo.gid)?.takeIf { it.gid == galleryInfo.gid && it.token == galleryInfo.token }
private fun readPreviews(body: String, index: Int, spiderInfo: SpiderInfo) {
val previewList = parsePreviewList(body)
if (index == 0) {
spiderInfo.previewPerPage = previewList.size
} else {
spiderInfo.previewPerPage = previewList[0].position / index
spiderInfo.previewPages = parsePreviewPages(body)
val (previewList, pageUrlList) = parsePreviewList(body)
if (previewList.isNotEmpty()) {
if (index == 0) {
spiderInfo.previewPerPage = previewList.size
} else {
spiderInfo.previewPerPage = previewList[0].position / index
}
}
previewList.forEach {
spiderInfo.pTokenMap[it.position] = it.pToken
pageUrlList.forEach {
val result = GalleryPageUrlParser.parse(it)
if (result != null) {
spiderInfo.pTokenMap[result.page] = result.pToken
}
}
}
@@ -362,11 +370,16 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
}
suspend fun getPTokenFromInternet(index: Int): String? {
val previewIndex = if (spiderInfo.previewPerPage > 0) {
// Check previewIndex
var previewIndex: Int
previewIndex = if (spiderInfo.previewPerPage >= 0) {
index / spiderInfo.previewPerPage
} else {
0
}
if (spiderInfo.previewPages > 0) {
previewIndex = previewIndex.coerceAtMost(spiderInfo.previewPages - 1)
}
val url = getGalleryDetailUrl(
galleryInfo.gid,
galleryInfo.token,
@@ -805,7 +805,7 @@ private fun GalleryDetail.collectPreviewItems() = rememberInVM(previewList) {
(up..end).filterNot { it in previewPagesMap }.map { it / pageSize }.toSet()
.parMap(concurrency = Settings.multiThreadDownload) { page ->
val url = EhUrl.getGalleryDetailUrl(gid, token, page, false)
EhEngine.getPreviewList(url)
EhEngine.getPreviewList(url).first
}.flattenForEach {
previewPagesMap[it.position] = it
if (Settings.preloadThumbAggressively) {