Restore upstream cover URL handling
Some checks failed
CI / Prepare job (push) Has been cancelled
CI / Build extensions (${{ matrix.chunk.number }}) (push) Has been cancelled
CI / Publish extension repo (push) Has been cancelled
Create Release on Merge / release (push) Has been cancelled

This commit is contained in:
2026-05-23 18:19:34 +09:00
parent b38824219f
commit c551317051
5 changed files with 13 additions and 39 deletions

View File

@@ -2,7 +2,7 @@ ext {
kmkVersionCode = 1 kmkVersionCode = 1
extName = 'Kavita' extName = 'Kavita'
extClass = '.KavitaFactory' extClass = '.KavitaFactory'
extVersionCode = 27 extVersionCode = 28
isNsfw = false isNsfw = false
} }

View File

@@ -980,9 +980,9 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
title = (if (readingList.promoted) "🔺 " else "") + readingList.title title = (if (readingList.promoted) "🔺 " else "") + readingList.title
artist = "${readingList.itemCount} items" artist = "${readingList.itemCount} items"
thumbnail_url = if (!readingList.coverImage.isNullOrBlank()) { thumbnail_url = if (!readingList.coverImage.isNullOrBlank()) {
KavitaImageUrls.imagePath(apiUrl, readingList.coverImage, apiKey) "$apiUrl/image/${readingList.coverImage}?apiKey=$apiKey"
} else { } else {
KavitaImageUrls.cover(apiUrl, "readinglist-cover", "readingListId", readingListId ?: 0, apiKey) "$apiUrl/image/readinglist-cover?readingListId=$readingListId&apiKey=$apiKey"
} }
description = readingList.summary ?: "Reading List" description = readingList.summary ?: "Reading List"
genre = genreString genre = genreString
@@ -1110,7 +1110,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
if (isComicLibrary && volume.minNumber.toInt() == KavitaConstants.UNNUMBERED_VOLUME) { if (isComicLibrary && volume.minNumber.toInt() == KavitaConstants.UNNUMBERED_VOLUME) {
for (chapter in volume.chapters) { for (chapter in volume.chapters) {
if (chapter.coverImage.isNotBlank()) { if (chapter.coverImage.isNotBlank()) {
val url = KavitaImageUrls.cover(apiUrl, "chapter-cover", "chapterId", chapter.id, apiKey) val url = "$apiUrl/Image/chapter-cover?chapterId=${chapter.id}&apiKey=$apiKey"
coverCandidates.add( coverCandidates.add(
Triple(url, chapter.pagesRead < chapter.pages, chapter.number.toFloatOrNull() ?: 0f), Triple(url, chapter.pagesRead < chapter.pages, chapter.number.toFloatOrNull() ?: 0f),
) )
@@ -1124,7 +1124,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
ChapterType.of(chapter, volume) == ChapterType.SingleFileVolume ChapterType.of(chapter, volume) == ChapterType.SingleFileVolume
} }
if (hasSingleFile && volume.coverImage.isNotBlank()) { if (hasSingleFile && volume.coverImage.isNotBlank()) {
val url = KavitaImageUrls.cover(apiUrl, "volume-cover", "volumeId", volume.id, apiKey) val url = "$apiUrl/Image/volume-cover?volumeId=${volume.id}&apiKey=$apiKey"
val isUnread = volume.pagesRead < volume.pages val isUnread = volume.pagesRead < volume.pages
val number = volume.minNumber.toFloat() val number = volume.minNumber.toFloat()
coverCandidates.add(Triple(url, isUnread, number)) coverCandidates.add(Triple(url, isUnread, number))
@@ -1155,14 +1155,14 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
} ?: System.currentTimeMillis().toString() } ?: System.currentTimeMillis().toString()
// Append cache-busting timestamp to always get the latest cover // Append cache-busting timestamp to always get the latest cover
KavitaImageUrls.withTimestamp(baseUrl, timestamp) "$baseUrl&ts=$timestamp"
} ?: KavitaImageUrls.cover(apiUrl, "series-cover", "seriesId", seriesId, apiKey) } ?: "$apiUrl/image/series-cover?seriesId=$seriesId&apiKey=$apiKey"
} catch (e: Exception) { } catch (e: Exception) {
Log.e(LOG_TAG, "Error fetching volumes for cover selection", e) Log.e(LOG_TAG, "Error fetching volumes for cover selection", e)
KavitaImageUrls.cover(apiUrl, "series-cover", "seriesId", result.seriesId ?: 0, apiKey) "$apiUrl/image/series-cover?seriesId=${result.seriesId ?: 0}&apiKey=$apiKey"
} }
} else { } else {
KavitaImageUrls.cover(apiUrl, "series-cover", "seriesId", result.seriesId ?: 0, apiKey) "$apiUrl/image/series-cover?seriesId=${result.seriesId ?: 0}&apiKey=$apiKey"
} }
manga.status = when (result.publicationStatus) { manga.status = when (result.publicationStatus) {
@@ -1252,9 +1252,9 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
artist = "${list.itemCount} items" artist = "${list.itemCount} items"
author = list.ownerUserName author = list.ownerUserName
thumbnail_url = if (!list.coverImage.isNullOrBlank()) { thumbnail_url = if (!list.coverImage.isNullOrBlank()) {
KavitaImageUrls.imagePath(apiUrl, list.coverImage, apiKey) "$apiUrl/image/${list.coverImage}?apiKey=$apiKey"
} else { } else {
KavitaImageUrls.cover(apiUrl, "readinglist-cover", "readingListId", list.id, apiKey) "$apiUrl/Image/readinglist-cover?readingListId=${list.id}&apiKey=$apiKey"
} }
description = list.summary ?: "Reading List" description = list.summary ?: "Reading List"
url = "$baseUrl/ReadingList/items?readingListId=${list.id}&source=readinglist" url = "$baseUrl/ReadingList/items?readingListId=${list.id}&source=readinglist"

View File

@@ -73,7 +73,7 @@ class KavitaHelper {
SManga.create().apply { SManga.create().apply {
url = "$baseUrl/Series/${obj.id}" url = "$baseUrl/Series/${obj.id}"
title = obj.name title = obj.name
thumbnail_url = KavitaImageUrls.cover(baseUrl, "series-cover", "seriesId", obj.id, apiKey) thumbnail_url = "$baseUrl/image/series-cover?seriesId=${obj.id}&apiKey=$apiKey"
} }
fun chapterFromVolume( fun chapterFromVolume(

View File

@@ -1,25 +0,0 @@
package eu.kanade.tachiyomi.extension.all.kavita
internal object KavitaImageUrls {
fun cover(
apiUrl: String,
endpoint: String,
idParam: String,
id: Int,
apiKey: String,
timestamp: String? = null,
): String {
return "$apiUrl/image/$endpoint?$idParam=$id&apiKey=$apiKey${timestampQuery(timestamp)}"
}
fun imagePath(apiUrl: String, path: String, apiKey: String): String {
val separator = if (path.startsWith("/")) "" else "/"
return "$apiUrl/image$separator$path?apiKey=$apiKey"
}
fun withTimestamp(url: String, timestamp: String): String =
"$url${if (url.contains("?")) "&" else "?"}ts=$timestamp"
private fun timestampQuery(timestamp: String?): String =
if (timestamp.isNullOrBlank()) "" else "&ts=$timestamp"
}

View File

@@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.extension.all.kavita.dto package eu.kanade.tachiyomi.extension.all.kavita.dto
import eu.kanade.tachiyomi.extension.all.kavita.KavitaConstants import eu.kanade.tachiyomi.extension.all.kavita.KavitaConstants
import eu.kanade.tachiyomi.extension.all.kavita.KavitaImageUrls
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -170,7 +169,7 @@ data class RelatedSeriesItem(
url = "$baseUrl/Series/$id" url = "$baseUrl/Series/$id"
thumbnail_url = when { thumbnail_url = when {
!coverImage.isNullOrBlank() && (coverImage.startsWith("http://") || coverImage.startsWith("https://")) -> coverImage !coverImage.isNullOrBlank() && (coverImage.startsWith("http://") || coverImage.startsWith("https://")) -> coverImage
else -> KavitaImageUrls.cover(apiUrl, "series-cover", "seriesId", id, apiKey) else -> "$apiUrl/image/series-cover?seriesId=$id&apiKey=$apiKey"
} }
initialized = true initialized = true
} }