Skip to content

Commit

Permalink
Refactor backup and restore to support cross device sync. (#9699)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
kaiserbh authored Jul 22, 2023
1 parent 46e3b9e commit 7b2764e
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class BackupManager(
backupMangas(databaseManga, flags),
backupCategories(flags),
emptyList(),
backupExtensionInfo(databaseManga),
prepExtensionInfoForSync(databaseManga),
)

var file: UniFile? = null
Expand Down Expand Up @@ -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)
Expand All @@ -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()
Expand All @@ -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)
}
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand All @@ -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) {
Expand Down Expand Up @@ -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)
Expand All @@ -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
28 changes: 18 additions & 10 deletions app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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() }
Expand All @@ -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))
}
}

/**
Expand Down Expand Up @@ -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 changes: 4 additions & 0 deletions i18n/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit 7b2764e

Please sign in to comment.