diff --git a/src/all/komga/build.gradle b/src/all/komga/build.gradle index 38b8ca177..1cc7000b6 100644 --- a/src/all/komga/build.gradle +++ b/src/all/komga/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'Komga' pkgNameSuffix = 'all.komga' extClass = '.KomgaFactory' - extVersionCode = 31 + extVersionCode = 32 } dependencies { diff --git a/src/all/komga/src/eu/kanade/tachiyomi/extension/all/komga/Komga.kt b/src/all/komga/src/eu/kanade/tachiyomi/extension/all/komga/Komga.kt index 682f8f6ac..d4df72492 100644 --- a/src/all/komga/src/eu/kanade/tachiyomi/extension/all/komga/Komga.kt +++ b/src/all/komga/src/eu/kanade/tachiyomi/extension/all/komga/Komga.kt @@ -32,12 +32,14 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response +import okhttp3.ResponseBody import rx.Single import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy +import java.security.MessageDigest import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -176,20 +178,29 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { override fun mangaDetailsRequest(manga: SManga): Request = GET(manga.url, headers) - override fun mangaDetailsParse(response: Response): SManga = - if (response.fromReadList()) { - val readList = json.decodeFromString(response.body?.string()!!) - readList.toSManga() - } else { - val series = json.decodeFromString(response.body?.string()!!) - series.toSManga() + override fun mangaDetailsParse(response: Response): SManga { + val responseBody = response.body + ?: throw IllegalStateException("Response code ${response.code}") + + return responseBody.use { body -> + if (response.fromReadList()) { + val readList = json.decodeFromString(body.string()) + readList.toSManga() + } else { + val series = json.decodeFromString(body.string()) + series.toSManga() + } } + } override fun chapterListRequest(manga: SManga): Request = GET("${manga.url}/books?unpaged=true&media_status=READY&deleted=false", headers) override fun chapterListParse(response: Response): List { - val page = json.decodeFromString>(response.body?.string()!!).content + val responseBody = response.body + ?: throw IllegalStateException("Response code ${response.code}") + + val page = responseBody.use { json.decodeFromString>(it.string()).content } val r = page.mapIndexed { index, book -> SChapter.create().apply { @@ -207,7 +218,10 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { GET("${chapter.url}/pages") override fun pageListParse(response: Response): List { - val pages = json.decodeFromString>(response.body?.string()!!) + val responseBody = response.body + ?: throw IllegalStateException("Response code ${response.code}") + + val pages = responseBody.use { json.decodeFromString>(it.string()) } return pages.map { val url = "${response.request.url}/${it.number}" + if (!supportedImageTypes.contains(it.mediaType)) { @@ -223,13 +237,18 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { } private fun processSeriesPage(response: Response): MangasPage { - if (response.fromReadList()) { - with(json.decodeFromString>(response.body?.string()!!)) { - return MangasPage(content.map { it.toSManga() }, !last) - } - } else { - with(json.decodeFromString>(response.body?.string()!!)) { - return MangasPage(content.map { it.toSManga() }, !last) + val responseBody = response.body + ?: throw IllegalStateException("Response code ${response.code}") + + return responseBody.use { body -> + if (response.fromReadList()) { + with(json.decodeFromString>(body.string())) { + MangasPage(content.map { it.toSManga() }, !last) + } + } else { + with(json.decodeFromString>(body.string())) { + MangasPage(content.map { it.toSManga() }, !last) + } } } } @@ -350,10 +369,17 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { private var authors = emptyMap>() // roles to list of authors override val name = "Komga${if (suffix.isNotBlank()) " ($suffix)" else ""}" - override val lang = "en" + override val lang = "all" override val supportsLatest = true private val LOG_TAG = "extension.all.komga${if (suffix.isNotBlank()) ".$suffix" else ""}" + // keep the previous ID when lang was "en", so that preferences and manga bindings are not lost + override val id by lazy { + val key = "${name.toLowerCase()}/en/$versionId" + val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray()) + (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE + } + override val baseUrl by lazy { getPrefBaseUrl() } private val username by lazy { getPrefUsername() } private val password by lazy { getPrefPassword() } @@ -428,8 +454,15 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { .subscribe( { response -> libraries = try { - json.decodeFromString(response.body?.string()!!) + val responseBody = response.body + if (responseBody != null) { + responseBody.use { json.decodeFromString(it.string()) } + } else { + Log.e(LOG_TAG, "error while decoding JSON for libraries filter: response body is null. Response code: ${response.code}") + emptyList() + } } catch (e: Exception) { + Log.e(LOG_TAG, "error while decoding JSON for libraries filter", e) emptyList() } }, @@ -446,8 +479,15 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { .subscribe( { response -> collections = try { - json.decodeFromString>(response.body?.string()!!).content + val responseBody = response.body + if (responseBody != null) { + responseBody.use { json.decodeFromString>(it.string()).content } + } else { + Log.e(LOG_TAG, "error while decoding JSON for collections filter: response body is null. Response code: ${response.code}") + emptyList() + } } catch (e: Exception) { + Log.e(LOG_TAG, "error while decoding JSON for collections filter", e) emptyList() } }, @@ -464,8 +504,15 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { .subscribe( { response -> genres = try { - json.decodeFromString(response.body?.string()!!) + val responseBody = response.body + if (responseBody != null) { + responseBody.use { json.decodeFromString(it.string()) } + } else { + Log.e(LOG_TAG, "error while decoding JSON for genres filter: response body is null. Response code: ${response.code}") + emptySet() + } } catch (e: Exception) { + Log.e(LOG_TAG, "error while decoding JSON for genres filter", e) emptySet() } }, @@ -482,8 +529,15 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { .subscribe( { response -> tags = try { - json.decodeFromString(response.body?.string()!!) + val responseBody = response.body + if (responseBody != null) { + responseBody.use { json.decodeFromString(it.string()) } + } else { + Log.e(LOG_TAG, "error while decoding JSON for tags filter: response body is null. Response code: ${response.code}") + emptySet() + } } catch (e: Exception) { + Log.e(LOG_TAG, "error while decoding JSON for tags filter", e) emptySet() } }, @@ -500,8 +554,15 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { .subscribe( { response -> publishers = try { - json.decodeFromString(response.body?.string()!!) + val responseBody = response.body + if (responseBody != null) { + responseBody.use { json.decodeFromString(it.string()) } + } else { + Log.e(LOG_TAG, "error while decoding JSON for publishers filter: response body is null. Response code: ${response.code}") + emptySet() + } } catch (e: Exception) { + Log.e(LOG_TAG, "error while decoding JSON for publishers filter", e) emptySet() } }, @@ -518,9 +579,16 @@ open class Komga(suffix: String = "") : ConfigurableSource, HttpSource() { .subscribe( { response -> authors = try { - val list: List = json.decodeFromString(response.body?.string()!!) - list.groupBy { it.role } + val responseBody = response.body + if (responseBody != null) { + val list = responseBody.use> { json.decodeFromString(it.string()) } + list.groupBy { it.role } + } else { + Log.e(LOG_TAG, "error while decoding JSON for authors filter: response body is null. Response code: ${response.code}") + emptyMap() + } } catch (e: Exception) { + Log.e(LOG_TAG, "error while decoding JSON for authors filter", e) emptyMap() } },