Support closing Okio FileSystem

master
Koitharu 1 year ago
parent 6360731f34
commit 169539f42f
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -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)
}
}

Loading…
Cancel
Save