mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-05-09 03:51:06 +03:00
Minor fixes
This commit is contained in:
parent
f4554ff29e
commit
a0da791b28
@ -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
|
||||
}
|
||||
|
@ -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 ||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user