mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Remove online protobuf backup restore option
This commit is contained in:
		| @@ -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<Uri>(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) | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -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<Track>() | ||||
|  | ||||
|         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<Chapter>): 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<Chapter>) { | ||||
|     internal fun restoreChaptersForManga(manga: Manga, chapters: List<Chapter>) { | ||||
|         val dbChapters = databaseHelper.getChapters(manga).executeAsBlocking() | ||||
|  | ||||
|         chapters.forEach { chapter -> | ||||
|   | ||||
| @@ -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<FullBackupManager>(context, notifier) { | ||||
| class FullBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<FullBackupManager>(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<BackupCategory>, online: Boolean) { | ||||
|     private fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>) { | ||||
|         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<Chapter>, | ||||
|         categories: List<Int>, | ||||
|         history: List<BackupHistory>, | ||||
|         tracks: List<Track>, | ||||
|         backupCategories: List<BackupCategory>, | ||||
|         online: Boolean | ||||
|         backupCategories: List<BackupCategory> | ||||
|     ) { | ||||
|         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<Chapter>, | ||||
|         categories: List<Int>, | ||||
|         history: List<BackupHistory>, | ||||
|         tracks: List<Track>, | ||||
|         backupCategories: List<BackupCategory>, | ||||
|         online: Boolean | ||||
|         backupCategories: List<BackupCategory> | ||||
|     ) { | ||||
|         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<Chapter>, | ||||
|         categories: List<Int>, | ||||
|         history: List<BackupHistory>, | ||||
|         tracks: List<Track>, | ||||
|         backupCategories: List<BackupCategory>, | ||||
|         online: Boolean | ||||
|         backupCategories: List<BackupCategory> | ||||
|     ) { | ||||
|         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<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>) { | ||||
|   | ||||
| @@ -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" | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user