Some more code cleanup

(cherry picked from commit cf6c48744a3217b39d7980c2c283a01d3f2a0473)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt
This commit is contained in:
arkon 2020-11-21 15:30:04 -05:00 committed by Jobobby04
parent 692e7e17d8
commit 383a797469
7 changed files with 132 additions and 205 deletions

View File

@ -7,10 +7,16 @@ 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.source.online.all.EHentai
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
import exh.eh.EHentaiThrottleManager
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 +32,32 @@ 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 open fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>, throttleManager: EHentaiThrottleManager): Observable<Pair<List<Chapter>, List<Chapter>>> {
return (
if (source is EHentai) {
source.fetchChapterList(manga, throttleManager::throttle)
} else {
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
* *

View File

@ -2,21 +2,30 @@ 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 exh.eh.EHentaiThrottleManager import exh.eh.EHentaiThrottleManager
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
// SY --> // SY -->
@ -48,7 +57,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")
@ -66,4 +75,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 /* SY --> */, throttleManager /* SY <-- */)
// 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)
}
} }

View File

@ -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() {

View File

@ -31,11 +31,8 @@ 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.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
import exh.MERGED_SOURCE_ID import exh.MERGED_SOURCE_ID
import exh.eh.EHentaiThrottleManager
import exh.metadata.metadata.base.getFlatMetadataForManga import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadata import exh.metadata.metadata.base.insertFlatMetadata
import exh.savedsearches.JsonSavedSearch import exh.savedsearches.JsonSavedSearch
@ -264,35 +261,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
* @param throttleManager e-hentai throttle so it doesnt get banned
* @return [Observable] that contains manga
*/
fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter> /* SY --> */, throttleManager: EHentaiThrottleManager /* SY <-- */): Observable<Pair<List<Chapter>, List<Chapter>>> {
// SY -->
return (
if (source is EHentai) {
source.fetchChapterList(manga, throttleManager::throttle)
} else {
source.fetchChapterList(manga)
}
).map {
syncChaptersWithSource(databaseHelper, it, manga, source)
}
// SY <--
.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
* *

View File

@ -17,7 +17,6 @@ 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.source.online.all.MergedSource import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
import exh.EXHMigrations import exh.EXHMigrations
import exh.MERGED_SOURCE_ID import exh.MERGED_SOURCE_ID
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
@ -28,8 +27,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.
@ -43,10 +41,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 /* SY --> */ + 1 /* SY <-- */ // +1 for categories, +1 for saved searches restoreAmount = backup.backupManga.size + 1 /* SY --> */ + 1 /* SY <-- */ // +1 for categories, +1 for saved searches
restoreProgress = 0 restoreProgress = 0
@ -86,7 +84,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
@ -95,7 +93,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
// SY --> // SY -->
private fun restoreSavedSearches(backupSavedSearches: List<BackupSavedSearch>) { private fun restoreSavedSearches(backupSavedSearches: List<BackupSavedSearch>) {
fullBackupManager.restoreSavedSearches(backupSavedSearches) backupManager.restoreSavedSearches(backupSavedSearches)
restoreProgress += 1 restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.saved_searches)) showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.saved_searches))
@ -118,7 +116,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
// SY <-- // SY <--
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, mergedMangaReferences, flatMetadata, online) restoreMangaData(manga, source, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, online)
} else { } else {
@ -155,7 +153,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
flatMetadata: BackupFlatMetadata?, flatMetadata: BackupFlatMetadata?,
online: Boolean online: Boolean
) { ) {
val dbManga = fullBackupManager.getMangaFromDatabase(manga) val dbManga = backupManager.getMangaFromDatabase(manga)
db.inTransaction { db.inTransaction {
if (dbManga == null) { if (dbManga == null) {
@ -163,7 +161,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
restoreMangaFetch(source, manga, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, online) restoreMangaFetch(source, manga, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, 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, mergedMangaReferences, flatMetadata, online) restoreMangaNoFetch(source, manga, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, online)
} }
@ -189,7 +187,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
flatMetadata: BackupFlatMetadata?, flatMetadata: BackupFlatMetadata?,
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}")
} }
@ -206,7 +204,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
} }
// SY <-- // SY <--
} else { } else {
fullBackupManager.restoreChaptersForMangaOffline(it, chapters) backupManager.restoreChaptersForMangaOffline(it, chapters)
Observable.just(manga) Observable.just(manga)
} }
} }
@ -234,14 +232,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 (/* SY --> */ source !is MergedSource && /* SY <-- */ !fullBackupManager.restoreChaptersForManga(manga, chapters)) { if (/* SY --> */ source !is MergedSource && /* SY <-- */ !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)
} }
} }
@ -256,80 +254,20 @@ 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>, mergedMangaReferences: List<BackupMergedMangaReference>, flatMetadata: BackupFlatMetadata?) { private fun restoreExtraForManga(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>, mergedMangaReferences: List<BackupMergedMangaReference>, flatMetadata: BackupFlatMetadata?) {
// 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)
// SY --> // SY -->
// Restore merged manga references if its a merged manga // Restore merged manga references if its a merged manga
fullBackupManager.restoreMergedMangaReferencesForManga(manga, mergedMangaReferences) backupManager.restoreMergedMangaReferencesForManga(manga, mergedMangaReferences)
// Restore flat metadata for metadata sources // Restore flat metadata for metadata sources
flatMetadata?.let { fullBackupManager.restoreFlatMetadata(manga, it) } flatMetadata?.let { backupManager.restoreFlatMetadata(manga, it) }
// SY <-- // SY <--
} }
/**
* [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 /* SY --> */, throttleManager /* SY <-- */)
// 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)
}
} }

View File

@ -12,6 +12,7 @@ import com.google.gson.JsonArray
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupManager import eu.kanade.tachiyomi.data.backup.AbstractBackupManager
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY_MASK import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY_MASK
@ -50,9 +51,7 @@ import eu.kanade.tachiyomi.data.database.models.TrackImpl
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
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.source.online.all.EHentai
import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
import eu.kanade.tachiyomi.util.lang.asObservable import eu.kanade.tachiyomi.util.lang.asObservable
import exh.MERGED_SOURCE_ID import exh.MERGED_SOURCE_ID
import exh.eh.EHentaiThrottleManager import exh.eh.EHentaiThrottleManager
@ -71,10 +70,8 @@ import java.lang.RuntimeException
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()
@ -85,11 +82,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())
@ -317,31 +314,18 @@ class LegacyBackupManager(context: Context, version: Int = CURRENT_VERSION) : Ab
* @param manga manga that needs updating * @param manga manga that needs updating
* @return [Observable] that contains manga * @return [Observable] that contains manga
*/ */
fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>, throttleManager: EHentaiThrottleManager): Observable<Pair<List<Chapter>, List<Chapter>>> { override fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>, throttleManager: EHentaiThrottleManager): Observable<Pair<List<Chapter>, List<Chapter>>> {
// SY --> // SY -->
if (source is MergedSource) { return if (source is MergedSource) {
val syncedChapters = runBlocking { source.fetchChaptersAndSync(manga, false) } val syncedChapters = runBlocking { source.fetchChaptersAndSync(manga, false) }
return syncedChapters.onEach { pair -> syncedChapters.onEach { pair ->
if (pair.first.isNotEmpty()) { if (pair.first.isNotEmpty()) {
chapters.forEach { it.manga_id = manga.id } chapters.forEach { it.manga_id = manga.id }
updateChapters(chapters) updateChapters(chapters)
} }
}.asObservable() }.asObservable()
} else { } else {
return ( super.restoreChapterFetchObservable(source, manga, chapters, throttleManager)
if (source is EHentai) {
source.fetchChapterList(manga, throttleManager::throttle)
} else {
source.fetchChapterList(manga)
}
).map { syncChaptersWithSource(databaseHelper, it, manga, source) }
// SY <--
.doOnNext { pair ->
if (pair.first.isNotEmpty()) {
chapters.forEach { it.manga_id = manga.id }
updateChapters(chapters)
}
}
} }
} }

View File

@ -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,14 +21,11 @@ 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 exh.EXHMigrations import exh.EXHMigrations
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.
@ -261,64 +257,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 /* SY --> */, throttleManager /* SY <-- */)
// 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)
}
} }