Some more code cleanup
This commit is contained in:
parent
eed6db8e92
commit
cf6c48744a
7 changed files with 115 additions and 190 deletions
|
@ -7,10 +7,14 @@ 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.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
abstract class AbstractBackupManager(protected val context: Context) {
|
abstract class AbstractBackupManager(protected val context: Context) {
|
||||||
|
|
||||||
internal val databaseHelper: DatabaseHelper by injectLazy()
|
internal val databaseHelper: DatabaseHelper by injectLazy()
|
||||||
internal val sourceManager: SourceManager by injectLazy()
|
internal val sourceManager: SourceManager by injectLazy()
|
||||||
internal val trackManager: TrackManager by injectLazy()
|
internal val trackManager: TrackManager by injectLazy()
|
||||||
|
@ -26,6 +30,25 @@ abstract class AbstractBackupManager(protected val context: Context) {
|
||||||
internal fun getMangaFromDatabase(manga: Manga): Manga? =
|
internal fun getMangaFromDatabase(manga: Manga): Manga? =
|
||||||
databaseHelper.getManga(manga.url, manga.source).executeAsBlocking()
|
databaseHelper.getManga(manga.url, manga.source).executeAsBlocking()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Observable] that fetches chapter information
|
||||||
|
*
|
||||||
|
* @param source source of manga
|
||||||
|
* @param manga manga that needs updating
|
||||||
|
* @param chapters list of chapters in the backup
|
||||||
|
* @return [Observable] that contains manga
|
||||||
|
*/
|
||||||
|
internal fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
||||||
|
return source.fetchChapterList(manga)
|
||||||
|
.map { syncChaptersWithSource(databaseHelper, it, manga, source) }
|
||||||
|
.doOnNext { pair ->
|
||||||
|
if (pair.first.isNotEmpty()) {
|
||||||
|
chapters.forEach { it.manga_id = manga.id }
|
||||||
|
updateChapters(chapters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns list containing manga from library
|
* Returns list containing manga from library
|
||||||
*
|
*
|
||||||
|
|
|
@ -2,20 +2,29 @@ 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.data.database.DatabaseHelper
|
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.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
abstract class AbstractBackupRestore(protected val context: Context, protected val notifier: BackupNotifier) {
|
abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val context: Context, protected val notifier: BackupNotifier) {
|
||||||
protected val db: DatabaseHelper by injectLazy()
|
|
||||||
|
|
||||||
|
protected val db: DatabaseHelper by injectLazy()
|
||||||
protected val trackManager: TrackManager by injectLazy()
|
protected val trackManager: TrackManager by injectLazy()
|
||||||
|
|
||||||
|
protected lateinit var backupManager: T
|
||||||
|
|
||||||
var job: Job? = null
|
var job: Job? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +52,7 @@ abstract class AbstractBackupRestore(protected val context: Context, protected v
|
||||||
/**
|
/**
|
||||||
* Write errors to error log
|
* Write errors to error log
|
||||||
*/
|
*/
|
||||||
fun writeErrorLog(): File {
|
internal fun writeErrorLog(): File {
|
||||||
try {
|
try {
|
||||||
if (errors.isNotEmpty()) {
|
if (errors.isNotEmpty()) {
|
||||||
val destFile = File(context.externalCacheDir, "tachiyomi_restore.txt")
|
val destFile = File(context.externalCacheDir, "tachiyomi_restore.txt")
|
||||||
|
@ -61,4 +70,64 @@ abstract class AbstractBackupRestore(protected val context: Context, protected v
|
||||||
}
|
}
|
||||||
return File("")
|
return File("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Observable] that fetches chapter information
|
||||||
|
*
|
||||||
|
* @param source source of manga
|
||||||
|
* @param manga manga that needs updating
|
||||||
|
* @return [Observable] that contains manga
|
||||||
|
*/
|
||||||
|
internal fun chapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
||||||
|
return backupManager.restoreChapterFetchObservable(source, manga, chapters)
|
||||||
|
// If there's any error, return empty update and continue.
|
||||||
|
.onErrorReturn {
|
||||||
|
val errorMessage = if (it is NoChaptersException) {
|
||||||
|
context.getString(R.string.no_chapters_error)
|
||||||
|
} else {
|
||||||
|
it.message
|
||||||
|
}
|
||||||
|
errors.add(Date() to "${manga.title} - $errorMessage")
|
||||||
|
Pair(emptyList(), emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Observable] that refreshes tracking information
|
||||||
|
* @param manga manga that needs updating.
|
||||||
|
* @param tracks list containing tracks from restore file.
|
||||||
|
* @return [Observable] that contains updated track item
|
||||||
|
*/
|
||||||
|
internal fun trackingFetchObservable(manga: Manga, tracks: List<Track>): Observable<Track> {
|
||||||
|
return Observable.from(tracks)
|
||||||
|
.flatMap { track ->
|
||||||
|
val service = trackManager.getService(track.sync_id)
|
||||||
|
if (service != null && service.isLogged) {
|
||||||
|
service.refresh(track)
|
||||||
|
.doOnNext { db.insertTrack(it).executeAsBlocking() }
|
||||||
|
.onErrorReturn {
|
||||||
|
errors.add(Date() to "${manga.title} - ${it.message}")
|
||||||
|
track
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errors.add(Date() to "${manga.title} - ${context.getString(R.string.tracker_not_logged_in, service?.name)}")
|
||||||
|
Observable.empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ class BackupRestoreService : Service() {
|
||||||
*/
|
*/
|
||||||
private lateinit var wakeLock: PowerManager.WakeLock
|
private lateinit var wakeLock: PowerManager.WakeLock
|
||||||
|
|
||||||
private var backupRestore: AbstractBackupRestore? = null
|
private var backupRestore: AbstractBackupRestore<*>? = null
|
||||||
private lateinit var notifier: BackupNotifier
|
private lateinit var notifier: BackupNotifier
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
|
|
|
@ -27,7 +27,6 @@ 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.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.protobuf.ProtoBuf
|
import kotlinx.serialization.protobuf.ProtoBuf
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
|
@ -209,25 +208,6 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* [Observable] that fetches chapter information
|
|
||||||
*
|
|
||||||
* @param source source of manga
|
|
||||||
* @param manga manga that needs updating
|
|
||||||
* @param chapters list of chapters in the backup
|
|
||||||
* @return [Observable] that contains manga
|
|
||||||
*/
|
|
||||||
fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
|
||||||
return source.fetchChapterList(manga)
|
|
||||||
.map { syncChaptersWithSource(databaseHelper, it, manga, source) }
|
|
||||||
.doOnNext { pair ->
|
|
||||||
if (pair.first.isNotEmpty()) {
|
|
||||||
chapters.forEach { it.manga_id = manga.id }
|
|
||||||
updateChapters(chapters)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore the categories from Json
|
* Restore the categories from Json
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,7 +13,6 @@ 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.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
|
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.gzip
|
import okio.gzip
|
||||||
|
@ -22,8 +21,7 @@ import rx.Observable
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore(context, notifier) {
|
class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore<FullBackupManager>(context, notifier) {
|
||||||
private lateinit var fullBackupManager: FullBackupManager
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores data from backup file.
|
* Restores data from backup file.
|
||||||
|
@ -34,10 +32,10 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
|
|
||||||
// Initialize manager
|
// Initialize manager
|
||||||
fullBackupManager = FullBackupManager(context)
|
backupManager = FullBackupManager(context)
|
||||||
|
|
||||||
val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() }
|
val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() }
|
||||||
val backup = fullBackupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString)
|
||||||
|
|
||||||
restoreAmount = backup.backupManga.size + 1 // +1 for categories
|
restoreAmount = backup.backupManga.size + 1 // +1 for categories
|
||||||
restoreProgress = 0
|
restoreProgress = 0
|
||||||
|
@ -71,7 +69,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
|
|
||||||
private fun restoreCategories(backupCategories: List<BackupCategory>) {
|
private fun restoreCategories(backupCategories: List<BackupCategory>) {
|
||||||
db.inTransaction {
|
db.inTransaction {
|
||||||
fullBackupManager.restoreCategories(backupCategories)
|
backupManager.restoreCategories(backupCategories)
|
||||||
}
|
}
|
||||||
|
|
||||||
restoreProgress += 1
|
restoreProgress += 1
|
||||||
|
@ -86,7 +84,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
val tracks = backupManga.getTrackingImpl()
|
val tracks = backupManga.getTrackingImpl()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val source = fullBackupManager.sourceManager.get(manga.source)
|
val source = backupManager.sourceManager.get(manga.source)
|
||||||
if (source != null || !online) {
|
if (source != null || !online) {
|
||||||
restoreMangaData(manga, source, chapters, categories, history, tracks, backupCategories, online)
|
restoreMangaData(manga, source, chapters, categories, history, tracks, backupCategories, online)
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,7 +119,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
backupCategories: List<BackupCategory>,
|
backupCategories: List<BackupCategory>,
|
||||||
online: Boolean
|
online: Boolean
|
||||||
) {
|
) {
|
||||||
val dbManga = fullBackupManager.getMangaFromDatabase(manga)
|
val dbManga = backupManager.getMangaFromDatabase(manga)
|
||||||
|
|
||||||
db.inTransaction {
|
db.inTransaction {
|
||||||
if (dbManga == null) {
|
if (dbManga == null) {
|
||||||
|
@ -129,7 +127,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
restoreMangaFetch(source, manga, chapters, categories, history, tracks, backupCategories, online)
|
restoreMangaFetch(source, manga, chapters, categories, history, tracks, backupCategories, online)
|
||||||
} else { // Manga in database
|
} else { // Manga in database
|
||||||
// Copy information from manga already in database
|
// Copy information from manga already in database
|
||||||
fullBackupManager.restoreMangaNoFetch(manga, dbManga)
|
backupManager.restoreMangaNoFetch(manga, dbManga)
|
||||||
// Fetch rest of manga information
|
// Fetch rest of manga information
|
||||||
restoreMangaNoFetch(source, manga, chapters, categories, history, tracks, backupCategories, online)
|
restoreMangaNoFetch(source, manga, chapters, categories, history, tracks, backupCategories, online)
|
||||||
}
|
}
|
||||||
|
@ -153,7 +151,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
backupCategories: List<BackupCategory>,
|
backupCategories: List<BackupCategory>,
|
||||||
online: Boolean
|
online: Boolean
|
||||||
) {
|
) {
|
||||||
fullBackupManager.restoreMangaFetchObservable(source, manga, online)
|
backupManager.restoreMangaFetchObservable(source, manga, online)
|
||||||
.doOnError {
|
.doOnError {
|
||||||
errors.add(Date() to "${manga.title} - ${it.message}")
|
errors.add(Date() to "${manga.title} - ${it.message}")
|
||||||
}
|
}
|
||||||
|
@ -164,7 +162,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
// Convert to the manga that contains new chapters.
|
// Convert to the manga that contains new chapters.
|
||||||
.map { manga }
|
.map { manga }
|
||||||
} else {
|
} else {
|
||||||
fullBackupManager.restoreChaptersForMangaOffline(it, chapters)
|
backupManager.restoreChaptersForMangaOffline(it, chapters)
|
||||||
Observable.just(manga)
|
Observable.just(manga)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,14 +188,14 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
Observable.just(backupManga)
|
Observable.just(backupManga)
|
||||||
.flatMap { manga ->
|
.flatMap { manga ->
|
||||||
if (online && source != null) {
|
if (online && source != null) {
|
||||||
if (!fullBackupManager.restoreChaptersForManga(manga, chapters)) {
|
if (!backupManager.restoreChaptersForManga(manga, chapters)) {
|
||||||
chapterFetchObservable(source, manga, chapters)
|
chapterFetchObservable(source, manga, chapters)
|
||||||
.map { manga }
|
.map { manga }
|
||||||
} else {
|
} else {
|
||||||
Observable.just(manga)
|
Observable.just(manga)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fullBackupManager.restoreChaptersForMangaOffline(manga, chapters)
|
backupManager.restoreChaptersForMangaOffline(manga, chapters)
|
||||||
Observable.just(manga)
|
Observable.just(manga)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,72 +210,12 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
|
||||||
|
|
||||||
private fun restoreExtraForManga(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>) {
|
private fun restoreExtraForManga(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>) {
|
||||||
// Restore categories
|
// Restore categories
|
||||||
fullBackupManager.restoreCategoriesForManga(manga, categories, backupCategories)
|
backupManager.restoreCategoriesForManga(manga, categories, backupCategories)
|
||||||
|
|
||||||
// Restore history
|
// Restore history
|
||||||
fullBackupManager.restoreHistoryForManga(history)
|
backupManager.restoreHistoryForManga(history)
|
||||||
|
|
||||||
// Restore tracking
|
// Restore tracking
|
||||||
fullBackupManager.restoreTrackForManga(manga, tracks)
|
backupManager.restoreTrackForManga(manga, tracks)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [Observable] that fetches chapter information
|
|
||||||
*
|
|
||||||
* @param source source of manga
|
|
||||||
* @param manga manga that needs updating
|
|
||||||
* @return [Observable] that contains manga
|
|
||||||
*/
|
|
||||||
private fun chapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
|
||||||
return fullBackupManager.restoreChapterFetchObservable(source, manga, chapters)
|
|
||||||
// If there's any error, return empty update and continue.
|
|
||||||
.onErrorReturn {
|
|
||||||
val errorMessage = if (it is NoChaptersException) {
|
|
||||||
context.getString(R.string.no_chapters_error)
|
|
||||||
} else {
|
|
||||||
it.message
|
|
||||||
}
|
|
||||||
errors.add(Date() to "${manga.title} - $errorMessage")
|
|
||||||
Pair(emptyList(), emptyList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [Observable] that refreshes tracking information
|
|
||||||
* @param manga manga that needs updating.
|
|
||||||
* @param tracks list containing tracks from restore file.
|
|
||||||
* @return [Observable] that contains updated track item
|
|
||||||
*/
|
|
||||||
private fun trackingFetchObservable(manga: Manga, tracks: List<Track>): Observable<Track> {
|
|
||||||
return Observable.from(tracks)
|
|
||||||
.flatMap { track ->
|
|
||||||
val service = trackManager.getService(track.sync_id)
|
|
||||||
if (service != null && service.isLogged) {
|
|
||||||
service.refresh(track)
|
|
||||||
.doOnNext { db.insertTrack(it).executeAsBlocking() }
|
|
||||||
.onErrorReturn {
|
|
||||||
errors.add(Date() to "${manga.title} - ${it.message}")
|
|
||||||
track
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errors.add(Date() to "${manga.title} - ${context.getString(R.string.tracker_not_logged_in, service?.name)}")
|
|
||||||
Observable.empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,16 +46,13 @@ import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.database.models.TrackImpl
|
import eu.kanade.tachiyomi.data.database.models.TrackImpl
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : AbstractBackupManager(context) {
|
class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : AbstractBackupManager(context) {
|
||||||
/**
|
|
||||||
* Version of parser
|
var parserVersion: Int = version
|
||||||
*/
|
|
||||||
var version: Int = version
|
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var parser: Gson = initParser()
|
var parser: Gson = initParser()
|
||||||
|
@ -66,11 +63,11 @@ class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : Ab
|
||||||
* @param version version of parser
|
* @param version version of parser
|
||||||
*/
|
*/
|
||||||
internal fun setVersion(version: Int) {
|
internal fun setVersion(version: Int) {
|
||||||
this.version = version
|
this.parserVersion = version
|
||||||
parser = initParser()
|
parser = initParser()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initParser(): Gson = when (version) {
|
private fun initParser(): Gson = when (parserVersion) {
|
||||||
2 ->
|
2 ->
|
||||||
GsonBuilder()
|
GsonBuilder()
|
||||||
.registerTypeAdapter<MangaImpl>(MangaTypeAdapter.build())
|
.registerTypeAdapter<MangaImpl>(MangaTypeAdapter.build())
|
||||||
|
@ -269,24 +266,6 @@ class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : Ab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* [Observable] that fetches chapter information
|
|
||||||
*
|
|
||||||
* @param source source of manga
|
|
||||||
* @param manga manga that needs updating
|
|
||||||
* @return [Observable] that contains manga
|
|
||||||
*/
|
|
||||||
fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
|
||||||
return source.fetchChapterList(manga)
|
|
||||||
.map { syncChaptersWithSource(databaseHelper, it, manga, source) }
|
|
||||||
.doOnNext { pair ->
|
|
||||||
if (pair.first.isNotEmpty()) {
|
|
||||||
chapters.forEach { it.manga_id = manga.id }
|
|
||||||
updateChapters(chapters)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore the categories from Json
|
* Restore the categories from Json
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,6 @@ import com.google.gson.JsonParser
|
||||||
import com.google.gson.stream.JsonReader
|
import com.google.gson.stream.JsonReader
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.backup.AbstractBackupRestore
|
import eu.kanade.tachiyomi.data.backup.AbstractBackupRestore
|
||||||
import eu.kanade.tachiyomi.data.backup.BackupConst
|
|
||||||
import eu.kanade.tachiyomi.data.backup.BackupNotifier
|
import eu.kanade.tachiyomi.data.backup.BackupNotifier
|
||||||
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup
|
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup
|
||||||
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.MANGAS
|
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup.MANGAS
|
||||||
|
@ -22,13 +21,10 @@ import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.database.models.TrackImpl
|
import eu.kanade.tachiyomi.data.database.models.TrackImpl
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore(context, notifier) {
|
class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<LegacyBackupManager>(context, notifier) {
|
||||||
|
|
||||||
private lateinit var backupManager: LegacyBackupManager
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores data from backup file.
|
* Restores data from backup file.
|
||||||
|
@ -229,64 +225,4 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
|
||||||
// Restore tracking
|
// Restore tracking
|
||||||
backupManager.restoreTrackForManga(manga, tracks)
|
backupManager.restoreTrackForManga(manga, tracks)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* [Observable] that fetches chapter information
|
|
||||||
*
|
|
||||||
* @param source source of manga
|
|
||||||
* @param manga manga that needs updating
|
|
||||||
* @return [Observable] that contains manga
|
|
||||||
*/
|
|
||||||
private fun chapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
|
||||||
return backupManager.restoreChapterFetchObservable(source, manga, chapters)
|
|
||||||
// If there's any error, return empty update and continue.
|
|
||||||
.onErrorReturn {
|
|
||||||
val errorMessage = if (it is NoChaptersException) {
|
|
||||||
context.getString(R.string.no_chapters_error)
|
|
||||||
} else {
|
|
||||||
it.message
|
|
||||||
}
|
|
||||||
errors.add(Date() to "${manga.title} - $errorMessage")
|
|
||||||
Pair(emptyList(), emptyList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [Observable] that refreshes tracking information
|
|
||||||
* @param manga manga that needs updating.
|
|
||||||
* @param tracks list containing tracks from restore file.
|
|
||||||
* @return [Observable] that contains updated track item
|
|
||||||
*/
|
|
||||||
private fun trackingFetchObservable(manga: Manga, tracks: List<Track>): Observable<Track> {
|
|
||||||
return Observable.from(tracks)
|
|
||||||
.flatMap { track ->
|
|
||||||
val service = trackManager.getService(track.sync_id)
|
|
||||||
if (service != null && service.isLogged) {
|
|
||||||
service.refresh(track)
|
|
||||||
.doOnNext { db.insertTrack(it).executeAsBlocking() }
|
|
||||||
.onErrorReturn {
|
|
||||||
errors.add(Date() to "${manga.title} - ${it.message}")
|
|
||||||
track
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errors.add(Date() to "${manga.title} - ${context.getString(R.string.tracker_not_logged_in, service?.name)}")
|
|
||||||
Observable.empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue