Kavita API Change for v0.7.1.33+ ()

* Updated Kavita to pass apiKey for image apis as this is required in v0.7.1.33+. Non-breaking change for Stable branch users.

* Updated Kavita to pass apiKey for image apis as this is required in v0.7.1.33+. Non-breaking change for Stable branch users.

* Bumped version number

* Updated the Changelog with changes and corrected a dupe version number
This commit is contained in:
Joe Milazzo 2023-04-17 08:54:09 -05:00 committed by GitHub
parent 26fc3f1be2
commit 2a3d267721
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 12 deletions
src/all/kavita
CHANGELOG.mdbuild.gradle
src/eu/kanade/tachiyomi/extension/all/kavita

@ -1,4 +1,10 @@
## 1.3.8 ## 1.3.10
### Features
* API Change for Kavita v0.7.2
## 1.3.9
### Features ### Features

@ -6,7 +6,7 @@ ext {
extName = 'Kavita' extName = 'Kavita'
pkgNameSuffix = 'all.kavita' pkgNameSuffix = 'all.kavita'
extClass = '.KavitaFactory' extClass = '.KavitaFactory'
extVersionCode = 9 extVersionCode = 10
} }
dependencies { dependencies {

@ -106,9 +106,10 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
private val apiUrl by lazy { getPrefApiUrl() } private val apiUrl by lazy { getPrefApiUrl() }
override val baseUrl by lazy { getPrefBaseUrl() } override val baseUrl by lazy { getPrefBaseUrl() }
private val address by lazy { getPrefAddress() } // Address for the Kavita OPDS url. Should be http(s)://host:(port)/api/opds/api-key private val address by lazy { getPrefAddress() } // Address for the Kavita OPDS url. Should be http(s)://host:(port)/api/opds/api-key
private val apiKey by lazy { getPrefApiKey() }
private var jwtToken = "" // * JWT Token for authentication with the server. Stored in memory. private var jwtToken = "" // * JWT Token for authentication with the server. Stored in memory.
private val LOG_TAG = """extension.all.kavita_${"[$suffix]_" + preferences.getString(KavitaConstants.customSourceNamePref,"[$suffix]")!!.replace(' ','_')}""" private val LOG_TAG = """extension.all.kavita_${"[$suffix]_" + preferences.getString(KavitaConstants.customSourceNamePref,"[$suffix]")!!.replace(' ','_')}"""
private var isLoged = false // Used to know if login was correct and not send login requests anymore private var isLogged = false // Used to know if login was correct and not send login requests anymore
private val json: Json by injectLazy() private val json: Json by injectLazy()
private val helper = KavitaHelper() private val helper = KavitaHelper()
@ -135,7 +136,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
private var series = emptyList<SeriesDto>() // Acts as a cache private var series = emptyList<SeriesDto>() // Acts as a cache
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
if (!isLoged) { if (!isLogged) {
doLogin() doLogin()
} }
return POST( return POST(
@ -149,7 +150,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
try { try {
val result = response.parseAs<List<SeriesDto>>() val result = response.parseAs<List<SeriesDto>>()
series = result series = result
val mangaList = result.map { item -> helper.createSeriesDto(item, apiUrl) } val mangaList = result.map { item -> helper.createSeriesDto(item, apiUrl, apiKey) }
return MangasPage(mangaList, helper.hasNextPage(response)) return MangasPage(mangaList, helper.hasNextPage(response))
} catch (e: Exception) { } catch (e: Exception) {
Log.e(LOG_TAG, "Possible outdated kavita", e) Log.e(LOG_TAG, "Possible outdated kavita", e)
@ -158,7 +159,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
} }
override fun latestUpdatesRequest(page: Int): Request { override fun latestUpdatesRequest(page: Int): Request {
if (!isLoged) { if (!isLogged) {
doLogin() doLogin()
} }
return POST( return POST(
@ -378,13 +379,13 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
val existingSeries = series.find { dto -> dto.id == result.seriesId } val existingSeries = series.find { dto -> dto.id == result.seriesId }
if (existingSeries != null) { if (existingSeries != null) {
val manga = helper.createSeriesDto(existingSeries, apiUrl) val manga = helper.createSeriesDto(existingSeries, apiUrl, apiKey)
manga.url = "$apiUrl/Series/${result.seriesId}" manga.url = "$apiUrl/Series/${result.seriesId}"
manga.artist = result.coverArtists.joinToString { it.name } manga.artist = result.coverArtists.joinToString { it.name }
manga.description = result.summary manga.description = result.summary
manga.author = result.writers.joinToString { it.name } manga.author = result.writers.joinToString { it.name }
manga.genre = result.genres.joinToString { it.title } manga.genre = result.genres.joinToString { it.title }
manga.thumbnail_url = "$apiUrl/image/series-cover?seriesId=${result.seriesId}" manga.thumbnail_url = "$apiUrl/image/series-cover?seriesId=${result.seriesId}&apiKey=$apiKey"
return manga return manga
} }
@ -504,7 +505,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
pages.add( pages.add(
Page( Page(
index = i, index = i,
imageUrl = "$apiUrl/Reader/image?chapterId=$chapterId&page=$i&extractPdf=true", imageUrl = "$apiUrl/Reader/image?chapterId=$chapterId&page=$i&extractPdf=true&apiKey=$apiKey",
), ),
) )
} }
@ -1045,6 +1046,12 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
return path return path
} }
private fun getPrefApiKey(): String {
// http(s)://host:(port)/api/opds/api-key
var existingKey = preferences.getString("APIKEY", "")
return existingKey!!.ifEmpty { preferences.getString(ADDRESS_TITLE, "")!!.split("/opds/")[1] }
}
companion object { companion object {
private const val ADDRESS_TITLE = "Address" private const val ADDRESS_TITLE = "Address"
private val JSON_MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull() private val JSON_MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull()
@ -1119,7 +1126,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
if (it.code == 200) { if (it.code == 200) {
try { try {
jwtToken = it.parseAs<AuthenticationDto>().token jwtToken = it.parseAs<AuthenticationDto>().token
isLoged = true isLogged = true
} catch (e: Exception) { } catch (e: Exception) {
Log.e(LOG_TAG, "Possible outdated kavita", e) Log.e(LOG_TAG, "Possible outdated kavita", e)
throw IOException("Please check your kavita version.\nv0.5+ is required for the extension to work properly") throw IOException("Please check your kavita version.\nv0.5+ is required for the extension to work properly")

@ -38,11 +38,11 @@ class KavitaHelper {
return url.split("/").last().toInt() return url.split("/").last().toInt()
} }
fun createSeriesDto(obj: SeriesDto, baseUrl: String): SManga = fun createSeriesDto(obj: SeriesDto, baseUrl: String, apiKey: String): SManga =
SManga.create().apply { SManga.create().apply {
url = "$baseUrl/Series/${obj.id}" url = "$baseUrl/Series/${obj.id}"
title = obj.name title = obj.name
// Deprecated: description = obj.summary // Deprecated: description = obj.summary
thumbnail_url = "$baseUrl/image/series-cover?seriesId=${obj.id}" thumbnail_url = "$baseUrl/image/series-cover?seriesId=${obj.id}&apiKey=$apiKey"
} }
} }