mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	Add source preferences to backups
Closes #1857 Co-authored-by: jmir1 <jmir1@users.noreply.github.com>
This commit is contained in:
		@@ -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() }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<BackupPreference> {
 | 
			
		||||
        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<BackupSourcePreferences> {
 | 
			
		||||
        if (flags and BACKUP_SOURCE_PREFS_MASK != BACKUP_SOURCE_PREFS) return emptyList()
 | 
			
		||||
 | 
			
		||||
        return sourceManager.getOnlineSources()
 | 
			
		||||
            .filterIsInstance<ConfigurableSource>()
 | 
			
		||||
            .map {
 | 
			
		||||
                BackupSourcePreferences(
 | 
			
		||||
                    it.preferenceKey(),
 | 
			
		||||
                    it.sourcePreferences().all.toBackupPreferences()
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Suppress("UNCHECKED_CAST")
 | 
			
		||||
    private fun Map<String, *>.toBackupPreferences(): List<BackupPreference> {
 | 
			
		||||
        return this.filterKeys { !Preference.isPrivate(it) }
 | 
			
		||||
            .mapNotNull { (key, value) ->
 | 
			
		||||
                when (value) {
 | 
			
		||||
                    is Int -> BackupPreference(key, IntPreferenceValue(value))
 | 
			
		||||
 
 | 
			
		||||
@@ -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<BackupPreference>) {
 | 
			
		||||
        val prefs = preferenceStore.getAll()
 | 
			
		||||
        restorePreferences(preferences, preferenceStore)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        preferences.forEach { (key, value) ->
 | 
			
		||||
    private fun restoreSourcePreferences(preferences: List<BackupSourcePreferences>) {
 | 
			
		||||
        preferences.forEach {
 | 
			
		||||
            val sourcePrefs = AndroidPreferenceStore(context, sourcePreferences(it.sourceKey))
 | 
			
		||||
            restorePreferences(it.prefs, sourcePrefs)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun restorePreferences(
 | 
			
		||||
        toRestore: List<BackupPreference>,
 | 
			
		||||
        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)
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ data class Backup(
 | 
			
		||||
    @ProtoNumber(100) var backupBrokenSources: List<BrokenBackupSource> = emptyList(),
 | 
			
		||||
    @ProtoNumber(101) var backupSources: List<BackupSource> = emptyList(),
 | 
			
		||||
    @ProtoNumber(104) var backupPreferences: List<BackupPreference> = emptyList(),
 | 
			
		||||
    @ProtoNumber(105) var backupSourcePreferences: List<BackupSourcePreferences> = emptyList(),
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
 
 | 
			
		||||
@@ -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<BackupPreference>,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@Serializable
 | 
			
		||||
sealed class PreferenceValue
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user