Эх сурвалжийг харах

Refactor backup and restore to support cross device sync. (#9699)

* refactor: backup and restore to support cross device sync.

* chore: Updated string resources

* refactor: change function name.

* refactor: Use URI SyncHolder.kt not needed anymore.
KaiserBh 1 жил өмнө
parent
commit
7b2764e8f7

+ 5 - 5
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt

@@ -81,7 +81,7 @@ class BackupManager(
             backupMangas(databaseManga, flags),
             backupCategories(flags),
             emptyList(),
-            backupExtensionInfo(databaseManga),
+            prepExtensionInfoForSync(databaseManga),
         )
 
         var file: UniFile? = null
@@ -135,7 +135,7 @@ class BackupManager(
         }
     }
 
-    private fun backupExtensionInfo(mangas: List<Manga>): List<BackupSource> {
+    fun prepExtensionInfoForSync(mangas: List<Manga>): List<BackupSource> {
         return mangas
             .asSequence()
             .map(Manga::source)
@@ -150,7 +150,7 @@ class BackupManager(
      *
      * @return list of [BackupCategory] to be backed up
      */
-    private suspend fun backupCategories(options: Int): List<BackupCategory> {
+    suspend fun backupCategories(options: Int): List<BackupCategory> {
         // Check if user wants category information in backup
         return if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) {
             getCategories.await()
@@ -161,7 +161,7 @@ class BackupManager(
         }
     }
 
-    private suspend fun backupMangas(mangas: List<Manga>, flags: Int): List<BackupManga> {
+    suspend fun backupMangas(mangas: List<Manga>, flags: Int): List<BackupManga> {
         return mangas.map {
             backupManga(it, flags)
         }
@@ -514,7 +514,7 @@ class BackupManager(
         }
     }
 
-    private suspend fun updateManga(manga: Manga): Long {
+    suspend fun updateManga(manga: Manga): Long {
         handler.await(true) {
             mangasQueries.update(
                 source = manga.source,

+ 4 - 4
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupNotifier.kt

@@ -79,9 +79,9 @@ class BackupNotifier(private val context: Context) {
         }
     }
 
-    fun showRestoreProgress(content: String = "", progress: Int = 0, maxAmount: Int = 100): NotificationCompat.Builder {
+    fun showRestoreProgress(content: String = "", contentTitle: String = context.getString(R.string.restoring_backup), progress: Int = 0, maxAmount: Int = 100): NotificationCompat.Builder {
         val builder = with(progressNotificationBuilder) {
-            setContentTitle(context.getString(R.string.restoring_backup))
+            setContentTitle(contentTitle)
 
             if (!preferences.hideNotificationContent().get()) {
                 setContentText(content)
@@ -114,7 +114,7 @@ class BackupNotifier(private val context: Context) {
         }
     }
 
-    fun showRestoreComplete(time: Long, errorCount: Int, path: String?, file: String?) {
+    fun showRestoreComplete(time: Long, errorCount: Int, path: String?, file: String?, contentTitle: String = context.getString(R.string.restore_completed)) {
         context.cancelNotification(Notifications.ID_RESTORE_PROGRESS)
 
         val timeString = context.getString(
@@ -126,7 +126,7 @@ class BackupNotifier(private val context: Context) {
         )
 
         with(completeNotificationBuilder) {
-            setContentTitle(context.getString(R.string.restore_completed))
+            setContentTitle(contentTitle)
             setContentText(context.resources.getQuantityString(R.plurals.restore_completed_message, errorCount, timeString, errorCount))
 
             clearActions()

+ 6 - 2
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreJob.kt

@@ -26,6 +26,7 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
     override suspend fun doWork(): Result {
         val uri = inputData.getString(LOCATION_URI_KEY)?.toUri()
             ?: return Result.failure()
+        val sync = inputData.getBoolean(SYNC, false)
 
         try {
             setForeground(getForegroundInfo())
@@ -35,7 +36,7 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
 
         return try {
             val restorer = BackupRestorer(context, notifier)
-            restorer.restoreBackup(uri)
+            restorer.syncFromBackup(uri, sync)
             Result.success()
         } catch (e: Exception) {
             if (e is CancellationException) {
@@ -63,9 +64,10 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
             return context.workManager.isRunning(TAG)
         }
 
-        fun start(context: Context, uri: Uri) {
+        fun start(context: Context, uri: Uri, sync: Boolean = false) {
             val inputData = workDataOf(
                 LOCATION_URI_KEY to uri.toString(),
+                SYNC to sync,
             )
             val request = OneTimeWorkRequestBuilder<BackupRestoreJob>()
                 .addTag(TAG)
@@ -83,3 +85,5 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
 private const val TAG = "BackupRestore"
 
 private const val LOCATION_URI_KEY = "location_uri" // String
+
+private const val SYNC = "sync" // Boolean

+ 18 - 10
app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt

@@ -36,12 +36,12 @@ class BackupRestorer(
 
     private val errors = mutableListOf<Pair<Date, String>>()
 
-    suspend fun restoreBackup(uri: Uri): Boolean {
+    suspend fun syncFromBackup(uri: Uri, sync: Boolean): Boolean {
         val startTime = System.currentTimeMillis()
         restoreProgress = 0
         errors.clear()
 
-        if (!performRestore(uri)) {
+        if (!performRestore(uri, sync)) {
             return false
         }
 
@@ -50,7 +50,11 @@ class BackupRestorer(
 
         val logFile = writeErrorLog()
 
-        notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
+        if (sync) {
+            notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name, contentTitle = context.getString(R.string.library_sync_complete))
+        } else {
+            notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
+        }
         return true
     }
 
@@ -73,7 +77,7 @@ class BackupRestorer(
         return File("")
     }
 
-    private suspend fun performRestore(uri: Uri): Boolean {
+    private suspend fun performRestore(uri: Uri, sync: Boolean): Boolean {
         val backup = BackupUtil.decodeBackup(context, uri)
 
         restoreAmount = backup.backupManga.size + 1 // +1 for categories
@@ -94,7 +98,7 @@ class BackupRestorer(
                     return@coroutineScope false
                 }
 
-                restoreManga(it, backup.backupCategories)
+                restoreManga(it, backup.backupCategories, sync)
             }
             // TODO: optionally trigger online library + tracker update
             true
@@ -105,10 +109,10 @@ class BackupRestorer(
         backupManager.restoreCategories(backupCategories)
 
         restoreProgress += 1
-        showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories))
+        showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories), context.getString(R.string.restoring_backup))
     }
 
-    private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>) {
+    private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, sync: Boolean) {
         val manga = backupManga.getMangaImpl()
         val chapters = backupManga.getChaptersImpl()
         val categories = backupManga.categories.map { it.toInt() }
@@ -134,7 +138,11 @@ class BackupRestorer(
         }
 
         restoreProgress += 1
-        showRestoreProgress(restoreProgress, restoreAmount, manga.title)
+        if (sync) {
+            showRestoreProgress(restoreProgress, restoreAmount, manga.title, context.getString(R.string.syncing_library))
+        } else {
+            showRestoreProgress(restoreProgress, restoreAmount, manga.title, context.getString(R.string.restoring_backup))
+        }
     }
 
     /**
@@ -182,7 +190,7 @@ class BackupRestorer(
      * @param amount total restoreAmount of manga
      * @param title title of restored manga
      */
-    private fun showRestoreProgress(progress: Int, amount: Int, title: String) {
-        notifier.showRestoreProgress(title, progress, amount)
+    private fun showRestoreProgress(progress: Int, amount: Int, title: String, contentTitle: String) {
+        notifier.showRestoreProgress(title, contentTitle, progress, amount)
     }
 }

+ 4 - 0
i18n/src/main/res/values/strings.xml

@@ -516,6 +516,10 @@
     <string name="restoring_backup_canceled">Canceled restore</string>
     <string name="backup_info">You should keep copies of backups in other places as well.</string>
 
+    <!-- Sync section -->
+    <string name="syncing_library">Syncing library</string>
+    <string name="library_sync_complete">Library sync complete</string>
+
       <!-- Advanced section -->
     <string name="label_network">Network</string>
     <string name="pref_clear_cookies">Clear cookies</string>