mirror of
https://github.com/gotson/komga.git
synced 2025-12-06 08:32:25 +01:00
properly close streams to avoid file/folder locking
This commit is contained in:
parent
89c3b50bb0
commit
70cc75da72
6 changed files with 62 additions and 60 deletions
|
|
@ -11,7 +11,6 @@ import org.gotson.komga.infrastructure.archive.RarExtractor
|
|||
import org.gotson.komga.infrastructure.archive.ZipExtractor
|
||||
import org.springframework.stereotype.Service
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
|
|
@ -42,12 +41,14 @@ class BookParser(
|
|||
logger.info { "Book has ${pages.size} pages" }
|
||||
|
||||
val thumbnail = try {
|
||||
ByteArrayOutputStream().let {
|
||||
Thumbnails.of(supportedMediaTypes.getValue(mediaType).getPageStream(book.path(), pages.first().fileName))
|
||||
.size(thumbnailSize, thumbnailSize)
|
||||
.outputFormat(thumbnailFormat)
|
||||
.toOutputStream(it)
|
||||
it.toByteArray()
|
||||
ByteArrayOutputStream().use {
|
||||
supportedMediaTypes.getValue(mediaType).getPageStream(book.path(), pages.first().fileName).let { cover ->
|
||||
Thumbnails.of(cover.inputStream())
|
||||
.size(thumbnailSize, thumbnailSize)
|
||||
.outputFormat(thumbnailFormat)
|
||||
.toOutputStream(it)
|
||||
it.toByteArray()
|
||||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
logger.warn(ex) { "Could not generate thumbnail for book: ${book.url}" }
|
||||
|
|
@ -57,7 +58,7 @@ class BookParser(
|
|||
return BookMetadata(mediaType = mediaType, status = Status.READY, pages = pages.toMutableList(), thumbnail = thumbnail)
|
||||
}
|
||||
|
||||
fun getPageStream(book: Book, number: Int): InputStream {
|
||||
fun getPageContent(book: Book, number: Int): ByteArray {
|
||||
logger.info { "Get page #$number for book: ${book.url}" }
|
||||
|
||||
if (book.metadata.status != Status.READY) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package org.gotson.komga.infrastructure.archive
|
|||
|
||||
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
||||
import org.gotson.komga.domain.model.BookPage
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
|
|
@ -10,5 +9,5 @@ abstract class ArchiveExtractor {
|
|||
protected val natSortComparator: Comparator<String> = CaseInsensitiveSimpleNaturalComparator.getInstance()
|
||||
|
||||
abstract fun getPagesList(path: Path): List<BookPage>
|
||||
abstract fun getPageStream(path: Path, entryName: String): InputStream
|
||||
abstract fun getPageStream(path: Path, entryName: String): ByteArray
|
||||
}
|
||||
|
|
@ -19,18 +19,21 @@ class ContentDetector(
|
|||
val metadata = Metadata().also {
|
||||
it[Metadata.RESOURCE_NAME_KEY] = path.fileName.toString()
|
||||
}
|
||||
val mediaType = tika.detector.detect(TikaInputStream.get(path), metadata)
|
||||
|
||||
return mediaType.toString()
|
||||
}
|
||||
|
||||
fun detectMediaType(stream: InputStream): String {
|
||||
stream.use {
|
||||
val mediaType = tika.detector.detect(TikaInputStream.get(it), Metadata())
|
||||
return mediaType.toString()
|
||||
return TikaInputStream.get(path).use {
|
||||
val mediaType = tika.detector.detect(it, metadata)
|
||||
mediaType.toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun detectMediaType(stream: InputStream): String =
|
||||
stream.use {
|
||||
TikaInputStream.get(it).use { tikaStream ->
|
||||
val mediaType = tika.detector.detect(tikaStream, Metadata())
|
||||
mediaType.toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun isImage(mediaType: String): Boolean =
|
||||
mediaType.startsWith("image/")
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package org.gotson.komga.infrastructure.archive
|
|||
import com.github.junrar.Archive
|
||||
import org.gotson.komga.domain.model.BookPage
|
||||
import org.springframework.stereotype.Service
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
|
|
@ -12,26 +11,25 @@ class RarExtractor(
|
|||
private val contentDetector: ContentDetector
|
||||
) : ArchiveExtractor() {
|
||||
|
||||
override fun getPagesList(path: Path): List<BookPage> {
|
||||
val rar = Archive(Files.newInputStream(path))
|
||||
override fun getPagesList(path: Path): List<BookPage> =
|
||||
Archive(Files.newInputStream(path)).use { rar ->
|
||||
rar.fileHeaders
|
||||
.filter { !it.isDirectory }
|
||||
.map {
|
||||
BookPage(
|
||||
it.fileNameString,
|
||||
contentDetector.detectMediaType(rar.getInputStream(it))
|
||||
)
|
||||
}
|
||||
.filter { contentDetector.isImage(it.mediaType) }
|
||||
.sortedWith(
|
||||
compareBy(natSortComparator) { it.fileName }
|
||||
)
|
||||
}
|
||||
|
||||
return rar.fileHeaders
|
||||
.filter { !it.isDirectory }
|
||||
.map {
|
||||
BookPage(
|
||||
it.fileNameString,
|
||||
contentDetector.detectMediaType(rar.getInputStream(it))
|
||||
)
|
||||
}
|
||||
.filter { contentDetector.isImage(it.mediaType) }
|
||||
.sortedWith(
|
||||
compareBy(natSortComparator) { it.fileName }
|
||||
)
|
||||
}
|
||||
|
||||
override fun getPageStream(path: Path, entryName: String): InputStream {
|
||||
val archive = Archive(Files.newInputStream(path))
|
||||
val header = archive.fileHeaders.find { it.fileNameString == entryName }
|
||||
return archive.getInputStream(header)
|
||||
}
|
||||
override fun getPageStream(path: Path, entryName: String): ByteArray =
|
||||
Archive(Files.newInputStream(path)).use { rar ->
|
||||
val header = rar.fileHeaders.find { it.fileNameString == entryName }
|
||||
rar.getInputStream(header).readBytes()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package org.gotson.komga.infrastructure.archive
|
|||
|
||||
import org.gotson.komga.domain.model.BookPage
|
||||
import org.springframework.stereotype.Service
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
|
|
@ -11,24 +10,24 @@ class ZipExtractor(
|
|||
private val contentDetector: ContentDetector
|
||||
) : ArchiveExtractor() {
|
||||
|
||||
override fun getPagesList(path: Path): List<BookPage> {
|
||||
val zip = ZipFile(path.toFile())
|
||||
return zip.entries().toList()
|
||||
.filter { !it.isDirectory }
|
||||
.map {
|
||||
BookPage(
|
||||
it.name,
|
||||
contentDetector.detectMediaType(zip.getInputStream(it))
|
||||
)
|
||||
}
|
||||
.filter { contentDetector.isImage(it.mediaType) }
|
||||
.sortedWith(
|
||||
compareBy(natSortComparator) { it.fileName }
|
||||
)
|
||||
}
|
||||
override fun getPagesList(path: Path): List<BookPage> =
|
||||
ZipFile(path.toFile()).use { zip ->
|
||||
zip.entries().toList()
|
||||
.filter { !it.isDirectory }
|
||||
.map {
|
||||
BookPage(
|
||||
it.name,
|
||||
contentDetector.detectMediaType(zip.getInputStream(it))
|
||||
)
|
||||
}
|
||||
.filter { contentDetector.isImage(it.mediaType) }
|
||||
.sortedWith(
|
||||
compareBy(natSortComparator) { it.fileName }
|
||||
)
|
||||
}
|
||||
|
||||
override fun getPageStream(path: Path, entryName: String): InputStream =
|
||||
ZipFile(path.toFile()).let {
|
||||
it.getInputStream(it.getEntry(entryName))
|
||||
override fun getPageStream(path: Path, entryName: String): ByteArray =
|
||||
ZipFile(path.toFile()).use {
|
||||
it.getInputStream(it.getEntry(entryName)).readBytes()
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,9 @@ import org.gotson.komga.domain.persistence.SerieRepository
|
|||
import org.gotson.komga.domain.service.BookParser
|
||||
import org.gotson.komga.domain.service.MetadataNotReadyException
|
||||
import org.springframework.data.domain.Page
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
|
|
@ -121,7 +123,7 @@ class SerieController(
|
|||
|
||||
try {
|
||||
return bookRepository.findByIdOrNull((bookId))?.let { book ->
|
||||
val pageContent = bookParser.getPageStream(book, pageNumber).readBytes()
|
||||
val pageContent = bookParser.getPageContent(book, pageNumber)
|
||||
|
||||
val mediaType = try {
|
||||
MediaType.parseMediaType(book.metadata.pages[pageNumber - 1].mediaType)
|
||||
|
|
|
|||
Loading…
Reference in a new issue