|
@@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.backup.create
|
|
|
import android.content.Context
|
|
|
import android.net.Uri
|
|
|
import com.hippo.unifile.UniFile
|
|
|
+import eu.kanade.tachiyomi.BuildConfig
|
|
|
import eu.kanade.tachiyomi.data.backup.BackupFileValidator
|
|
|
import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags.BACKUP_APP_PREFS
|
|
|
import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags.BACKUP_CATEGORY
|
|
@@ -11,13 +12,6 @@ import eu.kanade.tachiyomi.data.backup.create.creators.CategoriesBackupCreator
|
|
|
import eu.kanade.tachiyomi.data.backup.create.creators.MangaBackupCreator
|
|
|
import eu.kanade.tachiyomi.data.backup.create.creators.PreferenceBackupCreator
|
|
|
import eu.kanade.tachiyomi.data.backup.create.creators.SourcesBackupCreator
|
|
|
-import eu.kanade.tachiyomi.data.backup.models.Backup
|
|
|
-import eu.kanade.tachiyomi.data.backup.models.BackupCategory
|
|
|
-import eu.kanade.tachiyomi.data.backup.models.BackupManga
|
|
|
-import eu.kanade.tachiyomi.data.backup.models.BackupPreference
|
|
|
-import eu.kanade.tachiyomi.data.backup.models.BackupSerializer
|
|
|
-import eu.kanade.tachiyomi.data.backup.models.BackupSource
|
|
|
-import eu.kanade.tachiyomi.data.backup.models.BackupSourcePreferences
|
|
|
import kotlinx.serialization.protobuf.ProtoBuf
|
|
|
import logcat.LogPriority
|
|
|
import okio.buffer
|
|
@@ -25,31 +19,40 @@ import okio.gzip
|
|
|
import okio.sink
|
|
|
import tachiyomi.core.i18n.stringResource
|
|
|
import tachiyomi.core.util.system.logcat
|
|
|
+import tachiyomi.domain.backup.model.Backup
|
|
|
+import tachiyomi.domain.backup.model.BackupCategory
|
|
|
+import tachiyomi.domain.backup.model.BackupManga
|
|
|
+import tachiyomi.domain.backup.model.BackupPreference
|
|
|
+import tachiyomi.domain.backup.model.BackupSerializer
|
|
|
+import tachiyomi.domain.backup.model.BackupSource
|
|
|
+import tachiyomi.domain.backup.model.BackupSourcePreferences
|
|
|
+import tachiyomi.domain.backup.service.BackupPreferences
|
|
|
import tachiyomi.domain.manga.interactor.GetFavorites
|
|
|
import tachiyomi.domain.manga.model.Manga
|
|
|
import tachiyomi.i18n.MR
|
|
|
import uy.kohesive.injekt.Injekt
|
|
|
import uy.kohesive.injekt.api.get
|
|
|
import java.io.FileOutputStream
|
|
|
+import java.text.SimpleDateFormat
|
|
|
+import java.time.Instant
|
|
|
+import java.util.Date
|
|
|
+import java.util.Locale
|
|
|
|
|
|
class BackupCreator(
|
|
|
private val context: Context,
|
|
|
+ private val isAutoBackup: Boolean,
|
|
|
+
|
|
|
+ private val parser: ProtoBuf = Injekt.get(),
|
|
|
+ private val getFavorites: GetFavorites = Injekt.get(),
|
|
|
+ private val backupPreferences: BackupPreferences = Injekt.get(),
|
|
|
+
|
|
|
private val categoriesBackupCreator: CategoriesBackupCreator = CategoriesBackupCreator(),
|
|
|
private val mangaBackupCreator: MangaBackupCreator = MangaBackupCreator(),
|
|
|
private val preferenceBackupCreator: PreferenceBackupCreator = PreferenceBackupCreator(),
|
|
|
private val sourcesBackupCreator: SourcesBackupCreator = SourcesBackupCreator(),
|
|
|
- private val getFavorites: GetFavorites = Injekt.get(),
|
|
|
) {
|
|
|
|
|
|
- internal val parser = ProtoBuf
|
|
|
-
|
|
|
- /**
|
|
|
- * Create backup file.
|
|
|
- *
|
|
|
- * @param uri path of Uri
|
|
|
- * @param isAutoBackup backup called from scheduled backup job
|
|
|
- */
|
|
|
- suspend fun createBackup(uri: Uri, flags: Int, isAutoBackup: Boolean): String {
|
|
|
+ suspend fun backup(uri: Uri, flags: Int): String {
|
|
|
var file: UniFile? = null
|
|
|
try {
|
|
|
file = (
|
|
@@ -58,14 +61,14 @@ class BackupCreator(
|
|
|
val dir = UniFile.fromUri(context, uri)
|
|
|
|
|
|
// Delete older backups
|
|
|
- dir?.listFiles { _, filename -> Backup.filenameRegex.matches(filename) }
|
|
|
+ dir?.listFiles { _, filename -> FILENAME_REGEX.matches(filename) }
|
|
|
.orEmpty()
|
|
|
.sortedByDescending { it.name }
|
|
|
.drop(MAX_AUTO_BACKUPS - 1)
|
|
|
.forEach { it.delete() }
|
|
|
|
|
|
// Create new file to place backup
|
|
|
- dir?.createFile(Backup.getFilename())
|
|
|
+ dir?.createFile(BackupCreator.getFilename())
|
|
|
} else {
|
|
|
UniFile.fromUri(context, uri)
|
|
|
}
|
|
@@ -90,14 +93,22 @@ class BackupCreator(
|
|
|
throw IllegalStateException(context.stringResource(MR.strings.empty_backup_error))
|
|
|
}
|
|
|
|
|
|
- file.openOutputStream().also {
|
|
|
- // Force overwrite old file
|
|
|
- (it as? FileOutputStream)?.channel?.truncate(0)
|
|
|
- }.sink().gzip().buffer().use { it.write(byteArray) }
|
|
|
+ file.openOutputStream()
|
|
|
+ .also {
|
|
|
+ // Force overwrite old file
|
|
|
+ (it as? FileOutputStream)?.channel?.truncate(0)
|
|
|
+ }
|
|
|
+ .sink().gzip().buffer().use {
|
|
|
+ it.write(byteArray)
|
|
|
+ }
|
|
|
val fileUri = file.uri
|
|
|
|
|
|
// Make sure it's a valid backup file
|
|
|
- BackupFileValidator().validate(context, fileUri)
|
|
|
+ BackupFileValidator(context).validate(fileUri)
|
|
|
+
|
|
|
+ if (isAutoBackup) {
|
|
|
+ backupPreferences.lastAutoBackupTimestamp().set(Instant.now().toEpochMilli())
|
|
|
+ }
|
|
|
|
|
|
return fileUri.toString()
|
|
|
} catch (e: Exception) {
|
|
@@ -132,6 +143,14 @@ class BackupCreator(
|
|
|
|
|
|
return preferenceBackupCreator.backupSourcePreferences()
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-private val MAX_AUTO_BACKUPS: Int = 4
|
|
|
+ companion object {
|
|
|
+ private const val MAX_AUTO_BACKUPS: Int = 4
|
|
|
+ private val FILENAME_REGEX = """${BuildConfig.APPLICATION_ID}_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}.tachibk""".toRegex()
|
|
|
+
|
|
|
+ fun getFilename(): String {
|
|
|
+ val date = SimpleDateFormat("yyyy-MM-dd_HH-mm", Locale.ENGLISH).format(Date())
|
|
|
+ return "${BuildConfig.APPLICATION_ID}_$date.tachibk"
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|