From 0f42b9f1544b188362d1c0046c8ff853827ed270 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 8 Oct 2023 16:02:03 -0400 Subject: [PATCH] Add source preferences to backups Closes #1857 Co-authored-by: jmir1 --- .../settings/screen/SettingsBackupScreen.kt | 1 + .../tachiyomi/data/backup/BackupConst.kt | 5 +++- .../tachiyomi/data/backup/BackupManager.kt | 29 +++++++++++++++++-- .../tachiyomi/data/backup/BackupRestorer.kt | 28 ++++++++++++------ .../tachiyomi/data/backup/models/Backup.kt | 1 + .../data/backup/models/BackupPreference.kt | 6 ++++ .../core/preference/AndroidPreferenceStore.kt | 3 +- i18n/src/main/res/values/strings.xml | 1 + .../tachiyomi/source/ConfigurableSource.kt | 5 +++- 9 files changed, 63 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt index a5adfb75da..ec6b2a1dab 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt @@ -148,6 +148,7 @@ object SettingsBackupScreen : SearchableSettings { BackupConst.BACKUP_TRACK to R.string.track, BackupConst.BACKUP_HISTORY to R.string.history, BackupConst.BACKUP_APP_PREFS to R.string.app_settings, + BackupConst.BACKUP_SOURCE_PREFS to R.string.source_settings, ) } val flags = remember { choices.keys.toMutableStateList() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt index a137046e4d..6bc4771dc4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt @@ -17,5 +17,8 @@ internal object BackupConst { const val BACKUP_APP_PREFS = 0x10 const val BACKUP_APP_PREFS_MASK = 0x10 - const val BACKUP_ALL = 0x1F + const val BACKUP_SOURCE_PREFS = 0x20 + const val BACKUP_SOURCE_PREFS_MASK = 0x20 + + const val BACKUP_ALL = 0x3F } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt index 1ae5ec202d..890f32bbb3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt @@ -12,12 +12,15 @@ import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY_MASK import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CHAPTER import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CHAPTER_MASK +import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_SOURCE_PREFS +import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_SOURCE_PREFS_MASK import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_HISTORY import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_HISTORY_MASK import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_TRACK import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_TRACK_MASK import eu.kanade.tachiyomi.data.backup.models.Backup import eu.kanade.tachiyomi.data.backup.models.BackupCategory +import eu.kanade.tachiyomi.data.backup.models.BackupSourcePreferences import eu.kanade.tachiyomi.data.backup.models.BackupHistory import eu.kanade.tachiyomi.data.backup.models.BackupManga import eu.kanade.tachiyomi.data.backup.models.BackupPreference @@ -32,7 +35,10 @@ import eu.kanade.tachiyomi.data.backup.models.StringSetPreferenceValue import eu.kanade.tachiyomi.data.backup.models.backupCategoryMapper import eu.kanade.tachiyomi.data.backup.models.backupChapterMapper import eu.kanade.tachiyomi.data.backup.models.backupTrackMapper +import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.model.copyFrom +import eu.kanade.tachiyomi.source.preferenceKey +import eu.kanade.tachiyomi.source.sourcePreferences import eu.kanade.tachiyomi.util.system.hasPermission import kotlinx.serialization.protobuf.ProtoBuf import logcat.LogPriority @@ -94,6 +100,7 @@ class BackupManager( emptyList(), prepExtensionInfoForSync(databaseManga), backupAppPreferences(flags), + backupSourcePreferences(flags), ) var file: UniFile? = null @@ -232,12 +239,28 @@ class BackupManager( return mangaObject } - @Suppress("UNCHECKED_CAST") private fun backupAppPreferences(flags: Int): List { if (flags and BACKUP_APP_PREFS_MASK != BACKUP_APP_PREFS) return emptyList() - return preferenceStore.getAll() - .filterKeys { !Preference.isPrivate(it) } + return preferenceStore.getAll().toBackupPreferences() + } + + private fun backupSourcePreferences(flags: Int): List { + if (flags and BACKUP_SOURCE_PREFS_MASK != BACKUP_SOURCE_PREFS) return emptyList() + + return sourceManager.getOnlineSources() + .filterIsInstance() + .map { + BackupSourcePreferences( + it.preferenceKey(), + it.sourcePreferences().all.toBackupPreferences() + ) + } + } + + @Suppress("UNCHECKED_CAST") + private fun Map.toBackupPreferences(): List { + return this.filterKeys { !Preference.isPrivate(it) } .mapNotNull { (key, value) -> when (value) { is Int -> BackupPreference(key, IntPreferenceValue(value)) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt index 1c0558b4d9..2cd4bbc4a3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt @@ -9,16 +9,19 @@ import eu.kanade.tachiyomi.data.backup.models.BackupHistory import eu.kanade.tachiyomi.data.backup.models.BackupManga import eu.kanade.tachiyomi.data.backup.models.BackupPreference import eu.kanade.tachiyomi.data.backup.models.BackupSource +import eu.kanade.tachiyomi.data.backup.models.BackupSourcePreferences import eu.kanade.tachiyomi.data.backup.models.BooleanPreferenceValue import eu.kanade.tachiyomi.data.backup.models.FloatPreferenceValue import eu.kanade.tachiyomi.data.backup.models.IntPreferenceValue import eu.kanade.tachiyomi.data.backup.models.LongPreferenceValue import eu.kanade.tachiyomi.data.backup.models.StringPreferenceValue import eu.kanade.tachiyomi.data.backup.models.StringSetPreferenceValue +import eu.kanade.tachiyomi.source.sourcePreferences import eu.kanade.tachiyomi.util.BackupUtil import eu.kanade.tachiyomi.util.system.createFileInCacheDir import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.isActive +import tachiyomi.core.preference.AndroidPreferenceStore import tachiyomi.core.preference.PreferenceStore import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.manga.interactor.FetchInterval @@ -114,6 +117,7 @@ class BackupRestorer( return coroutineScope { restoreAppPreferences(backup.backupPreferences) + restoreSourcePreferences(backup.backupSourcePreferences) // Restore individual manga backup.backupManga.forEach { @@ -211,9 +215,22 @@ class BackupRestorer( } private fun restoreAppPreferences(preferences: List) { - val prefs = preferenceStore.getAll() + restorePreferences(preferences, preferenceStore) + } - preferences.forEach { (key, value) -> + private fun restoreSourcePreferences(preferences: List) { + preferences.forEach { + val sourcePrefs = AndroidPreferenceStore(context, sourcePreferences(it.sourceKey)) + restorePreferences(it.prefs, sourcePrefs) + } + } + + private fun restorePreferences( + toRestore: List, + preferenceStore: PreferenceStore, + ) { + val prefs = preferenceStore.getAll() + toRestore.forEach { (key, value) -> when (value) { is IntPreferenceValue -> { if (prefs[key] is Int?) { @@ -249,13 +266,6 @@ class BackupRestorer( } } - /** - * Called to update dialog in [BackupConst] - * - * @param progress restore progress - * @param amount total restoreAmount of manga - * @param title title of restored manga - */ private fun showRestoreProgress(progress: Int, amount: Int, title: String, contentTitle: String) { notifier.showRestoreProgress(title, contentTitle, progress, amount) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/Backup.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/Backup.kt index db9047f0da..0bfe17e597 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/Backup.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/Backup.kt @@ -14,6 +14,7 @@ data class Backup( @ProtoNumber(100) var backupBrokenSources: List = emptyList(), @ProtoNumber(101) var backupSources: List = emptyList(), @ProtoNumber(104) var backupPreferences: List = emptyList(), + @ProtoNumber(105) var backupSourcePreferences: List = emptyList(), ) { companion object { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupPreference.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupPreference.kt index 791c9706f1..3884f37e3f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupPreference.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupPreference.kt @@ -9,6 +9,12 @@ data class BackupPreference( @ProtoNumber(2) val value: PreferenceValue, ) +@Serializable +data class BackupSourcePreferences( + @ProtoNumber(1) val sourceKey: String, + @ProtoNumber(2) val prefs: List, +) + @Serializable sealed class PreferenceValue diff --git a/core/src/main/java/tachiyomi/core/preference/AndroidPreferenceStore.kt b/core/src/main/java/tachiyomi/core/preference/AndroidPreferenceStore.kt index 67e4db7fcd..b24fa5dcc4 100644 --- a/core/src/main/java/tachiyomi/core/preference/AndroidPreferenceStore.kt +++ b/core/src/main/java/tachiyomi/core/preference/AndroidPreferenceStore.kt @@ -15,10 +15,9 @@ import tachiyomi.core.preference.AndroidPreference.StringSetPrimitive class AndroidPreferenceStore( context: Context, + private val sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context), ) : PreferenceStore { - private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) - private val keyFlow = sharedPreferences.keyFlow override fun getString(key: String, defaultValue: String): Preference { diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index caebd66b76..ac21d13f6b 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -494,6 +494,7 @@ Backup is already in progress What do you want to backup? App settings + Source settings Creating backup Backup failed Storage permissions not granted diff --git a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt index ea5eb848ed..db9a985200 100644 --- a/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt +++ b/source-api/src/commonMain/kotlin/eu/kanade/tachiyomi/source/ConfigurableSource.kt @@ -19,8 +19,11 @@ interface ConfigurableSource : Source { fun setupPreferenceScreen(screen: PreferenceScreen) } -private fun ConfigurableSource.preferenceKey(): String = "source_$id" +fun ConfigurableSource.preferenceKey(): String = "source_$id" // TODO: use getSourcePreferences once all extensions are on ext-lib 1.5 fun ConfigurableSource.sourcePreferences(): SharedPreferences = Injekt.get().getSharedPreferences(preferenceKey(), Context.MODE_PRIVATE) + +fun sourcePreferences(key: String): SharedPreferences = + Injekt.get().getSharedPreferences(key, Context.MODE_PRIVATE)