Fix new private parameter in tracking backup (#1463)

* Fix new private parameter in tracking backup

* Cleanup uneeded models
This commit is contained in:
Mitchell Syer
2025-06-22 20:17:31 -04:00
committed by GitHub
parent b54dc6f967
commit ee9de376a3
12 changed files with 33 additions and 511 deletions

View File

@@ -1,29 +0,0 @@
@file:Suppress("ktlint:standard:property-naming")
package suwayomi.tachidesk.manga.impl.backup.models
import eu.kanade.tachiyomi.source.model.SChapter
import java.io.Serializable
interface Chapter :
SChapter,
Serializable {
var id: Long?
var manga_id: Long?
var read: Boolean
var bookmark: Boolean
var last_page_read: Int
var date_fetch: Long
var source_order: Int
var meta: Map<String, String>
val isRecognizedNumber: Boolean
get() = chapter_number >= 0f
}

View File

@@ -1,42 +0,0 @@
@file:Suppress("ktlint:standard:property-naming")
package suwayomi.tachidesk.manga.impl.backup.models
class ChapterImpl : Chapter {
override var id: Long? = null
override var manga_id: Long? = null
override lateinit var url: String
override lateinit var name: String
override var scanlator: String? = null
override var read: Boolean = false
override var bookmark: Boolean = false
override var last_page_read: Int = 0
override var date_fetch: Long = 0
override var date_upload: Long = 0
override var chapter_number: Float = 0f
override var source_order: Int = 0
override var meta: Map<String, String> = emptyMap()
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
val chapter = other as Chapter
if (url != chapter.url) return false
return id == chapter.id
}
override fun hashCode(): Int = url.hashCode() + id.hashCode()
}

View File

@@ -1,135 +0,0 @@
@file:Suppress("ktlint:standard:property-naming")
package suwayomi.tachidesk.manga.impl.backup.models
import eu.kanade.tachiyomi.source.model.SManga
// import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
// import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
// substitute for eu.kanade.tachiyomi.ui.reader.setting.OrientationType
object OrientationType {
const val MASK = 0x00000038
}
// substitute for eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
object ReadingModeType {
const val MASK = 0x00000007
}
interface Manga : SManga {
var id: Long?
var source: Long
var favorite: Boolean
// last time the chapter list changed in any way
var last_update: Long
// predicted next update time based on latest (by date) 4 chapters' deltas
var next_update: Long
var date_added: Long
var viewer_flags: Int
var chapter_flags: Int
var cover_last_modified: Long
var meta: Map<String, String>
fun setChapterOrder(order: Int) {
setChapterFlags(order, CHAPTER_SORT_MASK)
}
fun sortDescending(): Boolean = chapter_flags and CHAPTER_SORT_MASK == CHAPTER_SORT_DESC
fun getGenres(): List<String>? = genre?.split(", ")?.map { it.trim() }
private fun setChapterFlags(
flag: Int,
mask: Int,
) {
chapter_flags = chapter_flags and mask.inv() or (flag and mask)
}
private fun setViewerFlags(
flag: Int,
mask: Int,
) {
viewer_flags = viewer_flags and mask.inv() or (flag and mask)
}
// Used to display the chapter's title one way or another
var displayMode: Int
get() = chapter_flags and CHAPTER_DISPLAY_MASK
set(mode) = setChapterFlags(mode, CHAPTER_DISPLAY_MASK)
var readFilter: Int
get() = chapter_flags and CHAPTER_READ_MASK
set(filter) = setChapterFlags(filter, CHAPTER_READ_MASK)
var downloadedFilter: Int
get() = chapter_flags and CHAPTER_DOWNLOADED_MASK
set(filter) = setChapterFlags(filter, CHAPTER_DOWNLOADED_MASK)
var bookmarkedFilter: Int
get() = chapter_flags and CHAPTER_BOOKMARKED_MASK
set(filter) = setChapterFlags(filter, CHAPTER_BOOKMARKED_MASK)
var sorting: Int
get() = chapter_flags and CHAPTER_SORTING_MASK
set(sort) = setChapterFlags(sort, CHAPTER_SORTING_MASK)
var readingModeType: Int
get() = viewer_flags and ReadingModeType.MASK
set(readingMode) = setViewerFlags(readingMode, ReadingModeType.MASK)
var orientationType: Int
get() = viewer_flags and OrientationType.MASK
set(rotationType) = setViewerFlags(rotationType, OrientationType.MASK)
companion object {
// Generic filter that does not filter anything
const val SHOW_ALL = 0x00000000
const val CHAPTER_SORT_DESC = 0x00000000
const val CHAPTER_SORT_ASC = 0x00000001
const val CHAPTER_SORT_MASK = 0x00000001
const val CHAPTER_SHOW_UNREAD = 0x00000002
const val CHAPTER_SHOW_READ = 0x00000004
const val CHAPTER_READ_MASK = 0x00000006
const val CHAPTER_SHOW_DOWNLOADED = 0x00000008
const val CHAPTER_SHOW_NOT_DOWNLOADED = 0x00000010
const val CHAPTER_DOWNLOADED_MASK = 0x00000018
const val CHAPTER_SHOW_BOOKMARKED = 0x00000020
const val CHAPTER_SHOW_NOT_BOOKMARKED = 0x00000040
const val CHAPTER_BOOKMARKED_MASK = 0x00000060
const val CHAPTER_SORTING_SOURCE = 0x00000000
const val CHAPTER_SORTING_NUMBER = 0x00000100
const val CHAPTER_SORTING_UPLOAD_DATE = 0x00000200
const val CHAPTER_SORTING_MASK = 0x00000300
const val CHAPTER_DISPLAY_NAME = 0x00000000
const val CHAPTER_DISPLAY_NUMBER = 0x00100000
const val CHAPTER_DISPLAY_MASK = 0x00100000
}
}
// fun Manga.toMangaInfo(): MangaInfo {
// return MangaInfo(
// artist = this.artist ?: "",
// author = this.author ?: "",
// cover = this.thumbnail_url ?: "",
// description = this.description ?: "",
// genres = this.getGenres() ?: emptyList(),
// key = this.url,
// status = this.status,
// title = this.title
// )
// }

View File

@@ -1,69 +0,0 @@
@file:Suppress("ktlint:standard:property-naming")
package suwayomi.tachidesk.manga.impl.backup.models
import eu.kanade.tachiyomi.source.model.UpdateStrategy
open class MangaImpl : Manga {
override var id: Long? = null
override var source: Long = -1
override lateinit var url: String
override lateinit var title: String
override var artist: String? = null
override var author: String? = null
override var description: String? = null
override var genre: String? = null
override var status: Int = 0
override var thumbnail_url: String? = null
override var update_strategy: UpdateStrategy = UpdateStrategy.ALWAYS_UPDATE
override var favorite: Boolean = false
override var last_update: Long = 0
override var next_update: Long = 0
override var date_added: Long = 0
override var initialized: Boolean = false
override var meta: Map<String, String> = emptyMap()
/** Reader mode value
* ref: https://github.com/tachiyomiorg/tachiyomi/blob/ff369010074b058bb734ce24c66508300e6e9ac6/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt#L8
* 0 -> Default
* 1 -> Left to Right
* 2 -> Right to Left
* 3 -> Vertical
* 4 -> Webtoon
* 5 -> Continues Vertical
*/
override var viewer_flags: Int = 0
/** Contains some useful info about
*/
override var chapter_flags: Int = 0
override var cover_last_modified: Long = 0
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
val manga = other as Manga
if (url != manga.url) return false
return id == manga.id
}
override fun hashCode(): Int = url.hashCode() + id.hashCode()
}

View File

@@ -1,33 +0,0 @@
@file:Suppress("ktlint:standard:property-naming")
package suwayomi.tachidesk.manga.impl.backup.models
import java.io.Serializable
interface Track : Serializable {
var id: Long?
var manga_id: Long
var sync_id: Int
var media_id: Long
var library_id: Long?
var title: String
var last_chapter_read: Int
var total_chapters: Int
var score: Float
var status: Int
var started_reading_date: Long
var finished_reading_date: Long
var tracking_url: String
}

View File

@@ -1,49 +0,0 @@
@file:Suppress("ktlint:standard:property-naming")
package suwayomi.tachidesk.manga.impl.backup.models
class TrackImpl : Track {
override var id: Long? = null
override var manga_id: Long = 0
override var sync_id: Int = 0
override var media_id: Long = 0L
override var library_id: Long? = null
override lateinit var title: String
override var last_chapter_read: Int = 0
override var total_chapters: Int = 0
override var score: Float = 0f
override var status: Int = 0
override var started_reading_date: Long = 0
override var finished_reading_date: Long = 0
override var tracking_url: String = ""
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
other as Track
if (manga_id != other.manga_id) return false
if (sync_id != other.sync_id) return false
return media_id == other.media_id
}
override fun hashCode(): Int {
var result = (manga_id xor manga_id.ushr(32)).toInt()
result = 31 * result + sync_id
result = (31 * result + media_id).toInt()
return result
}
}

View File

@@ -290,6 +290,7 @@ object ProtoBackupExport : ProtoBackupBase() {
startedReadingDate = it.record.startDate, startedReadingDate = it.record.startDate,
finishedReadingDate = it.record.finishDate, finishedReadingDate = it.record.finishDate,
trackingUrl = it.record.remoteUrl, trackingUrl = it.record.remoteUrl,
private = it.record.private,
) )
} }
} }

View File

@@ -40,12 +40,11 @@ import suwayomi.tachidesk.manga.impl.Chapter.modifyChaptersMetas
import suwayomi.tachidesk.manga.impl.Manga.clearThumbnail import suwayomi.tachidesk.manga.impl.Manga.clearThumbnail
import suwayomi.tachidesk.manga.impl.Manga.modifyMangasMetas import suwayomi.tachidesk.manga.impl.Manga.modifyMangasMetas
import suwayomi.tachidesk.manga.impl.Source.modifySourceMetas import suwayomi.tachidesk.manga.impl.Source.modifySourceMetas
import suwayomi.tachidesk.manga.impl.backup.models.Chapter
import suwayomi.tachidesk.manga.impl.backup.models.Manga
import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupValidator.ValidationResult import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupValidator.ValidationResult
import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupValidator.validate import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupValidator.validate
import suwayomi.tachidesk.manga.impl.backup.proto.models.Backup import suwayomi.tachidesk.manga.impl.backup.proto.models.Backup
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupCategory import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupCategory
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupChapter
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupHistory import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupHistory
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupManga import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupManga
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupServerSettings import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupServerSettings
@@ -62,8 +61,8 @@ import java.io.InputStream
import java.util.Date import java.util.Date
import java.util.Timer import java.util.Timer
import java.util.TimerTask import java.util.TimerTask
import java.util.concurrent.TimeUnit
import kotlin.math.max import kotlin.math.max
import kotlin.time.Duration.Companion.milliseconds
import suwayomi.tachidesk.manga.impl.track.Track as Tracker import suwayomi.tachidesk.manga.impl.track.Track as Tracker
enum class RestoreMode { enum class RestoreMode {
@@ -144,7 +143,7 @@ object ProtoBackupImport : ProtoBackupBase() {
} }
@OptIn(DelicateCoroutinesApi::class) @OptIn(DelicateCoroutinesApi::class)
suspend fun restore(sourceStream: InputStream): String { fun restore(sourceStream: InputStream): String {
val restoreId = System.currentTimeMillis().toString() val restoreId = System.currentTimeMillis().toString()
logger.info { "restore($restoreId): queued" } logger.info { "restore($restoreId): queued" }
@@ -279,25 +278,24 @@ object ProtoBackupImport : ProtoBackupBase() {
backupManga: BackupManga, backupManga: BackupManga,
categoryMapping: Map<Int, Int>, categoryMapping: Map<Int, Int>,
) { ) {
val manga = backupManga.getMangaImpl() val chapters = backupManga.chapters
val chapters = backupManga.getChaptersImpl()
val categories = backupManga.categories val categories = backupManga.categories
val history = backupManga.history val history = backupManga.history
val dbCategoryIds = categories.map { categoryMapping[it]!! } val dbCategoryIds = categories.map { categoryMapping[it]!! }
try { try {
restoreMangaData(manga, chapters, dbCategoryIds, history, backupManga.tracking) restoreMangaData(backupManga, chapters, dbCategoryIds, history, backupManga.tracking)
} catch (e: Exception) { } catch (e: Exception) {
val sourceName = sourceMapping[manga.source] ?: manga.source.toString() val sourceName = sourceMapping[backupManga.source] ?: backupManga.source.toString()
errors.add(Date() to "${manga.title} [$sourceName]: ${e.message}") errors.add(Date() to "${backupManga.title} [$sourceName]: ${e.message}")
} }
} }
@Suppress("UNUSED_PARAMETER") // TODO: remove @Suppress("UNUSED_PARAMETER") // TODO: remove
private fun restoreMangaData( private fun restoreMangaData(
manga: Manga, manga: BackupManga,
chapters: List<Chapter>, chapters: List<BackupChapter>,
categoryIds: List<Int>, categoryIds: List<Int>,
history: List<BackupHistory>, history: List<BackupHistory>,
tracks: List<BackupTracking>, tracks: List<BackupTracking>,
@@ -324,10 +322,10 @@ object ProtoBackupImport : ProtoBackupBase() {
it[artist] = manga.artist it[artist] = manga.artist
it[author] = manga.author it[author] = manga.author
it[description] = manga.description it[description] = manga.description
it[genre] = manga.genre it[genre] = manga.genre.joinToString()
it[status] = manga.status it[status] = manga.status
it[thumbnail_url] = manga.thumbnail_url it[thumbnail_url] = manga.thumbnailUrl
it[updateStrategy] = manga.update_strategy.name it[updateStrategy] = manga.updateStrategy.name
it[sourceReference] = manga.source it[sourceReference] = manga.source
@@ -335,7 +333,7 @@ object ProtoBackupImport : ProtoBackupBase() {
it[inLibrary] = manga.favorite it[inLibrary] = manga.favorite
it[inLibraryAt] = TimeUnit.MILLISECONDS.toSeconds(manga.date_added) it[inLibraryAt] = manga.dateAdded.milliseconds.inWholeSeconds
}.value }.value
} else { } else {
val dbMangaId = dbManga[MangaTable.id].value val dbMangaId = dbManga[MangaTable.id].value
@@ -345,16 +343,16 @@ object ProtoBackupImport : ProtoBackupBase() {
it[artist] = manga.artist ?: dbManga[artist] it[artist] = manga.artist ?: dbManga[artist]
it[author] = manga.author ?: dbManga[author] it[author] = manga.author ?: dbManga[author]
it[description] = manga.description ?: dbManga[description] it[description] = manga.description ?: dbManga[description]
it[genre] = manga.genre ?: dbManga[genre] it[genre] = manga.genre.ifEmpty { null }?.joinToString() ?: dbManga[genre]
it[status] = manga.status it[status] = manga.status
it[thumbnail_url] = manga.thumbnail_url ?: dbManga[thumbnail_url] it[thumbnail_url] = manga.thumbnailUrl ?: dbManga[thumbnail_url]
it[updateStrategy] = manga.update_strategy.name it[updateStrategy] = manga.updateStrategy.name
it[initialized] = dbManga[initialized] || manga.description != null it[initialized] = dbManga[initialized] || manga.description != null
it[inLibrary] = manga.favorite || dbManga[inLibrary] it[inLibrary] = manga.favorite || dbManga[inLibrary]
it[inLibraryAt] = TimeUnit.MILLISECONDS.toSeconds(manga.date_added) it[inLibraryAt] = manga.dateAdded.milliseconds.inWholeSeconds
} }
dbMangaId dbMangaId
@@ -384,8 +382,8 @@ object ProtoBackupImport : ProtoBackupBase() {
private fun getMangaChapterToRestoreInfo( private fun getMangaChapterToRestoreInfo(
mangaId: Int, mangaId: Int,
restoreMode: RestoreMode, restoreMode: RestoreMode,
chapters: List<Chapter>, chapters: List<BackupChapter>,
): Pair<List<Chapter>, List<Pair<Chapter, ResultRow>>> { ): Pair<List<BackupChapter>, List<Pair<BackupChapter, ResultRow>>> {
val uniqueChapters = chapters.distinctBy { it.url } val uniqueChapters = chapters.distinctBy { it.url }
if (restoreMode == RestoreMode.NEW) { if (restoreMode == RestoreMode.NEW) {
@@ -403,7 +401,7 @@ object ProtoBackupImport : ProtoBackupBase() {
private fun restoreMangaChapterData( private fun restoreMangaChapterData(
mangaId: Int, mangaId: Int,
restoreMode: RestoreMode, restoreMode: RestoreMode,
chapters: List<Chapter>, chapters: List<BackupChapter>,
) = dbTransaction { ) = dbTransaction {
val (chaptersToInsert, chaptersToUpdateToDbChapter) = getMangaChapterToRestoreInfo(mangaId, restoreMode, chapters) val (chaptersToInsert, chaptersToUpdateToDbChapter) = getMangaChapterToRestoreInfo(mangaId, restoreMode, chapters)
@@ -412,22 +410,22 @@ object ProtoBackupImport : ProtoBackupBase() {
.batchInsert(chaptersToInsert) { chapter -> .batchInsert(chaptersToInsert) { chapter ->
this[ChapterTable.url] = chapter.url this[ChapterTable.url] = chapter.url
this[ChapterTable.name] = chapter.name this[ChapterTable.name] = chapter.name
if (chapter.date_upload == 0L) { if (chapter.dateUpload == 0L) {
this[ChapterTable.date_upload] = chapter.date_fetch this[ChapterTable.date_upload] = chapter.dateFetch
} else { } else {
this[ChapterTable.date_upload] = chapter.date_upload this[ChapterTable.date_upload] = chapter.dateUpload
} }
this[ChapterTable.chapter_number] = chapter.chapter_number this[ChapterTable.chapter_number] = chapter.chapterNumber
this[ChapterTable.scanlator] = chapter.scanlator this[ChapterTable.scanlator] = chapter.scanlator
this[ChapterTable.sourceOrder] = chaptersToInsert.size - chapter.source_order this[ChapterTable.sourceOrder] = chaptersToInsert.size - chapter.sourceOrder
this[ChapterTable.manga] = mangaId this[ChapterTable.manga] = mangaId
this[ChapterTable.isRead] = chapter.read this[ChapterTable.isRead] = chapter.read
this[ChapterTable.lastPageRead] = chapter.last_page_read.coerceAtLeast(0) this[ChapterTable.lastPageRead] = chapter.lastPageRead.coerceAtLeast(0)
this[ChapterTable.isBookmarked] = chapter.bookmark this[ChapterTable.isBookmarked] = chapter.bookmark
this[ChapterTable.fetchedAt] = TimeUnit.MILLISECONDS.toSeconds(chapter.date_fetch) this[ChapterTable.fetchedAt] = chapter.dateFetch.milliseconds.inWholeSeconds
}.map { it[ChapterTable.id].value } }.map { it[ChapterTable.id].value }
if (chaptersToUpdateToDbChapter.isNotEmpty()) { if (chaptersToUpdateToDbChapter.isNotEmpty()) {
@@ -436,7 +434,7 @@ object ProtoBackupImport : ProtoBackupBase() {
addBatch(EntityID(dbChapter[ChapterTable.id].value, ChapterTable)) addBatch(EntityID(dbChapter[ChapterTable.id].value, ChapterTable))
this[ChapterTable.isRead] = backupChapter.read || dbChapter[ChapterTable.isRead] this[ChapterTable.isRead] = backupChapter.read || dbChapter[ChapterTable.isRead]
this[ChapterTable.lastPageRead] = this[ChapterTable.lastPageRead] =
max(backupChapter.last_page_read, dbChapter[ChapterTable.lastPageRead]).coerceAtLeast(0) max(backupChapter.lastPageRead, dbChapter[ChapterTable.lastPageRead]).coerceAtLeast(0)
this[ChapterTable.isBookmarked] = backupChapter.bookmark || dbChapter[ChapterTable.isBookmarked] this[ChapterTable.isBookmarked] = backupChapter.bookmark || dbChapter[ChapterTable.isBookmarked]
} }
execute(this@dbTransaction) execute(this@dbTransaction)

View File

@@ -2,7 +2,6 @@ package suwayomi.tachidesk.manga.impl.backup.proto.models
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import suwayomi.tachidesk.manga.impl.backup.models.ChapterImpl
@Serializable @Serializable
data class BackupChapter( data class BackupChapter(
@@ -22,19 +21,4 @@ data class BackupChapter(
@ProtoNumber(10) var sourceOrder: Int = 0, @ProtoNumber(10) var sourceOrder: Int = 0,
// suwayomi // suwayomi
@ProtoNumber(9000) var meta: Map<String, String> = emptyMap(), @ProtoNumber(9000) var meta: Map<String, String> = emptyMap(),
) { )
fun toChapterImpl(): ChapterImpl =
ChapterImpl().apply {
url = this@BackupChapter.url
name = this@BackupChapter.name
chapter_number = this@BackupChapter.chapterNumber
scanlator = this@BackupChapter.scanlator
read = this@BackupChapter.read
bookmark = this@BackupChapter.bookmark
last_page_read = this@BackupChapter.lastPageRead
date_fetch = this@BackupChapter.dateFetch
date_upload = this@BackupChapter.dateUpload
source_order = this@BackupChapter.sourceOrder
meta = this@BackupChapter.meta
}
}

View File

@@ -3,10 +3,6 @@ package suwayomi.tachidesk.manga.impl.backup.proto.models
import eu.kanade.tachiyomi.source.model.UpdateStrategy import eu.kanade.tachiyomi.source.model.UpdateStrategy
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import suwayomi.tachidesk.manga.impl.backup.models.ChapterImpl
import suwayomi.tachidesk.manga.impl.backup.models.Manga
import suwayomi.tachidesk.manga.impl.backup.models.MangaImpl
import suwayomi.tachidesk.manga.impl.backup.models.TrackImpl
@Serializable @Serializable
data class BackupManga( data class BackupManga(
@@ -40,53 +36,4 @@ data class BackupManga(
@ProtoNumber(105) var updateStrategy: UpdateStrategy = UpdateStrategy.ALWAYS_UPDATE, @ProtoNumber(105) var updateStrategy: UpdateStrategy = UpdateStrategy.ALWAYS_UPDATE,
// suwayomi // suwayomi
@ProtoNumber(9000) var meta: Map<String, String> = emptyMap(), @ProtoNumber(9000) var meta: Map<String, String> = emptyMap(),
) {
fun getMangaImpl(): MangaImpl =
MangaImpl().apply {
url = this@BackupManga.url
title = this@BackupManga.title
artist = this@BackupManga.artist
author = this@BackupManga.author
description = this@BackupManga.description
genre = this@BackupManga.genre.joinToString()
status = this@BackupManga.status
thumbnail_url = this@BackupManga.thumbnailUrl
favorite = this@BackupManga.favorite
source = this@BackupManga.source
date_added = this@BackupManga.dateAdded
viewer_flags = this@BackupManga.viewer_flags ?: this@BackupManga.viewer
chapter_flags = this@BackupManga.chapterFlags
update_strategy = this@BackupManga.updateStrategy
meta = this@BackupManga.meta
}
fun getChaptersImpl(): List<ChapterImpl> =
chapters.map {
it.toChapterImpl()
}
fun getTrackingImpl(): List<TrackImpl> =
tracking.map {
it.getTrackingImpl()
}
companion object {
fun copyFrom(manga: Manga): BackupManga =
BackupManga(
url = manga.url,
title = manga.title,
artist = manga.artist,
author = manga.author,
description = manga.description,
genre = manga.getGenres() ?: emptyList(),
status = manga.status,
thumbnailUrl = manga.thumbnail_url,
favorite = manga.favorite,
source = manga.source,
dateAdded = manga.date_added,
viewer = manga.readingModeType,
viewer_flags = manga.viewer_flags,
chapterFlags = manga.chapter_flags,
) )
}
}

View File

@@ -1,6 +1,5 @@
package suwayomi.tachidesk.manga.impl.backup.proto.models package suwayomi.tachidesk.manga.impl.backup.proto.models
import eu.kanade.tachiyomi.source.Source
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
@@ -10,12 +9,4 @@ data class BackupSource(
@ProtoNumber(2) var sourceId: Long, @ProtoNumber(2) var sourceId: Long,
// suwayomi // suwayomi
@ProtoNumber(9000) var meta: Map<String, String> = emptyMap(), @ProtoNumber(9000) var meta: Map<String, String> = emptyMap(),
) {
companion object {
fun copyFrom(source: Source): BackupSource =
BackupSource(
name = source.name,
sourceId = source.id,
) )
}
}

View File

@@ -2,8 +2,6 @@ package suwayomi.tachidesk.manga.impl.backup.proto.models
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import suwayomi.tachidesk.manga.impl.backup.models.Track
import suwayomi.tachidesk.manga.impl.backup.models.TrackImpl
@Serializable @Serializable
data class BackupTracking( data class BackupTracking(
@@ -28,44 +26,4 @@ data class BackupTracking(
@ProtoNumber(11) var finishedReadingDate: Long = 0, @ProtoNumber(11) var finishedReadingDate: Long = 0,
@ProtoNumber(12) var private: Boolean = false, @ProtoNumber(12) var private: Boolean = false,
@ProtoNumber(100) var mediaId: Long = 0, @ProtoNumber(100) var mediaId: Long = 0,
) {
fun getTrackingImpl(): TrackImpl =
TrackImpl().apply {
sync_id = this@BackupTracking.syncId
media_id =
if (this@BackupTracking.mediaIdInt != 0) {
this@BackupTracking.mediaIdInt.toLong()
} else {
this@BackupTracking.mediaId
}
library_id = this@BackupTracking.libraryId
title = this@BackupTracking.title
// convert from float to int because of 1.x types
last_chapter_read = this@BackupTracking.lastChapterRead.toInt()
total_chapters = this@BackupTracking.totalChapters
score = this@BackupTracking.score
status = this@BackupTracking.status
started_reading_date = this@BackupTracking.startedReadingDate
finished_reading_date = this@BackupTracking.finishedReadingDate
tracking_url = this@BackupTracking.trackingUrl
}
companion object {
fun copyFrom(track: Track): BackupTracking =
BackupTracking(
syncId = track.sync_id,
mediaId = track.media_id,
// forced not null so its compatible with 1.x backup system
libraryId = track.library_id!!,
title = track.title,
// convert to float for 1.x
lastChapterRead = track.last_chapter_read.toFloat(),
totalChapters = track.total_chapters,
score = track.score,
status = track.status,
startedReadingDate = track.started_reading_date,
finishedReadingDate = track.finished_reading_date,
trackingUrl = track.tracking_url,
) )
}
}