mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Clean up category restoring logic
This commit is contained in:
		@@ -26,8 +26,6 @@ class BackupRestoreJob(private val context: Context, workerParams: WorkerParamet
 | 
			
		||||
    private val notifier = BackupNotifier(context)
 | 
			
		||||
 | 
			
		||||
    override suspend fun doWork(): Result {
 | 
			
		||||
        if (isRunning(context)) return Result.failure()
 | 
			
		||||
 | 
			
		||||
        val uri = inputData.getString(LOCATION_URI_KEY)?.toUri()
 | 
			
		||||
            ?: return Result.failure()
 | 
			
		||||
        val sync = inputData.getBoolean(SYNC_KEY, false)
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ import eu.kanade.tachiyomi.source.sourcePreferences
 | 
			
		||||
import eu.kanade.tachiyomi.util.BackupUtil
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
 | 
			
		||||
import kotlinx.coroutines.coroutineScope
 | 
			
		||||
import kotlinx.coroutines.isActive
 | 
			
		||||
import kotlinx.coroutines.ensureActive
 | 
			
		||||
import tachiyomi.core.i18n.stringResource
 | 
			
		||||
import tachiyomi.core.preference.AndroidPreferenceStore
 | 
			
		||||
import tachiyomi.core.preference.PreferenceStore
 | 
			
		||||
@@ -74,14 +74,12 @@ class BackupRestorer(
 | 
			
		||||
 | 
			
		||||
    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()
 | 
			
		||||
        restoreProgress = 0
 | 
			
		||||
        errors.clear()
 | 
			
		||||
 | 
			
		||||
        if (!performRestore(uri, sync)) {
 | 
			
		||||
            return false
 | 
			
		||||
        }
 | 
			
		||||
        performRestore(uri, sync)
 | 
			
		||||
 | 
			
		||||
        val endTime = System.currentTimeMillis()
 | 
			
		||||
        val time = endTime - startTime
 | 
			
		||||
@@ -99,7 +97,6 @@ class BackupRestorer(
 | 
			
		||||
        } else {
 | 
			
		||||
            notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun writeErrorLog(): File {
 | 
			
		||||
@@ -121,74 +118,57 @@ class BackupRestorer(
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
        val backupMaps = backup.backupBrokenSources.map { BackupSource(it.name, it.sourceId) } + backup.backupSources
 | 
			
		||||
        sourceMapping = backupMaps.associate { it.sourceId to it.name }
 | 
			
		||||
        now = ZonedDateTime.now()
 | 
			
		||||
        currentFetchWindow = fetchInterval.getWindow(now)
 | 
			
		||||
 | 
			
		||||
        return coroutineScope {
 | 
			
		||||
        coroutineScope {
 | 
			
		||||
            ensureActive()
 | 
			
		||||
            restoreCategories(backup.backupCategories)
 | 
			
		||||
 | 
			
		||||
            ensureActive()
 | 
			
		||||
            restoreAppPreferences(backup.backupPreferences)
 | 
			
		||||
 | 
			
		||||
            ensureActive()
 | 
			
		||||
            restoreSourcePreferences(backup.backupSourcePreferences)
 | 
			
		||||
 | 
			
		||||
            // Restore individual manga
 | 
			
		||||
            backup.backupManga.forEach {
 | 
			
		||||
                if (!isActive) {
 | 
			
		||||
                    return@coroutineScope false
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ensureActive()
 | 
			
		||||
                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>) {
 | 
			
		||||
        // Get categories from file and from db
 | 
			
		||||
        val dbCategories = getCategories.await()
 | 
			
		||||
        if (backupCategories.isNotEmpty()) {
 | 
			
		||||
            val dbCategories = getCategories.await()
 | 
			
		||||
            val dbCategoriesByName = dbCategories.associateBy { it.name }
 | 
			
		||||
 | 
			
		||||
        val categories = backupCategories.map {
 | 
			
		||||
            var category = it.getCategory()
 | 
			
		||||
            var found = false
 | 
			
		||||
            for (dbCategory in dbCategories) {
 | 
			
		||||
                // 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()
 | 
			
		||||
                }
 | 
			
		||||
                category = category.copy(id = id)
 | 
			
		||||
            val categories = backupCategories.map {
 | 
			
		||||
                dbCategoriesByName[it.name]
 | 
			
		||||
                    ?: handler.awaitOneExecutable {
 | 
			
		||||
                        categoriesQueries.insert(it.name, it.order, it.flags)
 | 
			
		||||
                        categoriesQueries.selectLastInsertedRowId()
 | 
			
		||||
                    }.let { id -> it.toCategory(id) }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            category
 | 
			
		||||
            libraryPreferences.categorizedDisplaySettings().set(
 | 
			
		||||
                (dbCategories + categories)
 | 
			
		||||
                    .distinctBy { it.flags }
 | 
			
		||||
                    .size > 1,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        libraryPreferences.categorizedDisplaySettings().set(
 | 
			
		||||
            (dbCategories + categories)
 | 
			
		||||
                .distinctBy { it.flags }
 | 
			
		||||
                .size > 1,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        restoreProgress += 1
 | 
			
		||||
        showRestoreProgress(
 | 
			
		||||
            restoreProgress,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,14 +11,12 @@ class BackupCategory(
 | 
			
		||||
    // @ProtoNumber(3) val updateInterval: Int = 0, 1.x value not used in 0.x
 | 
			
		||||
    @ProtoNumber(100) var flags: Long = 0,
 | 
			
		||||
) {
 | 
			
		||||
    fun getCategory(): Category {
 | 
			
		||||
        return Category(
 | 
			
		||||
            id = 0,
 | 
			
		||||
            name = this@BackupCategory.name,
 | 
			
		||||
            flags = this@BackupCategory.flags,
 | 
			
		||||
            order = this@BackupCategory.order,
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
    fun toCategory(id: Long) = Category(
 | 
			
		||||
        id = id,
 | 
			
		||||
        name = this@BackupCategory.name,
 | 
			
		||||
        flags = this@BackupCategory.flags,
 | 
			
		||||
        order = this@BackupCategory.order,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
val backupCategoryMapper = { category: Category ->
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user