mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 06:17:57 +01:00 
			
		
		
		
	Make backup restoring logic more sequential
This commit is contained in:
		| @@ -37,9 +37,9 @@ abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val co | ||||
|  | ||||
|     protected val errors = mutableListOf<Pair<Date, String>>() | ||||
|  | ||||
|     abstract fun performRestore(uri: Uri): Boolean | ||||
|     abstract suspend fun performRestore(uri: Uri): Boolean | ||||
|  | ||||
|     fun restoreBackup(uri: Uri): Boolean { | ||||
|     suspend fun restoreBackup(uri: Uri): Boolean { | ||||
|         val startTime = System.currentTimeMillis() | ||||
|         restoreProgress = 0 | ||||
|         errors.clear() | ||||
|   | ||||
| @@ -14,7 +14,10 @@ import eu.kanade.tachiyomi.data.notification.Notifications | ||||
| import eu.kanade.tachiyomi.util.system.acquireWakeLock | ||||
| import eu.kanade.tachiyomi.util.system.isServiceRunning | ||||
| import kotlinx.coroutines.CoroutineExceptionHandler | ||||
| import kotlinx.coroutines.GlobalScope | ||||
| import kotlinx.coroutines.CoroutineScope | ||||
| import kotlinx.coroutines.Dispatchers | ||||
| import kotlinx.coroutines.SupervisorJob | ||||
| import kotlinx.coroutines.cancel | ||||
| import kotlinx.coroutines.launch | ||||
| import timber.log.Timber | ||||
|  | ||||
| @@ -68,12 +71,14 @@ class BackupRestoreService : Service() { | ||||
|      */ | ||||
|     private lateinit var wakeLock: PowerManager.WakeLock | ||||
|  | ||||
|     private lateinit var ioScope: CoroutineScope | ||||
|     private var backupRestore: AbstractBackupRestore<*>? = null | ||||
|     private lateinit var notifier: BackupNotifier | ||||
|  | ||||
|     override fun onCreate() { | ||||
|         super.onCreate() | ||||
|  | ||||
|         ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) | ||||
|         notifier = BackupNotifier(this) | ||||
|         wakeLock = acquireWakeLock(javaClass.name) | ||||
|  | ||||
| @@ -92,6 +97,7 @@ class BackupRestoreService : Service() { | ||||
|  | ||||
|     private fun destroyJob() { | ||||
|         backupRestore?.job?.cancel() | ||||
|         ioScope?.cancel() | ||||
|         if (wakeLock.isHeld) { | ||||
|             wakeLock.release() | ||||
|         } | ||||
| @@ -122,6 +128,7 @@ class BackupRestoreService : Service() { | ||||
|             BackupConst.BACKUP_TYPE_FULL -> FullBackupRestore(this, notifier, online) | ||||
|             else -> LegacyBackupRestore(this, notifier) | ||||
|         } | ||||
|  | ||||
|         val handler = CoroutineExceptionHandler { _, exception -> | ||||
|             Timber.e(exception) | ||||
|             backupRestore?.writeErrorLog() | ||||
| @@ -129,14 +136,15 @@ class BackupRestoreService : Service() { | ||||
|             notifier.showRestoreError(exception.message) | ||||
|             stopSelf(startId) | ||||
|         } | ||||
|         backupRestore?.job = GlobalScope.launch(handler) { | ||||
|         val job = ioScope.launch(handler) { | ||||
|             if (backupRestore?.restoreBackup(uri) == false) { | ||||
|                 notifier.showRestoreError(getString(R.string.restoring_backup_canceled)) | ||||
|             } | ||||
|         } | ||||
|         backupRestore?.job?.invokeOnCompletion { | ||||
|         job.invokeOnCompletion { | ||||
|             stopSelf(startId) | ||||
|         } | ||||
|         backupRestore?.job = job | ||||
|  | ||||
|         return START_NOT_STICKY | ||||
|     } | ||||
|   | ||||
| @@ -13,7 +13,6 @@ import eu.kanade.tachiyomi.data.database.models.Chapter | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| import eu.kanade.tachiyomi.data.database.models.Track | ||||
| import eu.kanade.tachiyomi.source.Source | ||||
| import eu.kanade.tachiyomi.util.lang.launchIO | ||||
| import okio.buffer | ||||
| import okio.gzip | ||||
| import okio.source | ||||
| @@ -21,7 +20,7 @@ import java.util.Date | ||||
|  | ||||
| class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore<FullBackupManager>(context, notifier) { | ||||
|  | ||||
|     override fun performRestore(uri: Uri): Boolean { | ||||
|     override suspend fun performRestore(uri: Uri): Boolean { | ||||
|         backupManager = FullBackupManager(context) | ||||
|  | ||||
|         val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() } | ||||
| @@ -58,7 +57,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val | ||||
|         showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories)) | ||||
|     } | ||||
|  | ||||
|     private fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, online: Boolean) { | ||||
|     private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, online: Boolean) { | ||||
|         val manga = backupManga.getMangaImpl() | ||||
|         val chapters = backupManga.getChaptersImpl() | ||||
|         val categories = backupManga.categories | ||||
| @@ -92,7 +91,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val | ||||
|      * @param history history data from json | ||||
|      * @param tracks tracking data from json | ||||
|      */ | ||||
|     private fun restoreMangaData( | ||||
|     private suspend fun restoreMangaData( | ||||
|         manga: Manga, | ||||
|         source: Source?, | ||||
|         chapters: List<Chapter>, | ||||
| @@ -124,7 +123,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val | ||||
|      * @param chapters chapters of manga that needs updating | ||||
|      * @param categories categories that need updating | ||||
|      */ | ||||
|     private fun restoreMangaFetch( | ||||
|     private suspend fun restoreMangaFetch( | ||||
|         source: Source?, | ||||
|         manga: Manga, | ||||
|         chapters: List<Chapter>, | ||||
| @@ -134,27 +133,25 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val | ||||
|         backupCategories: List<BackupCategory>, | ||||
|         online: Boolean | ||||
|     ) { | ||||
|         launchIO { | ||||
|             try { | ||||
|                 val fetchedManga = backupManager.restoreMangaFetch(source, manga, online) | ||||
|                 fetchedManga.id ?: (return@launchIO) | ||||
|         try { | ||||
|             val fetchedManga = backupManager.restoreMangaFetch(source, manga, online) | ||||
|             fetchedManga.id ?: return | ||||
|  | ||||
|                 if (online && source != null) { | ||||
|                     updateChapters(source, fetchedManga, chapters) | ||||
|                 } else { | ||||
|                     backupManager.restoreChaptersForMangaOffline(fetchedManga, chapters) | ||||
|                 } | ||||
|  | ||||
|                 restoreExtraForManga(fetchedManga, categories, history, tracks, backupCategories) | ||||
|  | ||||
|                 updateTracking(fetchedManga, tracks) | ||||
|             } catch (e: Exception) { | ||||
|                 errors.add(Date() to "${manga.title} - ${e.message}") | ||||
|             if (online && source != null) { | ||||
|                 updateChapters(source, fetchedManga, chapters) | ||||
|             } else { | ||||
|                 backupManager.restoreChaptersForMangaOffline(fetchedManga, chapters) | ||||
|             } | ||||
|  | ||||
|             restoreExtraForManga(fetchedManga, categories, history, tracks, backupCategories) | ||||
|  | ||||
|             updateTracking(fetchedManga, tracks) | ||||
|         } catch (e: Exception) { | ||||
|             errors.add(Date() to "${manga.title} - ${e.message}") | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun restoreMangaNoFetch( | ||||
|     private suspend fun restoreMangaNoFetch( | ||||
|         source: Source?, | ||||
|         backupManga: Manga, | ||||
|         chapters: List<Chapter>, | ||||
| @@ -164,19 +161,17 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val | ||||
|         backupCategories: List<BackupCategory>, | ||||
|         online: Boolean | ||||
|     ) { | ||||
|         launchIO { | ||||
|             if (online && source != null) { | ||||
|                 if (!backupManager.restoreChaptersForManga(backupManga, chapters)) { | ||||
|                     updateChapters(source, backupManga, chapters) | ||||
|                 } | ||||
|             } else { | ||||
|                 backupManager.restoreChaptersForMangaOffline(backupManga, chapters) | ||||
|         if (online && source != null) { | ||||
|             if (!backupManager.restoreChaptersForManga(backupManga, chapters)) { | ||||
|                 updateChapters(source, backupManga, chapters) | ||||
|             } | ||||
|  | ||||
|             restoreExtraForManga(backupManga, categories, history, tracks, backupCategories) | ||||
|  | ||||
|             updateTracking(backupManga, tracks) | ||||
|         } else { | ||||
|             backupManager.restoreChaptersForMangaOffline(backupManga, chapters) | ||||
|         } | ||||
|  | ||||
|         restoreExtraForManga(backupManga, categories, history, tracks, backupCategories) | ||||
|  | ||||
|         updateTracking(backupManga, tracks) | ||||
|     } | ||||
|  | ||||
|     private fun restoreExtraForManga(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>) { | ||||
|   | ||||
| @@ -21,12 +21,11 @@ import eu.kanade.tachiyomi.data.database.models.MangaImpl | ||||
| import eu.kanade.tachiyomi.data.database.models.Track | ||||
| import eu.kanade.tachiyomi.data.database.models.TrackImpl | ||||
| import eu.kanade.tachiyomi.source.Source | ||||
| import eu.kanade.tachiyomi.util.lang.launchIO | ||||
| import java.util.Date | ||||
|  | ||||
| class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<LegacyBackupManager>(context, notifier) { | ||||
|  | ||||
|     override fun performRestore(uri: Uri): Boolean { | ||||
|     override suspend fun performRestore(uri: Uri): Boolean { | ||||
|         val reader = JsonReader(context.contentResolver.openInputStream(uri)!!.bufferedReader()) | ||||
|         val json = JsonParser.parseReader(reader).asJsonObject | ||||
|  | ||||
| @@ -63,7 +62,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract | ||||
|         showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories)) | ||||
|     } | ||||
|  | ||||
|     private fun restoreManga(mangaJson: JsonObject) { | ||||
|     private suspend fun restoreManga(mangaJson: JsonObject) { | ||||
|         val manga = backupManager.parser.fromJson<MangaImpl>( | ||||
|             mangaJson.get( | ||||
|                 Backup.MANGA | ||||
| @@ -113,7 +112,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract | ||||
|      * @param history history data from json | ||||
|      * @param tracks tracking data from json | ||||
|      */ | ||||
|     private fun restoreMangaData( | ||||
|     private suspend fun restoreMangaData( | ||||
|         manga: Manga, | ||||
|         source: Source, | ||||
|         chapters: List<Chapter>, | ||||
| @@ -143,7 +142,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract | ||||
|      * @param chapters chapters of manga that needs updating | ||||
|      * @param categories categories that need updating | ||||
|      */ | ||||
|     private fun restoreMangaFetch( | ||||
|     private suspend fun restoreMangaFetch( | ||||
|         source: Source, | ||||
|         manga: Manga, | ||||
|         chapters: List<Chapter>, | ||||
| @@ -151,23 +150,21 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract | ||||
|         history: List<DHistory>, | ||||
|         tracks: List<Track> | ||||
|     ) { | ||||
|         launchIO { | ||||
|             try { | ||||
|                 val fetchedManga = backupManager.fetchManga(source, manga) | ||||
|                 fetchedManga.id ?: (return@launchIO) | ||||
|         try { | ||||
|             val fetchedManga = backupManager.fetchManga(source, manga) | ||||
|             fetchedManga.id ?: return | ||||
|  | ||||
|                 updateChapters(source, fetchedManga, chapters) | ||||
|             updateChapters(source, fetchedManga, chapters) | ||||
|  | ||||
|                 restoreExtraForManga(fetchedManga, categories, history, tracks) | ||||
|             restoreExtraForManga(fetchedManga, categories, history, tracks) | ||||
|  | ||||
|                 updateTracking(fetchedManga, tracks) | ||||
|             } catch (e: Exception) { | ||||
|                 errors.add(Date() to "${manga.title} - ${e.message}") | ||||
|             } | ||||
|             updateTracking(fetchedManga, tracks) | ||||
|         } catch (e: Exception) { | ||||
|             errors.add(Date() to "${manga.title} - ${e.message}") | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun restoreMangaNoFetch( | ||||
|     private suspend fun restoreMangaNoFetch( | ||||
|         source: Source, | ||||
|         backupManga: Manga, | ||||
|         chapters: List<Chapter>, | ||||
| @@ -175,15 +172,13 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract | ||||
|         history: List<DHistory>, | ||||
|         tracks: List<Track> | ||||
|     ) { | ||||
|         launchIO { | ||||
|             if (!backupManager.restoreChaptersForManga(backupManga, chapters)) { | ||||
|                 updateChapters(source, backupManga, chapters) | ||||
|             } | ||||
|  | ||||
|             restoreExtraForManga(backupManga, categories, history, tracks) | ||||
|  | ||||
|             updateTracking(backupManga, tracks) | ||||
|         if (!backupManager.restoreChaptersForManga(backupManga, chapters)) { | ||||
|             updateChapters(source, backupManga, chapters) | ||||
|         } | ||||
|  | ||||
|         restoreExtraForManga(backupManga, categories, history, tracks) | ||||
|  | ||||
|         updateTracking(backupManga, tracks) | ||||
|     } | ||||
|  | ||||
|     private fun restoreExtraForManga(manga: Manga, categories: List<String>, history: List<DHistory>, tracks: List<Track>) { | ||||
|   | ||||
| @@ -158,8 +158,8 @@ class LibraryUpdateService( | ||||
|      * lock. | ||||
|      */ | ||||
|     override fun onDestroy() { | ||||
|         ioScope?.cancel() | ||||
|         updateJob?.cancel() | ||||
|         ioScope?.cancel() | ||||
|         if (wakeLock.isHeld) { | ||||
|             wakeLock.release() | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user