Add Backup and Restore of Extension Repos (#1057)

* Backup/Restore Extension Repos

* Refactor

* Moving to Under App Settings

* Sort by URL, Check existing by SHA and Error Logging

Untested. Currently in a lecture and can't test if the changes really work.

* Changes to logic

* Don't ask me what's happening here

* Renaming Variables

* Fixing restoreAmount & changes to logic

Co-Authored-By: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 31263084eca3ba98624d258a317d53094bba2256)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupOptions.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/models/Backup.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/restore/BackupRestorer.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/restore/RestoreOptions.kt
This commit is contained in:
Roshan Varughese 2024-08-07 19:49:17 +12:00 committed by Jobobby04
parent e21149cb37
commit 94f9aaf351
13 changed files with 176 additions and 17 deletions

View File

@ -53,12 +53,14 @@ class SyncPreferences(
tracking = preferenceStore.getBoolean("tracking", true).get(), tracking = preferenceStore.getBoolean("tracking", true).get(),
history = preferenceStore.getBoolean("history", true).get(), history = preferenceStore.getBoolean("history", true).get(),
appSettings = preferenceStore.getBoolean("appSettings", true).get(), appSettings = preferenceStore.getBoolean("appSettings", true).get(),
extensionRepoSettings = preferenceStore.getBoolean("extensionRepoSettings", true).get(),
sourceSettings = preferenceStore.getBoolean("sourceSettings", true).get(), sourceSettings = preferenceStore.getBoolean("sourceSettings", true).get(),
privateSettings = preferenceStore.getBoolean("privateSettings", true).get(), privateSettings = preferenceStore.getBoolean("privateSettings", true).get(),
// SY --> // SY -->
customInfo = preferenceStore.getBoolean("customInfo", true).get(), customInfo = preferenceStore.getBoolean("customInfo", true).get(),
readEntries = preferenceStore.getBoolean("readEntries", true).get() readEntries = preferenceStore.getBoolean("readEntries", true).get(),
savedSearches = preferenceStore.getBoolean("savedSearches", true).get(),
// SY <-- // SY <--
) )
} }
@ -70,12 +72,14 @@ class SyncPreferences(
preferenceStore.getBoolean("tracking", true).set(syncSettings.tracking) preferenceStore.getBoolean("tracking", true).set(syncSettings.tracking)
preferenceStore.getBoolean("history", true).set(syncSettings.history) preferenceStore.getBoolean("history", true).set(syncSettings.history)
preferenceStore.getBoolean("appSettings", true).set(syncSettings.appSettings) preferenceStore.getBoolean("appSettings", true).set(syncSettings.appSettings)
preferenceStore.getBoolean("extensionRepoSettings", true).set(syncSettings.extensionRepoSettings)
preferenceStore.getBoolean("sourceSettings", true).set(syncSettings.sourceSettings) preferenceStore.getBoolean("sourceSettings", true).set(syncSettings.sourceSettings)
preferenceStore.getBoolean("privateSettings", true).set(syncSettings.privateSettings) preferenceStore.getBoolean("privateSettings", true).set(syncSettings.privateSettings)
// SY --> // SY -->
preferenceStore.getBoolean("customInfo", true).set(syncSettings.customInfo) preferenceStore.getBoolean("customInfo", true).set(syncSettings.customInfo)
preferenceStore.getBoolean("readEntries", true).set(syncSettings.readEntries) preferenceStore.getBoolean("readEntries", true).set(syncSettings.readEntries)
preferenceStore.getBoolean("savedSearches", true).set(syncSettings.savedSearches)
// SY <-- // SY <--
} }

View File

@ -7,11 +7,13 @@ data class SyncSettings(
val tracking: Boolean = true, val tracking: Boolean = true,
val history: Boolean = true, val history: Boolean = true,
val appSettings: Boolean = true, val appSettings: Boolean = true,
val extensionRepoSettings: Boolean = true,
val sourceSettings: Boolean = true, val sourceSettings: Boolean = true,
val privateSettings: Boolean = false, val privateSettings: Boolean = false,
// SY --> // SY -->
val customInfo: Boolean = true, val customInfo: Boolean = true,
val readEntries: Boolean = true val readEntries: Boolean = true,
val savedSearches: Boolean = true,
// SY <-- // SY <--
) )

View File

@ -49,7 +49,7 @@ class SyncSettingsSelector : Screen() {
LazyColumnWithAction( LazyColumnWithAction(
contentPadding = contentPadding, contentPadding = contentPadding,
actionLabel = stringResource(SYMR.strings.label_sync), actionLabel = stringResource(SYMR.strings.label_sync),
actionEnabled = state.options.anyEnabled(), actionEnabled = state.options.canCreate(),
onClickAction = { onClickAction = {
if (!SyncDataJob.isRunning(context)) { if (!SyncDataJob.isRunning(context)) {
model.syncNow(context) model.syncNow(context)
@ -122,12 +122,14 @@ private class SyncSettingsSelectorModel(
tracking = syncSettings.tracking, tracking = syncSettings.tracking,
history = syncSettings.history, history = syncSettings.history,
appSettings = syncSettings.appSettings, appSettings = syncSettings.appSettings,
extensionRepoSettings = syncSettings.extensionRepoSettings,
sourceSettings = syncSettings.sourceSettings, sourceSettings = syncSettings.sourceSettings,
privateSettings = syncSettings.privateSettings, privateSettings = syncSettings.privateSettings,
// SY --> // SY -->
customInfo = syncSettings.customInfo, customInfo = syncSettings.customInfo,
readEntries = syncSettings.readEntries, readEntries = syncSettings.readEntries,
savedSearches = syncSettings.savedSearches,
// SY <-- // SY <--
) )
} }
@ -140,12 +142,14 @@ private class SyncSettingsSelectorModel(
tracking = backupOptions.tracking, tracking = backupOptions.tracking,
history = backupOptions.history, history = backupOptions.history,
appSettings = backupOptions.appSettings, appSettings = backupOptions.appSettings,
extensionRepoSettings = backupOptions.extensionRepoSettings,
sourceSettings = backupOptions.sourceSettings, sourceSettings = backupOptions.sourceSettings,
privateSettings = backupOptions.privateSettings, privateSettings = backupOptions.privateSettings,
// SY --> // SY -->
customInfo = backupOptions.customInfo, customInfo = backupOptions.customInfo,
readEntries = backupOptions.readEntries, readEntries = backupOptions.readEntries,
savedSearches = backupOptions.savedSearches,
// SY <-- // SY <--
) )
} }

View File

@ -6,12 +6,14 @@ import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.data.backup.BackupFileValidator import eu.kanade.tachiyomi.data.backup.BackupFileValidator
import eu.kanade.tachiyomi.data.backup.create.creators.CategoriesBackupCreator import eu.kanade.tachiyomi.data.backup.create.creators.CategoriesBackupCreator
import eu.kanade.tachiyomi.data.backup.create.creators.ExtensionRepoBackupCreator
import eu.kanade.tachiyomi.data.backup.create.creators.MangaBackupCreator import eu.kanade.tachiyomi.data.backup.create.creators.MangaBackupCreator
import eu.kanade.tachiyomi.data.backup.create.creators.PreferenceBackupCreator import eu.kanade.tachiyomi.data.backup.create.creators.PreferenceBackupCreator
import eu.kanade.tachiyomi.data.backup.create.creators.SavedSearchBackupCreator import eu.kanade.tachiyomi.data.backup.create.creators.SavedSearchBackupCreator
import eu.kanade.tachiyomi.data.backup.create.creators.SourcesBackupCreator import eu.kanade.tachiyomi.data.backup.create.creators.SourcesBackupCreator
import eu.kanade.tachiyomi.data.backup.models.Backup import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.data.backup.models.BackupCategory import eu.kanade.tachiyomi.data.backup.models.BackupCategory
import eu.kanade.tachiyomi.data.backup.models.BackupExtensionRepos
import eu.kanade.tachiyomi.data.backup.models.BackupManga import eu.kanade.tachiyomi.data.backup.models.BackupManga
import eu.kanade.tachiyomi.data.backup.models.BackupPreference import eu.kanade.tachiyomi.data.backup.models.BackupPreference
import eu.kanade.tachiyomi.data.backup.models.BackupSavedSearch import eu.kanade.tachiyomi.data.backup.models.BackupSavedSearch
@ -50,6 +52,7 @@ class BackupCreator(
private val categoriesBackupCreator: CategoriesBackupCreator = CategoriesBackupCreator(), private val categoriesBackupCreator: CategoriesBackupCreator = CategoriesBackupCreator(),
private val mangaBackupCreator: MangaBackupCreator = MangaBackupCreator(), private val mangaBackupCreator: MangaBackupCreator = MangaBackupCreator(),
private val preferenceBackupCreator: PreferenceBackupCreator = PreferenceBackupCreator(), private val preferenceBackupCreator: PreferenceBackupCreator = PreferenceBackupCreator(),
private val extensionRepoBackupCreator: ExtensionRepoBackupCreator = ExtensionRepoBackupCreator(),
private val sourcesBackupCreator: SourcesBackupCreator = SourcesBackupCreator(), private val sourcesBackupCreator: SourcesBackupCreator = SourcesBackupCreator(),
// SY --> // SY -->
private val savedSearchBackupCreator: SavedSearchBackupCreator = SavedSearchBackupCreator(), private val savedSearchBackupCreator: SavedSearchBackupCreator = SavedSearchBackupCreator(),
@ -96,6 +99,7 @@ class BackupCreator(
backupCategories = backupCategories(options), backupCategories = backupCategories(options),
backupSources = backupSources(backupManga), backupSources = backupSources(backupManga),
backupPreferences = backupAppPreferences(options), backupPreferences = backupAppPreferences(options),
backupExtensionRepo = backupExtensionRepos(options),
backupSourcePreferences = backupSourcePreferences(options), backupSourcePreferences = backupSourcePreferences(options),
// SY --> // SY -->
backupSavedSearches = backupSavedSearches(options), backupSavedSearches = backupSavedSearches(options),
@ -160,6 +164,12 @@ class BackupCreator(
return preferenceBackupCreator.createSource(includePrivatePreferences = options.privateSettings) return preferenceBackupCreator.createSource(includePrivatePreferences = options.privateSettings)
} }
suspend fun backupExtensionRepos(options: BackupOptions): List<BackupExtensionRepos> {
if (!options.extensionRepoSettings) return emptyList()
return extensionRepoBackupCreator()
}
// SY --> // SY -->
suspend fun backupSavedSearches(options: BackupOptions): List<BackupSavedSearch> { suspend fun backupSavedSearches(options: BackupOptions): List<BackupSavedSearch> {
if (!options.savedSearches) return emptyList() if (!options.savedSearches) return emptyList()

View File

@ -12,6 +12,7 @@ data class BackupOptions(
val tracking: Boolean = true, val tracking: Boolean = true,
val history: Boolean = true, val history: Boolean = true,
val appSettings: Boolean = true, val appSettings: Boolean = true,
val extensionRepoSettings: Boolean = true,
val sourceSettings: Boolean = true, val sourceSettings: Boolean = true,
val privateSettings: Boolean = false, val privateSettings: Boolean = false,
// SY --> // SY -->
@ -28,6 +29,7 @@ data class BackupOptions(
tracking, tracking,
history, history,
appSettings, appSettings,
extensionRepoSettings,
sourceSettings, sourceSettings,
privateSettings, privateSettings,
// SY --> // SY -->
@ -37,7 +39,7 @@ data class BackupOptions(
// SY <-- // SY <--
) )
fun canCreate() = libraryEntries || categories || appSettings || sourceSettings fun canCreate() = libraryEntries || categories || appSettings || extensionRepoSettings || sourceSettings || savedSearches
companion object { companion object {
val libraryOptions = persistentListOf( val libraryOptions = persistentListOf(
@ -96,6 +98,11 @@ data class BackupOptions(
getter = BackupOptions::appSettings, getter = BackupOptions::appSettings,
setter = { options, enabled -> options.copy(appSettings = enabled) }, setter = { options, enabled -> options.copy(appSettings = enabled) },
), ),
Entry(
label = MR.strings.extensionRepo_settings,
getter = BackupOptions::extensionRepoSettings,
setter = { options, enabled -> options.copy(extensionRepoSettings = enabled) },
),
Entry( Entry(
label = MR.strings.source_settings, label = MR.strings.source_settings,
getter = BackupOptions::sourceSettings, getter = BackupOptions::sourceSettings,
@ -116,12 +123,13 @@ data class BackupOptions(
tracking = array[3], tracking = array[3],
history = array[4], history = array[4],
appSettings = array[5], appSettings = array[5],
sourceSettings = array[6], extensionRepoSettings = array[6],
privateSettings = array[7], sourceSettings = array[7],
privateSettings = array[8],
// SY --> // SY -->
customInfo = array[8], customInfo = array[9],
readEntries = array[9], readEntries = array[10],
savedSearches = array[10], savedSearches = array[11],
// SY <-- // SY <--
) )
} }

View File

@ -0,0 +1,17 @@
package eu.kanade.tachiyomi.data.backup.create.creators
import eu.kanade.tachiyomi.data.backup.models.BackupExtensionRepos
import eu.kanade.tachiyomi.data.backup.models.backupExtensionReposMapper
import mihon.domain.extensionrepo.interactor.GetExtensionRepo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class ExtensionRepoBackupCreator(
private val getExtensionRepos: GetExtensionRepo = Injekt.get(),
) {
suspend operator fun invoke(): List<BackupExtensionRepos> {
return getExtensionRepos.getAll()
.map(backupExtensionReposMapper)
}
}

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.backup.models
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
@Suppress("MagicNumber")
@Serializable @Serializable
data class Backup( data class Backup(
@ProtoNumber(1) val backupManga: List<BackupManga>, @ProtoNumber(1) val backupManga: List<BackupManga>,
@ -11,6 +12,7 @@ data class Backup(
@ProtoNumber(101) var backupSources: List<BackupSource> = emptyList(), @ProtoNumber(101) var backupSources: List<BackupSource> = emptyList(),
@ProtoNumber(104) var backupPreferences: List<BackupPreference> = emptyList(), @ProtoNumber(104) var backupPreferences: List<BackupPreference> = emptyList(),
@ProtoNumber(105) var backupSourcePreferences: List<BackupSourcePreferences> = emptyList(), @ProtoNumber(105) var backupSourcePreferences: List<BackupSourcePreferences> = emptyList(),
@ProtoNumber(106) var backupExtensionRepo: List<BackupExtensionRepos> = emptyList(),
// SY specific values // SY specific values
@ProtoNumber(600) var backupSavedSearches: List<BackupSavedSearch> = emptyList(), @ProtoNumber(600) var backupSavedSearches: List<BackupSavedSearch> = emptyList(),
) )

View File

@ -0,0 +1,25 @@
package eu.kanade.tachiyomi.data.backup.models
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
import mihon.domain.extensionrepo.model.ExtensionRepo
@Suppress("MagicNumber")
@Serializable
class BackupExtensionRepos(
@ProtoNumber(1) var baseUrl: String,
@ProtoNumber(2) var name: String,
@ProtoNumber(3) var shortName: String?,
@ProtoNumber(4) var website: String,
@ProtoNumber(5) var signingKeyFingerprint: String,
)
val backupExtensionReposMapper = { repo: ExtensionRepo ->
BackupExtensionRepos(
baseUrl = repo.baseUrl,
name = repo.name,
shortName = repo.shortName,
website = repo.website,
signingKeyFingerprint = repo.signingKeyFingerprint,
)
}

View File

@ -5,11 +5,13 @@ import android.net.Uri
import eu.kanade.tachiyomi.data.backup.BackupDecoder import eu.kanade.tachiyomi.data.backup.BackupDecoder
import eu.kanade.tachiyomi.data.backup.BackupNotifier import eu.kanade.tachiyomi.data.backup.BackupNotifier
import eu.kanade.tachiyomi.data.backup.models.BackupCategory import eu.kanade.tachiyomi.data.backup.models.BackupCategory
import eu.kanade.tachiyomi.data.backup.models.BackupExtensionRepos
import eu.kanade.tachiyomi.data.backup.models.BackupManga import eu.kanade.tachiyomi.data.backup.models.BackupManga
import eu.kanade.tachiyomi.data.backup.models.BackupPreference import eu.kanade.tachiyomi.data.backup.models.BackupPreference
import eu.kanade.tachiyomi.data.backup.models.BackupSavedSearch import eu.kanade.tachiyomi.data.backup.models.BackupSavedSearch
import eu.kanade.tachiyomi.data.backup.models.BackupSourcePreferences import eu.kanade.tachiyomi.data.backup.models.BackupSourcePreferences
import eu.kanade.tachiyomi.data.backup.restore.restorers.CategoriesRestorer import eu.kanade.tachiyomi.data.backup.restore.restorers.CategoriesRestorer
import eu.kanade.tachiyomi.data.backup.restore.restorers.ExtensionRepoRestorer
import eu.kanade.tachiyomi.data.backup.restore.restorers.MangaRestorer import eu.kanade.tachiyomi.data.backup.restore.restorers.MangaRestorer
import eu.kanade.tachiyomi.data.backup.restore.restorers.PreferenceRestorer import eu.kanade.tachiyomi.data.backup.restore.restorers.PreferenceRestorer
import eu.kanade.tachiyomi.data.backup.restore.restorers.SavedSearchRestorer import eu.kanade.tachiyomi.data.backup.restore.restorers.SavedSearchRestorer
@ -34,6 +36,7 @@ class BackupRestorer(
private val categoriesRestorer: CategoriesRestorer = CategoriesRestorer(), private val categoriesRestorer: CategoriesRestorer = CategoriesRestorer(),
private val preferenceRestorer: PreferenceRestorer = PreferenceRestorer(context), private val preferenceRestorer: PreferenceRestorer = PreferenceRestorer(context),
private val extensionRepoRestorer: ExtensionRepoRestorer = ExtensionRepoRestorer(),
private val mangaRestorer: MangaRestorer = MangaRestorer(isSync), private val mangaRestorer: MangaRestorer = MangaRestorer(isSync),
// SY --> // SY -->
private val savedSearchRestorer: SavedSearchRestorer = SavedSearchRestorer(), private val savedSearchRestorer: SavedSearchRestorer = SavedSearchRestorer(),
@ -88,6 +91,9 @@ class BackupRestorer(
if (options.appSettings) { if (options.appSettings) {
restoreAmount += 1 restoreAmount += 1
} }
if (options.extensionRepoSettings) {
restoreAmount += backup.backupExtensionRepo.size
}
if (options.sourceSettings) { if (options.sourceSettings) {
restoreAmount += 1 restoreAmount += 1
} }
@ -110,6 +116,9 @@ class BackupRestorer(
if (options.libraryEntries) { if (options.libraryEntries) {
restoreManga(backup.backupManga, if (options.categories) backup.backupCategories else emptyList()) restoreManga(backup.backupManga, if (options.categories) backup.backupCategories else emptyList())
} }
if (options.extensionRepoSettings) {
restoreExtensionRepos(backup.backupExtensionRepo)
}
// TODO: optionally trigger online library + tracker update // TODO: optionally trigger online library + tracker update
} }
@ -190,6 +199,29 @@ class BackupRestorer(
) )
} }
private fun CoroutineScope.restoreExtensionRepos(
backupExtensionRepo: List<BackupExtensionRepos>
) = launch {
backupExtensionRepo
.forEach {
ensureActive()
try {
extensionRepoRestorer(it)
} catch (e: Exception) {
errors.add(Date() to "Error Adding Repo: ${it.name} : ${e.message}")
}
restoreProgress += 1
notifier.showRestoreProgress(
context.stringResource(MR.strings.extensionRepo_settings),
restoreProgress,
restoreAmount,
isSync,
)
}
}
private fun writeErrorLog(): File { private fun writeErrorLog(): File {
try { try {
if (errors.isNotEmpty()) { if (errors.isNotEmpty()) {

View File

@ -9,6 +9,7 @@ data class RestoreOptions(
val libraryEntries: Boolean = true, val libraryEntries: Boolean = true,
val categories: Boolean = true, val categories: Boolean = true,
val appSettings: Boolean = true, val appSettings: Boolean = true,
val extensionRepoSettings: Boolean = true,
val sourceSettings: Boolean = true, val sourceSettings: Boolean = true,
// SY --> // SY -->
val savedSearches: Boolean = true, val savedSearches: Boolean = true,
@ -19,13 +20,14 @@ data class RestoreOptions(
libraryEntries, libraryEntries,
categories, categories,
appSettings, appSettings,
extensionRepoSettings,
sourceSettings, sourceSettings,
// SY --> // SY -->
savedSearches savedSearches,
// SY <-- // SY <--
) )
fun canRestore() = libraryEntries || categories || appSettings || sourceSettings /* SY --> */ || savedSearches /* SY <-- */ fun canRestore() = libraryEntries || categories || appSettings || extensionRepoSettings || sourceSettings /* SY --> */ || savedSearches /* SY <-- */
companion object { companion object {
val options = persistentListOf( val options = persistentListOf(
@ -44,6 +46,11 @@ data class RestoreOptions(
getter = RestoreOptions::appSettings, getter = RestoreOptions::appSettings,
setter = { options, enabled -> options.copy(appSettings = enabled) }, setter = { options, enabled -> options.copy(appSettings = enabled) },
), ),
Entry(
label = MR.strings.extensionRepo_settings,
getter = RestoreOptions::extensionRepoSettings,
setter = { options, enabled -> options.copy(extensionRepoSettings = enabled) },
),
Entry( Entry(
label = MR.strings.source_settings, label = MR.strings.source_settings,
getter = RestoreOptions::sourceSettings, getter = RestoreOptions::sourceSettings,
@ -62,9 +69,10 @@ data class RestoreOptions(
libraryEntries = array[0], libraryEntries = array[0],
categories = array[1], categories = array[1],
appSettings = array[2], appSettings = array[2],
sourceSettings = array[3], extensionRepoSettings = array[3],
sourceSettings = array[4],
// SY --> // SY -->
savedSearches = array[4] savedSearches = array[5]
// SY <-- // SY <--
) )
} }

View File

@ -0,0 +1,40 @@
package eu.kanade.tachiyomi.data.backup.restore.restorers
import eu.kanade.tachiyomi.data.backup.models.BackupExtensionRepos
import mihon.domain.extensionrepo.interactor.GetExtensionRepo
import tachiyomi.data.DatabaseHandler
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class ExtensionRepoRestorer(
private val handler: DatabaseHandler = Injekt.get(),
private val getExtensionRepos: GetExtensionRepo = Injekt.get()
) {
suspend operator fun invoke(
backupRepo: BackupExtensionRepos,
) {
val dbRepos = getExtensionRepos.getAll()
val existingReposBySHA = dbRepos.associateBy { it.signingKeyFingerprint }
val existingReposByUrl = dbRepos.associateBy { it.baseUrl }
val urlExists = existingReposByUrl[backupRepo.baseUrl]
val shaExists = existingReposBySHA[backupRepo.signingKeyFingerprint]
if (urlExists != null && urlExists.signingKeyFingerprint != backupRepo.signingKeyFingerprint) {
error("Already Exists with different signing key fingerprint")
} else if (shaExists != null) {
error("${shaExists.name} has the same signing key fingerprint")
} else {
handler.await {
extension_reposQueries.insert(
backupRepo.baseUrl,
backupRepo.name,
backupRepo.shortName,
backupRepo.website,
backupRepo.signingKeyFingerprint
)
}
}
}
}

View File

@ -84,6 +84,7 @@ class SyncManager(
chapters = syncOptions.chapters, chapters = syncOptions.chapters,
tracking = syncOptions.tracking, tracking = syncOptions.tracking,
history = syncOptions.history, history = syncOptions.history,
extensionRepoSettings = syncOptions.extensionRepoSettings,
appSettings = syncOptions.appSettings, appSettings = syncOptions.appSettings,
sourceSettings = syncOptions.sourceSettings, sourceSettings = syncOptions.sourceSettings,
privateSettings = syncOptions.privateSettings, privateSettings = syncOptions.privateSettings,
@ -91,19 +92,22 @@ class SyncManager(
// SY --> // SY -->
customInfo = syncOptions.customInfo, customInfo = syncOptions.customInfo,
readEntries = syncOptions.readEntries, readEntries = syncOptions.readEntries,
savedSearches = syncOptions.savedSearches,
// SY <-- // SY <--
) )
logcat(LogPriority.DEBUG) { "Begin create backup" } logcat(LogPriority.DEBUG) { "Begin create backup" }
val backupManga = backupCreator.backupMangas(databaseManga, backupOptions)
val backup = Backup( val backup = Backup(
backupManga = backupCreator.backupMangas(databaseManga, backupOptions), backupManga = backupManga,
backupCategories = backupCreator.backupCategories(backupOptions), backupCategories = backupCreator.backupCategories(backupOptions),
backupSources = backupCreator.backupSources(databaseManga), backupSources = backupCreator.backupSources(backupManga),
backupPreferences = backupCreator.backupAppPreferences(backupOptions), backupPreferences = backupCreator.backupAppPreferences(backupOptions),
backupSourcePreferences = backupCreator.backupSourcePreferences(backupOptions), backupSourcePreferences = backupCreator.backupSourcePreferences(backupOptions),
backupExtensionRepo = backupCreator.backupExtensionRepos(backupOptions),
// SY --> // SY -->
backupSavedSearches = backupCreator.backupSavedSearches(), backupSavedSearches = backupCreator.backupSavedSearches(backupOptions),
// SY <-- // SY <--
) )
logcat(LogPriority.DEBUG) { "End create backup" } logcat(LogPriority.DEBUG) { "End create backup" }
@ -174,6 +178,7 @@ class SyncManager(
backupSources = remoteBackup.backupSources, backupSources = remoteBackup.backupSources,
backupPreferences = remoteBackup.backupPreferences, backupPreferences = remoteBackup.backupPreferences,
backupSourcePreferences = remoteBackup.backupSourcePreferences, backupSourcePreferences = remoteBackup.backupSourcePreferences,
backupExtensionRepo = remoteBackup.backupExtensionRepo,
// SY --> // SY -->
backupSavedSearches = remoteBackup.backupSavedSearches, backupSavedSearches = remoteBackup.backupSavedSearches,
@ -198,7 +203,8 @@ class SyncManager(
options = RestoreOptions( options = RestoreOptions(
appSettings = true, appSettings = true,
sourceSettings = true, sourceSettings = true,
library = true, libraryEntries = true,
extensionRepoSettings = true,
), ),
) )

View File

@ -529,6 +529,7 @@
<string name="backup_choice">What do you want to backup?</string> <string name="backup_choice">What do you want to backup?</string>
<string name="app_settings">App settings</string> <string name="app_settings">App settings</string>
<string name="source_settings">Source settings</string> <string name="source_settings">Source settings</string>
<string name="extensionRepo_settings">Extension Repos</string>
<string name="private_settings">Include sensitive settings (e.g., tracker login tokens)</string> <string name="private_settings">Include sensitive settings (e.g., tracker login tokens)</string>
<string name="creating_backup">Creating backup</string> <string name="creating_backup">Creating backup</string>
<string name="creating_backup_error">Backup failed</string> <string name="creating_backup_error">Backup failed</string>