mirror of
https://github.com/gotson/komga.git
synced 2025-12-22 16:33:29 +01:00
fix(opds): cannot retrieve full size poster for epub books
Closes: #1312
This commit is contained in:
parent
86f0fcd706
commit
5a71cf757b
7 changed files with 42 additions and 23 deletions
|
|
@ -136,13 +136,8 @@ class BookAnalyzer(
|
|||
}
|
||||
|
||||
val thumbnail = try {
|
||||
when (book.media.profile) {
|
||||
MediaProfile.DIVINA -> divinaExtractors[book.media.mediaType]?.getEntryStream(book.book.path, book.media.pages.first().fileName)
|
||||
MediaProfile.PDF -> pdfExtractor.getPageContentAsImage(book.book.path, 1).content
|
||||
MediaProfile.EPUB -> epubExtractor.getCover(book.book.path)?.content
|
||||
null -> null
|
||||
}?.let { cover ->
|
||||
imageConverter.resizeImageToByteArray(cover, thumbnailType, komgaSettingsProvider.thumbnailSize.maxEdge)
|
||||
getPoster(book)?.let { cover ->
|
||||
imageConverter.resizeImageToByteArray(cover.content, thumbnailType, komgaSettingsProvider.thumbnailSize.maxEdge)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
logger.warn(ex) { "Could not generate thumbnail for book: $book" }
|
||||
|
|
@ -159,6 +154,19 @@ class BookAnalyzer(
|
|||
)
|
||||
}
|
||||
|
||||
fun getPoster(book: BookWithMedia): BookPageContent? = when (book.media.profile) {
|
||||
MediaProfile.DIVINA -> divinaExtractors[book.media.mediaType]?.getEntryStream(book.book.path, book.media.pages.first().fileName)?.let {
|
||||
BookPageContent(
|
||||
it,
|
||||
book.media.pages.first().mediaType,
|
||||
)
|
||||
}
|
||||
|
||||
MediaProfile.PDF -> pdfExtractor.getPageContentAsImage(book.book.path, 1)
|
||||
MediaProfile.EPUB -> epubExtractor.getCover(book.book.path)
|
||||
null -> null
|
||||
}
|
||||
|
||||
@Throws(
|
||||
MediaNotReadyException::class,
|
||||
IndexOutOfBoundsException::class,
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ class BookLifecycle(
|
|||
return selected
|
||||
}
|
||||
|
||||
fun getThumbnailBytes(bookId: String, resizeTo: Int? = null): ByteArray? {
|
||||
fun getThumbnailBytes(bookId: String, resizeTo: Int? = null): BookPageContent? {
|
||||
getThumbnail(bookId)?.let {
|
||||
val thumbnailBytes = when {
|
||||
it.thumbnail != null -> it.thumbnail
|
||||
|
|
@ -190,19 +190,32 @@ class BookLifecycle(
|
|||
}
|
||||
|
||||
if (resizeTo != null) {
|
||||
return try {
|
||||
imageConverter.resizeImageToByteArray(thumbnailBytes, resizeTargetFormat, resizeTo)
|
||||
try {
|
||||
return BookPageContent(
|
||||
imageConverter.resizeImageToByteArray(thumbnailBytes, resizeTargetFormat, resizeTo),
|
||||
resizeTargetFormat.mediaType,
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
logger.error(e) { "Resize thumbnail of book $bookId to $resizeTo: failed" }
|
||||
thumbnailBytes
|
||||
}
|
||||
}
|
||||
|
||||
return thumbnailBytes
|
||||
return BookPageContent(thumbnailBytes, it.mediaType)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun getThumbnailBytesOriginal(bookId: String): BookPageContent? {
|
||||
val thumbnail = getThumbnail(bookId) ?: return null
|
||||
return if (thumbnail.type == ThumbnailBook.Type.GENERATED) {
|
||||
val book = bookRepository.findByIdOrNull(bookId) ?: return null
|
||||
val media = mediaRepository.findById(book.id)
|
||||
bookAnalyzer.getPoster(BookWithMedia(book, media))
|
||||
} else {
|
||||
getThumbnailBytes(bookId)
|
||||
}
|
||||
}
|
||||
|
||||
fun getThumbnailBytesByThumbnailId(thumbnailId: String): ByteArray? =
|
||||
thumbnailBookRepository.findByIdOrNull(thumbnailId)?.let {
|
||||
getBytesFromThumbnailBook(it)
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class ReadListLifecycle(
|
|||
this.take(4)
|
||||
}
|
||||
|
||||
val images = ids.mapNotNull { bookLifecycle.getThumbnailBytes(it) }
|
||||
val images = ids.mapNotNull { bookLifecycle.getThumbnailBytes(it)?.content }
|
||||
return mosaicGenerator.createMosaic(images)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ class SeriesLifecycle(
|
|||
?: bookRepository.findLastIdInSeriesOrNull(seriesId)
|
||||
Library.SeriesCover.LAST -> bookRepository.findLastIdInSeriesOrNull(seriesId)
|
||||
}
|
||||
if (bookId != null) return bookLifecycle.getThumbnailBytes(bookId)
|
||||
if (bookId != null) return bookLifecycle.getThumbnailBytes(bookId)?.content
|
||||
}
|
||||
|
||||
return null
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ package org.gotson.komga.interfaces.api.opds
|
|||
import io.swagger.v3.oas.annotations.media.Content
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse
|
||||
import org.gotson.komga.domain.model.ThumbnailBook
|
||||
import org.gotson.komga.domain.persistence.BookRepository
|
||||
import org.gotson.komga.domain.persistence.SeriesMetadataRepository
|
||||
import org.gotson.komga.domain.service.BookLifecycle
|
||||
import org.gotson.komga.infrastructure.image.ImageConverter
|
||||
import org.gotson.komga.infrastructure.image.ImageType
|
||||
import org.gotson.komga.infrastructure.security.KomgaPrincipal
|
||||
import org.gotson.komga.interfaces.api.checkContentRestriction
|
||||
|
|
@ -23,6 +23,7 @@ class OpdsCommonController(
|
|||
private val seriesMetadataRepository: SeriesMetadataRepository,
|
||||
private val bookRepository: BookRepository,
|
||||
private val bookLifecycle: BookLifecycle,
|
||||
private val imageConverter: ImageConverter,
|
||||
) {
|
||||
|
||||
@ApiResponse(content = [Content(schema = Schema(type = "string", format = "binary"))])
|
||||
|
|
@ -38,11 +39,8 @@ class OpdsCommonController(
|
|||
@PathVariable bookId: String,
|
||||
): ByteArray {
|
||||
principal.user.checkContentRestriction(bookId, bookRepository, seriesMetadataRepository)
|
||||
val thumbnail = bookLifecycle.getThumbnail(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
return if (thumbnail.type == ThumbnailBook.Type.GENERATED) {
|
||||
bookLifecycle.getBookPage(bookRepository.findByIdOrNull(bookId)!!, 1, ImageType.JPEG).content
|
||||
} else {
|
||||
bookLifecycle.getThumbnailBytes(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
}
|
||||
val poster = bookLifecycle.getThumbnailBytesOriginal(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
return if (poster.mediaType != ImageType.JPEG.mediaType) imageConverter.convertImage(poster.content, ImageType.JPEG.imageIOFormat)
|
||||
else poster.content
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -670,7 +670,7 @@ class OpdsController(
|
|||
principal.user.checkContentRestriction(bookId, bookRepository, seriesMetadataRepository)
|
||||
val thumbnail = bookLifecycle.getThumbnail(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
|
||||
return bookLifecycle.getThumbnailBytes(bookId, if (thumbnail.type == ThumbnailBook.Type.GENERATED) null else komgaSettingsProvider.thumbnailSize.maxEdge)
|
||||
return bookLifecycle.getThumbnailBytes(bookId, if (thumbnail.type == ThumbnailBook.Type.GENERATED) null else komgaSettingsProvider.thumbnailSize.maxEdge)?.content
|
||||
?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ class BookController(
|
|||
): ByteArray {
|
||||
principal.user.checkContentRestriction(bookId, bookRepository, seriesMetadataRepository)
|
||||
|
||||
return bookLifecycle.getThumbnailBytes(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
return bookLifecycle.getThumbnailBytes(bookId)?.content ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
}
|
||||
|
||||
@ApiResponse(content = [Content(schema = Schema(type = "string", format = "binary"))])
|
||||
|
|
|
|||
Loading…
Reference in a new issue