From 94f5117941c368ee5cb300af0d89b39b5427b8ad Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 13 Mar 2021 18:45:22 -0500 Subject: [PATCH] Remove online protobuf backup restore option --- .../data/backup/BackupRestoreService.kt | 6 +- .../data/backup/full/FullBackupManager.kt | 103 ++++-------------- .../data/backup/full/FullBackupRestore.kt | 60 ++++------ .../ui/setting/SettingsBackupController.kt | 48 +++----- app/src/main/res/values/strings.xml | 4 +- 5 files changed, 63 insertions(+), 158 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt index d057792dc..dcae87dbc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt @@ -43,12 +43,11 @@ class BackupRestoreService : Service() { * @param context context of application * @param uri path of Uri */ - fun start(context: Context, uri: Uri, mode: Int, online: Boolean?) { + fun start(context: Context, uri: Uri, mode: Int) { if (!isRunning(context)) { val intent = Intent(context, BackupRestoreService::class.java).apply { putExtra(BackupConst.EXTRA_URI, uri) putExtra(BackupConst.EXTRA_MODE, mode) - online?.let { putExtra(BackupConst.EXTRA_TYPE, it) } } ContextCompat.startForegroundService(context, intent) } @@ -119,13 +118,12 @@ class BackupRestoreService : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val uri = intent?.getParcelableExtra(BackupConst.EXTRA_URI) ?: return START_NOT_STICKY val mode = intent.getIntExtra(BackupConst.EXTRA_MODE, BackupConst.BACKUP_TYPE_FULL) - val online = intent.getBooleanExtra(BackupConst.EXTRA_TYPE, true) // Cancel any previous job if needed. backupRestore?.job?.cancel() backupRestore = when (mode) { - BackupConst.BACKUP_TYPE_FULL -> FullBackupRestore(this, notifier, online) + BackupConst.BACKUP_TYPE_FULL -> FullBackupRestore(this, notifier) else -> LegacyBackupRestore(this, notifier) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt index ab5ad6648..61a244857 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt @@ -26,9 +26,6 @@ import eu.kanade.tachiyomi.data.database.models.History import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.MangaCategory import eu.kanade.tachiyomi.data.database.models.Track -import eu.kanade.tachiyomi.data.database.models.toMangaInfo -import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.source.model.toSManga import kotlinx.serialization.protobuf.ProtoBuf import okio.buffer import okio.gzip @@ -183,24 +180,13 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { /** * Fetches manga information * - * @param source source of manga * @param manga manga that needs updating * @return Updated manga info. */ - suspend fun restoreMangaFetch(source: Source?, manga: Manga, online: Boolean): Manga { - return if (online && source != null) { - val networkManga = source.getMangaDetails(manga.toMangaInfo()) - manga.also { - it.copyFrom(networkManga.toSManga()) - it.favorite = manga.favorite - it.initialized = true - it.id = insertManga(manga) - } - } else { - manga.also { - it.initialized = it.description != null - it.id = insertManga(it) - } + fun restoreManga(manga: Manga): Manga { + return manga.also { + it.initialized = it.description != null + it.id = insertManga(it) } } @@ -309,29 +295,26 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { val trackToUpdate = mutableListOf() tracks.forEach { track -> - val service = trackManager.getService(track.sync_id) - if (service != null && service.isLogged) { - var isInDatabase = false - for (dbTrack in dbTracks) { - if (track.sync_id == dbTrack.sync_id) { - // The sync is already in the db, only update its fields - if (track.media_id != dbTrack.media_id) { - dbTrack.media_id = track.media_id - } - if (track.library_id != dbTrack.library_id) { - dbTrack.library_id = track.library_id - } - dbTrack.last_chapter_read = max(dbTrack.last_chapter_read, track.last_chapter_read) - isInDatabase = true - trackToUpdate.add(dbTrack) - break + var isInDatabase = false + for (dbTrack in dbTracks) { + if (track.sync_id == dbTrack.sync_id) { + // The sync is already in the db, only update its fields + if (track.media_id != dbTrack.media_id) { + dbTrack.media_id = track.media_id } + if (track.library_id != dbTrack.library_id) { + dbTrack.library_id = track.library_id + } + dbTrack.last_chapter_read = max(dbTrack.last_chapter_read, track.last_chapter_read) + isInDatabase = true + trackToUpdate.add(dbTrack) + break } - if (!isInDatabase) { - // Insert new sync. Let the db assign the id - track.id = null - trackToUpdate.add(track) - } + } + if (!isInDatabase) { + // Insert new sync. Let the db assign the id + track.id = null + trackToUpdate.add(track) } } // Update database @@ -340,47 +323,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) { } } - /** - * Restore the chapters for manga if chapters already in database - * - * @param manga manga of chapters - * @param chapters list containing chapters that get restored - * @return boolean answering if chapter fetch is not needed - */ - internal fun restoreChaptersForManga(manga: Manga, chapters: List): Boolean { - val dbChapters = databaseHelper.getChapters(manga).executeAsBlocking() - - // Return if fetch is needed - if (dbChapters.isEmpty() || dbChapters.size < chapters.size) { - return false - } - - chapters.forEach { chapter -> - val dbChapter = dbChapters.find { it.url == chapter.url } - if (dbChapter != null) { - chapter.id = dbChapter.id - chapter.copyFrom(dbChapter) - if (dbChapter.read && !chapter.read) { - chapter.read = dbChapter.read - chapter.last_page_read = dbChapter.last_page_read - } else if (chapter.last_page_read == 0 && dbChapter.last_page_read != 0) { - chapter.last_page_read = dbChapter.last_page_read - } - if (!chapter.bookmark && dbChapter.bookmark) { - chapter.bookmark = dbChapter.bookmark - } - } - - chapter.manga_id = manga.id - } - - // Filter the chapters that couldn't be found. - updateChapters(chapters.filter { it.id != null }) - - return true - } - - internal fun restoreChaptersForMangaOffline(manga: Manga, chapters: List) { + internal fun restoreChaptersForManga(manga: Manga, chapters: List) { val dbChapters = databaseHelper.getChapters(manga).executeAsBlocking() chapters.forEach { chapter -> diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt index f6cbb72eb..f2fea79b5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt @@ -12,13 +12,12 @@ import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer 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 okio.buffer import okio.gzip import okio.source import java.util.Date -class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore(context, notifier) { +class FullBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore(context, notifier) { override suspend fun performRestore(uri: Uri): Boolean { backupManager = FullBackupManager(context) @@ -42,7 +41,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val return false } - restoreManga(it, backup.backupCategories, online) + restoreManga(it, backup.backupCategories) } return true @@ -57,7 +56,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories)) } - private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List, online: Boolean) { + private fun restoreManga(backupManga: BackupManga, backupCategories: List) { val manga = backupManga.getMangaImpl() val chapters = backupManga.getChaptersImpl() val categories = backupManga.categories @@ -68,8 +67,8 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val val sourceName = sourceMapping[manga.source] ?: manga.source.toString() try { - if (source != null || !online) { - restoreMangaData(manga, source, chapters, categories, history, tracks, backupCategories, online) + if (source != null) { + restoreMangaData(manga, chapters, categories, history, tracks, backupCategories) } else { errors.add(Date() to "${manga.title} [$sourceName]: ${context.getString(R.string.source_not_found_name, sourceName)}") } @@ -85,33 +84,30 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val * Returns a manga restore observable * * @param manga manga data from json - * @param source source to get manga data from * @param chapters chapters data from json * @param categories categories data from json * @param history history data from json * @param tracks tracking data from json */ - private suspend fun restoreMangaData( + private fun restoreMangaData( manga: Manga, - source: Source?, chapters: List, categories: List, history: List, tracks: List, - backupCategories: List, - online: Boolean + backupCategories: List ) { - val dbManga = backupManager.getMangaFromDatabase(manga) - db.inTransaction { + val dbManga = backupManager.getMangaFromDatabase(manga) if (dbManga == null) { // Manga not in database - restoreMangaFetch(source, manga, chapters, categories, history, tracks, backupCategories, online) - } else { // Manga in database + restoreMangaFetch(manga, chapters, categories, history, tracks, backupCategories) + } else { + // Manga in database // Copy information from manga already in database backupManager.restoreMangaNoFetch(manga, dbManga) // Fetch rest of manga information - restoreMangaNoFetch(source, manga, chapters, categories, history, tracks, backupCategories, online) + restoreMangaNoFetch(manga, chapters, categories, history, tracks, backupCategories) } } } @@ -123,55 +119,37 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val * @param chapters chapters of manga that needs updating * @param categories categories that need updating */ - private suspend fun restoreMangaFetch( - source: Source?, + private fun restoreMangaFetch( manga: Manga, chapters: List, categories: List, history: List, tracks: List, - backupCategories: List, - online: Boolean + backupCategories: List ) { try { - val fetchedManga = backupManager.restoreMangaFetch(source, manga, online) + val fetchedManga = backupManager.restoreManga(manga) fetchedManga.id ?: return - if (online && source != null) { - updateChapters(source, fetchedManga, chapters) - } else { - backupManager.restoreChaptersForMangaOffline(fetchedManga, chapters) - } + backupManager.restoreChaptersForManga(fetchedManga, chapters) restoreExtraForManga(fetchedManga, categories, history, tracks, backupCategories) - - updateTracking(fetchedManga, tracks) } catch (e: Exception) { errors.add(Date() to "${manga.title} - ${e.message}") } } - private suspend fun restoreMangaNoFetch( - source: Source?, + private fun restoreMangaNoFetch( backupManga: Manga, chapters: List, categories: List, history: List, tracks: List, - backupCategories: List, - online: Boolean + backupCategories: List ) { - if (online && source != null) { - if (!backupManager.restoreChaptersForManga(backupManga, chapters)) { - updateChapters(source, backupManga, chapters) - } - } else { - backupManager.restoreChaptersForMangaOffline(backupManga, chapters) - } + backupManager.restoreChaptersForManga(backupManga, chapters) restoreExtraForManga(backupManga, categories, history, tracks, backupCategories) - - updateTracking(backupManga, tracks) } private fun restoreExtraForManga(manga: Manga, categories: List, history: List, tracks: List, backupCategories: List) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt index 68ac22e63..e27149a21 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt @@ -15,7 +15,6 @@ import androidx.documentfile.provider.DocumentFile import androidx.preference.PreferenceScreen import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.list.listItemsMultiChoice -import com.afollestad.materialdialogs.list.listItemsSingleChoice import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.backup.BackupConst @@ -206,31 +205,15 @@ class SettingsBackupController : SettingsController() { val fileName = DocumentFile.fromSingleUri(activity, uri)?.name ?: uri.toString() when { fileName.endsWith(".proto.gz") -> { - val options = arrayOf( - R.string.full_restore_offline, - R.string.full_restore_online - ) - .map { activity.getString(it) } - MaterialDialog(activity) - .title(R.string.full_restore_mode) - .listItemsSingleChoice( - items = options, - initialSelection = 0 - ) { _, index, _ -> - RestoreBackupDialog( - uri, - BackupConst.BACKUP_TYPE_FULL, - isOnline = index != 0 - ).showDialog(router) - } - .positiveButton(R.string.action_restore) - .show() + RestoreBackupDialog( + uri, + BackupConst.BACKUP_TYPE_FULL + ).showDialog(router) } fileName.endsWith(".json") -> { RestoreBackupDialog( uri, - BackupConst.BACKUP_TYPE_LEGACY, - isOnline = true + BackupConst.BACKUP_TYPE_LEGACY ).showDialog(router) } else -> { @@ -326,11 +309,10 @@ class SettingsBackupController : SettingsController() { } class RestoreBackupDialog(bundle: Bundle? = null) : DialogController(bundle) { - constructor(uri: Uri, type: Int, isOnline: Boolean) : this( + constructor(uri: Uri, type: Int) : this( bundleOf( KEY_URI to uri, - KEY_TYPE to type, - KEY_MODE to isOnline + KEY_TYPE to type ) ) @@ -338,12 +320,19 @@ class SettingsBackupController : SettingsController() { val activity = activity!! val uri: Uri = args.getParcelable(KEY_URI)!! val type: Int = args.getInt(KEY_TYPE) - val isOnline: Boolean = args.getBoolean(KEY_MODE, true) return try { - var message = activity.getString(R.string.backup_restore_content) + var message = if (type == BackupConst.BACKUP_TYPE_FULL) { + activity.getString(R.string.backup_restore_content_full) + } else { + activity.getString(R.string.backup_restore_content) + } - val validator = if (type == BackupConst.BACKUP_TYPE_FULL) FullBackupRestoreValidator() else LegacyBackupRestoreValidator() + val validator = if (type == BackupConst.BACKUP_TYPE_FULL) { + FullBackupRestoreValidator() + } else { + LegacyBackupRestoreValidator() + } val results = validator.validate(activity, uri) if (results.missingSources.isNotEmpty()) { @@ -357,7 +346,7 @@ class SettingsBackupController : SettingsController() { .title(R.string.pref_restore_backup) .message(text = message) .positiveButton(R.string.action_restore) { - BackupRestoreService.start(activity, uri, type, isOnline) + BackupRestoreService.start(activity, uri, type) } } catch (e: Exception) { MaterialDialog(activity) @@ -370,7 +359,6 @@ class SettingsBackupController : SettingsController() { private companion object { const val KEY_URI = "RestoreBackupDialog.uri" const val KEY_TYPE = "RestoreBackupDialog.type" - const val KEY_MODE = "RestoreBackupDialog.mode" } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3ea845fd0..c5dbed665 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -377,9 +377,6 @@ Automatic backups Backup frequency Maximum backups - Network Mode - Restore online, much slower but gives you more updated info and chapters - Restore offline, finishes quickly but contains only what your backup has Source not found: %1$s Not logged in: %1$s Backup created @@ -390,6 +387,7 @@ Missing sources: Trackers not logged into: Restore uses sources to fetch data, carrier costs may apply.\n\nMake sure you have installed all necessary extensions and are logged in to sources and tracking services before restoring. + Data from the backup file will be restored.\n\nYou will need to install any missing extensions and log in to tracking services afterwards to use them. Restore completed %02d min, %02d sec