Support closing Okio FileSystem
This commit is contained in:
@@ -55,15 +55,16 @@ class LocalMangaParser(private val uri: Uri) {
|
||||
private val rootFile: File = File(uri.schemeSpecificPart)
|
||||
|
||||
suspend fun getManga(withDetails: Boolean): LocalManga = runInterruptible(Dispatchers.IO) {
|
||||
val (fileSystem, rootPath) = uri.resolveFsAndPath()
|
||||
(uri.resolveFsAndPath()).use { (fileSystem, rootPath) ->
|
||||
val index = MangaIndex.read(fileSystem, rootPath / ENTRY_NAME_INDEX)
|
||||
val mangaInfo = index?.getMangaInfo()
|
||||
if (mangaInfo != null) {
|
||||
val coverEntry: Path? = index.getCoverEntry()?.let { rootPath / it } ?: fileSystem.findFirstImage(rootPath)
|
||||
val coverEntry: Path? =
|
||||
index.getCoverEntry()?.let { rootPath / it } ?: fileSystem.findFirstImage(rootPath)
|
||||
mangaInfo.copy(
|
||||
source = LocalMangaSource,
|
||||
url = rootFile.toUri().toString(),
|
||||
coverUrl = coverEntry?.let { uri.child(it, resolve = true).toString() }.orEmpty(),
|
||||
coverUrl = coverEntry?.let { uri.child(it, resolve = true).toString() },
|
||||
largeCoverUrl = null,
|
||||
chapters = if (withDetails) {
|
||||
mangaInfo.chapters?.mapNotNull { c ->
|
||||
@@ -92,9 +93,7 @@ class LocalMangaParser(private val uri: Uri) {
|
||||
url = rootFile.toUri().toString(),
|
||||
publicUrl = rootFile.toUri().toString(),
|
||||
source = LocalMangaSource,
|
||||
coverUrl = coverEntry?.let {
|
||||
uri.child(it, resolve = true).toString()
|
||||
}.orEmpty(),
|
||||
coverUrl = coverEntry?.let { uri.child(it, resolve = true).toString() },
|
||||
chapters = if (withDetails) {
|
||||
val chapters = fileSystem.listRecursively(rootPath)
|
||||
.mapNotNullTo(HashSet()) { path ->
|
||||
@@ -138,16 +137,18 @@ class LocalMangaParser(private val uri: Uri) {
|
||||
)
|
||||
}.let { LocalManga(it, rootFile) }
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getMangaInfo(): Manga? = runInterruptible(Dispatchers.IO) {
|
||||
val (fileSystem, rootPath) = uri.resolveFsAndPath()
|
||||
uri.resolveFsAndPath().use { (fileSystem, rootPath) ->
|
||||
val index = MangaIndex.read(fileSystem, rootPath / ENTRY_NAME_INDEX)
|
||||
index?.getMangaInfo()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getPages(chapter: MangaChapter): List<MangaPage> = runInterruptible(Dispatchers.IO) {
|
||||
val chapterUri = chapter.url.toUri().resolve()
|
||||
val (fileSystem, rootPath) = chapterUri.resolveFsAndPath()
|
||||
chapterUri.resolveFsAndPath().use { (fileSystem, rootPath) ->
|
||||
val index = MangaIndex.read(fileSystem, rootPath / ENTRY_NAME_INDEX)
|
||||
val entries = fileSystem.listRecursively(rootPath)
|
||||
.filter { fileSystem.isRegularFile(it) }
|
||||
@@ -167,6 +168,7 @@ class LocalMangaParser(private val uri: Uri) {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Uri.child(path: Path, resolve: Boolean): Uri {
|
||||
val builder = buildUpon()
|
||||
@@ -184,6 +186,23 @@ class LocalMangaParser(private val uri: Uri) {
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
private class FsAndPath(
|
||||
val fileSystem: FileSystem,
|
||||
val path: Path,
|
||||
private val isCloseable: Boolean,
|
||||
) : AutoCloseable {
|
||||
|
||||
override fun close() {
|
||||
if (isCloseable) {
|
||||
fileSystem.close()
|
||||
}
|
||||
}
|
||||
|
||||
operator fun component1() = fileSystem
|
||||
|
||||
operator fun component2() = path
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@Blocking
|
||||
@@ -240,20 +259,25 @@ class LocalMangaParser(private val uri: Uri) {
|
||||
}
|
||||
|
||||
@Blocking
|
||||
private fun Uri.resolveFsAndPath(): Pair<FileSystem, Path> {
|
||||
private fun Uri.resolveFsAndPath(): FsAndPath {
|
||||
val resolved = resolve()
|
||||
return when {
|
||||
resolved.isZipUri() -> {
|
||||
FileSystem.SYSTEM.openZip(resolved.schemeSpecificPart.toPath()) to resolved.fragment.orEmpty()
|
||||
.toRootedPath()
|
||||
}
|
||||
resolved.isZipUri() -> FsAndPath(
|
||||
FileSystem.SYSTEM.openZip(resolved.schemeSpecificPart.toPath()),
|
||||
resolved.fragment.orEmpty().toRootedPath(),
|
||||
isCloseable = true,
|
||||
)
|
||||
|
||||
isFileUri() -> {
|
||||
val file = toFile()
|
||||
if (file.isZipArchive) {
|
||||
FileSystem.SYSTEM.openZip(schemeSpecificPart.toPath()) to fragment.orEmpty().toRootedPath()
|
||||
FsAndPath(
|
||||
FileSystem.SYSTEM.openZip(schemeSpecificPart.toPath()),
|
||||
fragment.orEmpty().toRootedPath(),
|
||||
isCloseable = true,
|
||||
)
|
||||
} else {
|
||||
FileSystem.SYSTEM to file.toOkioPath()
|
||||
FsAndPath(FileSystem.SYSTEM, file.toOkioPath(), isCloseable = false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user