7zip local manga

it crashes
This commit is contained in:
Abdallah Mehiz 2024-01-02 19:47:47 +01:00
parent 22589a9c30
commit ed18014430
No known key found for this signature in database
GPG Key ID: 975266399F5BAF34
8 changed files with 62 additions and 2 deletions

View File

@ -213,6 +213,7 @@ dependencies {
implementation(libs.disklrucache)
implementation(libs.unifile)
implementation(libs.junrar)
implementation(libs.bundles.sevenzip)
// Preferences
implementation(libs.preferencektx)

View File

@ -90,6 +90,7 @@ class ChapterLoader(
when (format) {
is Format.Directory -> DirectoryPageLoader(format.file)
is Format.Zip -> ZipPageLoader(format.file.toTempFile(context))
is Format.SevenZip -> SevenZipPageLoader(format.file.toTempFile(context))
is Format.Rar -> try {
RarPageLoader(format.file.toTempFile(context))
} catch (e: UnsupportedRarV5Exception) {

View File

@ -0,0 +1,42 @@
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 org.apache.commons.compress.archivers.sevenz.SevenZFile
import tachiyomi.core.util.system.ImageUtil
import java.io.File
/**
* Loader used to load a chapter from a .7z or .cb7 file.
*/
internal class SevenZipPageLoader(file: File) : PageLoader() {
private val zip = SevenZFile(file)
override var isLocal: Boolean = true
override suspend fun getPages(): List<ReaderPage> {
return zip.entries.asSequence()
.filter { !it.isDirectory && ImageUtil.isImage(it.name) { zip.getInputStream(it) } }
.sortedWith { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }
.mapIndexed { i, entry ->
ReaderPage(i).apply {
stream = {
zip.getInputStream(entry)
}
status = Page.State.READY
}
}
.toList()
}
override suspend fun loadPage(page: ReaderPage) {
check(!isRecycled)
}
override fun recycle() {
super.recycle()
zip.close()
}
}

View File

@ -32,6 +32,8 @@ jsoup = "org.jsoup:jsoup:1.17.2"
disklrucache = "com.jakewharton:disklrucache:2.0.2"
unifile = "com.github.tachiyomiorg:unifile:7c257e1c64"
junrar = "com.github.junrar:junrar:7.5.5"
common-compress = "org.apache.commons:commons-compress:1.25.0"
xz = "org.tukaani:xz:1.9"
sqlite-framework = { module = "androidx.sqlite:sqlite-framework", version.ref = "sqlite" }
sqlite-ktx = { module = "androidx.sqlite:sqlite-ktx", version.ref = "sqlite" }
@ -108,4 +110,5 @@ shizuku = ["shizuku-api", "shizuku-provider"]
sqldelight = ["sqldelight-android-driver", "sqldelight-coroutines", "sqldelight-android-paging"]
voyager = ["voyager-navigator", "voyager-screenmodel", "voyager-tab-navigator", "voyager-transitions"]
richtext = ["richtext-commonmark", "richtext-m3"]
test = ["junit", "kotest-assertions", "mockk"]
test = ["junit", "kotest-assertions", "mockk"]
sevenzip = ["common-compress", "xz"]

View File

@ -13,6 +13,7 @@ kotlin {
implementation(libs.unifile)
implementation(libs.junrar)
implementation(libs.bundles.sevenzip)
}
}
val androidMain by getting {

View File

@ -18,6 +18,7 @@ import kotlinx.serialization.json.decodeFromStream
import logcat.LogPriority
import nl.adaptivity.xmlutil.AndroidXmlReader
import nl.adaptivity.xmlutil.serialization.XML
import org.apache.commons.compress.archivers.sevenz.SevenZFile
import tachiyomi.core.i18n.stringResource
import tachiyomi.core.metadata.comicinfo.COMIC_INFO_FILE
import tachiyomi.core.metadata.comicinfo.ComicInfo
@ -339,6 +340,15 @@ actual class LocalSource(
entry?.let { coverManager.update(manga, zip.getInputStream(it)) }
}
}
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) } }
entry?.let { coverManager.update(manga, archive.getInputStream(it)) }
}
}
is Format.Rar -> {
JunrarArchive(format.file.toTempFile(context)).use { archive ->
val entry = archive.fileHeaders

View File

@ -5,7 +5,7 @@ import tachiyomi.core.storage.extension
object Archive {
private val SUPPORTED_ARCHIVE_TYPES = listOf("zip", "cbz", "rar", "cbr", "epub")
private val SUPPORTED_ARCHIVE_TYPES = listOf("zip", "cbz", "7z", "cb7", "rar", "cbr", "epub")
fun isSupported(file: UniFile): Boolean {
return file.extension in SUPPORTED_ARCHIVE_TYPES

View File

@ -6,6 +6,7 @@ import tachiyomi.core.storage.extension
sealed interface Format {
data class Directory(val file: UniFile) : Format
data class Zip(val file: UniFile) : Format
data class SevenZip(val file: UniFile) : Format
data class Rar(val file: UniFile) : Format
data class Epub(val file: UniFile) : Format
@ -17,6 +18,7 @@ sealed interface Format {
when {
isDirectory -> Directory(this)
extension.equals("zip", true) || extension.equals("cbz", true) -> Zip(this)
extension.equals("7z", true) || extension.equals("cb7", true) -> SevenZip(this)
extension.equals("rar", true) || extension.equals("cbr", true) -> Rar(this)
extension.equals("epub", true) -> Epub(this)
else -> throw UnknownFormatException()