mirror of
https://github.com/gotson/komga.git
synced 2025-12-06 08:32:25 +01:00
added cbr/rar support
archive entries are sorted using natural sort comparator
This commit is contained in:
parent
f88279b29b
commit
08c78f6a92
6 changed files with 54 additions and 11 deletions
|
|
@ -56,6 +56,8 @@ dependencies {
|
|||
|
||||
implementation("org.apache.tika:tika-core:1.22")
|
||||
implementation("net.lingala.zip4j:zip4j:2.1.2")
|
||||
implementation("com.github.junrar:junrar:4.0.0")
|
||||
implementation("net.grey-panther:natural-comparator:1.1")
|
||||
|
||||
runtimeOnly("com.h2database:h2:1.4.199")
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.gotson.komga.domain.model.BookMetadata
|
|||
import org.gotson.komga.domain.model.Status
|
||||
import org.gotson.komga.domain.model.path
|
||||
import org.gotson.komga.infrastructure.archive.ContentDetector
|
||||
import org.gotson.komga.infrastructure.archive.RarExtractor
|
||||
import org.gotson.komga.infrastructure.archive.ZipExtractor
|
||||
import org.springframework.stereotype.Service
|
||||
import java.io.InputStream
|
||||
|
|
@ -15,11 +16,13 @@ private val logger = KotlinLogging.logger {}
|
|||
@Service
|
||||
class BookParser(
|
||||
private val contentDetector: ContentDetector,
|
||||
private val zipExtractor: ZipExtractor
|
||||
private val zipExtractor: ZipExtractor,
|
||||
private val rarExtractor: RarExtractor
|
||||
) {
|
||||
|
||||
val supportedMimeTypes = listOf(
|
||||
"application/zip"
|
||||
val supportedMediaTypes = mapOf(
|
||||
"application/zip" to zipExtractor,
|
||||
"application/x-rar-compressed" to rarExtractor
|
||||
)
|
||||
|
||||
fun parse(book: Book): BookMetadata {
|
||||
|
|
@ -27,10 +30,10 @@ class BookParser(
|
|||
|
||||
val mediaType = contentDetector.detectMediaType(book.path())
|
||||
logger.info { "Detected media type: $mediaType" }
|
||||
if (!supportedMimeTypes.contains(mediaType))
|
||||
if (!supportedMediaTypes.keys.contains(mediaType))
|
||||
throw UnsupportedMediaTypeException("Unsupported mime type: $mediaType. File: ${book.url}", mediaType)
|
||||
|
||||
val pageNames = zipExtractor.getFilenames(book.path())
|
||||
val pageNames = supportedMediaTypes.getValue(mediaType).getFilenames(book.path())
|
||||
logger.info { "Book has ${pageNames.size} pages" }
|
||||
|
||||
return BookMetadata(mediaType = mediaType, status = Status.READY, pages = pageNames)
|
||||
|
|
@ -49,7 +52,7 @@ class BookParser(
|
|||
throw ArrayIndexOutOfBoundsException("Page $number does not exist")
|
||||
}
|
||||
|
||||
return zipExtractor.getEntryStream(book.path(), book.metadata.pages[number - 1])
|
||||
return supportedMediaTypes.getValue(book.metadata.mediaType!!).getEntryStream(book.path(), book.metadata.pages[number - 1])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ private val logger = KotlinLogging.logger {}
|
|||
@Service
|
||||
class FileSystemScanner {
|
||||
|
||||
val supportedExtensions = listOf("cbz", "zip")
|
||||
val supportedExtensions = listOf("cbz", "zip", "cbr", "rar")
|
||||
|
||||
fun scanRootFolder(root: Path): List<Serie> {
|
||||
logger.info { "Scanning folder: $root" }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package org.gotson.komga.infrastructure.archive
|
||||
|
||||
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
abstract class ArchiveExtractor {
|
||||
|
||||
protected val natSortComparator: Comparator<String> = CaseInsensitiveSimpleNaturalComparator.getInstance()
|
||||
|
||||
abstract fun getFilenames(path: Path): List<String>
|
||||
abstract fun getEntryStream(path: Path, entryName: String): InputStream
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.gotson.komga.infrastructure.archive
|
||||
|
||||
import com.github.junrar.Archive
|
||||
import com.github.junrar.Junrar
|
||||
import org.springframework.stereotype.Service
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
@Service
|
||||
class RarExtractor : ArchiveExtractor() {
|
||||
|
||||
override fun getFilenames(path: Path): List<String> {
|
||||
val contentsDescription = Junrar.getContentsDescription(path.toFile())
|
||||
|
||||
return contentsDescription.map { it.path }.sortedWith(natSortComparator)
|
||||
}
|
||||
|
||||
override fun getEntryStream(path: Path, entryName: String): InputStream {
|
||||
val archive = Archive(Files.newInputStream(path))
|
||||
val header = archive.fileHeaders.find { it.fileNameString == entryName }
|
||||
return archive.getInputStream(header)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,12 @@ import java.io.InputStream
|
|||
import java.nio.file.Path
|
||||
|
||||
@Service
|
||||
class ZipExtractor {
|
||||
class ZipExtractor : ArchiveExtractor() {
|
||||
|
||||
fun getFilenames(path: Path) =
|
||||
ZipFile(path.toFile()).fileHeaders.map { it.fileName }.toMutableList()
|
||||
override fun getFilenames(path: Path) =
|
||||
ZipFile(path.toFile()).fileHeaders.map { it.fileName }.sortedWith(natSortComparator)
|
||||
|
||||
fun getEntryStream(path: Path, entryName: String): InputStream =
|
||||
override fun getEntryStream(path: Path, entryName: String): InputStream =
|
||||
ZipFile(path.toFile()).let {
|
||||
it.getInputStream(it.getFileHeader(entryName))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue