[BackupRestorer] Handle uncompressed backups (#8988)
[Backups] Handle uncompressed backups
This commit is contained in:
parent
3a82b4d924
commit
c892c793a8
3 changed files with 36 additions and 15 deletions
|
@ -3,12 +3,9 @@ package eu.kanade.tachiyomi.data.backup
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.backup.models.BackupSerializer
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import okio.buffer
|
import eu.kanade.tachiyomi.util.BackupUtil
|
||||||
import okio.gzip
|
|
||||||
import okio.source
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
@ -24,13 +21,8 @@ class BackupFileValidator(
|
||||||
* @return List of missing sources or missing trackers.
|
* @return List of missing sources or missing trackers.
|
||||||
*/
|
*/
|
||||||
fun validate(context: Context, uri: Uri): Results {
|
fun validate(context: Context, uri: Uri): Results {
|
||||||
val backupManager = BackupManager(context)
|
|
||||||
|
|
||||||
val backup = try {
|
val backup = try {
|
||||||
val backupString =
|
BackupUtil.decodeBackup(context, uri)
|
||||||
context.contentResolver.openInputStream(uri)!!.source().gzip().buffer()
|
|
||||||
.use { it.readByteArray() }
|
|
||||||
backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw IllegalStateException(e)
|
throw IllegalStateException(e)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,13 @@ import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.backup.models.BackupCategory
|
import eu.kanade.tachiyomi.data.backup.models.BackupCategory
|
||||||
import eu.kanade.tachiyomi.data.backup.models.BackupHistory
|
import eu.kanade.tachiyomi.data.backup.models.BackupHistory
|
||||||
import eu.kanade.tachiyomi.data.backup.models.BackupManga
|
import eu.kanade.tachiyomi.data.backup.models.BackupManga
|
||||||
import eu.kanade.tachiyomi.data.backup.models.BackupSerializer
|
|
||||||
import eu.kanade.tachiyomi.data.backup.models.BackupSource
|
import eu.kanade.tachiyomi.data.backup.models.BackupSource
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.util.BackupUtil
|
||||||
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
|
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import okio.buffer
|
|
||||||
import okio.gzip
|
|
||||||
import okio.source
|
import okio.source
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -79,8 +77,7 @@ class BackupRestorer(
|
||||||
|
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
private suspend fun performRestore(uri: Uri): Boolean {
|
private suspend fun performRestore(uri: Uri): Boolean {
|
||||||
val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() }
|
val backup = BackupUtil.decodeBackup(context, uri)
|
||||||
val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
|
||||||
|
|
||||||
restoreAmount = backup.backupManga.size + 1 // +1 for categories
|
restoreAmount = backup.backupManga.size + 1 // +1 for categories
|
||||||
|
|
||||||
|
|
32
app/src/main/java/eu/kanade/tachiyomi/util/BackupUtil.kt
Normal file
32
app/src/main/java/eu/kanade/tachiyomi/util/BackupUtil.kt
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package eu.kanade.tachiyomi.util
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import eu.kanade.tachiyomi.data.backup.BackupManager
|
||||||
|
import eu.kanade.tachiyomi.data.backup.models.Backup
|
||||||
|
import eu.kanade.tachiyomi.data.backup.models.BackupSerializer
|
||||||
|
import okio.buffer
|
||||||
|
import okio.gzip
|
||||||
|
import okio.source
|
||||||
|
|
||||||
|
object BackupUtil {
|
||||||
|
/**
|
||||||
|
* Decode a potentially-gzipped backup.
|
||||||
|
*/
|
||||||
|
fun decodeBackup(context: Context, uri: Uri): Backup {
|
||||||
|
val backupManager = BackupManager(context)
|
||||||
|
|
||||||
|
val backupStringSource = context.contentResolver.openInputStream(uri)!!.source().buffer()
|
||||||
|
|
||||||
|
val peeked = backupStringSource.peek()
|
||||||
|
peeked.require(2)
|
||||||
|
val id1id2 = peeked.readShort()
|
||||||
|
val backupString = if (id1id2.toInt() == 0x1f8b) { // 0x1f8b is gzip magic bytes
|
||||||
|
backupStringSource.gzip().buffer()
|
||||||
|
} else {
|
||||||
|
backupStringSource
|
||||||
|
}.use { it.readByteArray() }
|
||||||
|
|
||||||
|
return backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue