extension settings
This commit is contained in:
parent
9c0ef7a788
commit
3368a1bc8d
76 changed files with 2320 additions and 131 deletions
117
app/src/main/java/eu/kanade/tachiyomi/util/storage/DiskUtil.kt
Normal file
117
app/src/main/java/eu/kanade/tachiyomi/util/storage/DiskUtil.kt
Normal file
|
@ -0,0 +1,117 @@
|
|||
package eu.kanade.tachiyomi.util.storage
|
||||
|
||||
import android.content.Context
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.os.StatFs
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.util.lang.Hash
|
||||
import java.io.File
|
||||
|
||||
object DiskUtil {
|
||||
|
||||
fun hashKeyForDisk(key: String): String {
|
||||
return Hash.md5(key)
|
||||
}
|
||||
|
||||
fun getDirectorySize(f: File): Long {
|
||||
var size: Long = 0
|
||||
if (f.isDirectory) {
|
||||
for (file in f.listFiles().orEmpty()) {
|
||||
size += getDirectorySize(file)
|
||||
}
|
||||
} else {
|
||||
size = f.length()
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the available space for the disk that a file path points to, in bytes.
|
||||
*/
|
||||
fun getAvailableStorageSpace(f: UniFile): Long {
|
||||
return try {
|
||||
val stat = StatFs(f.uri.path)
|
||||
stat.availableBlocksLong * stat.blockSizeLong
|
||||
} catch (_: Exception) {
|
||||
-1L
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root folders of all the available external storages.
|
||||
*/
|
||||
fun getExternalStorages(context: Context): List<File> {
|
||||
return ContextCompat.getExternalFilesDirs(context, null)
|
||||
.filterNotNull()
|
||||
.mapNotNull {
|
||||
val file = File(it.absolutePath.substringBefore("/Android/"))
|
||||
val state = Environment.getExternalStorageState(file)
|
||||
if (state == Environment.MEDIA_MOUNTED || state == Environment.MEDIA_MOUNTED_READ_ONLY) {
|
||||
file
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't display downloaded chapters in gallery apps creating `.nomedia`.
|
||||
*/
|
||||
fun createNoMediaFile(dir: UniFile?, context: Context?) {
|
||||
if (dir != null && dir.exists()) {
|
||||
val nomedia = dir.findFile(NOMEDIA_FILE)
|
||||
if (nomedia == null) {
|
||||
dir.createFile(NOMEDIA_FILE)
|
||||
context?.let { scanMedia(it, dir.uri) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the given file so that it can be shown in gallery apps, for example.
|
||||
*/
|
||||
fun scanMedia(context: Context, uri: Uri) {
|
||||
MediaScannerConnection.scanFile(context, arrayOf(uri.path), null, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutate the given filename to make it valid for a FAT filesystem,
|
||||
* replacing any invalid characters with "_". This method doesn't allow hidden files (starting
|
||||
* with a dot), but you can manually add it later.
|
||||
*/
|
||||
fun buildValidFilename(origName: String): String {
|
||||
val name = origName.trim('.', ' ')
|
||||
if (name.isEmpty()) {
|
||||
return "(invalid)"
|
||||
}
|
||||
val sb = StringBuilder(name.length)
|
||||
name.forEach { c ->
|
||||
if (isValidFatFilenameChar(c)) {
|
||||
sb.append(c)
|
||||
} else {
|
||||
sb.append('_')
|
||||
}
|
||||
}
|
||||
// Even though vfat allows 255 UCS-2 chars, we might eventually write to
|
||||
// ext4 through a FUSE layer, so use that limit minus 15 reserved characters.
|
||||
return sb.toString().take(240)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given character is a valid filename character, false otherwise.
|
||||
*/
|
||||
private fun isValidFatFilenameChar(c: Char): Boolean {
|
||||
if (0x00.toChar() <= c && c <= 0x1f.toChar()) {
|
||||
return false
|
||||
}
|
||||
return when (c) {
|
||||
'"', '*', '/', ':', '<', '>', '?', '\\', '|', 0x7f.toChar() -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
const val NOMEDIA_FILE = ".nomedia"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
@file:Suppress("PackageDirectoryMismatch")
|
||||
|
||||
package androidx.preference
|
||||
|
||||
/**
|
||||
* Returns package-private [EditTextPreference.getOnBindEditTextListener]
|
||||
*/
|
||||
fun EditTextPreference.getOnBindEditTextListener(): EditTextPreference.OnBindEditTextListener? {
|
||||
return onBindEditTextListener
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue