From e349d0cef3682a462273eee16c1e84181f3074ee Mon Sep 17 00:00:00 2001 From: Aria Moradi Date: Sat, 31 Jul 2021 03:50:41 +0430 Subject: [PATCH] add pereference change --- .../manga/{TachideskAPI.kt => MangaAPI.kt} | 13 +++- .../suwayomi/tachidesk/manga/impl/Source.kt | 62 ++++++++++++++----- .../manga/impl/util/GetHttpSource.kt | 4 ++ .../suwayomi/tachidesk/server/JavalinSetup.kt | 4 +- 4 files changed, 62 insertions(+), 21 deletions(-) rename server/src/main/kotlin/suwayomi/tachidesk/manga/{TachideskAPI.kt => MangaAPI.kt} (96%) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/TachideskAPI.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt similarity index 96% rename from server/src/main/kotlin/suwayomi/tachidesk/manga/TachideskAPI.kt rename to server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt index e70ce519..77ddce49 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/TachideskAPI.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt @@ -28,9 +28,11 @@ import suwayomi.tachidesk.manga.impl.Page.getPageImage import suwayomi.tachidesk.manga.impl.Search.sourceFilters import suwayomi.tachidesk.manga.impl.Search.sourceGlobalSearch import suwayomi.tachidesk.manga.impl.Search.sourceSearch +import suwayomi.tachidesk.manga.impl.Source.SourcePreferenceChange import suwayomi.tachidesk.manga.impl.Source.getSource import suwayomi.tachidesk.manga.impl.Source.getSourceList import suwayomi.tachidesk.manga.impl.Source.getSourcePreferences +import suwayomi.tachidesk.manga.impl.Source.setSourcePreference import suwayomi.tachidesk.manga.impl.backup.BackupFlags import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupExport.createLegacyBackup import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupImport.restoreLegacyBackup @@ -45,7 +47,7 @@ import suwayomi.tachidesk.server.impl.About import java.text.SimpleDateFormat import java.util.Date -object TachideskAPI { +object MangaAPI { fun defineEndpoints(app: Javalin) { // list all extensions app.get("/api/v1/extension/list") { ctx -> @@ -111,11 +113,18 @@ object TachideskAPI { } // fetch preferences of source with id `sourceId` - app.get("/api/v1/source/:sourceId/preference-screen") { ctx -> + app.get("/api/v1/source/:sourceId/preference") { ctx -> val sourceId = ctx.pathParam("sourceId").toLong() ctx.json(getSourcePreferences(sourceId)) } + // fetch preferences of source with id `sourceId` + app.post("/api/v1/source/:sourceId/preference") { ctx -> + val sourceId = ctx.pathParam("sourceId").toLong() + val preferenceChange = ctx.bodyAsClass(SourcePreferenceChange::class.java) + ctx.json(setSourcePreference(sourceId, preferenceChange)) + } + // popular mangas from source with id `sourceId` app.get("/api/v1/source/:sourceId/popular/:pageNum") { ctx -> val sourceId = ctx.pathParam("sourceId").toLong() diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Source.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Source.kt index b4bc4f36..886d378b 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Source.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Source.kt @@ -18,6 +18,7 @@ import org.kodein.di.conf.global import org.kodein.di.instance import suwayomi.tachidesk.manga.impl.extension.Extension.getExtensionIconUrl import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource +import suwayomi.tachidesk.manga.impl.util.GetHttpSource.invalidateSourceCache import suwayomi.tachidesk.manga.model.dataclass.SourceDataClass import suwayomi.tachidesk.manga.model.table.ExtensionTable import suwayomi.tachidesk.manga.model.table.SourceTable @@ -30,12 +31,12 @@ object Source { return transaction { SourceTable.selectAll().map { SourceDataClass( - it[SourceTable.id].value.toString(), - it[SourceTable.name], - it[SourceTable.lang], - getExtensionIconUrl(ExtensionTable.select { ExtensionTable.id eq it[SourceTable.extension] }.first()[ExtensionTable.apkName]), - getHttpSource(it[SourceTable.id].value).supportsLatest, - getHttpSource(it[SourceTable.id].value) is ConfigurableSource + it[SourceTable.id].value.toString(), + it[SourceTable.name], + it[SourceTable.lang], + getExtensionIconUrl(ExtensionTable.select { ExtensionTable.id eq it[SourceTable.extension] }.first()[ExtensionTable.apkName]), + getHttpSource(it[SourceTable.id].value).supportsLatest, + getHttpSource(it[SourceTable.id].value) is ConfigurableSource ) } } @@ -46,12 +47,12 @@ object Source { val source = SourceTable.select { SourceTable.id eq sourceId }.firstOrNull() SourceDataClass( - sourceId.toString(), - source?.get(SourceTable.name), - source?.get(SourceTable.lang), - source?.let { ExtensionTable.select { ExtensionTable.id eq source[SourceTable.extension] }.first()[ExtensionTable.iconUrl] }, - source?.let { getHttpSource(sourceId).supportsLatest }, - source?.let { getHttpSource(sourceId) is ConfigurableSource }, + sourceId.toString(), + source?.get(SourceTable.name), + source?.get(SourceTable.lang), + source?.let { ExtensionTable.select { ExtensionTable.id eq source[SourceTable.extension] }.first()[ExtensionTable.iconUrl] }, + source?.let { getHttpSource(sourceId).supportsLatest }, + source?.let { getHttpSource(sourceId) is ConfigurableSource }, ) } } @@ -59,22 +60,24 @@ object Source { private val context by DI.global.instance() data class PreferenceObject( - val type: String, - val props: Any + val type: String, + val props: Any ) - var lastPreferenceScreen: PreferenceScreen? = null + var preferenceScreenMap: MutableMap = mutableMapOf() + /** + * Gets a source's PreferenceScreen, puts the result into [preferenceScreenMap] + */ fun getSourcePreferences(sourceId: Long): List { val source = getHttpSource(sourceId) if (source is ConfigurableSource) { val screen = PreferenceScreen(context) - lastPreferenceScreen = screen source.setupPreferenceScreen(screen) - screen.preferences.first().callChangeListener("yo") + preferenceScreenMap[sourceId] = screen return screen.preferences.map { PreferenceObject(it::class.java.name, it) @@ -82,4 +85,29 @@ object Source { } return emptyList() } + + data class SourcePreferenceChange( + val position: Int, + val type: String, + val value: String + ) + + fun setSourcePreference(sourceId: Long, change: SourcePreferenceChange ) { + val screen = preferenceScreenMap[sourceId]!! + + val newValue = when(change.type) { + "String" -> change.value + "Int" -> change.value.toInt() + "Long" -> change.value.toLong() + "Float" -> change.value.toLong() + "Double" -> change.value.toDouble() + "Boolean" -> change.value.toBoolean() + else -> throw RuntimeException("Unsupported type conversion") + } + + screen.preferences[change.position].callChangeListener(newValue) + + // must reload the source cache because a preference was changed + invalidateSourceCache(sourceId) + } } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/GetHttpSource.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/GetHttpSource.kt index 09ec499c..e2a98d9c 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/GetHttpSource.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/GetHttpSource.kt @@ -54,4 +54,8 @@ object GetHttpSource { } return sourceCache[sourceId]!! } + + fun invalidateSourceCache(sourceId: Long) { + sourceCache.remove(sourceId) + } } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/server/JavalinSetup.kt b/server/src/main/kotlin/suwayomi/tachidesk/server/JavalinSetup.kt index 1a6ca2e8..5aa19b73 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/server/JavalinSetup.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/server/JavalinSetup.kt @@ -14,7 +14,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.future.future import mu.KotlinLogging import suwayomi.tachidesk.anime.AnimeAPI -import suwayomi.tachidesk.manga.TachideskAPI +import suwayomi.tachidesk.manga.MangaAPI import suwayomi.tachidesk.server.util.Browser import java.io.IOException import java.util.concurrent.CompletableFuture @@ -75,7 +75,7 @@ object JavalinSetup { ctx.result(e.message ?: "Internal Server Error") } - TachideskAPI.defineEndpoints(app) + MangaAPI.defineEndpoints(app) AnimeAPI.defineEndpoints(app) } }