mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-28 09:15:12 +03:00
fix restoring "full" backups with preferences
This commit is contained in:
parent
183107c482
commit
2daac8b976
5 changed files with 155 additions and 2 deletions
|
@ -3,15 +3,31 @@ package eu.kanade.tachiyomi.data.backup
|
|||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.backup.models.Backup
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupPreference
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupSerializer
|
||||
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.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.source.anime.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.manga.MangaSourceManager
|
||||
import kotlinx.serialization.SerializationException
|
||||
import okio.buffer
|
||||
import okio.gzip
|
||||
import okio.source
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer as FullBackupSerializer
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.BooleanPreferenceValue as FullBooleanPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.FloatPreferenceValue as FullFloatPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.IntPreferenceValue as FullIntPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.LongPreferenceValue as FullLongPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.StringPreferenceValue as FullStringPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.StringSetPreferenceValue as FullStringSetPreferenceValue
|
||||
|
||||
class BackupFileValidator(
|
||||
private val mangaSourceManager: MangaSourceManager = Injekt.get(),
|
||||
|
@ -32,7 +48,34 @@ class BackupFileValidator(
|
|||
val backupString =
|
||||
context.contentResolver.openInputStream(uri)!!.source().gzip().buffer()
|
||||
.use { it.readByteArray() }
|
||||
backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
||||
// Sadly, this is necessary because of old "full" backups.
|
||||
try {
|
||||
backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
||||
} catch (e: SerializationException) {
|
||||
val fullBackup = backupManager.parser.decodeFromByteArray(FullBackupSerializer, backupString)
|
||||
val backupPreferences = fullBackup.backupPreferences.map {
|
||||
val value = when (it.value) {
|
||||
is FullIntPreferenceValue -> IntPreferenceValue(it.value.value)
|
||||
is FullLongPreferenceValue -> LongPreferenceValue(it.value.value)
|
||||
is FullFloatPreferenceValue -> FloatPreferenceValue(it.value.value)
|
||||
is FullBooleanPreferenceValue -> BooleanPreferenceValue(it.value.value)
|
||||
is FullStringPreferenceValue -> StringPreferenceValue(it.value.value)
|
||||
is FullStringSetPreferenceValue -> StringSetPreferenceValue(it.value.value)
|
||||
}
|
||||
BackupPreference(it.key, value)
|
||||
}
|
||||
Backup(
|
||||
fullBackup.backupManga,
|
||||
fullBackup.backupCategories,
|
||||
fullBackup.backupAnime,
|
||||
fullBackup.backupAnimeCategories,
|
||||
fullBackup.backupBrokenSources,
|
||||
fullBackup.backupSources,
|
||||
fullBackup.backupBrokenAnimeSources,
|
||||
fullBackup.backupAnimeSources,
|
||||
backupPreferences,
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw IllegalStateException(e)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import android.net.Uri
|
||||
import androidx.preference.PreferenceManager
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.backup.models.Backup
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupAnime
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupAnimeHistory
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupAnimeSource
|
||||
|
@ -27,6 +28,7 @@ import eu.kanade.tachiyomi.data.database.models.manga.Manga
|
|||
import eu.kanade.tachiyomi.data.database.models.manga.MangaTrack
|
||||
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.serialization.SerializationException
|
||||
import okio.buffer
|
||||
import okio.gzip
|
||||
import okio.source
|
||||
|
@ -34,6 +36,13 @@ import java.io.File
|
|||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer as FullBackupSerializer
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.BooleanPreferenceValue as FullBooleanPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.FloatPreferenceValue as FullFloatPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.IntPreferenceValue as FullIntPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.LongPreferenceValue as FullLongPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.StringPreferenceValue as FullStringPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.full.models.StringSetPreferenceValue as FullStringSetPreferenceValue
|
||||
|
||||
class BackupRestorer(
|
||||
private val context: Context,
|
||||
|
@ -95,7 +104,35 @@ class BackupRestorer(
|
|||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
private suspend fun performRestore(uri: Uri): Boolean {
|
||||
val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() }
|
||||
val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
||||
|
||||
// Sadly, this is necessary because of old "full" backups.
|
||||
val backup = try {
|
||||
backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
||||
} catch (e: SerializationException) {
|
||||
val fullBackup = backupManager.parser.decodeFromByteArray(FullBackupSerializer, backupString)
|
||||
val backupPreferences = fullBackup.backupPreferences.map {
|
||||
val value = when (it.value) {
|
||||
is FullIntPreferenceValue -> IntPreferenceValue(it.value.value)
|
||||
is FullLongPreferenceValue -> LongPreferenceValue(it.value.value)
|
||||
is FullFloatPreferenceValue -> FloatPreferenceValue(it.value.value)
|
||||
is FullBooleanPreferenceValue -> BooleanPreferenceValue(it.value.value)
|
||||
is FullStringPreferenceValue -> StringPreferenceValue(it.value.value)
|
||||
is FullStringSetPreferenceValue -> StringSetPreferenceValue(it.value.value)
|
||||
}
|
||||
BackupPreference(it.key, value)
|
||||
}
|
||||
Backup(
|
||||
fullBackup.backupManga,
|
||||
fullBackup.backupCategories,
|
||||
fullBackup.backupAnime,
|
||||
fullBackup.backupAnimeCategories,
|
||||
fullBackup.backupBrokenSources,
|
||||
fullBackup.backupSources,
|
||||
fullBackup.backupBrokenAnimeSources,
|
||||
fullBackup.backupAnimeSources,
|
||||
backupPreferences,
|
||||
)
|
||||
}
|
||||
|
||||
restoreAmount = backup.backupManga.size + backup.backupAnime.size + 2 // +2 for categories
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package eu.kanade.tachiyomi.data.backup.full.models
|
||||
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupAnime
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupAnimeSource
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupCategory
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupManga
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupSource
|
||||
import eu.kanade.tachiyomi.data.backup.models.BrokenBackupAnimeSource
|
||||
import eu.kanade.tachiyomi.data.backup.models.BrokenBackupSource
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
@Serializable
|
||||
data class Backup(
|
||||
@ProtoNumber(1) val backupManga: List<BackupManga> = emptyList(),
|
||||
@ProtoNumber(2) var backupCategories: List<BackupCategory> = emptyList(),
|
||||
@ProtoNumber(3) val backupAnime: List<BackupAnime> = emptyList(),
|
||||
@ProtoNumber(4) var backupAnimeCategories: List<BackupCategory> = emptyList(),
|
||||
// Bump by 100 to specify this is a 0.x value
|
||||
@ProtoNumber(100) var backupBrokenSources: List<BrokenBackupSource> = emptyList(),
|
||||
@ProtoNumber(101) var backupSources: List<BackupSource> = emptyList(),
|
||||
@ProtoNumber(102) var backupBrokenAnimeSources: List<BrokenBackupAnimeSource> = emptyList(),
|
||||
@ProtoNumber(103) var backupAnimeSources: List<BackupAnimeSource> = emptyList(),
|
||||
@ProtoNumber(104) var backupPreferences: List<BackupPreference> = emptyList(),
|
||||
) {
|
||||
|
||||
companion object {
|
||||
fun getBackupFilename(): String {
|
||||
val date = SimpleDateFormat("yyyy-MM-dd_HH-mm", Locale.getDefault()).format(Date())
|
||||
return "aniyomi_$date.proto.gz"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package eu.kanade.tachiyomi.data.backup.full.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
@Serializable
|
||||
data class BackupPreference(
|
||||
@ProtoNumber(1) val key: String,
|
||||
@ProtoNumber(2) val value: PreferenceValue,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
sealed class PreferenceValue
|
||||
|
||||
@Serializable
|
||||
data class IntPreferenceValue(val value: Int) : PreferenceValue()
|
||||
|
||||
@Serializable
|
||||
data class LongPreferenceValue(val value: Long) : PreferenceValue()
|
||||
|
||||
@Serializable
|
||||
data class FloatPreferenceValue(val value: Float) : PreferenceValue()
|
||||
|
||||
@Serializable
|
||||
data class StringPreferenceValue(val value: String) : PreferenceValue()
|
||||
|
||||
@Serializable
|
||||
data class BooleanPreferenceValue(val value: Boolean) : PreferenceValue()
|
||||
|
||||
@Serializable
|
||||
data class StringSetPreferenceValue(val value: Set<String>) : PreferenceValue()
|
|
@ -0,0 +1,6 @@
|
|||
package eu.kanade.tachiyomi.data.backup.full.models
|
||||
|
||||
import kotlinx.serialization.Serializer
|
||||
|
||||
@Serializer(forClass = Backup::class)
|
||||
object BackupSerializer
|
Loading…
Reference in a new issue