mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
Remove abstract backup classes
This commit is contained in:
parent
884f46ba19
commit
1559c317d7
4 changed files with 97 additions and 251 deletions
|
@ -1,99 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.data.backup
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.net.Uri
|
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
|
||||||
import eu.kanade.tachiyomi.data.library.CustomMangaManager
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
|
||||||
import eu.kanade.tachiyomi.source.Source
|
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
|
|
||||||
abstract class AbstractBackupManager(protected val context: Context) {
|
|
||||||
|
|
||||||
internal val db: DatabaseHelper = Injekt.get()
|
|
||||||
internal val sourceManager: SourceManager = Injekt.get()
|
|
||||||
internal val trackManager: TrackManager = Injekt.get()
|
|
||||||
protected val preferences: PreferencesHelper = Injekt.get()
|
|
||||||
protected val customMangaManager: CustomMangaManager = Injekt.get()
|
|
||||||
|
|
||||||
abstract fun createBackup(uri: Uri, flags: Int, isAutoBackup: Boolean): String?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns manga
|
|
||||||
*
|
|
||||||
* @return [Manga], null if not found
|
|
||||||
*/
|
|
||||||
internal fun getMangaFromDatabase(manga: Manga): Manga? =
|
|
||||||
db.getManga(manga.url, manga.source).executeAsBlocking()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches chapter information.
|
|
||||||
*
|
|
||||||
* @param source source of manga
|
|
||||||
* @param manga manga that needs updating
|
|
||||||
* @param chapters list of chapters in the backup
|
|
||||||
* @return Updated manga chapters.
|
|
||||||
*/
|
|
||||||
internal suspend fun restoreChapters(source: Source, manga: Manga, chapters: List<Chapter>): Pair<List<Chapter>, List<Chapter>> {
|
|
||||||
val fetchedChapters = source.getChapterList(manga)
|
|
||||||
val syncedChapters = syncChaptersWithSource(db, fetchedChapters, manga, source)
|
|
||||||
if (syncedChapters.first.isNotEmpty()) {
|
|
||||||
chapters.forEach { it.manga_id = manga.id }
|
|
||||||
updateChapters(chapters)
|
|
||||||
}
|
|
||||||
return syncedChapters
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns list containing manga from library
|
|
||||||
*
|
|
||||||
* @return [Manga] from library
|
|
||||||
*/
|
|
||||||
protected fun getFavoriteManga(): List<Manga> =
|
|
||||||
db.getFavoriteMangas().executeAsBlocking()
|
|
||||||
|
|
||||||
protected fun getReadManga(): List<Manga> =
|
|
||||||
db.getReadNotInLibraryMangas().executeAsBlocking()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inserts manga and returns id
|
|
||||||
*
|
|
||||||
* @return id of [Manga], null if not found
|
|
||||||
*/
|
|
||||||
internal fun insertManga(manga: Manga): Long? =
|
|
||||||
db.insertManga(manga).executeAsBlocking().insertedId()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inserts list of chapters
|
|
||||||
*/
|
|
||||||
protected fun insertChapters(chapters: List<Chapter>) {
|
|
||||||
db.insertChapters(chapters).executeAsBlocking()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a list of chapters
|
|
||||||
*/
|
|
||||||
protected fun updateChapters(chapters: List<Chapter>) {
|
|
||||||
db.updateChaptersBackup(chapters).executeAsBlocking()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a list of chapters with known database ids
|
|
||||||
*/
|
|
||||||
protected fun updateKnownChapters(chapters: List<Chapter>) {
|
|
||||||
db.updateKnownChaptersBackup(chapters).executeAsBlocking()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return number of backups.
|
|
||||||
*
|
|
||||||
* @return number of backups selected by user
|
|
||||||
*/
|
|
||||||
protected fun numberOfBackups(): Int = preferences.numberOfBackups().get()
|
|
||||||
}
|
|
|
@ -1,137 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.data.backup
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.net.Uri
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
|
||||||
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.data.library.CustomMangaManager
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
|
||||||
import eu.kanade.tachiyomi.source.Source
|
|
||||||
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
|
|
||||||
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import java.io.File
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val context: Context, protected val notifier: BackupNotifier) {
|
|
||||||
|
|
||||||
protected val db: DatabaseHelper by injectLazy()
|
|
||||||
protected val trackManager: TrackManager by injectLazy()
|
|
||||||
protected val customMangaManager: CustomMangaManager by injectLazy()
|
|
||||||
|
|
||||||
protected lateinit var backupManager: T
|
|
||||||
|
|
||||||
protected var restoreAmount = 0
|
|
||||||
protected var restoreProgress = 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mapping of source ID to source name from backup data
|
|
||||||
*/
|
|
||||||
protected var sourceMapping: Map<Long, String> = emptyMap()
|
|
||||||
|
|
||||||
protected val errors = mutableListOf<Pair<Date, String>>()
|
|
||||||
|
|
||||||
abstract suspend fun performRestore(uri: Uri): Boolean
|
|
||||||
|
|
||||||
suspend fun restoreBackup(uri: Uri): Boolean {
|
|
||||||
val startTime = System.currentTimeMillis()
|
|
||||||
restoreProgress = 0
|
|
||||||
errors.clear()
|
|
||||||
|
|
||||||
if (!performRestore(uri)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val endTime = System.currentTimeMillis()
|
|
||||||
val time = endTime - startTime
|
|
||||||
|
|
||||||
val logFile = writeErrorLog()
|
|
||||||
|
|
||||||
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches chapter information.
|
|
||||||
*
|
|
||||||
* @param source source of manga
|
|
||||||
* @param manga manga that needs updating
|
|
||||||
* @return Updated manga chapters.
|
|
||||||
*/
|
|
||||||
internal suspend fun updateChapters(source: Source, manga: Manga, chapters: List<Chapter>): Pair<List<Chapter>, List<Chapter>> {
|
|
||||||
return try {
|
|
||||||
backupManager.restoreChapters(source, manga, chapters)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
// If there's any error, return empty update and continue.
|
|
||||||
val errorMessage = if (e is NoChaptersException) {
|
|
||||||
context.getString(R.string.no_chapters_error)
|
|
||||||
} else {
|
|
||||||
e.message
|
|
||||||
}
|
|
||||||
errors.add(Date() to "${manga.title} - $errorMessage")
|
|
||||||
Pair(emptyList(), emptyList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refreshes tracking information.
|
|
||||||
*
|
|
||||||
* @param manga manga that needs updating.
|
|
||||||
* @param tracks list containing tracks from restore file.
|
|
||||||
*/
|
|
||||||
internal suspend fun updateTracking(manga: Manga, tracks: List<Track>) {
|
|
||||||
tracks.forEach { track ->
|
|
||||||
val service = trackManager.getService(track.sync_id)
|
|
||||||
if (service != null && service.isLogged) {
|
|
||||||
try {
|
|
||||||
val updatedTrack = service.refresh(track)
|
|
||||||
db.insertTrack(updatedTrack).executeAsBlocking()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
errors.add(Date() to "${manga.title} - ${e.message}")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val serviceName = service?.nameRes()?.let { context.getString(it) }
|
|
||||||
errors.add(Date() to "${manga.title} - ${context.getString(R.string.not_logged_into_, serviceName)}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to update dialog in [BackupConst]
|
|
||||||
*
|
|
||||||
* @param progress restore progress
|
|
||||||
* @param amount total restoreAmount of manga
|
|
||||||
* @param title title of restored manga
|
|
||||||
*/
|
|
||||||
internal fun showRestoreProgress(
|
|
||||||
progress: Int,
|
|
||||||
amount: Int,
|
|
||||||
title: String,
|
|
||||||
) {
|
|
||||||
notifier.showRestoreProgress(title, progress, amount)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun writeErrorLog(): File {
|
|
||||||
try {
|
|
||||||
if (errors.isNotEmpty()) {
|
|
||||||
val file = context.createFileInCacheDir("tachiyomi_restore.txt")
|
|
||||||
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
|
|
||||||
|
|
||||||
file.bufferedWriter().use { out ->
|
|
||||||
errors.forEach { (date, message) ->
|
|
||||||
out.write("[${sdf.format(date)}] $message\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
return File("")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,14 +36,19 @@ import eu.kanade.tachiyomi.data.backup.models.IntPreferenceValue
|
||||||
import eu.kanade.tachiyomi.data.backup.models.LongPreferenceValue
|
import eu.kanade.tachiyomi.data.backup.models.LongPreferenceValue
|
||||||
import eu.kanade.tachiyomi.data.backup.models.StringPreferenceValue
|
import eu.kanade.tachiyomi.data.backup.models.StringPreferenceValue
|
||||||
import eu.kanade.tachiyomi.data.backup.models.StringSetPreferenceValue
|
import eu.kanade.tachiyomi.data.backup.models.StringSetPreferenceValue
|
||||||
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.History
|
import eu.kanade.tachiyomi.data.database.models.History
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.library.CustomMangaManager
|
||||||
import eu.kanade.tachiyomi.data.preference.Preference
|
import eu.kanade.tachiyomi.data.preference.Preference
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceStore
|
import eu.kanade.tachiyomi.data.preference.PreferenceStore
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.preferenceKey
|
import eu.kanade.tachiyomi.source.preferenceKey
|
||||||
import eu.kanade.tachiyomi.source.sourcePreferences
|
import eu.kanade.tachiyomi.source.sourcePreferences
|
||||||
|
@ -57,10 +62,15 @@ import uy.kohesive.injekt.api.get
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
class BackupManager(context: Context) : AbstractBackupManager(context) {
|
class BackupManager(val context: Context) {
|
||||||
|
|
||||||
private val preferenceStore: PreferenceStore = Injekt.get()
|
private val preferenceStore: PreferenceStore = Injekt.get()
|
||||||
val parser = ProtoBuf
|
val parser = ProtoBuf
|
||||||
|
private val db: DatabaseHelper = Injekt.get()
|
||||||
|
private val sourceManager: SourceManager = Injekt.get()
|
||||||
|
private val trackManager: TrackManager = Injekt.get()
|
||||||
|
private val preferences: PreferencesHelper = Injekt.get()
|
||||||
|
private val customMangaManager: CustomMangaManager = Injekt.get()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create backup Json file from database
|
* Create backup Json file from database
|
||||||
|
@ -68,16 +78,17 @@ class BackupManager(context: Context) : AbstractBackupManager(context) {
|
||||||
* @param uri path of Uri
|
* @param uri path of Uri
|
||||||
* @param isAutoBackup backup called from scheduled backup job
|
* @param isAutoBackup backup called from scheduled backup job
|
||||||
*/
|
*/
|
||||||
override fun createBackup(uri: Uri, flags: Int, isAutoBackup: Boolean): String {
|
fun createBackup(uri: Uri, flags: Int, isAutoBackup: Boolean): String {
|
||||||
// Create root object
|
// Create root object
|
||||||
var backup: Backup? = null
|
var backup: Backup? = null
|
||||||
|
|
||||||
db.inTransaction {
|
db.inTransaction {
|
||||||
val databaseManga = getFavoriteManga() + if (flags and BACKUP_READ_MANGA_MASK == BACKUP_READ_MANGA) {
|
val databaseManga = db.getFavoriteMangas().executeAsBlocking() +
|
||||||
getReadManga()
|
if (flags and BACKUP_READ_MANGA_MASK == BACKUP_READ_MANGA) {
|
||||||
} else {
|
db.getReadNotInLibraryMangas().executeAsBlocking()
|
||||||
emptyList()
|
} else {
|
||||||
}
|
emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
backup = Backup(
|
backup = Backup(
|
||||||
backupMangas(databaseManga, flags),
|
backupMangas(databaseManga, flags),
|
||||||
|
@ -98,7 +109,7 @@ class BackupManager(context: Context) : AbstractBackupManager(context) {
|
||||||
dir = dir.createDirectory("automatic")
|
dir = dir.createDirectory("automatic")
|
||||||
|
|
||||||
// Delete older backups
|
// Delete older backups
|
||||||
val numberOfBackups = numberOfBackups()
|
val numberOfBackups = preferences.numberOfBackups().get()
|
||||||
dir.listFiles { _, filename -> Backup.filenameRegex.matches(filename) }
|
dir.listFiles { _, filename -> Backup.filenameRegex.matches(filename) }
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
.sortedByDescending { it.name }
|
.sortedByDescending { it.name }
|
||||||
|
@ -258,7 +269,7 @@ class BackupManager(context: Context) : AbstractBackupManager(context) {
|
||||||
fun restoreExistingManga(manga: Manga, dbManga: Manga) {
|
fun restoreExistingManga(manga: Manga, dbManga: Manga) {
|
||||||
manga.id = dbManga.id
|
manga.id = dbManga.id
|
||||||
manga.copyFrom(dbManga)
|
manga.copyFrom(dbManga)
|
||||||
insertManga(manga)
|
db.insertManga(manga).executeAsBlocking()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -270,7 +281,7 @@ class BackupManager(context: Context) : AbstractBackupManager(context) {
|
||||||
fun restoreNewManga(manga: Manga): Manga {
|
fun restoreNewManga(manga: Manga): Manga {
|
||||||
return manga.also {
|
return manga.also {
|
||||||
it.initialized = it.description != null
|
it.initialized = it.description != null
|
||||||
it.id = insertManga(it)
|
it.id = db.insertManga(it).executeAsBlocking().insertedId()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,7 +443,7 @@ class BackupManager(context: Context) : AbstractBackupManager(context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
val newChapters = chapters.groupBy { it.id != null }
|
val newChapters = chapters.groupBy { it.id != null }
|
||||||
newChapters[true]?.let { updateKnownChapters(it) }
|
newChapters[true]?.let { db.updateKnownChaptersBackup(it).executeAsBlocking() }
|
||||||
newChapters[false]?.let { insertChapters(it) }
|
newChapters[false]?.let { db.insertChapters(it).executeAsBlocking() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.data.backup.models.IntPreferenceValue
|
||||||
import eu.kanade.tachiyomi.data.backup.models.LongPreferenceValue
|
import eu.kanade.tachiyomi.data.backup.models.LongPreferenceValue
|
||||||
import eu.kanade.tachiyomi.data.backup.models.StringPreferenceValue
|
import eu.kanade.tachiyomi.data.backup.models.StringPreferenceValue
|
||||||
import eu.kanade.tachiyomi.data.backup.models.StringSetPreferenceValue
|
import eu.kanade.tachiyomi.data.backup.models.StringSetPreferenceValue
|
||||||
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
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
|
||||||
|
@ -25,6 +26,7 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||||
import eu.kanade.tachiyomi.data.preference.AndroidPreferenceStore
|
import eu.kanade.tachiyomi.data.preference.AndroidPreferenceStore
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceStore
|
import eu.kanade.tachiyomi.data.preference.PreferenceStore
|
||||||
import eu.kanade.tachiyomi.source.sourcePreferences
|
import eu.kanade.tachiyomi.source.sourcePreferences
|
||||||
|
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
|
@ -32,14 +34,49 @@ import okio.gzip
|
||||||
import okio.source
|
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
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import java.io.File
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class BackupRestorer(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<BackupManager>(context, notifier) {
|
class BackupRestorer(val context: Context, val notifier: BackupNotifier) {
|
||||||
|
|
||||||
|
private lateinit var backupManager: BackupManager
|
||||||
|
private val db: DatabaseHelper by injectLazy()
|
||||||
|
private val customMangaManager: CustomMangaManager by injectLazy()
|
||||||
private val preferenceStore: PreferenceStore = Injekt.get()
|
private val preferenceStore: PreferenceStore = Injekt.get()
|
||||||
|
|
||||||
|
private var restoreAmount = 0
|
||||||
|
private var restoreProgress = 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping of source ID to source name from backup data
|
||||||
|
*/
|
||||||
|
private var sourceMapping: Map<Long, String> = emptyMap()
|
||||||
|
|
||||||
|
private val errors = mutableListOf<Pair<Date, String>>()
|
||||||
|
|
||||||
|
suspend fun restoreBackup(uri: Uri): Boolean {
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
restoreProgress = 0
|
||||||
|
errors.clear()
|
||||||
|
|
||||||
|
if (!performRestore(uri)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val endTime = System.currentTimeMillis()
|
||||||
|
val time = endTime - startTime
|
||||||
|
|
||||||
|
val logFile = writeErrorLog()
|
||||||
|
|
||||||
|
notifier.showRestoreComplete(time, errors.size, logFile.parent, logFile.name)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("Recycle")
|
@SuppressLint("Recycle")
|
||||||
override suspend fun performRestore(uri: Uri): Boolean {
|
suspend fun performRestore(uri: Uri): Boolean {
|
||||||
backupManager = BackupManager(context)
|
backupManager = BackupManager(context)
|
||||||
|
|
||||||
val stream = context.contentResolver.openInputStream(uri)
|
val stream = context.contentResolver.openInputStream(uri)
|
||||||
|
@ -93,7 +130,7 @@ class BackupRestorer(context: Context, notifier: BackupNotifier) : AbstractBacku
|
||||||
val customManga = backupManga.getCustomMangaInfo()
|
val customManga = backupManga.getCustomMangaInfo()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val dbManga = backupManager.getMangaFromDatabase(manga)
|
val dbManga = db.getManga(manga.url, manga.source).executeAsBlocking()
|
||||||
if (dbManga == null) {
|
if (dbManga == null) {
|
||||||
// Manga not in database
|
// Manga not in database
|
||||||
restoreExistingManga(manga, chapters, categories, history, tracks, backupCategories, customManga)
|
restoreExistingManga(manga, chapters, categories, history, tracks, backupCategories, customManga)
|
||||||
|
@ -216,4 +253,38 @@ class BackupRestorer(context: Context, notifier: BackupNotifier) : AbstractBacku
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to update dialog in [BackupConst]
|
||||||
|
*
|
||||||
|
* @param progress restore progress
|
||||||
|
* @param amount total restoreAmount of manga
|
||||||
|
* @param title title of restored manga
|
||||||
|
*/
|
||||||
|
private fun showRestoreProgress(
|
||||||
|
progress: Int,
|
||||||
|
amount: Int,
|
||||||
|
title: String,
|
||||||
|
) {
|
||||||
|
notifier.showRestoreProgress(title, progress, amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun writeErrorLog(): File {
|
||||||
|
try {
|
||||||
|
if (errors.isNotEmpty()) {
|
||||||
|
val file = context.createFileInCacheDir("tachiyomi_restore.txt")
|
||||||
|
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
|
||||||
|
|
||||||
|
file.bufferedWriter().use { out ->
|
||||||
|
errors.forEach { (date, message) ->
|
||||||
|
out.write("[${sdf.format(date)}] $message\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
return File("")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue