mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 06:17:57 +01:00 
			
		
		
		
	More restore code cleanup, remove some SY-specific logic
This commit is contained in:
		| @@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager | ||||
| import eu.kanade.tachiyomi.source.Source | ||||
| import eu.kanade.tachiyomi.util.chapter.NoChaptersException | ||||
| import kotlinx.coroutines.Job | ||||
| import okio.source | ||||
| import rx.Observable | ||||
| import uy.kohesive.injekt.injectLazy | ||||
| import java.io.File | ||||
| @@ -23,52 +24,38 @@ abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val co | ||||
|     protected val db: DatabaseHelper by injectLazy() | ||||
|     protected val trackManager: TrackManager by injectLazy() | ||||
|  | ||||
|     protected lateinit var backupManager: T | ||||
|  | ||||
|     var job: Job? = null | ||||
|  | ||||
|     /** | ||||
|      * The progress of a backup restore | ||||
|      */ | ||||
|     protected var restoreProgress = 0 | ||||
|     protected lateinit var backupManager: T | ||||
|  | ||||
|     /** | ||||
|      * Amount of manga in Json file (needed for restore) | ||||
|      */ | ||||
|     protected var restoreAmount = 0 | ||||
|     protected var restoreProgress = 0 | ||||
|  | ||||
|     /** | ||||
|      * Mapping of source ID to source name from backup data | ||||
|      */ | ||||
|     protected var sourceMapping: Map<Long, String> = emptyMap() | ||||
|  | ||||
|     /** | ||||
|      * List containing errors | ||||
|      */ | ||||
|     protected val errors = mutableListOf<Pair<Date, String>>() | ||||
|  | ||||
|     abstract fun restoreBackup(uri: Uri): Boolean | ||||
|     abstract fun performRestore(uri: Uri): Boolean | ||||
|  | ||||
|     /** | ||||
|      * Write errors to error log | ||||
|      */ | ||||
|     internal fun writeErrorLog(): File { | ||||
|         try { | ||||
|             if (errors.isNotEmpty()) { | ||||
|                 val destFile = File(context.externalCacheDir, "tachiyomi_restore.txt") | ||||
|                 val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault()) | ||||
|     fun restoreBackup(uri: Uri): Boolean { | ||||
|         val startTime = System.currentTimeMillis() | ||||
|         restoreProgress = 0 | ||||
|         errors.clear() | ||||
|  | ||||
|                 destFile.bufferedWriter().use { out -> | ||||
|                     errors.forEach { (date, message) -> | ||||
|                         out.write("[${sdf.format(date)}] $message\n") | ||||
|                     } | ||||
|                 } | ||||
|                 return destFile | ||||
|             } | ||||
|         } catch (e: Exception) { | ||||
|             // Empty | ||||
|         if (!performRestore(uri)) { | ||||
|             return false | ||||
|         } | ||||
|         return File("") | ||||
|  | ||||
|         val endTime = System.currentTimeMillis() | ||||
|         val time = endTime - startTime | ||||
|  | ||||
|         val logFile = writeErrorLog() | ||||
|  | ||||
|         notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name) | ||||
|         return true | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -130,4 +117,23 @@ abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val co | ||||
|     ) { | ||||
|         notifier.showRestoreProgress(title, progress, amount) | ||||
|     } | ||||
|  | ||||
|     internal fun writeErrorLog(): File { | ||||
|         try { | ||||
|             if (errors.isNotEmpty()) { | ||||
|                 val destFile = File(context.externalCacheDir, "tachiyomi_restore.txt") | ||||
|                 val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault()) | ||||
|  | ||||
|                 destFile.bufferedWriter().use { out -> | ||||
|                     errors.forEach { (date, message) -> | ||||
|                         out.write("[${sdf.format(date)}] $message\n") | ||||
|                     } | ||||
|                 } | ||||
|                 return destFile | ||||
|             } | ||||
|         } catch (e: Exception) { | ||||
|             // Empty | ||||
|         } | ||||
|         return File("") | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,7 @@ import kotlinx.coroutines.launch | ||||
| import timber.log.Timber | ||||
|  | ||||
| /** | ||||
|  * Restores backup from a JSON file. | ||||
|  * Restores backup. | ||||
|  */ | ||||
| class BackupRestoreService : Service() { | ||||
|  | ||||
| @@ -118,13 +118,15 @@ class BackupRestoreService : Service() { | ||||
|         // Cancel any previous job if needed. | ||||
|         backupRestore?.job?.cancel() | ||||
|  | ||||
|         backupRestore = if (mode == BackupConst.BACKUP_TYPE_FULL) FullBackupRestore(this, notifier, online) else LegacyBackupRestore(this, notifier) | ||||
|         backupRestore = when (mode) { | ||||
|             BackupConst.BACKUP_TYPE_FULL -> FullBackupRestore(this, notifier, online) | ||||
|             else -> LegacyBackupRestore(this, notifier) | ||||
|         } | ||||
|         val handler = CoroutineExceptionHandler { _, exception -> | ||||
|             Timber.e(exception) | ||||
|             backupRestore?.writeErrorLog() | ||||
|  | ||||
|             notifier.showRestoreError(exception.message) | ||||
|  | ||||
|             stopSelf(startId) | ||||
|         } | ||||
|         backupRestore?.job = GlobalScope.launch(handler) { | ||||
|   | ||||
| @@ -23,23 +23,13 @@ import java.util.Date | ||||
| @OptIn(ExperimentalSerializationApi::class) | ||||
| class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore<FullBackupManager>(context, notifier) { | ||||
|  | ||||
|     /** | ||||
|      * Restores data from backup file. | ||||
|      * | ||||
|      * @param uri backup file to restore | ||||
|      */ | ||||
|     override fun restoreBackup(uri: Uri): Boolean { | ||||
|         val startTime = System.currentTimeMillis() | ||||
|  | ||||
|         // Initialize manager | ||||
|     override fun performRestore(uri: Uri): Boolean { | ||||
|         backupManager = FullBackupManager(context) | ||||
|  | ||||
|         val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() } | ||||
|         val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString) | ||||
|  | ||||
|         restoreAmount = backup.backupManga.size + 1 // +1 for categories | ||||
|         restoreProgress = 0 | ||||
|         errors.clear() | ||||
|  | ||||
|         // Restore categories | ||||
|         if (backup.backupCategories.isNotEmpty()) { | ||||
| @@ -49,7 +39,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val | ||||
|         // Store source mapping for error messages | ||||
|         sourceMapping = backup.backupSources.map { it.sourceId to it.name }.toMap() | ||||
|  | ||||
|         // Restore individual manga, sort by merged source so that merged source manga go last and merged references get the proper ids | ||||
|         // Restore individual manga | ||||
|         backup.backupManga.forEach { | ||||
|             if (job?.isActive != true) { | ||||
|                 return false | ||||
| @@ -58,12 +48,6 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val | ||||
|             restoreManga(it, backup.backupCategories, online) | ||||
|         } | ||||
|  | ||||
|         val endTime = System.currentTimeMillis() | ||||
|         val time = endTime - startTime | ||||
|  | ||||
|         val logFile = writeErrorLog() | ||||
|  | ||||
|         notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name) | ||||
|         return true | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -26,28 +26,15 @@ import java.util.Date | ||||
|  | ||||
| class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<LegacyBackupManager>(context, notifier) { | ||||
|  | ||||
|     /** | ||||
|      * Restores data from backup file. | ||||
|      * | ||||
|      * @param uri backup file to restore | ||||
|      */ | ||||
|     override fun restoreBackup(uri: Uri): Boolean { | ||||
|         val startTime = System.currentTimeMillis() | ||||
|  | ||||
|     override fun performRestore(uri: Uri): Boolean { | ||||
|         val reader = JsonReader(context.contentResolver.openInputStream(uri)!!.bufferedReader()) | ||||
|         val json = JsonParser.parseReader(reader).asJsonObject | ||||
|  | ||||
|         // Get parser version | ||||
|         val version = json.get(Backup.VERSION)?.asInt ?: 1 | ||||
|  | ||||
|         // Initialize manager | ||||
|         backupManager = LegacyBackupManager(context, version) | ||||
|  | ||||
|         val mangasJson = json.get(MANGAS).asJsonArray | ||||
|  | ||||
|         restoreAmount = mangasJson.size() + 3 // +1 for categories, +1 for saved searches, +1 for merged manga references | ||||
|         restoreProgress = 0 | ||||
|         errors.clear() | ||||
|         restoreAmount = mangasJson.size() + 1 // +1 for categories | ||||
|  | ||||
|         // Restore categories | ||||
|         json.get(Backup.CATEGORIES)?.let { restoreCategories(it) } | ||||
| @@ -64,12 +51,6 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract | ||||
|             restoreManga(it.asJsonObject) | ||||
|         } | ||||
|  | ||||
|         val endTime = System.currentTimeMillis() | ||||
|         val time = endTime - startTime | ||||
|  | ||||
|         val logFile = writeErrorLog() | ||||
|  | ||||
|         notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name) | ||||
|         return true | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user