Make backup restoring logic more sequential
This commit is contained in:
parent
41d7cee020
commit
aded11e599
@ -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()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user