DeviantArt: Preserve token in multi-image posts (#9151)

* DeviantArt: Preserve token in multi-image posts

* DeviantArt: Use keiyoushi.utils.tryParse

* DeviantArt: Make when block nicer

* DeviantArt: No need for two variables

* DeviantArt: Only find firstImageUrl if needed

* DeviantArt: Use if expression for less indenting
This commit is contained in:
DokterKaj 2025-06-14 16:49:22 +08:00 committed by Draff
parent 8c6f4bfbcb
commit fcc13a63ed
Signed by: Draff
GPG Key ID: E8A89F3211677653
2 changed files with 15 additions and 22 deletions

View File

@ -1,7 +1,7 @@
ext { ext {
extName = 'DeviantArt' extName = 'DeviantArt'
extClass = '.DeviantArt' extClass = '.DeviantArt'
extVersionCode = 8 extVersionCode = 9
isNsfw = true isNsfw = true
} }

View File

@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import keiyoushi.utils.getPreferencesLazy import keiyoushi.utils.getPreferencesLazy
import keiyoushi.utils.tryParse
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request import okhttp3.Request
@ -20,7 +21,6 @@ import okhttp3.Response
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.parser.Parser import org.jsoup.parser.Parser
import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
@ -43,14 +43,6 @@ class DeviantArt : HttpSource(), ConfigurableSource {
SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH) SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)
} }
private fun parseDate(dateStr: String?): Long {
return try {
dateFormat.parse(dateStr ?: "")!!.time
} catch (_: ParseException) {
0L
}
}
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
throw UnsupportedOperationException(SEARCH_FORMAT_MSG) throw UnsupportedOperationException(SEARCH_FORMAT_MSG)
} }
@ -94,9 +86,9 @@ class DeviantArt : HttpSource(), ConfigurableSource {
return SManga.create().apply { return SManga.create().apply {
setUrlWithoutDomain(response.request.url.toString()) setUrlWithoutDomain(response.request.url.toString())
author = document.title().substringBefore(" ") author = document.title().substringBefore(" ")
title = when (artistInTitle) { title = when {
true -> "$author - $galleryName" artistInTitle -> "$author - $galleryName"
false -> galleryName else -> galleryName
} }
description = gallery?.selectFirst(".legacy-journal")?.wholeText() description = gallery?.selectFirst(".legacy-journal")?.wholeText()
thumbnail_url = gallery?.selectFirst("img[property=contentUrl]")?.absUrl("src") thumbnail_url = gallery?.selectFirst("img[property=contentUrl]")?.absUrl("src")
@ -142,7 +134,7 @@ class DeviantArt : HttpSource(), ConfigurableSource {
SChapter.create().apply { SChapter.create().apply {
setUrlWithoutDomain(it.selectFirst("link")!!.text()) setUrlWithoutDomain(it.selectFirst("link")!!.text())
name = it.selectFirst("title")!!.text() name = it.selectFirst("title")!!.text()
date_upload = parseDate(it.selectFirst("pubDate")?.text()) date_upload = dateFormat.tryParse(it.selectFirst("pubDate")?.text())
scanlator = it.selectFirst("media|credit")?.text() scanlator = it.selectFirst("media|credit")?.text()
} }
} }
@ -162,16 +154,17 @@ class DeviantArt : HttpSource(), ConfigurableSource {
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup() val document = response.asJsoup()
val firstImageUrl = document.selectFirst("img[fetchpriority=high]")?.absUrl("src") val buttons = document.selectFirst("[draggable=false]")?.children()
return when (val buttons = document.selectFirst("[draggable=false]")?.children()) { return if (buttons == null) {
null -> listOf(Page(0, imageUrl = firstImageUrl)) val imageUrl = document.selectFirst("img[fetchpriority=high]")?.absUrl("src")
else -> buttons.mapIndexed { i, button -> listOf(Page(0, imageUrl = imageUrl))
} else {
buttons.mapIndexed { i, button ->
// Remove everything past "/v1/" to get original instead of thumbnail // Remove everything past "/v1/" to get original instead of thumbnail
val imageUrl = button.selectFirst("img")?.absUrl("src")?.substringBefore("/v1/") // But need to preserve the query parameter where the token is
val imageUrl = button.selectFirst("img")?.absUrl("src")
?.replaceFirst(Regex("""/v1(/.*)?(?=\?)"""), "")
Page(i, imageUrl = imageUrl) Page(i, imageUrl = imageUrl)
}.also {
// First image needs token to get original, which is included in firstImageUrl
it[0].imageUrl = firstImageUrl
} }
} }
} }