diff --git a/komga/src/flyway/resources/db/migration/sqlite/V20231214163213__reanalyze_epub.sql b/komga/src/flyway/resources/db/migration/sqlite/V20231214163213__reanalyze_epub.sql new file mode 100644 index 00000000..9aa1d063 --- /dev/null +++ b/komga/src/flyway/resources/db/migration/sqlite/V20231214163213__reanalyze_epub.sql @@ -0,0 +1,9 @@ +update media +set STATUS = 'OUTDATED' +where MEDIA_TYPE = 'application/epub+zip'; + +update media +set STATUS = 'OUTDATED' +where BOOK_ID in (select ID + from BOOK + where URL like '%.epub' collate NOCASE); diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt index 08edf0f3..52ca4cc4 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt @@ -59,14 +59,17 @@ class BookAnalyzer( fun analyze(book: Book, analyzeDimensions: Boolean): Media { logger.info { "Trying to analyze book: $book" } return try { - val mediaType = contentDetector.detectMediaType(book.path).let { + var mediaType = contentDetector.detectMediaType(book.path).let { logger.info { "Detected media type: $it" } MediaType.fromMediaType(it) ?: return Media(mediaType = it, status = Media.Status.UNSUPPORTED, comment = "ERR_1001", bookId = book.id) } if (book.path.extension.lowercase() == "epub" && mediaType != MediaType.EPUB) { - logger.warn { "Epub file detected as zip, file is probably broken: ${book.path}" } - return Media(mediaType = mediaType.type, status = Media.Status.ERROR, comment = "ERR_1032", bookId = book.id) + if (epubExtractor.isEpub(book.path)) mediaType = MediaType.EPUB + else { + logger.warn { "Epub file is malformed, file is probably broken: ${book.path}" } + return Media(mediaType = mediaType.type, status = Media.Status.ERROR, comment = "ERR_1032", bookId = book.id) + } } when (mediaType.profile) { @@ -208,6 +211,7 @@ class BookAnalyzer( MediaProfile.EPUB -> if (book.media.epubDivinaCompatible) epubExtractor.getEntryStream(book.book.path, book.media.pages[number - 1].fileName) else throw MediaUnsupportedException("Epub profile does not support getting page content") + null -> throw MediaNotReadyException() } } diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/mediacontainer/epub/EpubExtractor.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/mediacontainer/epub/EpubExtractor.kt index 7546f348..c8d23c13 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/mediacontainer/epub/EpubExtractor.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/mediacontainer/epub/EpubExtractor.kt @@ -36,6 +36,13 @@ class EpubExtractor( zip.getInputStream(zip.getEntry(entryName)).use { it.readBytes() } } + fun isEpub(path: Path): Boolean = + try { + getEntryStream(path, "mimetype").decodeToString() == "application/epub+zip" + } catch (e: Exception) { + false + } + /** * Retrieves the book cover along with its mediaType from the epub 2/3 manifest */