mirror of
https://github.com/null2264/yokai.git
synced 2025-06-20 10:14:50 +00:00
refactor: Move archive related code to core.archive module
This commit is contained in:
parent
54a3059730
commit
b4377a4609
19 changed files with 61 additions and 55 deletions
|
@ -144,6 +144,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.core.archive)
|
||||
implementation(projects.core.main)
|
||||
implementation(projects.data)
|
||||
implementation(projects.domain)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
15
core/archive/build.gradle.kts
Normal file
15
core/archive/build.gradle.kts
Normal file
|
@ -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)
|
||||
}
|
2
core/archive/src/main/AndroidManifest.xml
Normal file
2
core/archive/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest />
|
|
@ -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
|
|
@ -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 <T> useEntries(block: (Sequence<ArchiveEntry>) -> T): T =
|
||||
AndroidArchiveInputStream(address, size).use { block(generateSequence { it.getNextEntry() }) }
|
||||
fun <T> useEntries(block: (Sequence<ArchiveEntry>) -> 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) }
|
|
@ -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.
|
|
@ -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")
|
|
@ -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))
|
|
@ -60,7 +60,7 @@ kotlin {
|
|||
}
|
||||
|
||||
android {
|
||||
namespace = "yokai.core"
|
||||
namespace = "yokai.core.main"
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
package yokai.core.archive
|
||||
|
||||
import java.io.InputStream
|
||||
|
||||
// TODO: Use Okio's Source
|
||||
abstract class ArchiveInputStream : InputStream()
|
|
@ -1,9 +0,0 @@
|
|||
package yokai.core.archive
|
||||
|
||||
import java.io.Closeable
|
||||
import java.io.InputStream
|
||||
|
||||
interface ArchiveReader : Closeable {
|
||||
fun <T> useEntries(block: (Sequence<ArchiveEntry>) -> T): T
|
||||
fun getInputStream(entryName: String): InputStream?
|
||||
}
|
|
@ -31,6 +31,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
|||
|
||||
rootProject.name = "Yokai"
|
||||
include(":app")
|
||||
include(":core:archive")
|
||||
include(":core:main")
|
||||
include(":data")
|
||||
include(":domain")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue