diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 1750bffd4e..75a95ee35e 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -144,6 +144,7 @@ android {
}
dependencies {
+ implementation(projects.core.archive)
implementation(projects.core.main)
implementation(projects.data)
implementation(projects.domain)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
index f7040a5c66..e8e9510f61 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
@@ -12,8 +12,6 @@ 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.DiskUtil
-import eu.kanade.tachiyomi.util.storage.EpubFile
-import eu.kanade.tachiyomi.util.storage.fillMetadata
import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.extension
import eu.kanade.tachiyomi.util.system.nameWithoutExtension
@@ -33,7 +31,8 @@ import nl.adaptivity.xmlutil.serialization.XML
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
-import yokai.core.archive.archiveReader
+import yokai.core.archive.util.archiveReader
+import yokai.core.archive.util.epubReader
import yokai.core.metadata.COMIC_INFO_FILE
import yokai.core.metadata.ComicInfo
import yokai.core.metadata.copyFromComicInfo
@@ -42,6 +41,7 @@ import yokai.domain.chapter.services.ChapterRecognition
import yokai.domain.source.SourcePreferences
import yokai.domain.storage.StorageManager
import yokai.i18n.MR
+import yokai.util.fillMetadata
import yokai.util.lang.getString
class LocalSource(private val context: Context) : CatalogueSource, UnmeteredSource {
@@ -410,7 +410,7 @@ class LocalSource(private val context: Context) : CatalogueSource, UnmeteredSour
}
}
is Format.Epub -> {
- EpubFile(format.file.archiveReader(context)).use { epub ->
+ format.file.epubReader(context).use { epub ->
val entry = epub.getImagesFromPages().firstOrNull()
entry?.let { updateCover(manga, epub.getInputStream(it)!!, context) }
@@ -433,7 +433,7 @@ class LocalSource(private val context: Context) : CatalogueSource, UnmeteredSour
true
}
is Format.Epub -> {
- EpubFile(format.file.archiveReader(context)).use { epub ->
+ format.file.epubReader(context).use { epub ->
epub.fillMetadata(chapter, manga)
}
true
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt
index 7756cdd585..44f89294e9 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt
@@ -10,7 +10,8 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.util.system.withIOContext
-import yokai.core.archive.archiveReader
+import yokai.core.archive.util.archiveReader
+import yokai.core.archive.util.epubReader
import yokai.i18n.MR
import yokai.util.lang.getString
@@ -82,7 +83,7 @@ class ChapterLoader(
when (format) {
is LocalSource.Format.Directory -> DirectoryPageLoader(format.file)
is LocalSource.Format.Archive -> ArchivePageLoader(format.file.archiveReader(context))
- is LocalSource.Format.Epub -> EpubPageLoader(format.file.archiveReader(context))
+ is LocalSource.Format.Epub -> EpubPageLoader(format.file.epubReader(context))
}
}
else -> error(context.getString(MR.strings.source_not_installed))
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt
index 6535ce9847..254db17580 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt
@@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import uy.kohesive.injekt.injectLazy
-import yokai.core.archive.archiveReader
+import yokai.core.archive.util.archiveReader
/**
* Loader used to load a chapter from the downloaded chapters.
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt
index 0823453d1c..77c782e87e 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt
@@ -2,21 +2,15 @@ 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 yokai.core.archive.ArchiveReader
+import yokai.core.archive.EpubReader
/**
* Loader used to load a chapter from a .epub file.
*/
-class EpubPageLoader(reader: ArchiveReader) : PageLoader() {
+class EpubPageLoader(private val epub: EpubReader) : PageLoader() {
override val isLocal: Boolean = true
- /**
- * The epub file.
- */
- private val epub = EpubFile(reader)
-
/**
* Recycles this loader and the open zip.
*/
diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/storage/EpubFile.kt b/app/src/main/java/yokai/util/EpubReader.kt
similarity index 90%
rename from app/src/main/java/eu/kanade/tachiyomi/util/storage/EpubFile.kt
rename to app/src/main/java/yokai/util/EpubReader.kt
index 54c9a3ebd6..2c0869aff4 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/util/storage/EpubFile.kt
+++ b/app/src/main/java/yokai/util/EpubReader.kt
@@ -1,15 +1,16 @@
-package eu.kanade.tachiyomi.util.storage
+package yokai.util
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import java.text.ParseException
import java.text.SimpleDateFormat
-import java.util.*
+import java.util.Locale
+import yokai.core.archive.EpubReader
/**
* Fills manga and chapter metadata using this epub file's metadata.
*/
-fun EpubFile.fillMetadata(chapter: SChapter, manga: SManga) {
+fun EpubReader.fillMetadata(chapter: SChapter, manga: SManga) {
val ref = getPackageHref()
val doc = getPackageDocument(ref)
diff --git a/core/archive/build.gradle.kts b/core/archive/build.gradle.kts
new file mode 100644
index 0000000000..e44e620ed5
--- /dev/null
+++ b/core/archive/build.gradle.kts
@@ -0,0 +1,15 @@
+plugins {
+ id("yokai.android.library")
+ kotlin("android")
+ alias(kotlinx.plugins.serialization)
+}
+
+android {
+ namespace = "yokai.core.archive"
+}
+
+dependencies {
+ implementation(libs.jsoup)
+ implementation(libs.libarchive)
+ implementation(libs.unifile)
+}
diff --git a/core/archive/src/main/AndroidManifest.xml b/core/archive/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..8072ee00db
--- /dev/null
+++ b/core/archive/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/core/main/src/androidMain/kotlin/yokai/core/archive/ArchiveEntry.kt b/core/archive/src/main/java/yokai/core/archive/ArchiveEntry.kt
similarity index 100%
rename from core/main/src/androidMain/kotlin/yokai/core/archive/ArchiveEntry.kt
rename to core/archive/src/main/java/yokai/core/archive/ArchiveEntry.kt
diff --git a/core/main/src/androidMain/kotlin/yokai/core/archive/AndroidArchiveInputStream.kt b/core/archive/src/main/java/yokai/core/archive/ArchiveInputStream.kt
similarity index 94%
rename from core/main/src/androidMain/kotlin/yokai/core/archive/AndroidArchiveInputStream.kt
rename to core/archive/src/main/java/yokai/core/archive/ArchiveInputStream.kt
index abe8da941b..5cd17aa026 100644
--- a/core/main/src/androidMain/kotlin/yokai/core/archive/AndroidArchiveInputStream.kt
+++ b/core/archive/src/main/java/yokai/core/archive/ArchiveInputStream.kt
@@ -1,12 +1,13 @@
package yokai.core.archive
+import java.io.InputStream
import java.nio.ByteBuffer
import kotlin.concurrent.Volatile
import me.zhanghai.android.libarchive.Archive
import me.zhanghai.android.libarchive.ArchiveEntry
import me.zhanghai.android.libarchive.ArchiveException
-class AndroidArchiveInputStream(buffer: Long, size: Long) : ArchiveInputStream() {
+class ArchiveInputStream(buffer: Long, size: Long) : InputStream() {
private val lock = Any()
@Volatile
private var isClosed = false
diff --git a/core/main/src/androidMain/kotlin/yokai/core/archive/AndroidArchiveReader.kt b/core/archive/src/main/java/yokai/core/archive/ArchiveReader.kt
similarity index 55%
rename from core/main/src/androidMain/kotlin/yokai/core/archive/AndroidArchiveReader.kt
rename to core/archive/src/main/java/yokai/core/archive/ArchiveReader.kt
index aee82a81fb..97584cc08f 100644
--- a/core/main/src/androidMain/kotlin/yokai/core/archive/AndroidArchiveReader.kt
+++ b/core/archive/src/main/java/yokai/core/archive/ArchiveReader.kt
@@ -1,23 +1,22 @@
package yokai.core.archive
-import android.content.Context
import android.os.ParcelFileDescriptor
import android.system.Os
import android.system.OsConstants
-import com.hippo.unifile.UniFile
-import eu.kanade.tachiyomi.util.system.openFileDescriptor
+import java.io.Closeable
import java.io.InputStream
import me.zhanghai.android.libarchive.ArchiveException
-class AndroidArchiveReader(pfd: ParcelFileDescriptor) : ArchiveReader {
+class ArchiveReader(pfd: ParcelFileDescriptor) : Closeable {
val size = pfd.statSize
val address = Os.mmap(0, size, OsConstants.PROT_READ, OsConstants.MAP_PRIVATE, pfd.fileDescriptor, 0)
- override fun useEntries(block: (Sequence) -> T): T =
- AndroidArchiveInputStream(address, size).use { block(generateSequence { it.getNextEntry() }) }
+ fun useEntries(block: (Sequence) -> T): T = ArchiveInputStream(address, size).use {
+ block(generateSequence { it.getNextEntry() })
+ }
- override fun getInputStream(entryName: String): InputStream? {
- val archive = AndroidArchiveInputStream(address, size)
+ fun getInputStream(entryName: String): InputStream? {
+ val archive = ArchiveInputStream(address, size)
try {
while (true) {
val entry = archive.getNextEntry() ?: break
@@ -37,6 +36,3 @@ class AndroidArchiveReader(pfd: ParcelFileDescriptor) : ArchiveReader {
Os.munmap(address, size)
}
}
-
-fun UniFile.archiveReader(context: Context): ArchiveReader =
- openFileDescriptor(context, "r").use { AndroidArchiveReader(it) }
diff --git a/core/main/src/androidMain/kotlin/eu/kanade/tachiyomi/util/storage/EpubFile.kt b/core/archive/src/main/java/yokai/core/archive/EpubReader.kt
similarity index 96%
rename from core/main/src/androidMain/kotlin/eu/kanade/tachiyomi/util/storage/EpubFile.kt
rename to core/archive/src/main/java/yokai/core/archive/EpubReader.kt
index b1a2711749..89ba98096b 100644
--- a/core/main/src/androidMain/kotlin/eu/kanade/tachiyomi/util/storage/EpubFile.kt
+++ b/core/archive/src/main/java/yokai/core/archive/EpubReader.kt
@@ -1,16 +1,15 @@
-package eu.kanade.tachiyomi.util.storage
+package yokai.core.archive
import java.io.Closeable
import java.io.File
import java.io.InputStream
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
-import yokai.core.archive.ArchiveReader
/**
* Wrapper over ZipFile 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.
diff --git a/core/main/src/androidMain/kotlin/yokai/core/archive/ZipWriter.kt b/core/archive/src/main/java/yokai/core/archive/ZipWriter.kt
similarity index 97%
rename from core/main/src/androidMain/kotlin/yokai/core/archive/ZipWriter.kt
rename to core/archive/src/main/java/yokai/core/archive/ZipWriter.kt
index a5d84edcfb..3ee02b02b7 100644
--- a/core/main/src/androidMain/kotlin/yokai/core/archive/ZipWriter.kt
+++ b/core/archive/src/main/java/yokai/core/archive/ZipWriter.kt
@@ -4,12 +4,12 @@ import android.content.Context
import android.system.Os
import android.system.StructStat
import com.hippo.unifile.UniFile
-import eu.kanade.tachiyomi.util.system.openFileDescriptor
import java.io.Closeable
import java.nio.ByteBuffer
import me.zhanghai.android.libarchive.Archive
import me.zhanghai.android.libarchive.ArchiveEntry
import me.zhanghai.android.libarchive.ArchiveException
+import yokai.core.archive.util.openFileDescriptor
class ZipWriter(val context: Context, file: UniFile) : Closeable {
private val pfd = file.openFileDescriptor(context, "wt")
diff --git a/core/archive/src/main/java/yokai/core/archive/util/UniFileExtensions.kt b/core/archive/src/main/java/yokai/core/archive/util/UniFileExtensions.kt
new file mode 100644
index 0000000000..588f8fcc81
--- /dev/null
+++ b/core/archive/src/main/java/yokai/core/archive/util/UniFileExtensions.kt
@@ -0,0 +1,14 @@
+package yokai.core.archive.util
+
+import android.content.Context
+import android.os.ParcelFileDescriptor
+import com.hippo.unifile.UniFile
+import yokai.core.archive.ArchiveReader
+import yokai.core.archive.EpubReader
+
+fun UniFile.openFileDescriptor(context: Context, mode: String): ParcelFileDescriptor =
+ context.contentResolver.openFileDescriptor(uri, mode) ?: error("Failed to open file descriptor: ${filePath ?: uri.toString()}")
+
+fun UniFile.archiveReader(context: Context): ArchiveReader = openFileDescriptor(context, "r").use { ArchiveReader(it) }
+
+fun UniFile.epubReader(context: Context): EpubReader = EpubReader(archiveReader(context))
diff --git a/core/main/build.gradle.kts b/core/main/build.gradle.kts
index d78b8e4392..db1374c6ab 100644
--- a/core/main/build.gradle.kts
+++ b/core/main/build.gradle.kts
@@ -60,7 +60,7 @@ kotlin {
}
android {
- namespace = "yokai.core"
+ namespace = "yokai.core.main"
}
tasks {
diff --git a/core/main/src/androidMain/kotlin/eu/kanade/tachiyomi/util/system/UniFileExtensions.kt b/core/main/src/androidMain/kotlin/eu/kanade/tachiyomi/util/system/UniFileExtensions.kt
index ce50162b3e..1e55656c32 100644
--- a/core/main/src/androidMain/kotlin/eu/kanade/tachiyomi/util/system/UniFileExtensions.kt
+++ b/core/main/src/androidMain/kotlin/eu/kanade/tachiyomi/util/system/UniFileExtensions.kt
@@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.util.system
import android.content.Context
import android.os.Build
import android.os.FileUtils
-import android.os.ParcelFileDescriptor
import com.hippo.unifile.UniFile
import java.io.BufferedOutputStream
import java.io.File
@@ -48,6 +47,3 @@ fun UniFile.writeText(string: String, onComplete: () -> Unit = {}) {
onComplete()
}
}
-
-fun UniFile.openFileDescriptor(context: Context, mode: String): ParcelFileDescriptor =
- context.contentResolver.openFileDescriptor(uri, mode) ?: error("Failed to open file descriptor: $displayablePath")
diff --git a/core/main/src/androidMain/kotlin/yokai/core/archive/ArchiveInputStream.kt b/core/main/src/androidMain/kotlin/yokai/core/archive/ArchiveInputStream.kt
deleted file mode 100644
index 6a9cd0185b..0000000000
--- a/core/main/src/androidMain/kotlin/yokai/core/archive/ArchiveInputStream.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package yokai.core.archive
-
-import java.io.InputStream
-
-// TODO: Use Okio's Source
-abstract class ArchiveInputStream : InputStream()
diff --git a/core/main/src/androidMain/kotlin/yokai/core/archive/ArchiveReader.kt b/core/main/src/androidMain/kotlin/yokai/core/archive/ArchiveReader.kt
deleted file mode 100644
index 00d646f3a7..0000000000
--- a/core/main/src/androidMain/kotlin/yokai/core/archive/ArchiveReader.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package yokai.core.archive
-
-import java.io.Closeable
-import java.io.InputStream
-
-interface ArchiveReader : Closeable {
- fun useEntries(block: (Sequence) -> T): T
- fun getInputStream(entryName: String): InputStream?
-}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 09869b29ff..bd2a49e70e 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -31,6 +31,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
rootProject.name = "Yokai"
include(":app")
+include(":core:archive")
include(":core:main")
include(":data")
include(":domain")