Add Kavita admin actions to extension
This commit is contained in:
@@ -2,7 +2,7 @@ ext {
|
|||||||
kmkVersionCode = 1
|
kmkVersionCode = 1
|
||||||
extName = 'Kavita'
|
extName = 'Kavita'
|
||||||
extClass = '.KavitaFactory'
|
extClass = '.KavitaFactory'
|
||||||
extVersionCode = 34
|
extVersionCode = 35
|
||||||
isNsfw = false
|
isNsfw = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1727,6 +1727,21 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seriesDtoForContext?.let { currentSeries ->
|
||||||
|
allChapters += adminActionChapter(
|
||||||
|
seriesId = currentSeries.id,
|
||||||
|
libraryId = currentSeries.libraryId,
|
||||||
|
action = ADMIN_ACTION_REFRESH_COVER,
|
||||||
|
title = "Kavita: 표지 새로고침",
|
||||||
|
)
|
||||||
|
allChapters += adminActionChapter(
|
||||||
|
seriesId = currentSeries.id,
|
||||||
|
libraryId = currentSeries.libraryId,
|
||||||
|
action = ADMIN_ACTION_SCAN_SERIES,
|
||||||
|
title = "Kavita: 시리즈 스캔",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// 1.0 (Chapter) > 0.0001 (Volume) > 0.00001 (Special)
|
// 1.0 (Chapter) > 0.0001 (Volume) > 0.00001 (Special)
|
||||||
return allChapters.sortedByDescending { it.chapter_number }
|
return allChapters.sortedByDescending { it.chapter_number }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -1735,6 +1750,15 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun adminActionChapter(seriesId: Int, libraryId: Int, action: String, title: String): SChapter =
|
||||||
|
SChapter.create().apply {
|
||||||
|
name = title
|
||||||
|
url = "$ADMIN_ACTION_URL?action=$action&seriesId=$seriesId&libraryId=$libraryId"
|
||||||
|
chapter_number = Float.MAX_VALUE
|
||||||
|
scanlator = "Kavita 관리"
|
||||||
|
date_upload = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the "url" of each page from the chapter
|
* Fetches the "url" of each page from the chapter
|
||||||
* **/
|
* **/
|
||||||
@@ -1861,6 +1885,10 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
private fun String.urlEncode(): String = URLEncoder.encode(this, Charsets.UTF_8.name())
|
private fun String.urlEncode(): String = URLEncoder.encode(this, Charsets.UTF_8.name())
|
||||||
|
|
||||||
override suspend fun getPageList(chapter: SChapter): List<Page> = withContext(Dispatchers.IO) {
|
override suspend fun getPageList(chapter: SChapter): List<Page> = withContext(Dispatchers.IO) {
|
||||||
|
if (chapter.url.startsWith(ADMIN_ACTION_URL)) {
|
||||||
|
return@withContext executeAdminAction(chapter.url)
|
||||||
|
}
|
||||||
|
|
||||||
// Check if this is a reading list item (has readingListId in URL)
|
// Check if this is a reading list item (has readingListId in URL)
|
||||||
if (chapter.url.contains("readingListId=")) {
|
if (chapter.url.contains("readingListId=")) {
|
||||||
try {
|
try {
|
||||||
@@ -2009,6 +2037,62 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun executeAdminAction(url: String): List<Page> {
|
||||||
|
val action = queryParam(url, "action") ?: throw IOException("Missing Kavita action")
|
||||||
|
val seriesId = queryParam(url, "seriesId")?.toIntOrNull() ?: throw IOException("Missing Kavita seriesId")
|
||||||
|
val libraryId = queryParam(url, "libraryId")?.toIntOrNull() ?: throw IOException("Missing Kavita libraryId")
|
||||||
|
|
||||||
|
val endpoint = when (action) {
|
||||||
|
ADMIN_ACTION_REFRESH_COVER -> "$apiUrl/Series/refresh-metadata"
|
||||||
|
ADMIN_ACTION_SCAN_SERIES -> "$apiUrl/Series/scan"
|
||||||
|
else -> throw IOException("Unknown Kavita action: $action")
|
||||||
|
}
|
||||||
|
|
||||||
|
val payload = buildJsonObject {
|
||||||
|
put("libraryId", libraryId)
|
||||||
|
put("seriesId", seriesId)
|
||||||
|
put("forceUpdate", true)
|
||||||
|
put("forceColorscape", true)
|
||||||
|
}.toString()
|
||||||
|
|
||||||
|
client.newCall(
|
||||||
|
POST(
|
||||||
|
endpoint,
|
||||||
|
headersBuilder().build(),
|
||||||
|
payload.toRequestBody(JSON_MEDIA_TYPE),
|
||||||
|
),
|
||||||
|
).execute().use { response ->
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
val message = when (response.code) {
|
||||||
|
401, 403 -> "Kavita 관리자 권한이 필요합니다."
|
||||||
|
else -> "Kavita action failed: HTTP ${response.code}"
|
||||||
|
}
|
||||||
|
throw IOException(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val coverUrl = "$apiUrl/image/series-cover".toHttpUrlOrNull()!!.newBuilder()
|
||||||
|
.addQueryParameter("seriesId", seriesId.toString())
|
||||||
|
.addQueryParameter("apiKey", apiKey)
|
||||||
|
.addQueryParameter("t", System.currentTimeMillis().toString())
|
||||||
|
.build()
|
||||||
|
.toString()
|
||||||
|
|
||||||
|
return listOf(Page(index = 0, url = coverUrl, imageUrl = coverUrl))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun queryParam(url: String, key: String): String? {
|
||||||
|
val query = url.substringAfter("?", "")
|
||||||
|
if (query.isBlank()) return null
|
||||||
|
|
||||||
|
return query.split("&")
|
||||||
|
.firstNotNullOfOrNull { part ->
|
||||||
|
val name = part.substringBefore("=")
|
||||||
|
val value = part.substringAfter("=", "")
|
||||||
|
value.takeIf { name == key && it.isNotBlank() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage =
|
override fun latestUpdatesParse(response: Response): MangasPage =
|
||||||
throw UnsupportedOperationException("Not used")
|
throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
@@ -2613,6 +2697,10 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
|
|||||||
|
|
||||||
private const val SCANLATOR_FORMAT_PREF = "scanlatorFormat"
|
private const val SCANLATOR_FORMAT_PREF = "scanlatorFormat"
|
||||||
const val SCANLATOR_FORMAT_DEFAULT = "\$Type"
|
const val SCANLATOR_FORMAT_DEFAULT = "\$Type"
|
||||||
|
|
||||||
|
private const val ADMIN_ACTION_URL = "kavita-admin://series"
|
||||||
|
private const val ADMIN_ACTION_REFRESH_COVER = "refresh-cover"
|
||||||
|
private const val ADMIN_ACTION_SCAN_SERIES = "scan-series"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user