Links added to Backup

BackupConst bits increased by 1 in to accommodate Links, which is now the msb.

BackupLink serializable class added to BackupManga
This commit is contained in:
Gfadebayo 2023-07-31 11:33:05 +01:00
parent 2c011c67b4
commit 19e29abe63
8 changed files with 71 additions and 14 deletions

View file

@ -147,6 +147,7 @@ object SettingsBackupScreen : SearchableSettings {
BackupConst.BACKUP_CHAPTER to R.string.chapters,
BackupConst.BACKUP_TRACK to R.string.track,
BackupConst.BACKUP_HISTORY to R.string.history,
BackupConst.BACKUP_LINK to R.string.links,
)
}
val flags = remember { choices.keys.toMutableStateList() }

View file

@ -2,13 +2,15 @@ package eu.kanade.tachiyomi.data.backup
// Filter options
internal object BackupConst {
const val BACKUP_CATEGORY = 0x1
const val BACKUP_CATEGORY_MASK = 0x1
const val BACKUP_CHAPTER = 0x2
const val BACKUP_CHAPTER_MASK = 0x2
const val BACKUP_HISTORY = 0x4
const val BACKUP_HISTORY_MASK = 0x4
const val BACKUP_TRACK = 0x8
const val BACKUP_TRACK_MASK = 0x8
const val BACKUP_ALL = 0xF
const val BACKUP_CATEGORY = 0x01
const val BACKUP_CATEGORY_MASK = 0x01
const val BACKUP_CHAPTER = 0x02
const val BACKUP_CHAPTER_MASK = 0x02
const val BACKUP_HISTORY = 0x04
const val BACKUP_HISTORY_MASK = 0x04
const val BACKUP_TRACK = 0x08
const val BACKUP_TRACK_MASK = 0x08
const val BACKUP_LINK = 0x10
const val BACKUP_LINK_MASK = 0x10
const val BACKUP_ALL = 0x1F
}

View file

@ -12,11 +12,14 @@ import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CHAPTER
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CHAPTER_MASK
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_HISTORY
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_HISTORY_MASK
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_LINK
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_LINK_MASK
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_TRACK
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_TRACK_MASK
import eu.kanade.tachiyomi.data.backup.models.Backup
import eu.kanade.tachiyomi.data.backup.models.BackupCategory
import eu.kanade.tachiyomi.data.backup.models.BackupHistory
import eu.kanade.tachiyomi.data.backup.models.BackupLink
import eu.kanade.tachiyomi.data.backup.models.BackupManga
import eu.kanade.tachiyomi.data.backup.models.BackupSerializer
import eu.kanade.tachiyomi.data.backup.models.BackupSource
@ -218,6 +221,14 @@ class BackupManager(
}
}
if (options and BACKUP_LINK_MASK == BACKUP_LINK) {
val backupLinks = handler.awaitList {
manga_linkQueries.linkInfo(manga.id) { tag, position -> BackupLink(tag, position) }
}
mangaObject.links = backupLinks
}
return mangaObject
}
@ -473,6 +484,19 @@ class BackupManager(
newChapters[false]?.let { insertChapters(it) }
}
internal suspend fun restoreLinks(manga: Manga, links: List<BackupLink>) {
handler.await(inTransaction = true) {
manga_linkQueries.delete(listOf(manga.id))
for (link in links) {
// Could lead to duplicate positions if a manga with that position already exists
manga_linkQueries.insert(link.tag, manga.id, link.position)
manga_linkQueries.setDuplicatePositionToLast(link.tag, manga.id, link.position)
}
}
}
/**
* Returns manga
*

View file

@ -5,6 +5,7 @@ import android.net.Uri
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.models.BackupCategory
import eu.kanade.tachiyomi.data.backup.models.BackupHistory
import eu.kanade.tachiyomi.data.backup.models.BackupLink
import eu.kanade.tachiyomi.data.backup.models.BackupManga
import eu.kanade.tachiyomi.data.backup.models.BackupSource
import eu.kanade.tachiyomi.util.BackupUtil
@ -115,18 +116,19 @@ class BackupRestorer(
val history =
backupManga.brokenHistory.map { BackupHistory(it.url, it.lastRead, it.readDuration) } + backupManga.history
val tracks = backupManga.getTrackingImpl()
val links = backupManga.links
try {
val dbManga = backupManager.getMangaFromDatabase(manga.url, manga.source)
if (dbManga == null) {
// Manga not in database
restoreExistingManga(manga, chapters, categories, history, tracks, backupCategories)
restoreExistingManga(manga, chapters, categories, history, tracks, backupCategories, links)
} else {
// Manga in database
// Copy information from manga already in database
val updatedManga = backupManager.restoreExistingManga(manga, dbManga)
// Fetch rest of manga information
restoreNewManga(updatedManga, chapters, categories, history, tracks, backupCategories)
restoreNewManga(updatedManga, chapters, categories, history, tracks, backupCategories, links)
}
} catch (e: Exception) {
val sourceName = sourceMapping[manga.source] ?: manga.source.toString()
@ -151,10 +153,11 @@ class BackupRestorer(
history: List<BackupHistory>,
tracks: List<Track>,
backupCategories: List<BackupCategory>,
links: List<BackupLink>,
) {
val fetchedManga = backupManager.restoreNewManga(manga)
backupManager.restoreChapters(fetchedManga, chapters)
restoreExtras(fetchedManga, categories, history, tracks, backupCategories)
restoreExtras(fetchedManga, categories, history, tracks, backupCategories, links)
}
private suspend fun restoreNewManga(
@ -164,15 +167,17 @@ class BackupRestorer(
history: List<BackupHistory>,
tracks: List<Track>,
backupCategories: List<BackupCategory>,
links: List<BackupLink>,
) {
backupManager.restoreChapters(backupManga, chapters)
restoreExtras(backupManga, categories, history, tracks, backupCategories)
restoreExtras(backupManga, categories, history, tracks, backupCategories, links)
}
private suspend fun restoreExtras(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>) {
private suspend fun restoreExtras(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>, links: List<BackupLink>) {
backupManager.restoreCategories(manga, categories, backupCategories)
backupManager.restoreHistory(history)
backupManager.restoreTracking(manga, tracks)
backupManager.restoreLinks(manga, links)
}
/**

View file

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.data.backup.models
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class BackupLink(
@ProtoNumber(0) val tag: Long,
@ProtoNumber(1) val position: Long,
)

View file

@ -32,6 +32,7 @@ data class BackupManga(
@ProtoNumber(16) var chapters: List<BackupChapter> = emptyList(),
@ProtoNumber(17) var categories: List<Long> = emptyList(),
@ProtoNumber(18) var tracking: List<BackupTracking> = emptyList(),
@ProtoNumber(19) var links: List<BackupLink> = emptyList(),
// Bump by 100 for values that are not saved/implemented in 1.x but are used in 0.x
@ProtoNumber(100) var favorite: Boolean = true,
@ProtoNumber(101) var chapterFlags: Int = 0,

View file

@ -51,3 +51,15 @@ manga_id
FROM manga_link
WHERE tag IN (SELECT tag FROM manga_link WHERE manga_id = :id))
ORDER BY ml.position;
linkInfo:
SELECT tag, coalesce(position, 0) AS position
FROM manga_link
WHERE manga_id = ?;
setDuplicatePositionToLast:
UPDATE manga_link
SET position = (SELECT max(position)+1 FROM manga_link WHERE tag = :tag)
WHERE tag = :tag
AND manga_id != :mangaId
AND position = :position;

View file

@ -14,6 +14,7 @@
<string name="track">Tracking</string>
<string name="delete_downloaded">Delete downloaded</string>
<string name="history">History</string>
<string name="links">Links</string>
<!-- Screen titles -->
<string name="label_more">More</string>
@ -106,6 +107,7 @@
<string name="action_show_manga">Show entry</string>
<string name="action_copy_to_clipboard">Copy to clipboard</string>
<string name="action_link">Link</string>
<string name="action_unlink">Unlink</string>
<!-- Do not translate "WebView" -->
<string name="action_open_in_web_view">Open in WebView</string>