mirror of
https://github.com/gotson/komga.git
synced 2025-01-09 04:08:00 +08:00
fix: sync progress not compatible between Cantook and web reader
Closes: #1477
This commit is contained in:
parent
bb046d648c
commit
02110962c1
@ -1,6 +1,7 @@
|
||||
import {Locator, ReadingPosition} from '@d-i-t-a/reader'
|
||||
import {R2Location, R2Locator, R2Progression} from '@/types/readium'
|
||||
import {Locations} from '@d-i-t-a/reader/dist/types/model/Locator'
|
||||
import urls from '@/functions/urls'
|
||||
|
||||
export function createR2Progression(locator: Locator): R2Progression {
|
||||
return {
|
||||
@ -15,7 +16,7 @@ export function createR2Progression(locator: Locator): R2Progression {
|
||||
|
||||
function locatorToR2Locator(locator: Locator): R2Locator {
|
||||
return {
|
||||
href: locator.href,
|
||||
href: locator.href.startsWith(urls.originNoSlash) ? locator.href.replace(/(.*\/resource\/)/, '') : locator.href,
|
||||
type: locator.type || 'application/octet-stream',
|
||||
title: locator.title,
|
||||
locations: locationsToR2Location(locator.locations),
|
||||
@ -32,11 +33,11 @@ function locationsToR2Location(location: Locations): R2Location {
|
||||
}
|
||||
}
|
||||
|
||||
export function r2ProgressionToReadingPosition(progression?: R2Progression): ReadingPosition | undefined {
|
||||
export function r2ProgressionToReadingPosition(progression?: R2Progression, bookId: string): ReadingPosition | undefined {
|
||||
try {
|
||||
return {
|
||||
created: progression.modified,
|
||||
href: progression.locator.href,
|
||||
href: `${urls.originNoSlash}/api/v1/books/${bookId}/resource/${progression.locator.href}`,
|
||||
type: progression.locator.type,
|
||||
title: progression.locator.title,
|
||||
locations: {
|
||||
|
@ -298,7 +298,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import D2Reader, {Locator, ReadingPosition} from '@d-i-t-a/reader'
|
||||
import D2Reader, {Locator} from '@d-i-t-a/reader'
|
||||
import {bookManifestUrl, bookPositionsUrl} from '@/functions/urls'
|
||||
import {BookDto} from '@/types/komga-books'
|
||||
import {getBookTitleCompact} from '@/functions/book-title'
|
||||
@ -700,7 +700,7 @@ export default Vue.extend({
|
||||
this.series = await this.$komgaSeries.getOneSeries(this.book.seriesId)
|
||||
|
||||
const progression = await this.$komgaBooks.getProgression(bookId)
|
||||
const initialLocation = r2ProgressionToReadingPosition(progression)
|
||||
const initialLocation = r2ProgressionToReadingPosition(progression, bookId)
|
||||
|
||||
// parse query params to get context and contextId
|
||||
if (this.$route.query.contextId && this.$route.query.context
|
||||
|
@ -0,0 +1,56 @@
|
||||
package db.migration.sqlite
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode
|
||||
import com.fasterxml.jackson.databind.node.TextNode
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.flywaydb.core.api.migration.BaseJavaMigration
|
||||
import org.flywaydb.core.api.migration.Context
|
||||
import org.springframework.jdbc.core.JdbcTemplate
|
||||
import org.springframework.jdbc.datasource.SingleConnectionDataSource
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.zip.GZIPInputStream
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
class V20240422132621__fix_read_progress_locators : BaseJavaMigration() {
|
||||
override fun migrate(context: Context) {
|
||||
val jdbcTemplate = JdbcTemplate(SingleConnectionDataSource(context.connection, true))
|
||||
|
||||
val readProgressList = jdbcTemplate.queryForList(
|
||||
"""select r.BOOK_ID, r.USER_ID, r.locator from READ_PROGRESS r where locator is not null""",
|
||||
)
|
||||
|
||||
if (readProgressList.isNotEmpty()) {
|
||||
val mapper = ObjectMapper()
|
||||
|
||||
readProgressList.mapNotNull {
|
||||
try {
|
||||
val locator = GZIPInputStream((it["LOCATOR"] as ByteArray).inputStream()).use { gz -> mapper.readTree(gz) }
|
||||
val href = locator["href"]?.asText()
|
||||
if (href == null) null
|
||||
else {
|
||||
val correctHref = href.replaceBefore("/resource/", "").removePrefix("/resource/")
|
||||
(locator as ObjectNode).replace("href", TextNode(correctHref))
|
||||
val gzLocator = ByteArrayOutputStream().use { baos ->
|
||||
GZIPOutputStream(baos).use { gz ->
|
||||
mapper.writeValue(gz, locator)
|
||||
baos.toByteArray()
|
||||
}
|
||||
}
|
||||
arrayOf(gzLocator, it["BOOK_ID"], it["USER_ID"])
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}.let { params ->
|
||||
logger.info { "Updating ${params.size} incorrect read progress locators" }
|
||||
jdbcTemplate.batchUpdate(
|
||||
"""update READ_PROGRESS set locator = ? where BOOK_ID = ? and USER_ID = ?""",
|
||||
params,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -448,7 +448,6 @@ class BookLifecycle(
|
||||
MediaProfile.EPUB -> {
|
||||
val href =
|
||||
newProgression.locator.href
|
||||
.replaceBefore("/resource/", "").removePrefix("/resource/")
|
||||
.replaceAfter("#", "").removeSuffix("#")
|
||||
.let { UriUtils.decode(it, Charsets.UTF_8) }
|
||||
require(href in media.files.map { it.fileName }) { "Resource does not exist in book: $href" }
|
||||
|
Loading…
Reference in New Issue
Block a user