fix: epub extension could get lost during book restoration

This commit is contained in:
Gauthier Roebroeck 2026-03-26 17:27:17 +08:00
parent 457a7247d5
commit 90d3a1dbc3
3 changed files with 39 additions and 7 deletions

View file

@ -24,6 +24,14 @@ interface MediaRepository {
fun update(media: Media)
/**
* Performs a full copy of a Media, including MediaExtension, pages, and files.
*/
fun copy(
fromBookId: String,
toBookId: String,
)
fun delete(bookId: String)
fun delete(bookIds: Collection<String>)

View file

@ -381,9 +381,7 @@ class LibraryContentLifecycle(
logger.info { "Match found, restore $match into $bookToAdd" }
transactionTemplate.executeWithoutResult {
// copy media
mediaRepository.findById(match.id).let { deleted ->
mediaRepository.update(deleted.copy(bookId = bookToAdd.id))
}
mediaRepository.copy(match.id, bookToAdd.id)
// copy generated and user uploaded thumbnails
thumbnailBookRepository.findAllByBookIdAndType(match.id, setOf(ThumbnailBook.Type.GENERATED, ThumbnailBook.Type.USER_UPLOADED)).forEach { deleted ->

View file

@ -1,6 +1,7 @@
package org.gotson.komga.infrastructure.jooq.main
import com.fasterxml.jackson.databind.ObjectMapper
import io.github.oshai.kotlinlogging.KotlinLogging
import org.gotson.komga.domain.model.BookPage
import org.gotson.komga.domain.model.Dimension
import org.gotson.komga.domain.model.Media
@ -26,6 +27,8 @@ import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
import java.time.ZoneId
private val logger = KotlinLogging.logger {}
@Component
class MediaDao(
dslRW: DSLContext,
@ -158,7 +161,14 @@ class MediaDao(
media.pageCount,
media.epubDivinaCompatible,
media.epubIsKepub,
media.extension?.let { if (it is ProxyExtension) null else it::class.qualifiedName },
media.extension?.let {
if (it is ProxyExtension) {
logger.error { "Found ProxyExtension while trying to insert Media: this is not expected and should be reported." }
null
} else {
it::class.qualifiedName
}
},
media.extension?.let { if (it is ProxyExtension) null else mapper.serializeJsonGz(it) },
)
}
@ -249,9 +259,13 @@ class MediaDao(
.set(m.EPUB_DIVINA_COMPATIBLE, media.epubDivinaCompatible)
.set(m.EPUB_IS_KEPUB, media.epubIsKepub)
.apply {
if (media.extension != null && media.extension !is ProxyExtension) {
set(m.EXTENSION_CLASS, media.extension::class.qualifiedName)
set(m.EXTENSION_VALUE_BLOB, mapper.serializeJsonGz(media.extension))
if (media.extension != null) {
if (media.extension !is ProxyExtension) {
set(m.EXTENSION_CLASS, media.extension::class.qualifiedName)
set(m.EXTENSION_VALUE_BLOB, mapper.serializeJsonGz(media.extension))
} else {
logger.error { "Found ProxyExtension while trying to update Media: this is not expected and should be reported." }
}
}
}.set(m.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
.where(m.BOOK_ID.eq(media.bookId))
@ -271,6 +285,18 @@ class MediaDao(
dslRW.insertFiles(listOf(media))
}
@Transactional
override fun copy(
fromBookId: String,
toBookId: String,
) {
val source = findById(fromBookId)
val sourceExtension = findExtensionByIdOrNull(fromBookId)
val copy = source.copy(bookId = toBookId, extension = sourceExtension)
update(copy)
}
@Transactional
override fun delete(bookId: String) {
dslRW.deleteFrom(p).where(p.BOOK_ID.eq(bookId)).execute()