Put manga metadata into backups

This commit is contained in:
Jobobby04 2020-10-21 23:01:57 -04:00
parent cb6a991e9f
commit 5e531ba469
7 changed files with 177 additions and 7 deletions

View File

@ -22,6 +22,7 @@ import eu.kanade.tachiyomi.data.backup.full.models.BackupSavedSearch
import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer
import eu.kanade.tachiyomi.data.backup.full.models.BackupSource import eu.kanade.tachiyomi.data.backup.full.models.BackupSource
import eu.kanade.tachiyomi.data.backup.full.models.BackupTracking import eu.kanade.tachiyomi.data.backup.full.models.BackupTracking
import eu.kanade.tachiyomi.data.backup.full.models.BackupFlatMetadata
import eu.kanade.tachiyomi.data.backup.models.AbstractBackupManager import eu.kanade.tachiyomi.data.backup.models.AbstractBackupManager
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
@ -29,12 +30,16 @@ 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.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.all.EHentai 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.chapter.syncChaptersWithSource
import exh.MERGED_SOURCE_ID import exh.MERGED_SOURCE_ID
import exh.eh.EHentaiThrottleManager import exh.eh.EHentaiThrottleManager
import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadata
import exh.savedsearches.JsonSavedSearch import exh.savedsearches.JsonSavedSearch
import exh.source.EnhancedHttpSource.Companion.getMainSource
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
@ -182,6 +187,15 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
.map { BackupMergedMangaReference.copyFrom(it) } .map { BackupMergedMangaReference.copyFrom(it) }
} }
} }
val source = sourceManager.get(manga.source)?.getMainSource()
if (source is MetadataSource<*, *>) {
manga.id?.let { mangaId ->
databaseHelper.getFlatMetadataForManga(mangaId).executeAsBlocking()?.let { flatMetadata ->
mangaObject.flatMetadata = BackupFlatMetadata.copyFrom(flatMetadata)
}
}
}
// SY <-- // SY <--
// Check if user wants chapter information in backup // Check if user wants chapter information in backup
@ -556,5 +570,16 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
} }
} }
} }
internal fun restoreFlatMetadata(manga: Manga, backupFlatMetadata: BackupFlatMetadata) {
manga.id?.let { mangaId ->
databaseHelper.getFlatMetadataForManga(mangaId).executeAsBlocking().let {
if (it == null) {
val flatMetadata = backupFlatMetadata.getFlatMetadata(mangaId)
databaseHelper.insertFlatMetadata(flatMetadata).await()
}
}
}
}
// SY <-- // SY <--
} }

View File

@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.data.backup.full.models.BackupManga
import eu.kanade.tachiyomi.data.backup.full.models.BackupMergedMangaReference import eu.kanade.tachiyomi.data.backup.full.models.BackupMergedMangaReference
import eu.kanade.tachiyomi.data.backup.full.models.BackupSavedSearch import eu.kanade.tachiyomi.data.backup.full.models.BackupSavedSearch
import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer import eu.kanade.tachiyomi.data.backup.full.models.BackupSerializer
import eu.kanade.tachiyomi.data.backup.full.models.BackupFlatMetadata
import eu.kanade.tachiyomi.data.backup.models.AbstractBackupRestore import eu.kanade.tachiyomi.data.backup.models.AbstractBackupRestore
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
@ -109,6 +110,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
val tracks = backupManga.getTrackingImpl() val tracks = backupManga.getTrackingImpl()
// SY --> // SY -->
val mergedMangaReferences = backupManga.mergedMangaReferences val mergedMangaReferences = backupManga.mergedMangaReferences
val flatMetadata = backupManga.flatMetadata
// SY <-- // SY <--
// SY --> // SY -->
@ -118,7 +120,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
try { try {
val source = fullBackupManager.sourceManager.get(manga.source) val source = fullBackupManager.sourceManager.get(manga.source)
if (source != null || !online) { if (source != null || !online) {
restoreMangaData(manga, source, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, online) restoreMangaData(manga, source, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, online)
} else { } else {
val sourceName = sourceMapping[manga.source] ?: manga.source.toString() val sourceName = sourceMapping[manga.source] ?: manga.source.toString()
errors.add(Date() to "${manga.title} - ${context.getString(R.string.source_not_found_name, sourceName)}") errors.add(Date() to "${manga.title} - ${context.getString(R.string.source_not_found_name, sourceName)}")
@ -150,6 +152,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
tracks: List<Track>, tracks: List<Track>,
backupCategories: List<BackupCategory>, backupCategories: List<BackupCategory>,
mergedMangaReferences: List<BackupMergedMangaReference>, mergedMangaReferences: List<BackupMergedMangaReference>,
flatMetadata: BackupFlatMetadata?,
online: Boolean online: Boolean
) { ) {
val dbManga = fullBackupManager.getMangaFromDatabase(manga) val dbManga = fullBackupManager.getMangaFromDatabase(manga)
@ -157,12 +160,12 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
db.inTransaction { db.inTransaction {
if (dbManga == null) { if (dbManga == null) {
// Manga not in database // Manga not in database
restoreMangaFetch(source, manga, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, 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) fullBackupManager.restoreMangaNoFetch(manga, dbManga)
// Fetch rest of manga information // Fetch rest of manga information
restoreMangaNoFetch(source, manga, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, online) restoreMangaNoFetch(source, manga, chapters, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata, online)
} }
} }
} }
@ -183,6 +186,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
tracks: List<Track>, tracks: List<Track>,
backupCategories: List<BackupCategory>, backupCategories: List<BackupCategory>,
mergedMangaReferences: List<BackupMergedMangaReference>, mergedMangaReferences: List<BackupMergedMangaReference>,
flatMetadata: BackupFlatMetadata?,
online: Boolean online: Boolean
) { ) {
fullBackupManager.restoreMangaFetchObservable(source, manga, online) fullBackupManager.restoreMangaFetchObservable(source, manga, online)
@ -207,7 +211,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
} }
} }
.doOnNext { .doOnNext {
restoreExtraForManga(it, categories, history, tracks, backupCategories, mergedMangaReferences) restoreExtraForManga(it, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata)
} }
.flatMap { .flatMap {
trackingFetchObservable(it, tracks) trackingFetchObservable(it, tracks)
@ -224,6 +228,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
tracks: List<Track>, tracks: List<Track>,
backupCategories: List<BackupCategory>, backupCategories: List<BackupCategory>,
mergedMangaReferences: List<BackupMergedMangaReference>, mergedMangaReferences: List<BackupMergedMangaReference>,
flatMetadata: BackupFlatMetadata?,
online: Boolean online: Boolean
) { ) {
Observable.just(backupManga) Observable.just(backupManga)
@ -241,7 +246,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
} }
} }
.doOnNext { .doOnNext {
restoreExtraForManga(it, categories, history, tracks, backupCategories, mergedMangaReferences) restoreExtraForManga(it, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata)
} }
.flatMap { manga -> .flatMap { manga ->
trackingFetchObservable(manga, tracks) trackingFetchObservable(manga, tracks)
@ -249,7 +254,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
.subscribe() .subscribe()
} }
private fun restoreExtraForManga(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>, mergedMangaReferences: List<BackupMergedMangaReference>) { 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) fullBackupManager.restoreCategoriesForManga(manga, categories, backupCategories)
@ -262,6 +267,9 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
// SY --> // SY -->
// Restore merged manga references if its a merged manga // Restore merged manga references if its a merged manga
fullBackupManager.restoreMergedMangaReferencesForManga(manga, mergedMangaReferences) fullBackupManager.restoreMergedMangaReferencesForManga(manga, mergedMangaReferences)
// Restore flat metadata for metadata sources
flatMetadata?.let { fullBackupManager.restoreFlatMetadata(manga, it) }
// SY <-- // SY <--
} }

View File

@ -0,0 +1,35 @@
package eu.kanade.tachiyomi.data.backup.full.models
import eu.kanade.tachiyomi.data.backup.full.models.metadata.BackupSearchMetadata
import eu.kanade.tachiyomi.data.backup.full.models.metadata.BackupSearchTag
import eu.kanade.tachiyomi.data.backup.full.models.metadata.BackupSearchTitle
import exh.metadata.metadata.base.FlatMetadata
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@ExperimentalSerializationApi
@Serializable
data class BackupFlatMetadata(
@ProtoNumber(1) var searchMetadata: BackupSearchMetadata,
@ProtoNumber(2) var searchTags: List<BackupSearchTag> = emptyList(),
@ProtoNumber(3) var searchTitles: List<BackupSearchTitle> = emptyList()
) {
fun getFlatMetadata(mangaId: Long): FlatMetadata {
return FlatMetadata(
metadata = searchMetadata.getSearchMetadata(mangaId),
tags = searchTags.map { it.getSearchTag(mangaId) },
titles = searchTitles.map { it.getSearchTitle(mangaId) }
)
}
companion object {
fun copyFrom(flatMetadata: FlatMetadata): BackupFlatMetadata {
return BackupFlatMetadata(
searchMetadata = BackupSearchMetadata.copyFrom(flatMetadata.metadata),
searchTags = flatMetadata.tags.map { BackupSearchTag.copyFrom(it) },
searchTitles = flatMetadata.titles.map { BackupSearchTitle.copyFrom(it) }
)
}
}
}

View File

@ -37,7 +37,8 @@ data class BackupManga(
@ProtoNumber(101) var chapterFlags: Int = 0, @ProtoNumber(101) var chapterFlags: Int = 0,
@ProtoNumber(102) var history: List<BackupHistory> = emptyList(), @ProtoNumber(102) var history: List<BackupHistory> = emptyList(),
// SY specific values // SY specific values
@ProtoNumber(600) var mergedMangaReferences: List<BackupMergedMangaReference> = emptyList() @ProtoNumber(600) var mergedMangaReferences: List<BackupMergedMangaReference> = emptyList(),
@ProtoNumber(601) var flatMetadata: BackupFlatMetadata? = null
) { ) {
fun getMangaImpl(): MangaImpl { fun getMangaImpl(): MangaImpl {
return MangaImpl().apply { return MangaImpl().apply {

View File

@ -0,0 +1,36 @@
package eu.kanade.tachiyomi.data.backup.full.models.metadata
import exh.metadata.sql.models.SearchMetadata
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@ExperimentalSerializationApi
@Serializable
data class BackupSearchMetadata(
@ProtoNumber(1) var uploader: String? = null,
@ProtoNumber(2) var extra: String,
@ProtoNumber(3) var indexedExtra: String? = null,
@ProtoNumber(4) var extraVersion: Int
) {
fun getSearchMetadata(mangaId: Long): SearchMetadata {
return SearchMetadata(
mangaId = mangaId,
uploader = uploader,
extra = extra,
indexedExtra = indexedExtra,
extraVersion = extraVersion
)
}
companion object {
fun copyFrom(searchMetadata: SearchMetadata): BackupSearchMetadata {
return BackupSearchMetadata(
uploader = searchMetadata.uploader,
extra = searchMetadata.extra,
indexedExtra = searchMetadata.indexedExtra,
extraVersion = searchMetadata.extraVersion
)
}
}
}

View File

@ -0,0 +1,34 @@
package eu.kanade.tachiyomi.data.backup.full.models.metadata
import exh.metadata.sql.models.SearchTag
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@ExperimentalSerializationApi
@Serializable
data class BackupSearchTag(
@ProtoNumber(1) var namespace: String? = null,
@ProtoNumber(2) var name: String,
@ProtoNumber(3) var type: Int
) {
fun getSearchTag(mangaId: Long): SearchTag {
return SearchTag(
id = null,
mangaId = mangaId,
namespace = namespace,
name = name,
type = type
)
}
companion object {
fun copyFrom(searchTag: SearchTag): BackupSearchTag {
return BackupSearchTag(
namespace = searchTag.namespace,
name = searchTag.name,
type = searchTag.type
)
}
}
}

View File

@ -0,0 +1,31 @@
package eu.kanade.tachiyomi.data.backup.full.models.metadata
import exh.metadata.sql.models.SearchTitle
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@ExperimentalSerializationApi
@Serializable
data class BackupSearchTitle(
@ProtoNumber(1) var title: String,
@ProtoNumber(2) var type: Int
) {
fun getSearchTitle(mangaId: Long): SearchTitle {
return SearchTitle(
id = null,
mangaId = mangaId,
title = title,
type = type
)
}
companion object {
fun copyFrom(searchTitle: SearchTitle): BackupSearchTitle {
return BackupSearchTitle(
title = searchTitle.title,
type = searchTitle.type
)
}
}
}