mirror of
https://github.com/gotson/komga.git
synced 2025-12-22 00:13:30 +01:00
parent
c5d9f10e92
commit
0a06a6f799
4 changed files with 61 additions and 1 deletions
|
|
@ -6,6 +6,8 @@ export function getBookFormatFromMediaType (mediaType: string): BookFormat {
|
|||
return { type: 'CBZ', color: '#4CAF50' }
|
||||
case 'application/pdf':
|
||||
return { type: 'PDF', color: '#FF5722' }
|
||||
case 'application/epub+zip':
|
||||
return { type: 'EPUB', color: '#ff5ab1' }
|
||||
default:
|
||||
return { type: '?', color: '#000000' }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ dependencies {
|
|||
implementation("com.github.junrar:junrar:4.0.0")
|
||||
implementation("org.apache.pdfbox:pdfbox:2.0.19")
|
||||
implementation("net.grey-panther:natural-comparator:1.1")
|
||||
implementation("org.jsoup:jsoup:1.13.1")
|
||||
|
||||
implementation("net.coobird:thumbnailator:0.4.11")
|
||||
implementation("com.twelvemonkeys.imageio:imageio-jpeg:3.5")
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class FileSystemScanner(
|
|||
private val komgaProperties: KomgaProperties
|
||||
) {
|
||||
|
||||
val supportedExtensions = listOf("cbz", "zip", "cbr", "rar", "pdf")
|
||||
val supportedExtensions = listOf("cbz", "zip", "cbr", "rar", "pdf", "epub")
|
||||
|
||||
fun scanRootFolder(root: Path): List<Series> {
|
||||
logger.info { "Scanning folder: $root" }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package org.gotson.komga.infrastructure.mediacontainer
|
||||
|
||||
import mu.KotlinLogging
|
||||
import org.apache.commons.compress.archivers.zip.ZipFile
|
||||
import org.gotson.komga.domain.model.MediaContainerEntry
|
||||
import org.jsoup.Jsoup
|
||||
import org.springframework.stereotype.Service
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
@Service
|
||||
class EpubExtractor(contentDetector: ContentDetector) : ZipExtractor(contentDetector) {
|
||||
|
||||
override fun mediaTypes(): List<String> = listOf("application/epub+zip")
|
||||
|
||||
override fun getEntries(path: Path): List<MediaContainerEntry> {
|
||||
ZipFile(path.toFile()).use { zip ->
|
||||
try {
|
||||
val packagePath = zip.getEntry("META-INF/container.xml").let { entry ->
|
||||
val container = zip.getInputStream(entry).use { Jsoup.parse(it, null, "") }
|
||||
container.getElementsByTag("rootfile").first().attr("full-path")
|
||||
}
|
||||
|
||||
val opf = zip.getInputStream(zip.getEntry(packagePath)).use { Jsoup.parse(it, null, "") }
|
||||
|
||||
val manifest = opf.select("manifest > item")
|
||||
.associate { it.attr("id") to ManifestItem(it.attr("id"), it.attr("href"), it.attr("media-type")) }
|
||||
|
||||
val pages = opf.select("spine > itemref").map { it.attr("idref") }
|
||||
.mapNotNull { manifest[it] }
|
||||
.map { it.href }
|
||||
|
||||
val images = pages.flatMap { pagePath ->
|
||||
val doc = zip.getInputStream(zip.getEntry(pagePath)).use { Jsoup.parse(it, null, "") }
|
||||
doc.getElementsByTag("img")
|
||||
.map { it.attr("src") }
|
||||
.map { Paths.get(pagePath).parent?.resolve(it).toString() }
|
||||
}
|
||||
|
||||
return images.map { image ->
|
||||
MediaContainerEntry(image, manifest.values.first { it.href == image }.mediaType)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger.error(e) { "File is not a proper Epub, treating it as a zip file" }
|
||||
return super.getEntries(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class ManifestItem(
|
||||
val id: String,
|
||||
val href: String,
|
||||
val mediaType: String
|
||||
)
|
||||
}
|
||||
Loading…
Reference in a new issue