musikr: cleanup

This commit is contained in:
Alexander Capehart 2025-03-07 11:27:38 -07:00
parent f5483b5bc5
commit 9a70ae1c4e
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
3 changed files with 35 additions and 90 deletions

View file

@ -75,7 +75,8 @@ private class DeviceFSImpl(
location.uri, location.uri,
DocumentsContract.getTreeDocumentId(location.uri), DocumentsContract.getTreeDocumentId(location.uri),
location.path, location.path,
null) null
)
} }
private fun exploreDirectoryImpl( private fun exploreDirectoryImpl(
@ -99,52 +100,38 @@ private class DeviceFSImpl(
val sizeIndex = cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_SIZE) val sizeIndex = cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_SIZE)
val lastModifiedIndex = val lastModifiedIndex =
cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_LAST_MODIFIED) cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_LAST_MODIFIED)
contentResolver.useQuery(
DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, treeDocumentId),
PROJECTION
) { cursor ->
val childUriIndex =
cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_DOCUMENT_ID)
val displayNameIndex =
cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_DISPLAY_NAME)
val mimeTypeIndex =
cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_MIME_TYPE)
val sizeIndex = cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_SIZE)
val lastModifiedIndex =
cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_LAST_MODIFIED)
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
val childId = cursor.getString(childUriIndex) val childId = cursor.getString(childUriIndex)
val displayName = cursor.getString(displayNameIndex) val displayName = cursor.getString(displayNameIndex)
// Skip hidden files/directories if ignoreHidden is true // Skip hidden files/directories if ignoreHidden is true
if (!withHidden && displayName.startsWith(".")) { if (!withHidden && displayName.startsWith(".")) {
continue continue
} }
val newPath = relativePath.file(displayName) val newPath = relativePath.file(displayName)
val mimeType = cursor.getString(mimeTypeIndex) val mimeType = cursor.getString(mimeTypeIndex)
val lastModified = cursor.getLong(lastModifiedIndex) val lastModified = cursor.getLong(lastModifiedIndex)
if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) { if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) {
recursive.add( recursive.add(
exploreDirectoryImpl(rootUri, childId, newPath, directoryDeferred) exploreDirectoryImpl(rootUri, childId, newPath, directoryDeferred)
)
} else {
val size = cursor.getLong(sizeIndex)
val childUri = DocumentsContract.buildDocumentUriUsingTree(rootUri, childId)
val file =
DeviceFile(
uri = childUri,
mimeType = mimeType,
path = newPath,
size = size,
modifiedMs = lastModified,
parent = directoryDeferred
) )
} else { children.add(file)
val size = cursor.getLong(sizeIndex) emit(file)
val childUri = DocumentsContract.buildDocumentUriUsingTree(rootUri, childId)
val file =
DeviceFile(
uri = childUri,
mimeType = mimeType,
path = newPath,
size = size,
modifiedMs = lastModified,
parent = directoryDeferred
)
children.add(file)
emit(file)
}
} }
} }
directoryDeferred.complete(DeviceDirectory(uri, relativePath, parent, children)) directoryDeferred.complete(DeviceDirectory(uri, relativePath, parent, children))
@ -159,6 +146,7 @@ private class DeviceFSImpl(
DocumentsContract.Document.COLUMN_DISPLAY_NAME, DocumentsContract.Document.COLUMN_DISPLAY_NAME,
DocumentsContract.Document.COLUMN_MIME_TYPE, DocumentsContract.Document.COLUMN_MIME_TYPE,
DocumentsContract.Document.COLUMN_SIZE, DocumentsContract.Document.COLUMN_SIZE,
DocumentsContract.Document.COLUMN_LAST_MODIFIED) DocumentsContract.Document.COLUMN_LAST_MODIFIED
)
} }
} }

View file

@ -52,7 +52,7 @@ private class EvaluateStepImpl(
override suspend fun evaluate(extractedMusic: Flow<Extracted>): MutableLibrary = override suspend fun evaluate(extractedMusic: Flow<Extracted>): MutableLibrary =
extractedMusic extractedMusic
.filterIsInstance<Extracted.Valid>() .filterIsInstance<Extracted.Valid>()
.fold(MusicGraph.builder()) { graphBuilder, extracted -> .tryFold(MusicGraph.builder()) { graphBuilder, extracted ->
when (extracted) { when (extracted) {
is RawSong -> graphBuilder.add(tagInterpreter.interpret(extracted)) is RawSong -> graphBuilder.add(tagInterpreter.interpret(extracted))
is RawPlaylist -> is RawPlaylist ->

View file

@ -26,39 +26,6 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.withIndex import kotlinx.coroutines.flow.withIndex
internal sealed interface Divert<L, R> {
data class Left<L, R>(val value: L) : Divert<L, R>
data class Right<L, R>(val value: R) : Divert<L, R>
}
internal class DivertedFlow<L, R>(
val manager: Flow<Nothing>,
val left: Flow<L>,
val right: Flow<R>
)
internal inline fun <T, L, R> Flow<T>.divert(
crossinline predicate: (T) -> Divert<L, R>
): DivertedFlow<L, R> {
val leftChannel = Channel<L>(Channel.UNLIMITED)
val rightChannel = Channel<R>(Channel.UNLIMITED)
val managedFlow =
flow<Nothing> {
collect {
when (val result = predicate(it)) {
is Divert.Left -> leftChannel.send(result.value)
is Divert.Right -> rightChannel.send(result.value)
}
}
leftChannel.close()
rightChannel.close()
}
return DivertedFlow(managedFlow, leftChannel.receiveAsFlow(), rightChannel.receiveAsFlow())
}
internal class DistributedFlow<T>(val manager: Flow<Nothing>, val flows: Flow<Flow<T>>)
/** /**
* Equally "distributes" the values of some flow across n new flows. * Equally "distributes" the values of some flow across n new flows.
* *
@ -95,24 +62,14 @@ internal fun <T, R> Flow<T>.tryMap(transform: suspend (T) -> R): Flow<R> = flow
} }
} }
internal fun <T, R> Flow<T>.tryMapNotNull(transform: suspend (T) -> R?): Flow<R> = flow { internal suspend fun <T, A> Flow<T>.tryFold(initial: A, operation: suspend (A, T) -> A): A {
collect { value ->
try {
transform(value)?.let { emit(it) }
} catch (e: Exception) {
throw PipelineException(value, e)
}
}
}
internal fun <A, T> Flow<T>.tryFold(initial: A, operation: suspend (A, T) -> A): Flow<A> = flow {
var accumulator = initial var accumulator = initial
collect { value -> collect { value ->
try { try {
accumulator = operation(accumulator, value) accumulator = operation(accumulator, value)
emit(accumulator)
} catch (e: Exception) { } catch (e: Exception) {
throw PipelineException(value, e) throw PipelineException(value, e)
} }
} }
} return accumulator
}