LANraragi: fix null tags (#9997)

* Fix nullpo

* Replace GSON with kotlinx

* Minor optimisations
This commit is contained in:
ObserverOfTime 2021-12-05 19:20:46 +02:00 committed by GitHub
parent 4fba689be7
commit 21f6f747ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 55 additions and 60 deletions

View File

@ -1,11 +1,12 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
ext { ext {
extName = 'LANraragi' extName = 'LANraragi'
pkgNameSuffix = 'all.lanraragi' pkgNameSuffix = 'all.lanraragi'
extClass = '.LANraragi' extClass = '.LANraragi'
extVersionCode = 7 extVersionCode = 8
} }
dependencies { dependencies {

View File

@ -0,0 +1,32 @@
package eu.kanade.tachiyomi.extension.all.lanraragi
import kotlinx.serialization.Serializable
@Serializable
data class Archive(
val arcid: String,
val isnew: String,
val tags: String?,
val title: String
)
@Serializable
data class ArchivePage(
val pages: List<String>
)
@Serializable
data class ArchiveSearchResult(
val data: List<Archive>,
val draw: Int,
val recordsFiltered: Int,
val recordsTotal: Int
)
@Serializable
data class Category(
val id: String,
val last_used: String,
val name: String,
val pinned: String
)

View File

@ -4,14 +4,6 @@ import android.app.Application
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.Uri import android.net.Uri
import android.util.Base64 import android.util.Base64
import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.get
import com.google.gson.Gson
import com.google.gson.JsonObject
import eu.kanade.tachiyomi.extension.all.lanraragi.model.Archive
import eu.kanade.tachiyomi.extension.all.lanraragi.model.ArchivePage
import eu.kanade.tachiyomi.extension.all.lanraragi.model.ArchiveSearchResult
import eu.kanade.tachiyomi.extension.all.lanraragi.model.Category
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
@ -22,6 +14,11 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.CacheControl import okhttp3.CacheControl
import okhttp3.Dns import okhttp3.Dns
import okhttp3.Headers import okhttp3.Headers
@ -35,8 +32,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.IOException import java.io.IOException
open class LANraragi : ConfigurableSource, HttpSource() { class LANraragi : ConfigurableSource, HttpSource() {
override val baseUrl: String override val baseUrl: String
get() = preferences.getString("hostname", "http://127.0.0.1:3000")!! get() = preferences.getString("hostname", "http://127.0.0.1:3000")!!
@ -52,7 +48,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
private val latestNamespacePref: String private val latestNamespacePref: String
get() = preferences.getString("latestNamespacePref", DEFAULT_SORT_BY_NS)!! get() = preferences.getString("latestNamespacePref", DEFAULT_SORT_BY_NS)!!
private val gson: Gson = Gson() private val json by lazy { Injekt.get<Json>() }
private var randomArchiveID: String = "" private var randomArchiveID: String = ""
@ -78,7 +74,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
val archive = gson.fromJson<Archive>(response.body!!.string()) val archive = json.decodeFromString<Archive>(response.body!!.string())
return archiveToSManga(archive) return archiveToSManga(archive)
} }
@ -91,7 +87,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val archive = gson.fromJson<Archive>(response.body!!.string()) val archive = json.decodeFromString<Archive>(response.body!!.string())
val uri = getApiUriBuilder("/api/archives/${archive.arcid}/files") val uri = getApiUriBuilder("/api/archives/${archive.arcid}/files")
// Replicate old behavior and unset "isnew" for the archive. // Replicate old behavior and unset "isnew" for the archive.
@ -125,7 +121,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val archivePage = gson.fromJson<ArchivePage>(response.body!!.string()) val archivePage = json.decodeFromString<ArchivePage>(response.body!!.string())
return archivePage.pages.mapIndexed { index, url -> return archivePage.pages.mapIndexed { index, url ->
val uri = Uri.parse("${baseUrl}${url.trimStart('.')}") val uri = Uri.parse("${baseUrl}${url.trimStart('.')}")
@ -185,6 +181,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
is DescendingOrder -> if (filter.state) uri.appendQueryParameter("order", "desc") is DescendingOrder -> if (filter.state) uri.appendQueryParameter("order", "desc")
is SortByNamespace -> if (filter.state.isNotEmpty()) uri.appendQueryParameter("sortby", filter.state.trim()) is SortByNamespace -> if (filter.state.isNotEmpty()) uri.appendQueryParameter("sortby", filter.state.trim())
is CategorySelect -> if (filter.state > 0) uri.appendQueryParameter("category", filter.toUriPart()) is CategorySelect -> if (filter.state > 0) uri.appendQueryParameter("category", filter.toUriPart())
else -> Unit
} }
} }
@ -198,7 +195,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val jsonResult = gson.fromJson<ArchiveSearchResult>(response.body!!.string()) val jsonResult = json.decodeFromString<ArchiveSearchResult>(response.body!!.string())
val currentStart = getStart(response) val currentStart = getStart(response)
val archives = arrayListOf<SManga>() val archives = arrayListOf<SManga>()
@ -233,7 +230,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
title = archive.title title = archive.title
description = archive.title description = archive.title
thumbnail_url = getThumbnailUri(archive.arcid) thumbnail_url = getThumbnailUri(archive.arcid)
genre = archive.tags.replace(",", ", ") genre = archive.tags?.replace(",", ", ")
artist = getArtist(archive.tags) artist = getArtist(archive.tags)
author = artist author = artist
status = SManga.COMPLETED status = SManga.COMPLETED
@ -351,12 +348,12 @@ open class LANraragi : ConfigurableSource, HttpSource() {
// Helper // Helper
private fun getRandomID(query: String): String { private fun getRandomID(query: String): String {
val searchRandom = client.newCall(GET("$baseUrl/api/search/random?$query", headers)).execute() val searchRandom = client.newCall(GET("$baseUrl/api/search/random?$query", headers)).execute()
val data = gson.fromJson<JsonObject>(searchRandom.body!!.string())["data"] val data = json.parseToJsonElement(searchRandom.body!!.string()).jsonObject["data"]
return data.asJsonArray.firstOrNull()?.get("id")?.asString ?: "" return data!!.jsonArray.firstOrNull()?.jsonObject?.get("id")?.jsonPrimitive?.content ?: ""
} }
protected open class UriPartFilter(displayName: String, val vals: Array<Pair<String?, String>>) : open class UriPartFilter(displayName: String, private val vals: Array<Pair<String?, String>>) :
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray()) { Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray()) {
fun toUriPart() = vals[state].first fun toUriPart() = vals[state].first
} }
@ -370,7 +367,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
.subscribe( .subscribe(
{ {
categories = try { categories = try {
gson.fromJson(it.body?.charStream()!!) json.decodeFromString(it.body!!.string())
} catch (e: Exception) { } catch (e: Exception) {
emptyList() emptyList()
} }
@ -406,9 +403,7 @@ open class LANraragi : ConfigurableSource, HttpSource() {
} }
private fun getApiUriBuilder(path: String): Uri.Builder { private fun getApiUriBuilder(path: String): Uri.Builder {
val uri = Uri.parse("$baseUrl$path").buildUpon() return Uri.parse("$baseUrl$path").buildUpon()
return uri
} }
private fun getThumbnailUri(id: String): String { private fun getThumbnailUri(id: String): String {
@ -417,24 +412,20 @@ open class LANraragi : ConfigurableSource, HttpSource() {
return uri.toString() return uri.toString()
} }
private fun getTopResponse(response: Response): Response { private tailrec fun getTopResponse(response: Response): Response {
return if (response.priorResponse == null) response else getTopResponse(response.priorResponse!!) return if (response.priorResponse == null) response else getTopResponse(response.priorResponse!!)
} }
private fun getId(response: Response): String {
return getTopResponse(response).request.url.queryParameter("id").toString()
}
private fun getStart(response: Response): Int { private fun getStart(response: Response): Int {
return getTopResponse(response).request.url.queryParameter("start")!!.toInt() return getTopResponse(response).request.url.queryParameter("start")!!.toInt()
} }
private fun getReaderId(url: String): String { private fun getReaderId(url: String): String {
return Regex("""\/reader\?id=(\w{40})""").find(url)?.groupValues?.get(1) ?: "" return Regex("""/reader\?id=(\w{40})""").find(url)?.groupValues?.get(1) ?: ""
} }
private fun getThumbnailId(url: String): String { private fun getThumbnailId(url: String): String {
return Regex("""\/(\w{40})\/thumbnail""").find(url)?.groupValues?.get(1) ?: "" return Regex("""/(\w{40})/thumbnail""").find(url)?.groupValues?.get(1) ?: ""
} }
private fun getNSTag(tags: String?, tag: String): List<String>? { private fun getNSTag(tags: String?, tag: String): List<String>? {

View File

@ -1,8 +0,0 @@
package eu.kanade.tachiyomi.extension.all.lanraragi.model
data class Archive(
val arcid: String,
val isnew: String,
val tags: String,
val title: String
)

View File

@ -1,5 +0,0 @@
package eu.kanade.tachiyomi.extension.all.lanraragi.model
data class ArchivePage(
val pages: List<String>
)

View File

@ -1,8 +0,0 @@
package eu.kanade.tachiyomi.extension.all.lanraragi.model
data class ArchiveSearchResult(
val data: List<Archive>,
val draw: Int,
val recordsFiltered: Int,
val recordsTotal: Int
)

View File

@ -1,8 +0,0 @@
package eu.kanade.tachiyomi.extension.all.lanraragi.model
data class Category(
val id: String,
val last_used: String,
val name: String,
val pinned: String
)