Move archive related code to :core:archive

(cherry picked from commit bd7b35419861df6d426d6ec0a188391910d0f615)
This commit is contained in:
AntsyLich 2024-09-05 16:00:46 +06:00 committed by Cuong-Tran
parent f7b9f372bd
commit a1e0a1cd4b
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
26 changed files with 80 additions and 62 deletions

View file

@ -169,11 +169,11 @@ dependencies {
implementation(projects.i18n)
// KMK -->
implementation(projects.i18nKmk)
implementation(projects.flagkit)
// KMK <--
// SY -->
implementation(projects.i18nSy)
// SY <--
implementation(projects.core.archive)
implementation(projects.core.common)
implementation(projects.coreMetadata)
implementation(projects.sourceApi)
@ -280,6 +280,7 @@ dependencies {
implementation(libs.material.kolor)
implementation(libs.haze)
implementation(compose.colorpicker)
implementation(projects.flagkit)
// KMK <--
// Logging

View file

@ -5,7 +5,7 @@ import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import eu.kanade.tachiyomi.util.storage.CbzCrypto
import mihon.core.archive.CbzCrypto
import tachiyomi.core.common.preference.TriState
import tachiyomi.core.metadata.comicinfo.ComicInfo
import tachiyomi.core.metadata.comicinfo.ComicInfoPublishingStatus

View file

@ -48,11 +48,11 @@ import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
import eu.kanade.tachiyomi.ui.category.biometric.BiometricTimesScreen
import eu.kanade.tachiyomi.util.storage.CbzCrypto
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.isAuthenticationSupported
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableMap
import mihon.core.archive.CbzCrypto
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR

View file

@ -12,10 +12,10 @@ import coil3.fetch.SourceFetchResult
import coil3.request.Options
import coil3.request.bitmapConfig
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.util.storage.CbzCrypto
import eu.kanade.tachiyomi.util.storage.CbzCrypto.getCoverStream
import eu.kanade.tachiyomi.util.system.GLUtil
import mihon.core.common.archive.archiveReader
import mihon.core.archive.CbzCrypto
import mihon.core.archive.CbzCrypto.getCoverStream
import mihon.core.archive.archiveReader
import okio.BufferedSource
import tachiyomi.core.common.util.system.ImageUtil
import tachiyomi.decoder.ImageDecoder

View file

@ -12,7 +12,6 @@ import eu.kanade.tachiyomi.data.notification.NotificationHandler
import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.storage.CbzCrypto
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.DiskUtil.NOMEDIA_FILE
import eu.kanade.tachiyomi.util.storage.saveTo
@ -44,7 +43,8 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope
import logcat.LogPriority
import mihon.core.common.archive.ZipWriter
import mihon.core.archive.CbzCrypto
import mihon.core.archive.ZipWriter
import nl.adaptivity.xmlutil.serialization.XML
import okhttp3.Response
import tachiyomi.core.common.i18n.stringResource

View file

@ -26,11 +26,11 @@ import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.network.JavaScriptEngine
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.AndroidSourceManager
import eu.kanade.tachiyomi.util.storage.CbzCrypto
import exh.eh.EHentaiUpdateHelper
import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory
import kotlinx.serialization.json.Json
import kotlinx.serialization.protobuf.ProtoBuf
import mihon.core.archive.CbzCrypto
import net.zetetic.database.sqlcipher.SupportOpenHelperFactory
import nl.adaptivity.xmlutil.XmlDeclMode
import nl.adaptivity.xmlutil.core.XmlVersion

View file

@ -13,7 +13,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import mihon.core.common.archive.ArchiveReader
import mihon.core.archive.ArchiveReader
import tachiyomi.core.common.util.system.ImageUtil
import uy.kohesive.injekt.injectLazy
import java.io.File

View file

@ -8,7 +8,8 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import mihon.core.common.archive.archiveReader
import mihon.core.archive.archiveReader
import mihon.core.archive.epubReader
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.core.common.util.system.logcat
@ -127,7 +128,7 @@ class ChapterLoader(
when (format) {
is Format.Directory -> DirectoryPageLoader(format.file)
is Format.Archive -> ArchivePageLoader(format.file.archiveReader(context))
is Format.Epub -> EpubPageLoader(format.file.archiveReader(context))
is Format.Epub -> EpubPageLoader(format.file.epubReader(context))
}
}
else -> error(context.stringResource(MR.strings.loader_not_implemented_error))
@ -145,7 +146,7 @@ class ChapterLoader(
when (format) {
is Format.Directory -> DirectoryPageLoader(format.file)
is Format.Archive -> ArchivePageLoader(format.file.archiveReader(context))
is Format.Epub -> EpubPageLoader(format.file.archiveReader(context))
is Format.Epub -> EpubPageLoader(format.file.epubReader(context))
}
}
source is HttpSource -> HttpPageLoader(chapter, source)

View file

@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import mihon.core.common.archive.archiveReader
import mihon.core.archive.archiveReader
import tachiyomi.domain.manga.model.Manga
import uy.kohesive.injekt.injectLazy

View file

@ -2,27 +2,22 @@ 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.storage.EpubFile
import mihon.core.common.archive.ArchiveReader
import mihon.core.archive.EpubReader
/**
* Loader used to load a chapter from a .epub file.
*/
internal class EpubPageLoader(reader: ArchiveReader) : PageLoader() {
private val epub = EpubFile(reader)
internal class EpubPageLoader(private val reader: EpubReader) : PageLoader() {
override var isLocal: Boolean = true
override suspend fun getPages(): List<ReaderPage> {
return epub.getImagesFromPages()
.mapIndexed { i, path ->
val streamFn = { epub.getInputStream(path)!! }
ReaderPage(i).apply {
stream = streamFn
status = Page.State.READY
}
return reader.getImagesFromPages().mapIndexed { i, path ->
ReaderPage(i).apply {
stream = { reader.getInputStream(path)!! }
status = Page.State.READY
}
}
}
override suspend fun loadPage(page: ReaderPage) {
@ -31,6 +26,6 @@ internal class EpubPageLoader(reader: ArchiveReader) : PageLoader() {
override fun recycle() {
super.recycle()
epub.close()
reader.close()
}
}

1
core/archive/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,19 @@
plugins {
id("mihon.library")
kotlin("android")
kotlin("plugin.serialization")
}
android {
namespace = "mihon.core.archive"
}
dependencies {
implementation(libs.jsoup)
implementation(libs.libarchive)
implementation(libs.unifile)
// KMK -->
implementation(projects.core.common)
implementation(libs.injekt.core)
// KMK <--
}

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

View file

@ -1,4 +1,4 @@
package mihon.core.common.archive
package mihon.core.archive
class ArchiveEntry(
val name: String,

View file

@ -1,6 +1,5 @@
package mihon.core.common.archive
package mihon.core.archive
import eu.kanade.tachiyomi.util.storage.CbzCrypto
import me.zhanghai.android.libarchive.Archive
import me.zhanghai.android.libarchive.ArchiveEntry
import me.zhanghai.android.libarchive.ArchiveException

View file

@ -1,12 +1,9 @@
package mihon.core.common.archive
package mihon.core.archive
import android.content.Context
import android.os.ParcelFileDescriptor
import android.system.Os
import android.system.OsConstants
import com.hippo.unifile.UniFile
import me.zhanghai.android.libarchive.ArchiveException
import tachiyomi.core.common.storage.openFileDescriptor
import java.io.Closeable
import java.io.InputStream
@ -90,5 +87,3 @@ class ArchiveReader(pfd: ParcelFileDescriptor) : Closeable {
Os.munmap(address, size)
}
}
fun UniFile.archiveReader(context: Context) = openFileDescriptor(context, "r").use { ArchiveReader(it) }

View file

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.util.storage
package mihon.core.archive
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
@ -9,7 +9,6 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import mihon.core.common.archive.ArchiveReader
import tachiyomi.core.common.util.system.ImageUtil
import uy.kohesive.injekt.injectLazy
import java.io.BufferedInputStream

View file

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.util.storage
package mihon.core.archive
import mihon.core.common.archive.ArchiveReader
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import java.io.Closeable
@ -8,9 +7,9 @@ import java.io.File
import java.io.InputStream
/**
* Wrapper over ZipFile to load files in epub format.
* Wrapper over ArchiveReader to load files in epub format.
*/
class EpubFile(private val reader: ArchiveReader) : Closeable by reader {
class EpubReader(private val reader: ArchiveReader) : Closeable by reader {
/**
* Path separator used by this epub.

View file

@ -0,0 +1,12 @@
package mihon.core.archive
import android.content.Context
import android.os.ParcelFileDescriptor
import com.hippo.unifile.UniFile
internal fun UniFile.openFileDescriptor(context: Context, mode: String): ParcelFileDescriptor =
context.contentResolver.openFileDescriptor(uri, mode) ?: error("Failed to open file descriptor: ${filePath ?: uri}")
fun UniFile.archiveReader(context: Context) = openFileDescriptor(context, "r").use { ArchiveReader(it) }
fun UniFile.epubReader(context: Context) = EpubReader(archiveReader(context))

View file

@ -1,15 +1,13 @@
package mihon.core.common.archive
package mihon.core.archive
import android.content.Context
import android.system.Os
import android.system.StructStat
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.util.storage.CbzCrypto
import me.zhanghai.android.libarchive.Archive
import me.zhanghai.android.libarchive.ArchiveEntry
import me.zhanghai.android.libarchive.ArchiveEntry.AE_IFREG
import me.zhanghai.android.libarchive.ArchiveException
import tachiyomi.core.common.storage.openFileDescriptor
import java.io.Closeable
import java.nio.ByteBuffer
@ -110,10 +108,10 @@ private fun StructStat.toArchiveStat() = ArchiveEntry.StructStat().apply {
stSize = st_size
stBlksize = st_blksize
stBlocks = st_blocks
stAtim = timespec(st_atime)
stMtim = timespec(st_mtime)
stCtim = timespec(st_ctime)
stAtim = st_atime.toTimespec()
stMtim = st_mtime.toTimespec()
stCtim = st_ctime.toTimespec()
stIno = st_ino
}
private fun timespec(tvSec: Long) = ArchiveEntry.StructTimespec().also { it.tvSec = tvSec }
private fun Long.toTimespec() = ArchiveEntry.StructTimespec().also { it.tvSec = this }

View file

@ -1,7 +1,5 @@
package tachiyomi.core.common.storage
import android.content.Context
import android.os.ParcelFileDescriptor
import com.hippo.unifile.UniFile
val UniFile.extension: String?
@ -12,6 +10,3 @@ val UniFile.nameWithoutExtension: String?
val UniFile.displayablePath: String
get() = filePath ?: uri.toString()
fun UniFile.openFileDescriptor(context: Context, mode: String): ParcelFileDescriptor =
context.contentResolver.openFileDescriptor(uri, mode) ?: error("Failed to open file descriptor: $displayablePath")

View file

@ -43,6 +43,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
rootProject.name = "Komikku"
include(":app")
include(":core-metadata")
include(":core:archive")
include(":core:common")
include(":data")
include(":domain")

View file

@ -19,6 +19,7 @@ kotlin {
}
val androidMain by getting {
dependencies {
implementation(projects.core.archive)
implementation(projects.core.common)
implementation(projects.coreMetadata)

View file

@ -11,14 +11,14 @@ import eu.kanade.tachiyomi.source.model.Page
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 kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import logcat.LogPriority
import mihon.core.common.archive.ZipWriter
import mihon.core.common.archive.archiveReader
import mihon.core.archive.ZipWriter
import mihon.core.archive.archiveReader
import mihon.core.archive.epubReader
import nl.adaptivity.xmlutil.AndroidXmlReader
import nl.adaptivity.xmlutil.serialization.XML
import tachiyomi.core.common.i18n.stringResource
@ -344,7 +344,7 @@ actual class LocalSource(
val format = Format.valueOf(chapterFile)
if (format is Format.Epub) {
EpubFile(format.file.archiveReader(context)).use { epub ->
format.file.epubReader(context).use { epub ->
epub.fillMetadata(manga, this)
}
}
@ -414,7 +414,7 @@ actual class LocalSource(
}
}
is Format.Epub -> {
EpubFile(format.file.archiveReader(context)).use { epub ->
format.file.epubReader(context).use { epub ->
val entry = epub.getImagesFromPages().firstOrNull()
entry?.let { coverManager.update(manga, epub.getInputStream(it)!!) }

View file

@ -4,7 +4,7 @@ import android.content.Context
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.storage.DiskUtil
import mihon.core.common.archive.ZipWriter
import mihon.core.archive.ZipWriter
import tachiyomi.core.common.storage.nameWithoutExtension
import tachiyomi.core.common.util.system.ImageUtil
import tachiyomi.source.local.io.LocalSourceFileSystem

View file

@ -2,7 +2,7 @@ package tachiyomi.source.local.metadata
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.storage.EpubFile
import mihon.core.archive.EpubReader
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Locale
@ -10,7 +10,7 @@ import java.util.Locale
/**
* Fills manga and chapter metadata using this epub file's metadata.
*/
fun EpubFile.fillMetadata(manga: SManga, chapter: SChapter) {
fun EpubReader.fillMetadata(manga: SManga, chapter: SChapter) {
val ref = getPackageHref()
val doc = getPackageDocument(ref)