Clean up category restoring logic

This commit is contained in:
arkon 2023-12-11 22:48:42 -05:00
parent f776c36e70
commit 0f9895eec8
3 changed files with 33 additions and 57 deletions

View file

@ -26,8 +26,6 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
private val notifier = BackupNotifier(context) private val notifier = BackupNotifier(context)
override suspend fun doWork(): Result { override suspend fun doWork(): Result {
if (isRunning(context)) return Result.failure()
val uri = inputData.getString(LOCATION_URI_KEY)?.toUri() val uri = inputData.getString(LOCATION_URI_KEY)?.toUri()
?: return Result.failure() ?: return Result.failure()
val sync = inputData.getBoolean(SYNC_KEY, false) val sync = inputData.getBoolean(SYNC_KEY, false)

View file

@ -21,7 +21,7 @@ import eu.kanade.tachiyomi.source.sourcePreferences
import eu.kanade.tachiyomi.util.BackupUtil import eu.kanade.tachiyomi.util.BackupUtil
import eu.kanade.tachiyomi.util.system.createFileInCacheDir import eu.kanade.tachiyomi.util.system.createFileInCacheDir
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.isActive import kotlinx.coroutines.ensureActive
import tachiyomi.core.i18n.stringResource import tachiyomi.core.i18n.stringResource
import tachiyomi.core.preference.AndroidPreferenceStore import tachiyomi.core.preference.AndroidPreferenceStore
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.preference.PreferenceStore
@ -74,14 +74,12 @@ class BackupRestorer(
private val errors = mutableListOf<Pair<Date, String>>() private val errors = mutableListOf<Pair<Date, String>>()
suspend fun syncFromBackup(uri: Uri, sync: Boolean): Boolean { suspend fun syncFromBackup(uri: Uri, sync: Boolean) {
val startTime = System.currentTimeMillis() val startTime = System.currentTimeMillis()
restoreProgress = 0 restoreProgress = 0
errors.clear() errors.clear()
if (!performRestore(uri, sync)) { performRestore(uri, sync)
return false
}
val endTime = System.currentTimeMillis() val endTime = System.currentTimeMillis()
val time = endTime - startTime val time = endTime - startTime
@ -99,7 +97,6 @@ class BackupRestorer(
} else { } else {
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name) notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
} }
return true
} }
private fun writeErrorLog(): File { private fun writeErrorLog(): File {
@ -121,66 +118,48 @@ class BackupRestorer(
return File("") return File("")
} }
private suspend fun performRestore(uri: Uri, sync: Boolean): Boolean { private suspend fun performRestore(uri: Uri, sync: Boolean) {
val backup = BackupUtil.decodeBackup(context, uri) val backup = BackupUtil.decodeBackup(context, uri)
restoreAmount = backup.backupManga.size + 3 // +3 for categories, app prefs, source prefs restoreAmount = backup.backupManga.size + 3 // +3 for categories, app prefs, source prefs
// Restore categories
if (backup.backupCategories.isNotEmpty()) {
restoreCategories(backup.backupCategories)
}
// Store source mapping for error messages // Store source mapping for error messages
val backupMaps = backup.backupBrokenSources.map { BackupSource(it.name, it.sourceId) } + backup.backupSources val backupMaps = backup.backupBrokenSources.map { BackupSource(it.name, it.sourceId) } + backup.backupSources
sourceMapping = backupMaps.associate { it.sourceId to it.name } sourceMapping = backupMaps.associate { it.sourceId to it.name }
now = ZonedDateTime.now() now = ZonedDateTime.now()
currentFetchWindow = fetchInterval.getWindow(now) currentFetchWindow = fetchInterval.getWindow(now)
return coroutineScope { coroutineScope {
ensureActive()
restoreCategories(backup.backupCategories)
ensureActive()
restoreAppPreferences(backup.backupPreferences) restoreAppPreferences(backup.backupPreferences)
ensureActive()
restoreSourcePreferences(backup.backupSourcePreferences) restoreSourcePreferences(backup.backupSourcePreferences)
// Restore individual manga // Restore individual manga
backup.backupManga.forEach { backup.backupManga.forEach {
if (!isActive) { ensureActive()
return@coroutineScope false
}
restoreManga(it, backup.backupCategories, sync) restoreManga(it, backup.backupCategories, sync)
} }
// TODO: optionally trigger online library + tracker update
true // TODO: optionally trigger online library + tracker update
} }
} }
private suspend fun restoreCategories(backupCategories: List<BackupCategory>) { private suspend fun restoreCategories(backupCategories: List<BackupCategory>) {
// Get categories from file and from db if (backupCategories.isNotEmpty()) {
val dbCategories = getCategories.await() val dbCategories = getCategories.await()
val dbCategoriesByName = dbCategories.associateBy { it.name }
val categories = backupCategories.map { val categories = backupCategories.map {
var category = it.getCategory() dbCategoriesByName[it.name]
var found = false ?: handler.awaitOneExecutable {
for (dbCategory in dbCategories) { categoriesQueries.insert(it.name, it.order, it.flags)
// If the category is already in the db, assign the id to the file's category
// and do nothing
if (category.name == dbCategory.name) {
category = category.copy(id = dbCategory.id)
found = true
break
}
}
if (!found) {
// Let the db assign the id
val id = handler.awaitOneExecutable {
categoriesQueries.insert(category.name, category.order, category.flags)
categoriesQueries.selectLastInsertedRowId() categoriesQueries.selectLastInsertedRowId()
} }.let { id -> it.toCategory(id) }
category = category.copy(id = id)
}
category
} }
libraryPreferences.categorizedDisplaySettings().set( libraryPreferences.categorizedDisplaySettings().set(
@ -188,6 +167,7 @@ class BackupRestorer(
.distinctBy { it.flags } .distinctBy { it.flags }
.size > 1, .size > 1,
) )
}
restoreProgress += 1 restoreProgress += 1
showRestoreProgress( showRestoreProgress(

View file

@ -11,15 +11,13 @@ class BackupCategory(
// @ProtoNumber(3) val updateInterval: Int = 0, 1.x value not used in 0.x // @ProtoNumber(3) val updateInterval: Int = 0, 1.x value not used in 0.x
@ProtoNumber(100) var flags: Long = 0, @ProtoNumber(100) var flags: Long = 0,
) { ) {
fun getCategory(): Category { fun toCategory(id: Long) = Category(
return Category( id = id,
id = 0,
name = this@BackupCategory.name, name = this@BackupCategory.name,
flags = this@BackupCategory.flags, flags = this@BackupCategory.flags,
order = this@BackupCategory.order, order = this@BackupCategory.order,
) )
} }
}
val backupCategoryMapper = { category: Category -> val backupCategoryMapper = { category: Category ->
BackupCategory( BackupCategory(