* Refactor UniFile, allow all image format, Resolve #529 * Refine --------- Co-authored-by: GG Bond <whatever@tagkong.com>
This commit is contained in:
1 parent
719dddeab9
commit
f79aa2350c
8 files changed
+48
-194
No files matched your search
@@ -40,9 +40,3 @@ abstract class PageLoader2 : PageLoader() {
|
||||
*/
|
||||
abstract fun save(index: Int, dir: UniFile, filename: String): UniFile?
|
||||
}
|
||||
|
||||
val SUPPORT_IMAGE_EXTENSIONS = arrayOf(
|
||||
".jpg",
|
||||
".png",
|
||||
".gif",
|
||||
)
|
||||
@@ -26,7 +26,6 @@ import com.hippo.ehviewer.client.getImageKey
|
||||
import com.hippo.ehviewer.coil.read
|
||||
import com.hippo.ehviewer.coil.suspendEdit
|
||||
import com.hippo.ehviewer.download.downloadLocation
|
||||
import com.hippo.ehviewer.gallery.SUPPORT_IMAGE_EXTENSIONS
|
||||
import com.hippo.ehviewer.image.Image.UniFileSource
|
||||
import com.hippo.ehviewer.util.FileUtils
|
||||
import com.hippo.ehviewer.util.sendTo
|
||||
@@ -72,7 +71,7 @@ class SpiderDen(mGalleryInfo: GalleryInfo) {
|
||||
val key = getImageKey(mGid, index)
|
||||
return runCatching {
|
||||
sCache.read(key) {
|
||||
val extension = fixExtension("." + metadata.toFile().readText())
|
||||
val extension = "." + metadata.toFile().readText()
|
||||
val file = dir.createFile(perFilename(index, extension)) ?: return false
|
||||
file.openFileDescriptor("w").use { outFd ->
|
||||
ParcelFileDescriptor.open(data.toFile(), MODE_READ_WRITE).use {
|
||||
@@ -117,7 +116,7 @@ class SpiderDen(mGalleryInfo: GalleryInfo) {
|
||||
|
||||
private fun findDownloadFileForIndex(index: Int, extension: String): UniFile? {
|
||||
val dir = downloadDir ?: return null
|
||||
val ext = fixExtension(".$extension")
|
||||
val ext = ".$extension"
|
||||
return dir.createFile(perFilename(index, ext))
|
||||
}
|
||||
|
||||
@@ -233,8 +232,6 @@ class SpiderDen(mGalleryInfo: GalleryInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
private val COMPAT_IMAGE_EXTENSIONS = SUPPORT_IMAGE_EXTENSIONS + ".jpeg"
|
||||
|
||||
/**
|
||||
* @param extension with dot
|
||||
*/
|
||||
@@ -242,15 +239,9 @@ fun perFilename(index: Int, extension: String?): String {
|
||||
return String.format(Locale.US, "%08d%s", index + 1, extension)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extension with dot
|
||||
*/
|
||||
private fun fixExtension(extension: String): String {
|
||||
return extension.takeIf { SUPPORT_IMAGE_EXTENSIONS.contains(it) } ?: SUPPORT_IMAGE_EXTENSIONS[0]
|
||||
}
|
||||
|
||||
private fun findImageFile(dir: UniFile, index: Int): UniFile? {
|
||||
return COMPAT_IMAGE_EXTENSIONS.firstNotNullOfOrNull { dir.findFile(perFilename(index, it)) }
|
||||
val head = perFilename(index, ".")
|
||||
return dir.findFirst { name -> name.startsWith(head) }
|
||||
}
|
||||
|
||||
suspend fun GalleryInfo.putToDownloadDir(): String {
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.hippo.unifile
|
||||
|
||||
/**
|
||||
* An interface for filtering [UniFile] objects based on their names
|
||||
* or the directory they reside in.
|
||||
*
|
||||
* @see UniFile
|
||||
*
|
||||
* @see UniFile.listFiles
|
||||
*/
|
||||
interface FilenameFilter {
|
||||
/**
|
||||
* Indicates if a specific filename matches this filter.
|
||||
*
|
||||
* @param dir the directory in which the `filename` was found.
|
||||
* @param filename the name of the file in `dir` to test.
|
||||
* @return `true` if the filename matches the filter
|
||||
* and can be included in the list, `false`
|
||||
* otherwise.
|
||||
*/
|
||||
fun accept(dir: UniFile?, filename: String?): Boolean
|
||||
}
|
||||
@@ -18,44 +18,28 @@ package com.hippo.unifile
|
||||
import android.content.Context
|
||||
import android.graphics.ImageDecoder
|
||||
import android.net.Uri
|
||||
import android.os.ParcelFileDescriptor
|
||||
import java.io.IOException
|
||||
|
||||
internal class MediaFile(context: Context, override val uri: Uri) : UniFile(null) {
|
||||
private val mContext: Context
|
||||
private val mContext = context.applicationContext
|
||||
|
||||
init {
|
||||
mContext = context.applicationContext
|
||||
}
|
||||
override fun createFile(displayName: String) = null
|
||||
|
||||
override fun createFile(displayName: String): UniFile? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun createDirectory(displayName: String): UniFile? {
|
||||
return null
|
||||
}
|
||||
override fun createDirectory(displayName: String) = null
|
||||
|
||||
override val name: String?
|
||||
get() = MediaContract.getName(mContext, uri)
|
||||
override val type: String?
|
||||
get() = MediaContract.getType(mContext, uri)
|
||||
override val isDirectory: Boolean
|
||||
get() = false
|
||||
override val isDirectory = false
|
||||
override val isFile: Boolean
|
||||
get() = DocumentsContractApi19.isFile(mContext, uri)
|
||||
|
||||
override fun lastModified(): Long {
|
||||
return MediaContract.lastModified(mContext, uri)
|
||||
}
|
||||
override fun lastModified() = MediaContract.lastModified(mContext, uri)
|
||||
|
||||
override fun length(): Long {
|
||||
return MediaContract.length(mContext, uri)
|
||||
}
|
||||
override fun length() = MediaContract.length(mContext, uri)
|
||||
|
||||
override fun canRead(): Boolean {
|
||||
return isFile
|
||||
}
|
||||
override fun canRead() = isFile
|
||||
|
||||
override fun canWrite(): Boolean {
|
||||
try {
|
||||
@@ -67,48 +51,28 @@ internal class MediaFile(context: Context, override val uri: Uri) : UniFile(null
|
||||
return true
|
||||
}
|
||||
|
||||
override fun ensureDir(): Boolean {
|
||||
return false
|
||||
}
|
||||
override fun ensureDir() = false
|
||||
|
||||
override fun ensureFile(): Boolean {
|
||||
return isFile
|
||||
}
|
||||
override fun ensureFile() = isFile
|
||||
|
||||
override fun subFile(displayName: String): UniFile? {
|
||||
return null
|
||||
}
|
||||
override fun subFile(displayName: String) = null
|
||||
|
||||
override fun delete(): Boolean {
|
||||
return false
|
||||
}
|
||||
override fun delete() = false
|
||||
|
||||
override fun exists(): Boolean {
|
||||
return isFile
|
||||
}
|
||||
override fun exists() = isFile
|
||||
|
||||
override fun listFiles(): Array<UniFile>? {
|
||||
return null
|
||||
}
|
||||
override fun listFiles() = null
|
||||
|
||||
override fun listFiles(filter: FilenameFilter?): Array<UniFile>? {
|
||||
return null
|
||||
}
|
||||
override fun findFirst(filter: (String) -> Boolean) = null
|
||||
|
||||
override fun findFile(displayName: String): UniFile? {
|
||||
return null
|
||||
}
|
||||
override fun findFile(displayName: String) = null
|
||||
|
||||
override fun renameTo(displayName: String): Boolean {
|
||||
return false
|
||||
}
|
||||
override fun renameTo(displayName: String) = false
|
||||
|
||||
override val imageSource: ImageDecoder.Source
|
||||
get() = Contracts.getImageSource(mContext, uri)
|
||||
|
||||
override fun openFileDescriptor(mode: String): ParcelFileDescriptor {
|
||||
return Contracts.openFileDescriptor(mContext, uri, mode)
|
||||
}
|
||||
override fun openFileDescriptor(mode: String) = Contracts.openFileDescriptor(mContext, uri, mode)
|
||||
|
||||
companion object {
|
||||
fun isMediaUri(context: Context, uri: Uri): Boolean {
|
||||
|
||||
@@ -119,18 +119,10 @@ internal class RawFile(parent: UniFile?, var mFile: File) : UniFile(parent) {
|
||||
return files.map { RawFile(this, it) }.toTypedArray()
|
||||
}
|
||||
|
||||
override fun listFiles(filter: FilenameFilter?): Array<UniFile>? {
|
||||
if (filter == null) {
|
||||
return listFiles()
|
||||
}
|
||||
val files = mFile.listFiles() ?: return null
|
||||
val results = ArrayList<UniFile>()
|
||||
for (file in files) {
|
||||
if (filter.accept(this, file.name)) {
|
||||
results.add(RawFile(this, file))
|
||||
}
|
||||
}
|
||||
return results.toTypedArray<UniFile>()
|
||||
override fun findFirst(filter: (String) -> Boolean) = mFile.listFiles { _, name ->
|
||||
filter(name)
|
||||
}?.firstOrNull()?.let {
|
||||
RawFile(this, it)
|
||||
}
|
||||
|
||||
override fun findFile(displayName: String): UniFile? {
|
||||
|
||||
@@ -18,23 +18,13 @@ package com.hippo.unifile
|
||||
import android.content.Context
|
||||
import android.graphics.ImageDecoder
|
||||
import android.net.Uri
|
||||
import android.os.ParcelFileDescriptor
|
||||
|
||||
internal class SingleDocumentFile(parent: UniFile?, context: Context, override val uri: Uri) :
|
||||
UniFile(parent) {
|
||||
private val mContext: Context
|
||||
class SingleDocumentFile(parent: UniFile?, context: Context, override val uri: Uri) : UniFile(parent) {
|
||||
private val mContext = context.applicationContext
|
||||
|
||||
init {
|
||||
mContext = context.applicationContext
|
||||
}
|
||||
override fun createFile(displayName: String) = null
|
||||
|
||||
override fun createFile(displayName: String): UniFile? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun createDirectory(displayName: String): UniFile? {
|
||||
return null
|
||||
}
|
||||
override fun createDirectory(displayName: String) = null
|
||||
|
||||
override val name: String?
|
||||
get() = DocumentsContractApi19.getName(mContext, uri)
|
||||
@@ -45,62 +35,34 @@ internal class SingleDocumentFile(parent: UniFile?, context: Context, override v
|
||||
override val isFile: Boolean
|
||||
get() = DocumentsContractApi19.isFile(mContext, uri)
|
||||
|
||||
override fun lastModified(): Long {
|
||||
return DocumentsContractApi19.lastModified(mContext, uri)
|
||||
}
|
||||
override fun lastModified() = DocumentsContractApi19.lastModified(mContext, uri)
|
||||
|
||||
override fun length(): Long {
|
||||
return DocumentsContractApi19.length(mContext, uri)
|
||||
}
|
||||
override fun length() = DocumentsContractApi19.length(mContext, uri)
|
||||
|
||||
override fun canRead(): Boolean {
|
||||
return DocumentsContractApi19.canRead(mContext, uri)
|
||||
}
|
||||
override fun canRead() = DocumentsContractApi19.canRead(mContext, uri)
|
||||
|
||||
override fun canWrite(): Boolean {
|
||||
return DocumentsContractApi19.canWrite(mContext, uri)
|
||||
}
|
||||
override fun canWrite() = DocumentsContractApi19.canWrite(mContext, uri)
|
||||
|
||||
override fun ensureDir(): Boolean {
|
||||
return isDirectory
|
||||
}
|
||||
override fun ensureDir() = isDirectory
|
||||
|
||||
override fun ensureFile(): Boolean {
|
||||
return isFile
|
||||
}
|
||||
override fun ensureFile() = isFile
|
||||
|
||||
override fun subFile(displayName: String): UniFile? {
|
||||
return null
|
||||
}
|
||||
override fun subFile(displayName: String) = null
|
||||
|
||||
override fun delete(): Boolean {
|
||||
return DocumentsContractApi19.delete(mContext, uri)
|
||||
}
|
||||
override fun delete() = DocumentsContractApi19.delete(mContext, uri)
|
||||
|
||||
override fun exists(): Boolean {
|
||||
return DocumentsContractApi19.exists(mContext, uri)
|
||||
}
|
||||
override fun exists() = DocumentsContractApi19.exists(mContext, uri)
|
||||
|
||||
override fun listFiles(): Array<UniFile>? {
|
||||
return null
|
||||
}
|
||||
override fun listFiles() = null
|
||||
|
||||
override fun listFiles(filter: FilenameFilter?): Array<UniFile>? {
|
||||
return null
|
||||
}
|
||||
override fun findFirst(filter: (String) -> Boolean) = null
|
||||
|
||||
override fun findFile(displayName: String): UniFile? {
|
||||
return null
|
||||
}
|
||||
override fun findFile(displayName: String) = null
|
||||
|
||||
override fun renameTo(displayName: String): Boolean {
|
||||
return false
|
||||
}
|
||||
override fun renameTo(displayName: String) = false
|
||||
|
||||
override val imageSource: ImageDecoder.Source
|
||||
get() = Contracts.getImageSource(mContext, uri)
|
||||
|
||||
override fun openFileDescriptor(mode: String): ParcelFileDescriptor {
|
||||
return Contracts.openFileDescriptor(mContext, uri, mode)
|
||||
}
|
||||
override fun openFileDescriptor(mode: String) = Contracts.openFileDescriptor(mContext, uri, mode)
|
||||
}
|
||||
@@ -199,19 +199,15 @@ internal class TreeDocumentFile : UniFile {
|
||||
return result.map { TreeDocumentFile(this, mContext, it, getFilenameForUri(it)) }.toTypedArray()
|
||||
}
|
||||
|
||||
override fun listFiles(filter: FilenameFilter?): Array<UniFile> {
|
||||
if (filter == null) {
|
||||
return listFiles()
|
||||
}
|
||||
override fun findFirst(filter: (String) -> Boolean): UniFile? {
|
||||
val result = DocumentsContractApi21.listFiles(mContext, uri)
|
||||
val results = ArrayList<UniFile>()
|
||||
for (uri in result) {
|
||||
val name = getFilenameForUri(uri)
|
||||
if (filter.accept(this, name)) {
|
||||
results.add(TreeDocumentFile(this, mContext, uri, name))
|
||||
if (name != null && filter(name)) {
|
||||
return TreeDocumentFile(this, mContext, uri, name)
|
||||
}
|
||||
}
|
||||
return results.toTypedArray<UniFile>()
|
||||
return null
|
||||
}
|
||||
|
||||
override fun findFile(displayName: String): UniFile? {
|
||||
|
||||
@@ -205,15 +205,7 @@ abstract class UniFile internal constructor(private val parent: UniFile?) {
|
||||
*/
|
||||
abstract fun listFiles(): Array<UniFile>?
|
||||
|
||||
/**
|
||||
* Gets a list of the files in the directory represented by this file. This
|
||||
* list is then filtered through a FilenameFilter and the names of files
|
||||
* with matching names are returned as an array of strings.
|
||||
*
|
||||
* @param filter the filter to match names against, may be `null`.
|
||||
* @return an array of files or `null`.
|
||||
*/
|
||||
abstract fun listFiles(filter: FilenameFilter?): Array<UniFile>?
|
||||
abstract fun findFirst(filter: (String) -> Boolean): UniFile?
|
||||
|
||||
/**
|
||||
* Test there is a file with the display name in the directory.
|
||||
|
||||
Reference in new issue
Block a user