Convert SY specific usages of Gson to Kotlin Serialization

Cleanup saved searches a bit
Cleanup json parsing
This commit is contained in:
Jobobby04
2020-10-12 14:20:54 -04:00
parent bbfce97125
commit f3365cef67
46 changed files with 490 additions and 366 deletions
+21 -18
View File
@@ -2,9 +2,6 @@ package exh
import android.content.Context
import com.elvishew.xlog.XLog
import com.github.salomonbrys.kotson.fromJson
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName
import com.pushtorefresh.storio.sqlite.queries.Query
import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.BuildConfig
@@ -28,6 +25,10 @@ import eu.kanade.tachiyomi.source.online.all.Hitomi
import eu.kanade.tachiyomi.source.online.all.NHentai
import exh.merged.sql.models.MergedMangaReference
import exh.source.BlacklistedSources
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.net.URI
@@ -36,7 +37,6 @@ import java.net.URISyntaxException
object EXHMigrations {
private val db: DatabaseHelper by injectLazy()
private val sourceManager: SourceManager by injectLazy()
private val gson: Gson by injectLazy()
private val logger = XLog.tag("EXHMigrations")
@@ -167,7 +167,7 @@ object EXHMigrations {
.executeAsBlocking()
if (mergedMangas.isNotEmpty()) {
val mangaConfigs = mergedMangas.mapNotNull { mergedManga -> readMangaConfig(mergedManga, gson)?.let { mergedManga to it } }
val mangaConfigs = mergedMangas.mapNotNull { mergedManga -> readMangaConfig(mergedManga)?.let { mergedManga to it } }
if (mangaConfigs.isNotEmpty()) {
val mangaToUpdate = mutableListOf<Manga>()
val mergedMangaReferences = mutableListOf<MergedMangaReference>()
@@ -237,7 +237,7 @@ object EXHMigrations {
.prepare()
.executeAsBlocking()
val mergedMangaChaptersMatched = mergedMangaChapters.mapNotNull { chapter -> loadedMangaList.firstOrNull { it.manga.id == chapter.id }?.let { it to chapter } }
val parsedChapters = chapters.filter { it.read || it.last_page_read != 0 }.mapNotNull { chapter -> readUrlConfig(chapter.url, gson)?.let { chapter to it } }
val parsedChapters = chapters.filter { it.read || it.last_page_read != 0 }.mapNotNull { chapter -> readUrlConfig(chapter.url)?.let { chapter to it } }
val chaptersToUpdate = mutableListOf<Chapter>()
parsedChapters.forEach { parsedChapter ->
mergedMangaChaptersMatched.firstOrNull { it.second.url == parsedChapter.second.url && it.first.source.id == parsedChapter.second.source && it.first.manga.url == parsedChapter.second.mangaUrl }?.let {
@@ -339,23 +339,25 @@ object EXHMigrations {
}
}
@Serializable
private data class UrlConfig(
@SerializedName("s")
@SerialName("s")
val source: Long,
@SerializedName("u")
@SerialName("u")
val url: String,
@SerializedName("m")
@SerialName("m")
val mangaUrl: String
)
@Serializable
private data class MangaConfig(
@SerializedName("c")
@SerialName("c")
val children: List<MangaSource>
) {
companion object {
fun readFromUrl(gson: Gson, url: String): MangaConfig? {
fun readFromUrl(url: String): MangaConfig? {
return try {
gson.fromJson(url)
Json.decodeFromString(url)
} catch (e: Exception) {
null
}
@@ -363,14 +365,15 @@ object EXHMigrations {
}
}
private fun readMangaConfig(manga: SManga, gson: Gson): MangaConfig? {
return MangaConfig.readFromUrl(gson, manga.url)
private fun readMangaConfig(manga: SManga): MangaConfig? {
return MangaConfig.readFromUrl(manga.url)
}
@Serializable
private data class MangaSource(
@SerializedName("s")
@SerialName("s")
val source: Long,
@SerializedName("u")
@SerialName("u")
val url: String
) {
fun load(db: DatabaseHelper, sourceManager: SourceManager): LoadedMangaSource? {
@@ -380,9 +383,9 @@ object EXHMigrations {
}
}
private fun readUrlConfig(url: String, gson: Gson): UrlConfig? {
private fun readUrlConfig(url: String): UrlConfig? {
return try {
gson.fromJson(url)
Json.decodeFromString(url)
} catch (e: Exception) {
null
}
+10 -55
View File
@@ -2,11 +2,6 @@ package exh.debug
import android.app.Application
import com.elvishew.xlog.XLog
import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.jsonObject
import com.github.salomonbrys.kotson.obj
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonParser
import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.tables.MangaTable
@@ -16,13 +11,13 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.SourceManager.Companion.currentDelegatedSources
import exh.EH_SOURCE_ID
import exh.EXHMigrations
import exh.EXHSavedSearch
import exh.EXH_SOURCE_ID
import exh.eh.EHentaiThrottleManager
import exh.eh.EHentaiUpdateWorker
import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadata
import exh.savedsearches.JsonSavedSearch
import exh.util.await
import exh.util.cancellable
import exh.util.jobScheduler
@@ -31,8 +26,10 @@ import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
import xyz.nulldev.ts.api.http.serializer.FilterSerializer
import java.lang.RuntimeException
@OptIn(FlowPreview::class)
@@ -236,22 +233,13 @@ object DebugFunctions {
fun copyEHentaiSavedSearchesToExhentai() {
runBlocking {
val filterSerializer = FilterSerializer()
val source = sourceManager.get(EH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val newSource = sourceManager.get(EXH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val savedSearches = prefs.eh_savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != source.id) return@mapNotNull null
val content = JsonParser.parseString(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (t: RuntimeException) {
// Load failed
XLog.e("Failed to load saved search!", t)
@@ -263,15 +251,7 @@ object DebugFunctions {
try {
val id = it.substringBefore(':').toLong()
if (id != newSource.id) return@mapNotNull null
val content = JsonParser.parseString(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (t: RuntimeException) {
// Load failed
XLog.e("Failed to load saved search!", t)
@@ -284,11 +264,7 @@ object DebugFunctions {
!it.startsWith("${newSource.id}:")
}
val newSerialized = savedSearches.map {
"${newSource.id}:" + jsonObject(
"name" to it.name,
"query" to it.query,
"filters" to filterSerializer.serialize(it.filterList)
).toString()
"${newSource.id}:" + Json.encodeToString(it)
}
prefs.eh_savedSearches().set((otherSerialized + newSerialized).toSet())
}
@@ -296,22 +272,13 @@ object DebugFunctions {
fun copyExhentaiSavedSearchesToEHentai() {
runBlocking {
val filterSerializer = FilterSerializer()
val source = sourceManager.get(EXH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val newSource = sourceManager.get(EH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val savedSearches = prefs.eh_savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != source.id) return@mapNotNull null
val content = JsonParser.parseString(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (t: RuntimeException) {
// Load failed
XLog.e("Failed to load saved search!", t)
@@ -323,15 +290,7 @@ object DebugFunctions {
try {
val id = it.substringBefore(':').toLong()
if (id != newSource.id) return@mapNotNull null
val content = JsonParser.parseString(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (t: RuntimeException) {
// Load failed
XLog.e("Failed to load saved search!", t)
@@ -344,11 +303,7 @@ object DebugFunctions {
!it.startsWith("${newSource.id}:")
}
val newSerialized = savedSearches.map {
"${newSource.id}:" + jsonObject(
"name" to it.name,
"query" to it.query,
"filters" to filterSerializer.serialize(it.filterList)
).toString()
"${newSource.id}:" + Json.encodeToString(it)
}
prefs.eh_savedSearches().set((otherSerialized + newSerialized).toSet())
}
@@ -8,7 +8,6 @@ import android.content.ComponentName
import android.content.Context
import android.os.Build
import com.elvishew.xlog.XLog
import com.google.gson.Gson
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
@@ -38,6 +37,8 @@ import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import rx.schedulers.Schedulers
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -54,7 +55,6 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
private val db: DatabaseHelper by injectLazy()
private val prefs: PreferencesHelper by injectLazy()
private val gson: Gson by injectLazy()
private val sourceManager: SourceManager by injectLazy()
private val updateHelper: EHentaiUpdateHelper by injectLazy()
private val logger = XLog.tag("EHUpdater")
@@ -242,7 +242,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
}
} finally {
prefs.eh_autoUpdateStats().set(
gson.toJson(
Json.encodeToString(
EHentaiUpdaterStats(
startTime,
allMeta.size,
@@ -1,5 +1,8 @@
package exh.eh
import kotlinx.serialization.Serializable
@Serializable
data class EHentaiUpdaterStats(
val startTime: Long,
val possibleUpdates: Int,
@@ -1,20 +1,19 @@
package exh.log
import com.elvishew.xlog.XLog
import com.google.gson.Gson
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
fun OkHttpClient.Builder.maybeInjectEHLogger(): OkHttpClient.Builder {
if (EHLogLevel.shouldLog(EHLogLevel.EXTREME)) {
val logger: HttpLoggingInterceptor.Logger = object : HttpLoggingInterceptor.Logger {
override fun log(message: String) {
try {
Gson().fromJson(message, Any::class.java)
XLog.tag("||EH-NETWORK-JSON").nst().json(message)
} catch (ex: Exception) {
XLog.tag("||EH-NETWORK").nb().nst().d(message)
}
val logger: HttpLoggingInterceptor.Logger = HttpLoggingInterceptor.Logger { message ->
try {
Json.decodeFromString<Any>(message)
XLog.tag("||EH-NETWORK-JSON").nst().json(message)
} catch (ex: Exception) {
XLog.tag("||EH-NETWORK").nb().nst().d(message)
}
}
return addInterceptor(HttpLoggingInterceptor(logger).apply { level = HttpLoggingInterceptor.Level.BODY })
@@ -1,24 +1,27 @@
package exh.md.handlers
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.source.model.Page
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Response
import java.util.Date
class ApiChapterParser {
fun pageListParse(response: Response): List<Page> {
val jsonData = response.body!!.string()
val json = JsonParser.parseString(jsonData).asJsonObject
val json = Json.decodeFromString<JsonObject>(jsonData)
val pages = mutableListOf<Page>()
val hash = json.get("hash").string
val pageArray = json.getAsJsonArray("page_array")
val server = json.get("server").string
val hash = json["hash"]!!.jsonPrimitive.content
val pageArray = json["page_array"]!!.jsonArray
val server = json["server"]!!.jsonPrimitive.content
pageArray.forEach {
val url = "$hash/${it.asString}"
val url = "$hash/${it.jsonPrimitive.content}"
pages.add(Page(pages.size, "$server,${response.request.url},${Date().time}", url))
}
@@ -27,8 +30,8 @@ class ApiChapterParser {
fun externalParse(response: Response): String {
val jsonData = response.body!!.string()
val json = JsonParser.parseString(jsonData).asJsonObject
val external = json.get("external").string
val json = Json.decodeFromString<JsonObject>(jsonData)
val external = json["external"]!!.jsonPrimitive.content
return external.substringAfterLast("/")
}
}
@@ -1,9 +1,6 @@
package exh.md.handlers
import com.elvishew.xlog.XLog
import com.github.salomonbrys.kotson.nullInt
import com.github.salomonbrys.kotson.obj
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.model.SChapter
@@ -18,6 +15,11 @@ import exh.metadata.metadata.base.RaisedTag
import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadata
import exh.util.floor
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Response
import rx.Completable
import rx.Single
@@ -232,8 +234,8 @@ class ApiMangaParser(private val langs: List<String>) {
throw Exception("Null Response")
}
val jsonObject = JsonParser.parseString(body).obj
return jsonObject["manga_id"]?.nullInt ?: throw Exception("No manga associated with chapter")
val jsonObject = Json.decodeFromString<JsonObject>(body)
return jsonObject["manga_id"]?.jsonPrimitive?.intOrNull ?: throw Exception("No manga associated with chapter")
} catch (e: Exception) {
XLog.e(e)
throw e
@@ -9,10 +9,12 @@ import exh.metadata.EX_DATE_FORMAT
import exh.metadata.ONGOING_SUFFIX
import exh.metadata.humanReadableByteCount
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date
@Serializable
class EHentaiSearchMetadata : RaisedSearchMetadata() {
var gId: String?
get() = indexedExtra
@@ -4,7 +4,9 @@ import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
@Serializable
class EightMusesSearchMetadata : RaisedSearchMetadata() {
var path: List<String> = emptyList()
@@ -5,7 +5,9 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.metadata.EightMusesSearchMetadata.Companion.ARTIST_NAMESPACE
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
@Serializable
class HBrowseSearchMetadata : RaisedSearchMetadata() {
var hbId: Long? = null
@@ -4,7 +4,9 @@ import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
@Serializable
class HentaiCafeSearchMetadata : RaisedSearchMetadata() {
var hcId: String? = null
var readerId: String? = null
@@ -5,9 +5,10 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.EX_DATE_FORMAT
import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.plusAssign
import kotlinx.serialization.Serializable
import java.util.Date
@Serializable
class HitomiSearchMetadata : RaisedSearchMetadata() {
var url get() = hlId?.let { urlFromHlId(it) }
set(a) {
@@ -26,7 +27,7 @@ class HitomiSearchMetadata : RaisedSearchMetadata() {
var group: String? = null
var type: String? = null
var genre: String? = null
var language: String? = null
@@ -101,7 +102,7 @@ class HitomiSearchMetadata : RaisedSearchMetadata() {
pairs += Pair(context.getString(R.string.artist), artists)
}
group?.let { pairs += Pair(context.getString(R.string.group), it) }
type?.let { pairs += Pair(context.getString(R.string.genre), it) }
genre?.let { pairs += Pair(context.getString(R.string.genre), it) }
language?.let { pairs += Pair(context.getString(R.string.language), it) }
val series = series.joinToString()
if (series.isNotBlank()) {
@@ -5,7 +5,9 @@ import androidx.core.net.toUri
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
@Serializable
class MangaDexSearchMetadata : RaisedSearchMetadata() {
var mdId: String? = null
@@ -6,9 +6,11 @@ import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.EX_DATE_FORMAT
import exh.metadata.ONGOING_SUFFIX
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
import uy.kohesive.injekt.api.get
import java.util.Date
@Serializable
class NHentaiSearchMetadata : RaisedSearchMetadata() {
var url get() = nhId?.let { BASE_URL + nhIdToPath(it) }
set(a) {
@@ -6,7 +6,9 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.metadata.base.RaisedSearchMetadata
import exh.metadata.metadata.base.RaisedTitle
import kotlinx.serialization.Serializable
@Serializable
class PervEdenSearchMetadata : RaisedSearchMetadata() {
var pvId: String? = null
@@ -23,7 +25,7 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
var artist: String? = null
var type: String? = null
var genre: String? = null
var rating: Float? = null
@@ -102,7 +104,7 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
pairs += Pair(context.getString(R.string.alt_titles), altTitles)
}
artist?.let { pairs += Pair(context.getString(R.string.artist), it) }
type?.let { pairs += Pair(context.getString(R.string.genre), it) }
genre?.let { pairs += Pair(context.getString(R.string.genre), it) }
rating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
status?.let { pairs += Pair(context.getString(R.string.status), it) }
lang?.let { pairs += Pair(context.getString(R.string.language), it) }
@@ -4,7 +4,9 @@ import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
@Serializable
class PururinSearchMetadata : RaisedSearchMetadata() {
var prId: Int? = null
@@ -6,10 +6,12 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.EX_DATE_FORMAT
import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.serialization.Serializable
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@Serializable
class TsuminoSearchMetadata : RaisedSearchMetadata() {
var tmId: Int? = null
@@ -5,10 +5,15 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
import exh.metadata.sql.models.SearchMetadata
import exh.metadata.sql.models.SearchTag
import exh.metadata.sql.models.SearchTitle
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.serializer
import rx.Completable
import rx.Single
import kotlin.reflect.KClass
@Serializable
data class FlatMetadata(
val metadata: SearchMetadata,
val tags: List<SearchTag>,
@@ -16,9 +21,10 @@ data class FlatMetadata(
) {
inline fun <reified T : RaisedSearchMetadata> raise(): T = raise(T::class)
@OptIn(InternalSerializationApi::class)
fun <T : RaisedSearchMetadata> raise(clazz: KClass<T>): T =
RaisedSearchMetadata.raiseFlattenGson
.fromJson(metadata.extra, clazz.java).apply {
RaisedSearchMetadata.raiseFlattenJson
.decodeFromString(clazz.serializer(), metadata.extra).apply {
fillBaseFields(this@FlatMetadata)
}
}
@@ -1,17 +1,35 @@
package exh.metadata.metadata.base
import android.content.Context
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.forEach
import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.EightMusesSearchMetadata
import exh.metadata.metadata.HBrowseSearchMetadata
import exh.metadata.metadata.HentaiCafeSearchMetadata
import exh.metadata.metadata.HitomiSearchMetadata
import exh.metadata.metadata.MangaDexSearchMetadata
import exh.metadata.metadata.NHentaiSearchMetadata
import exh.metadata.metadata.PervEdenSearchMetadata
import exh.metadata.metadata.PururinSearchMetadata
import exh.metadata.metadata.TsuminoSearchMetadata
import exh.metadata.sql.models.SearchMetadata
import exh.metadata.sql.models.SearchTag
import exh.metadata.sql.models.SearchTitle
import exh.plusAssign
import kotlinx.serialization.Polymorphic
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
@Polymorphic
@Serializable
abstract class RaisedSearchMetadata {
@Transient
var mangaId: Long = -1
@@ -67,7 +85,7 @@ abstract class RaisedSearchMetadata {
fun flatten(): FlatMetadata {
require(mangaId != -1L)
val extra = raiseFlattenGson.toJson(this)
val extra = raiseFlattenJson.encodeToString(this)
return FlatMetadata(
SearchMetadata(
mangaId,
@@ -122,7 +140,25 @@ abstract class RaisedSearchMetadata {
(this).filter { it.type != TAG_TYPE_VIRTUAL }
.joinToString { (if (it.namespace != null) "${it.namespace}: " else "") + it.name }
val raiseFlattenGson: Gson = GsonBuilder().create()
private val module = SerializersModule {
polymorphic(RaisedSearchMetadata::class) {
subclass(EHentaiSearchMetadata::class)
subclass(EightMusesSearchMetadata::class)
subclass(HBrowseSearchMetadata::class)
subclass(HentaiCafeSearchMetadata::class)
subclass(HitomiSearchMetadata::class)
subclass(MangaDexSearchMetadata::class)
subclass(NHentaiSearchMetadata::class)
subclass(PervEdenSearchMetadata::class)
subclass(PururinSearchMetadata::class)
subclass(TsuminoSearchMetadata::class)
}
}
val raiseFlattenJson = Json {
ignoreUnknownKeys = true
serializersModule = module
}
fun titleDelegate(type: Int) = object : ReadWriteProperty<RaisedSearchMetadata, String?> {
/**
@@ -1,5 +1,8 @@
package exh.metadata.metadata.base
import kotlinx.serialization.Serializable
@Serializable
data class RaisedTag(
val namespace: String?,
val name: String,
@@ -1,5 +1,8 @@
package exh.metadata.metadata.base
import kotlinx.serialization.Serializable
@Serializable
data class RaisedTitle(
val title: String,
val type: Int = 0
@@ -1,5 +1,9 @@
package exh.metadata.sql.models
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
@Serializable
data class SearchMetadata(
// Manga ID this gallery is linked to
val mangaId: Long,
@@ -17,5 +21,6 @@ data class SearchMetadata(
val extraVersion: Int
) {
// Transient information attached to this piece of metadata, useful for caching
var transientCache: Map<String, Any>? = null
var transientCache: Map<String, @Contextual Any>? = null
}
@@ -1,5 +1,8 @@
package exh.metadata.sql.models
import kotlinx.serialization.Serializable
@Serializable
data class SearchTag(
// Tag identifier, unique
val id: Long?,
@@ -1,5 +1,8 @@
package exh.metadata.sql.models
import kotlinx.serialization.Serializable
@Serializable
data class SearchTitle(
// Title identifier, unique
val id: Long?,
@@ -1,4 +1,4 @@
package exh
package exh.savedsearches
import eu.kanade.tachiyomi.source.model.FilterList
@@ -0,0 +1,11 @@
package exh.savedsearches
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonArray
@Serializable
data class JsonSavedSearch(
val name: String,
val query: String,
val filters: JsonArray
)
@@ -13,9 +13,6 @@ import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity
import com.afollestad.materialdialogs.MaterialDialog
import com.elvishew.xlog.XLog
import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.network.NetworkHelper
@@ -28,6 +25,12 @@ import exh.source.DelegatedHttpSource
import exh.util.melt
import kotlinx.android.synthetic.main.eh_activity_captcha.toolbar
import kotlinx.android.synthetic.main.eh_activity_captcha.webview
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
@@ -153,9 +156,9 @@ class BrowserActionActivity : AppCompatActivity() {
.asObservableSuccess()
.subscribeOn(Schedulers.io())
.map {
val json = JsonParser.parseString(it.body!!.string())
val json = Json.decodeFromString<JsonObject>(it.body!!.string())
it.close()
json["token"].string
json["token"]!!.jsonPrimitive.content
}.melt()
webview.addJavascriptInterface(this@BrowserActionActivity, "exh")
@@ -317,7 +320,7 @@ class BrowserActionActivity : AppCompatActivity() {
.build()
).asObservableSuccess()
}.map { response ->
JsonParser.parseString(response.body!!.string())["results"][0]["alternatives"][0]["transcript"].string.trim()
Json.decodeFromString<JsonObject>(response.body!!.string())["results"]!!.jsonArray[0].jsonObject["alternatives"]!!.jsonArray[0].jsonObject["transcript"]!!.jsonPrimitive.content.trim()
}.toSingle()
}
@@ -47,7 +47,7 @@ class HitomiDescriptionAdapter(
val meta = controller.presenter.meta
if (meta == null || meta !is HitomiSearchMetadata) return
val genre = meta.type
val genre = meta.genre
if (genre != null) {
val pair = when (genre) {
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
@@ -47,7 +47,7 @@ class PervEdenDescriptionAdapter(
val meta = controller.presenter.meta
if (meta == null || meta !is PervEdenSearchMetadata) return
val genre = meta.type
val genre = meta.genre
if (genre != null) {
val pair = when (genre) {
"Doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)