Skip to content

Commit

Permalink
fix: sync progress not compatible between Cantook and web reader
Browse files Browse the repository at this point in the history
Closes: #1477
  • Loading branch information
gotson committed Apr 22, 2024
1 parent bb046d6 commit 0211096
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 6 deletions.
7 changes: 4 additions & 3 deletions komga-webui/src/functions/readium.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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),
Expand All @@ -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: {
Expand Down
4 changes: 2 additions & 2 deletions komga-webui/src/views/EpubReader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down

0 comments on commit 0211096

Please sign in to comment.