More restore code cleanup

(cherry picked from commit 368c30a2cc6d680c2c5345d22a5646b2184c77fd)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
This commit is contained in:
arkon 2020-11-22 12:40:42 -05:00 committed by Jobobby04
parent 610cad3bc5
commit f594ee66e5
4 changed files with 46 additions and 73 deletions

View File

@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.chapter.NoChaptersException import eu.kanade.tachiyomi.util.chapter.NoChaptersException
import exh.eh.EHentaiThrottleManager import exh.eh.EHentaiThrottleManager
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import okio.source
import rx.Observable import rx.Observable
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
@ -24,56 +25,42 @@ abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val co
protected val db: DatabaseHelper by injectLazy() protected val db: DatabaseHelper by injectLazy()
protected val trackManager: TrackManager by injectLazy() protected val trackManager: TrackManager by injectLazy()
var job: Job? = null
protected lateinit var backupManager: T protected lateinit var backupManager: T
var job: Job? = null protected var restoreAmount = 0
protected var restoreProgress = 0
// SY --> // SY -->
protected val throttleManager = EHentaiThrottleManager() protected val throttleManager = EHentaiThrottleManager()
// SY <-- // SY <--
/**
* The progress of a backup restore
*/
protected var restoreProgress = 0
/**
* Amount of manga in Json file (needed for restore)
*/
protected var restoreAmount = 0
/** /**
* Mapping of source ID to source name from backup data * Mapping of source ID to source name from backup data
*/ */
protected var sourceMapping: Map<Long, String> = emptyMap() protected var sourceMapping: Map<Long, String> = emptyMap()
/**
* List containing errors
*/
protected val errors = mutableListOf<Pair<Date, String>>() protected val errors = mutableListOf<Pair<Date, String>>()
abstract fun restoreBackup(uri: Uri): Boolean abstract fun performRestore(uri: Uri): Boolean
/** fun restoreBackup(uri: Uri): Boolean {
* Write errors to error log val startTime = System.currentTimeMillis()
*/ restoreProgress = 0
internal fun writeErrorLog(): File { errors.clear()
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 -> if (!performRestore(uri)) {
errors.forEach { (date, message) -> return false
out.write("[${sdf.format(date)}] $message\n")
}
}
return destFile
}
} catch (e: Exception) {
// Empty
} }
return File("")
val endTime = System.currentTimeMillis()
val time = endTime - startTime
val logFile = writeErrorLog()
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
return true
} }
/** /**
@ -135,4 +122,23 @@ abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val co
) { ) {
notifier.showRestoreProgress(title, progress, amount) 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("")
}
} }

View File

@ -19,7 +19,7 @@ import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
/** /**
* Restores backup from a JSON file. * Restores backup.
*/ */
class BackupRestoreService : Service() { class BackupRestoreService : Service() {
@ -118,13 +118,15 @@ class BackupRestoreService : Service() {
// Cancel any previous job if needed. // Cancel any previous job if needed.
backupRestore?.job?.cancel() 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 -> val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception) Timber.e(exception)
backupRestore?.writeErrorLog() backupRestore?.writeErrorLog()
notifier.showRestoreError(exception.message) notifier.showRestoreError(exception.message)
stopSelf(startId) stopSelf(startId)
} }
backupRestore?.job = GlobalScope.launch(handler) { backupRestore?.job = GlobalScope.launch(handler) {

View File

@ -29,26 +29,16 @@ import java.util.Date
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)
class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore<FullBackupManager>(context, notifier) { class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore<FullBackupManager>(context, notifier) {
/** override fun performRestore(uri: Uri): Boolean {
* Restores data from backup file.
*
* @param uri backup file to restore
*/
override fun restoreBackup(uri: Uri): Boolean {
// SY --> // SY -->
throttleManager.resetThrottle() throttleManager.resetThrottle()
// SY <-- // SY <--
val startTime = System.currentTimeMillis()
// Initialize manager
backupManager = FullBackupManager(context) backupManager = FullBackupManager(context)
val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() } val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() }
val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString) val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
restoreAmount = backup.backupManga.size + 1 /* SY --> */ + 1 /* SY <-- */ // +1 for categories, +1 for saved searches restoreAmount = backup.backupManga.size + 1 /* SY --> */ + 1 /* SY <-- */ // +1 for categories, +1 for saved searches
restoreProgress = 0
errors.clear()
// Restore categories // Restore categories
if (backup.backupCategories.isNotEmpty()) { if (backup.backupCategories.isNotEmpty()) {
@ -73,12 +63,6 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
restoreManga(it, backup.backupCategories, online) 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 return true
} }

View File

@ -27,31 +27,18 @@ import java.util.Date
class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<LegacyBackupManager>(context, notifier) { class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<LegacyBackupManager>(context, notifier) {
/** override fun performRestore(uri: Uri): Boolean {
* Restores data from backup file.
*
* @param uri backup file to restore
*/
override fun restoreBackup(uri: Uri): Boolean {
// SY --> // SY -->
throttleManager.resetThrottle() throttleManager.resetThrottle()
// SY <-- // SY <--
val startTime = System.currentTimeMillis()
val reader = JsonReader(context.contentResolver.openInputStream(uri)!!.bufferedReader()) val reader = JsonReader(context.contentResolver.openInputStream(uri)!!.bufferedReader())
val json = JsonParser.parseReader(reader).asJsonObject val json = JsonParser.parseReader(reader).asJsonObject
// Get parser version
val version = json.get(Backup.VERSION)?.asInt ?: 1 val version = json.get(Backup.VERSION)?.asInt ?: 1
// Initialize manager
backupManager = LegacyBackupManager(context, version) backupManager = LegacyBackupManager(context, version)
val mangasJson = json.get(MANGAS).asJsonArray val mangasJson = json.get(MANGAS).asJsonArray
restoreAmount = mangasJson.size() + 3 // +1 for categories, +1 for saved searches, +1 for merged manga references restoreAmount = mangasJson.size() + 3 // +1 for categories, +1 for saved searches, +1 for merged manga references
restoreProgress = 0
errors.clear()
// Restore categories // Restore categories
json.get(Backup.CATEGORIES)?.let { restoreCategories(it) } json.get(Backup.CATEGORIES)?.let { restoreCategories(it) }
@ -74,12 +61,6 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
restoreManga(it.asJsonObject) 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 return true
} }