Minor fixes

This commit is contained in:
tzugen 2021-12-18 14:33:04 +01:00
parent f4554ff29e
commit a0da791b28
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
10 changed files with 57 additions and 74 deletions

View File

@ -221,7 +221,7 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
progress.text = null
}
DownloadStatus.FAILED,
DownloadStatus.ABORTED -> {
DownloadStatus.CANCELLED -> {
statusImage = imageHelper.errorImage
progress.text = null
}

View File

@ -167,6 +167,10 @@ class SettingsFragment :
update()
}
/**
* This function will be called when we return from the file picker
* with a new custom cache location
*/
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (
requestCode != SELECT_CACHE_ACTIVITY ||

View File

@ -167,9 +167,9 @@ class DownloadFile(
fun delete() {
cancelDownload()
FileUtil.delete(partialFile)
FileUtil.delete(completeFile)
FileUtil.delete(saveFile)
Storage.delete(partialFile)
Storage.delete(completeFile)
Storage.delete(saveFile)
status.postValue(DownloadStatus.IDLE)
@ -185,11 +185,11 @@ class DownloadFile(
fun cleanup(): Boolean {
var ok = true
if (Storage.isPathExists(completeFile) || Storage.isPathExists(saveFile)) {
ok = FileUtil.delete(partialFile)
ok = Storage.delete(partialFile)
}
if (Storage.isPathExists(saveFile)) {
ok = ok and FileUtil.delete(completeFile)
ok = ok and Storage.delete(completeFile)
}
return ok
@ -204,14 +204,14 @@ class DownloadFile(
private fun doPendingRename() {
try {
if (saveWhenDone) {
FileUtil.renameFile(completeFile, saveFile)
Storage.rename(completeFile, saveFile)
saveWhenDone = false
} else if (completeWhenDone) {
if (shouldSave) {
FileUtil.renameFile(partialFile, saveFile)
Storage.rename(partialFile, saveFile)
Util.scanMedia(saveFile)
} else {
FileUtil.renameFile(partialFile, completeFile)
Storage.rename(partialFile, completeFile)
}
completeWhenDone = false
}
@ -245,7 +245,7 @@ class DownloadFile(
if (isPlaying) {
saveWhenDone = true
} else {
FileUtil.renameFile(completeFile, saveFile)
Storage.rename(completeFile, saveFile)
newStatus = DownloadStatus.PINNED
}
} else {
@ -292,7 +292,7 @@ class DownloadFile(
outputStream.close()
if (isCancelled) {
status.postValue(DownloadStatus.ABORTED)
status.postValue(DownloadStatus.CANCELLED)
throw Exception(String.format("Download of '%s' was cancelled", song))
}
@ -307,18 +307,18 @@ class DownloadFile(
completeWhenDone = true
} else {
if (shouldSave) {
FileUtil.renameFile(partialFile, saveFile)
Storage.rename(partialFile, saveFile)
status.postValue(DownloadStatus.PINNED)
Util.scanMedia(saveFile)
} else {
FileUtil.renameFile(partialFile, completeFile)
Storage.rename(partialFile, completeFile)
status.postValue(DownloadStatus.DONE)
}
}
} catch (all: Exception) {
outputStream.safeClose()
FileUtil.delete(completeFile)
FileUtil.delete(saveFile)
Storage.delete(completeFile)
Storage.delete(saveFile)
if (!isCancelled) {
isFailed = true
if (retryCount > 1) {
@ -412,5 +412,5 @@ class DownloadFile(
}
enum class DownloadStatus {
IDLE, DOWNLOADING, RETRYING, FAILED, ABORTED, DONE, PINNED, UNKNOWN
IDLE, DOWNLOADING, RETRYING, FAILED, CANCELLED, DONE, PINNED, UNKNOWN
}

View File

@ -356,7 +356,7 @@ class LocalMediaPlayer : KoinComponent {
setAudioAttributes(mediaPlayer)
var dataSource: String? = null
var streamUrl: String? = null
if (partial) {
if (proxy == null) {
proxy = StreamProxy(object : Supplier<DownloadFile?>() {
@ -366,11 +366,11 @@ class LocalMediaPlayer : KoinComponent {
})
proxy!!.start()
}
dataSource = String.format(
streamUrl = String.format(
Locale.getDefault(), "http://127.0.0.1:%d/%s",
proxy!!.port, URLEncoder.encode(file!!.path, Constants.UTF_8)
)
Timber.i("Data Source: %s", dataSource)
Timber.i("Data Source: %s", streamUrl)
} else if (proxy != null) {
proxy?.stop()
proxy = null
@ -378,12 +378,12 @@ class LocalMediaPlayer : KoinComponent {
Timber.i("Preparing media player")
if (dataSource != null) {
Timber.v("LocalMediaPlayer doPlay dataSource: %s", dataSource)
mediaPlayer.setDataSource(dataSource)
if (streamUrl != null) {
Timber.v("LocalMediaPlayer doPlay dataSource: %s", streamUrl)
mediaPlayer.setDataSource(streamUrl)
} else {
Timber.v("LocalMediaPlayer doPlay Path: %s", file!!.path)
val descriptor = file!!.getDocumentFileDescriptor("r")!!
val descriptor = file.getDocumentFileDescriptor("r")!!
mediaPlayer.setDataSource(descriptor.fileDescriptor)
descriptor.close()
}
@ -468,7 +468,7 @@ class LocalMediaPlayer : KoinComponent {
}
Timber.v("LocalMediaPlayer setupNext Path: %s", file!!.path)
val descriptor = file!!.getDocumentFileDescriptor("r")!!
val descriptor = file.getDocumentFileDescriptor("r")!!
nextMediaPlayer!!.setDataSource(descriptor.fileDescriptor)
descriptor.close()

View File

@ -11,13 +11,13 @@ import org.koin.java.KoinJavaComponent.inject
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.domain.Playlist
import org.moire.ultrasonic.service.Downloader
import org.moire.ultrasonic.util.FileUtil.delete
import org.moire.ultrasonic.util.FileUtil.getAlbumArtFile
import org.moire.ultrasonic.util.FileUtil.getPlaylistDirectory
import org.moire.ultrasonic.util.FileUtil.getPlaylistFile
import org.moire.ultrasonic.util.FileUtil.listFiles
import org.moire.ultrasonic.util.FileUtil.musicDirectory
import org.moire.ultrasonic.util.Settings.cacheSizeMB
import org.moire.ultrasonic.util.Storage.delete
import org.moire.ultrasonic.util.Util.formatBytes
import timber.log.Timber
@ -144,7 +144,7 @@ class CacheCleaner : CoroutineScope by CoroutineScope(Dispatchers.IO) {
// No songs left in the folder
if (children.size == 1 && children[0].path == getAlbumArtFile(dir.path)) {
// Delete Artwork files
delete(getAlbumArtFile(dir.path))
delete(children[0].path)
children = dir.listFiles()
}
@ -166,17 +166,14 @@ class CacheCleaner : CoroutineScope by CoroutineScope(Dispatchers.IO) {
}
// Ensure that file system is not more than 95% full.
val bytesUsedFs: Long
val minFsAvailability: Long
val bytesTotalFs: Long
val bytesAvailableFs: Long
val descriptor = files[0].getDocumentFileDescriptor("r")!!
val stat = Os.fstatvfs(descriptor.fileDescriptor)
bytesTotalFs = stat.f_blocks * stat.f_bsize
bytesAvailableFs = stat.f_bfree * stat.f_bsize
bytesUsedFs = bytesTotalFs - bytesAvailableFs
minFsAvailability = bytesTotalFs - MIN_FREE_SPACE
val bytesTotalFs: Long = stat.f_blocks * stat.f_bsize
val bytesAvailableFs: Long = stat.f_bfree * stat.f_bsize
val bytesUsedFs: Long = bytesTotalFs - bytesAvailableFs
val minFsAvailability: Long = bytesTotalFs - MIN_FREE_SPACE
descriptor.close()
val bytesToDeleteCacheLimit = (bytesUsedBySubsonic - cacheSizeBytes).coerceAtLeast(0L)

View File

@ -30,6 +30,10 @@ import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.util.Util.safeClose
import timber.log.Timber
/**
* Provides Ultrasonic specific functions for managing the library files.
* Base storage functions like rename, create, delete should be handled in Storage.kt
*/
@Suppress("TooManyFunctions")
object FileUtil {
@ -89,6 +93,10 @@ object FileUtil {
return playlistDir
}
/**
* Get the directory where we store local copies of the playlists.
* It is always inside Ultrasonic base directory.
*/
@JvmStatic
fun getPlaylistDirectory(server: String? = null): File {
val playlistDir: File = if (server != null) {
@ -186,7 +194,7 @@ object FileUtil {
return albumArtDir
}
fun getAlbumDirectory(entry: MusicDirectory.Child): String {
private fun getAlbumDirectory(entry: MusicDirectory.Child): String {
val dir: String
if (!TextUtils.isEmpty(entry.path) && getParentPath(entry.path!!) != null) {
val f = fileSystemSafeDir(entry.path)
@ -318,10 +326,6 @@ object FileUtil {
@JvmStatic
fun listFiles(dir: AbstractFile): SortedSet<AbstractFile> {
val files = dir.listFiles()
if (files == null) {
Timber.w("Failed to list children for %s", dir.path)
return TreeSet()
}
return TreeSet(files.asList())
}
@ -486,35 +490,4 @@ object FileUtil {
fw.safeClose()
}
}
@JvmStatic
@Throws(IOException::class)
fun renameFile(from: String, to: String) {
Storage.rename(from, to)
}
@JvmStatic
fun delete(file: File?): Boolean {
if (file != null && file.exists()) {
if (!file.delete()) {
Timber.w("Failed to delete file %s", file)
return false
}
Timber.i("Deleted file %s", file)
}
return true
}
@JvmStatic
fun delete(file: String?): Boolean {
if (file != null) {
val storageFile = Storage.getFromPath(file)
if (storageFile != null && !storageFile.delete()) {
Timber.w("Failed to delete file %s", file)
return false
}
Timber.i("Deleted file %s", file)
}
return true
}
}

View File

@ -60,6 +60,15 @@ object Storage {
mediaRoot.value.rename(pathFrom, pathTo)
}
fun delete(path: String): Boolean {
val storageFile = getFromPath(path)
if (storageFile != null && !storageFile.delete()) {
Timber.w("Failed to delete file %s", path)
return false
}
return true
}
private fun getRoot(): AbstractFile? {
return if (Settings.cacheLocation.isUri()) {
val documentFile = DocumentFile.fromTreeUri(

View File

@ -16,7 +16,7 @@
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_gravity="center_vertical"
a:contentDescription="@null"
a:importantForAccessibility="no"
a:src="?attr/select_folder" />
<LinearLayout

View File

@ -190,7 +190,7 @@
<string name="settings.directory_cache_time_60">1 ora</string>
<string name="settings.disc_sort">Ordina Canzoni secondo Disco</string>
<string name="settings.disc_sort_summary">Ordina lista canzoni secondo il numero disco e traccia</string>
<string name="settings.display_bitrate">Visualizza Bitrate Ed Estensione FileAdapter</string>
<string name="settings.display_bitrate">Visualizza Bitrate Ed Estensione File</string>
<string name="settings.display_bitrate_summary">Aggiungi nome artista con bitrare ed estensione file</string>
<string name="settings.download_transition">Visualizza Download Durante Riproduzione</string>
<string name="settings.download_transition_summary">Passa al download quando inizia riproduzione</string>

View File

@ -216,7 +216,7 @@
<string name="settings.directory_cache_time_60">1 hour</string>
<string name="settings.disc_sort">Sort Songs By Disc</string>
<string name="settings.disc_sort_summary">Sort song list by disc number and track number</string>
<string name="settings.display_bitrate">Display Bitrate and FileAdapter Suffix</string>
<string name="settings.display_bitrate">Display Bitrate and File Suffix</string>
<string name="settings.display_bitrate_summary">Append artist name with bitrate and file suffix</string>
<string name="settings.download_transition">Show Downloads on Play</string>
<string name="settings.download_transition_summary">Transition to download activity when starting playback</string>