From 9e8b14d141b6003faba972a6463af6f0c24a74ef Mon Sep 17 00:00:00 2001 From: Claudemirovsky <63046606+Claudemirovsky@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:24:51 -0300 Subject: [PATCH] fix: Fix crash when reading local 7zip manga (#1) --- .../ui/reader/loader/SevenZipPageLoader.kt | 16 +++++----------- core/build.gradle.kts | 1 + .../kanade/tachiyomi/util/storage/SevenZUtil.kt | 16 ++++++++++++++++ .../kotlin/tachiyomi/source/local/LocalSource.kt | 7 +++---- 4 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 core/src/main/java/eu/kanade/tachiyomi/util/storage/SevenZUtil.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/SevenZipPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/SevenZipPageLoader.kt index 50b24ad54..cd69cb1f8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/SevenZipPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/SevenZipPageLoader.kt @@ -2,9 +2,8 @@ package eu.kanade.tachiyomi.ui.reader.loader import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.ui.reader.model.ReaderPage -import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder +import eu.kanade.tachiyomi.util.storage.SevenZUtil.getImages import org.apache.commons.compress.archivers.sevenz.SevenZFile -import tachiyomi.core.util.system.ImageUtil import java.io.File /** @@ -12,23 +11,18 @@ import java.io.File */ internal class SevenZipPageLoader(file: File) : PageLoader() { - private val zip = SevenZFile(file) + private val zip by lazy { SevenZFile(file) } override var isLocal: Boolean = true override suspend fun getPages(): List { - return zip.entries.asSequence() - .filter { !it.isDirectory && ImageUtil.isImage(it.name) { zip.getInputStream(it) } } - .sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) } + return zip.getImages() .mapIndexed { i, entry -> ReaderPage(i).apply { - stream = { - zip.getInputStream(entry) - } + stream = { entry } status = Page.State.READY } - } - .toList() + }.toList() } override suspend fun loadPage(page: ReaderPage) { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index e90a1fd06..6267cae2b 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -32,6 +32,7 @@ dependencies { implementation(libs.image.decoder) implementation(libs.unifile) + implementation(libs.bundles.sevenzip) api(kotlinx.coroutines.core) api(kotlinx.serialization.json) diff --git a/core/src/main/java/eu/kanade/tachiyomi/util/storage/SevenZUtil.kt b/core/src/main/java/eu/kanade/tachiyomi/util/storage/SevenZUtil.kt new file mode 100644 index 000000000..908d6219e --- /dev/null +++ b/core/src/main/java/eu/kanade/tachiyomi/util/storage/SevenZUtil.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.util.storage + +import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder +import org.apache.commons.compress.archivers.sevenz.SevenZFile +import tachiyomi.core.util.system.ImageUtil +import java.io.InputStream + +object SevenZUtil { + fun SevenZFile.getImages(): Sequence { + return generateSequence { runCatching { getNextEntry() }.getOrNull() } + .filter { !it.isDirectory && ImageUtil.isImage(it.name) { getInputStream(it) } } + .sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) } + .map(::getInputStream) + .map { it.use(InputStream::readBytes).inputStream() } // ByteArrayInputStream + } +} diff --git a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt index bebcec808..18f3079dc 100644 --- a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt +++ b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt @@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder import eu.kanade.tachiyomi.util.storage.EpubFile +import eu.kanade.tachiyomi.util.storage.SevenZUtil.getImages import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.serialization.json.Json @@ -342,11 +343,9 @@ actual class LocalSource( } is Format.SevenZip -> { SevenZFile(format.file.toTempFile(context)).use { archive -> - val entry = archive.entries.toList() - .sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) } - .find { !it.isDirectory && ImageUtil.isImage(it.name) { archive.getInputStream(it) } } + val entry = archive.getImages().firstOrNull() - entry?.let { coverManager.update(manga, archive.getInputStream(it)) } + entry?.let { coverManager.update(manga, it) } } } is Format.Rar -> {