musikr: streamline package structure

This commit is contained in:
Alexander Capehart 2025-03-03 19:59:11 -07:00
parent 0d0a20d760
commit 6feee93438
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
29 changed files with 118 additions and 148 deletions

View file

@ -28,7 +28,7 @@ import android.os.ParcelFileDescriptor
import kotlinx.coroutines.runBlocking
import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.image.covers.SettingCovers
import org.oxycblt.musikr.cover.CoverResult
import org.oxycblt.musikr.covers.CoverResult
class CoverProvider() : ContentProvider() {
override fun onCreate(): Boolean = true

View file

@ -64,7 +64,7 @@ import org.oxycblt.musikr.Artist
import org.oxycblt.musikr.Genre
import org.oxycblt.musikr.Playlist
import org.oxycblt.musikr.Song
import org.oxycblt.musikr.cover.CoverCollection
import org.oxycblt.musikr.covers.CoverCollection
/**
* Auxio's extension of [ImageView] that enables cover art loading and playing indicator and

View file

@ -46,7 +46,7 @@ import kotlinx.coroutines.withContext
import okio.FileSystem
import okio.buffer
import okio.source
import org.oxycblt.musikr.cover.CoverCollection
import org.oxycblt.musikr.covers.CoverCollection
class CoverCollectionFetcher
private constructor(

View file

@ -40,7 +40,7 @@ import javax.inject.Inject
import okio.FileSystem
import okio.buffer
import okio.source
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.covers.Cover
class CoverFetcher private constructor(private val context: Context, private val cover: Cover) :
Fetcher {

View file

@ -21,8 +21,8 @@ package org.oxycblt.auxio.image.coil
import coil3.key.Keyer
import coil3.request.Options
import javax.inject.Inject
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.cover.CoverCollection
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.CoverCollection
class CoverKeyer @Inject constructor() : Keyer<Cover> {
override fun key(data: Cover, options: Options) = "${data.id}&${options.size}"

View file

@ -23,7 +23,7 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.oxycblt.musikr.cover.CoverIdentifier
import org.oxycblt.musikr.covers.internal.CoverIdentifier
@Module
@InstallIn(SingletonComponent::class)

View file

@ -19,7 +19,7 @@
package org.oxycblt.auxio.image.covers
import java.util.UUID
import org.oxycblt.musikr.cover.CoverParams
import org.oxycblt.musikr.covers.internal.CoverParams
data class CoverSilo(val revision: UUID, val params: CoverParams?) {
override fun toString() =

View file

@ -19,9 +19,9 @@
package org.oxycblt.auxio.image.covers
import android.content.Context
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.cover.CoverResult
import org.oxycblt.musikr.cover.MutableCovers
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.CoverResult
import org.oxycblt.musikr.covers.MutableCovers
import org.oxycblt.musikr.fs.device.DeviceFile
import org.oxycblt.musikr.metadata.Metadata

View file

@ -23,21 +23,21 @@ import java.util.UUID
import javax.inject.Inject
import org.oxycblt.auxio.image.CoverMode
import org.oxycblt.auxio.image.ImageSettings
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.cover.CoverIdentifier
import org.oxycblt.musikr.cover.CoverParams
import org.oxycblt.musikr.cover.Covers
import org.oxycblt.musikr.cover.FileCover
import org.oxycblt.musikr.cover.FolderCovers
import org.oxycblt.musikr.cover.MutableCovers
import org.oxycblt.musikr.cover.MutableFolderCovers
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.internal.CoverIdentifier
import org.oxycblt.musikr.covers.internal.CoverParams
import org.oxycblt.musikr.covers.Covers
import org.oxycblt.musikr.covers.internal.FileCover
import org.oxycblt.musikr.covers.fs.FSCovers
import org.oxycblt.musikr.covers.MutableCovers
import org.oxycblt.musikr.covers.fs.MutableFSCovers
interface SettingCovers {
suspend fun mutate(context: Context, revision: UUID): MutableCovers<out Cover>
companion object {
fun immutable(context: Context): Covers<FileCover> =
Covers.chain(BaseSiloedCovers(context), FolderCovers(context))
Covers.chain(BaseSiloedCovers(context), FSCovers(context))
}
}
@ -57,5 +57,6 @@ constructor(private val imageSettings: ImageSettings, private val identifier: Co
private suspend fun siloedCovers(context: Context, revision: UUID, with: CoverParams?) =
MutableCovers.chain(
MutableSiloedCovers.from(context, CoverSilo(revision, with), identifier),
MutableFolderCovers(context))
MutableFSCovers(context)
)
}

View file

@ -22,16 +22,16 @@ import android.content.Context
import java.io.File
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.cover.CoverFormat
import org.oxycblt.musikr.cover.CoverIdentifier
import org.oxycblt.musikr.cover.CoverResult
import org.oxycblt.musikr.cover.Covers
import org.oxycblt.musikr.cover.FileCover
import org.oxycblt.musikr.cover.FileCovers
import org.oxycblt.musikr.cover.MutableCovers
import org.oxycblt.musikr.cover.MutableFileCovers
import org.oxycblt.musikr.fs.app.AppFiles
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.internal.CoverFormat
import org.oxycblt.musikr.covers.internal.CoverIdentifier
import org.oxycblt.musikr.covers.CoverResult
import org.oxycblt.musikr.covers.Covers
import org.oxycblt.musikr.covers.internal.FileCover
import org.oxycblt.musikr.covers.internal.InternalCovers
import org.oxycblt.musikr.covers.MutableCovers
import org.oxycblt.musikr.covers.internal.MutableInternalCovers
import org.oxycblt.musikr.fs.app.AppFS
import org.oxycblt.musikr.fs.device.DeviceFile
import org.oxycblt.musikr.metadata.Metadata
@ -39,20 +39,20 @@ class BaseSiloedCovers(private val context: Context) : Covers<FileCover> {
override suspend fun obtain(id: String): CoverResult<FileCover> {
val siloedId = SiloedCoverId.parse(id) ?: return CoverResult.Miss()
val core = SiloCore.from(context, siloedId.silo)
val fileCovers = FileCovers(core.files, core.format)
return when (val result = fileCovers.obtain(siloedId.id)) {
val internalCovers = InternalCovers(core.files, core.format)
return when (val result = internalCovers.obtain(siloedId.id)) {
is CoverResult.Hit -> CoverResult.Hit(SiloedCover(siloedId.silo, result.cover))
is CoverResult.Miss -> CoverResult.Miss()
}
}
}
open class SiloedCovers(private val silo: CoverSilo, private val fileCovers: FileCovers) :
open class SiloedCovers(private val silo: CoverSilo, private val internalCovers: InternalCovers) :
Covers<FileCover> {
override suspend fun obtain(id: String): CoverResult<FileCover> {
val coverId = SiloedCoverId.parse(id) ?: return CoverResult.Miss()
if (silo != coverId.silo) return CoverResult.Miss()
return when (val result = fileCovers.obtain(coverId.id)) {
return when (val result = internalCovers.obtain(coverId.id)) {
is CoverResult.Hit -> CoverResult.Hit(SiloedCover(silo, result.cover))
is CoverResult.Miss -> CoverResult.Miss()
}
@ -61,7 +61,7 @@ open class SiloedCovers(private val silo: CoverSilo, private val fileCovers: Fil
companion object {
suspend fun from(context: Context, silo: CoverSilo): SiloedCovers {
val core = SiloCore.from(context, silo)
return SiloedCovers(silo, FileCovers(core.files, core.format))
return SiloedCovers(silo, InternalCovers(core.files, core.format))
}
}
}
@ -70,7 +70,7 @@ class MutableSiloedCovers
private constructor(
private val rootDir: File,
private val silo: CoverSilo,
private val fileCovers: MutableFileCovers
private val fileCovers: MutableInternalCovers
) : SiloedCovers(silo, fileCovers), MutableCovers<FileCover> {
override suspend fun create(file: DeviceFile, metadata: Metadata): CoverResult<FileCover> =
when (val result = fileCovers.create(file, metadata)) {
@ -96,7 +96,8 @@ private constructor(
): MutableSiloedCovers {
val core = SiloCore.from(context, silo)
return MutableSiloedCovers(
core.rootDir, silo, MutableFileCovers(core.files, core.format, coverIdentifier))
core.rootDir, silo, MutableInternalCovers(core.files, core.format, coverIdentifier)
)
}
}
}
@ -120,7 +121,7 @@ data class SiloedCoverId(val silo: CoverSilo, val id: String) {
}
}
private data class SiloCore(val rootDir: File, val files: AppFiles, val format: CoverFormat) {
private data class SiloCore(val rootDir: File, val files: AppFS, val format: CoverFormat) {
companion object {
suspend fun from(context: Context, silo: CoverSilo): SiloCore {
val rootDir: File
@ -129,7 +130,7 @@ private data class SiloCore(val rootDir: File, val files: AppFiles, val format:
rootDir = context.coversDir()
revisionDir = rootDir.resolve(silo.toString()).apply { mkdirs() }
}
val files = AppFiles.at(revisionDir)
val files = AppFS.at(revisionDir)
val format = silo.params?.let(CoverFormat::jpeg) ?: CoverFormat.asIs()
return SiloCore(rootDir, files, format)
}

View file

@ -19,8 +19,8 @@
package org.oxycblt.musikr
import org.oxycblt.musikr.cache.MutableCache
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.cover.MutableCovers
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.MutableCovers
import org.oxycblt.musikr.playlist.db.StoredPlaylists
import org.oxycblt.musikr.tag.interpret.Naming
import org.oxycblt.musikr.tag.interpret.Separators

View file

@ -25,8 +25,8 @@ import java.security.MessageDigest
import java.util.UUID
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.cover.CoverCollection
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.CoverCollection
import org.oxycblt.musikr.fs.Format
import org.oxycblt.musikr.fs.Path
import org.oxycblt.musikr.tag.Date

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.cover
package org.oxycblt.musikr.covers
import java.io.InputStream
import org.oxycblt.musikr.fs.device.DeviceFile

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2025 Auxio Project
* FolderCovers.kt is part of Auxio.
* FSCovers.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.cover
package org.oxycblt.musikr.covers.fs
import android.content.Context
import android.net.Uri
@ -26,11 +26,16 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.withContext
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.CoverResult
import org.oxycblt.musikr.covers.Covers
import org.oxycblt.musikr.covers.MutableCovers
import org.oxycblt.musikr.covers.internal.FileCover
import org.oxycblt.musikr.fs.device.DeviceDirectory
import org.oxycblt.musikr.fs.device.DeviceFile
import org.oxycblt.musikr.metadata.Metadata
open class FolderCovers(private val context: Context) : Covers<FolderCover> {
open class FSCovers(private val context: Context) : Covers<FolderCover> {
override suspend fun obtain(id: String): CoverResult<FolderCover> {
// Parse the ID to get the directory URI
if (!id.startsWith("folder:")) {
@ -60,8 +65,8 @@ open class FolderCovers(private val context: Context) : Covers<FolderCover> {
}
}
class MutableFolderCovers(private val context: Context) :
FolderCovers(context), MutableCovers<FolderCover> {
class MutableFSCovers(private val context: Context) :
FSCovers(context), MutableCovers<FolderCover> {
override suspend fun create(file: DeviceFile, metadata: Metadata): CoverResult<FolderCover> {
val parent = file.parent
val coverFile = findCoverInDirectory(parent) ?: return CoverResult.Miss()

View file

@ -1,22 +1,4 @@
/*
* Copyright (c) 2024 Auxio Project
* CoverFormat.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.cover
package org.oxycblt.musikr.covers.internal
import android.graphics.Bitmap
import android.graphics.BitmapFactory

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.cover
package org.oxycblt.musikr.covers.internal
import java.security.MessageDigest

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.cover
package org.oxycblt.musikr.covers.internal
class CoverParams private constructor(val resolution: Int, val quality: Int) {
override fun hashCode() = 31 * resolution + quality

View file

@ -16,18 +16,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.cover
package org.oxycblt.musikr.covers.internal
import android.os.ParcelFileDescriptor
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.CoverResult
import org.oxycblt.musikr.covers.Covers
import org.oxycblt.musikr.covers.MutableCovers
import org.oxycblt.musikr.fs.app.AppFile
import org.oxycblt.musikr.fs.app.AppFiles
import org.oxycblt.musikr.fs.app.AppFS
import org.oxycblt.musikr.fs.device.DeviceFile
import org.oxycblt.musikr.metadata.Metadata
open class FileCovers(private val appFiles: AppFiles, private val coverFormat: CoverFormat) :
open class InternalCovers(private val appFS: AppFS, private val coverFormat: CoverFormat) :
Covers<FileCover> {
override suspend fun obtain(id: String): CoverResult<FileCover> {
val file = appFiles.find(getFileName(id))
val file = appFS.find(getFileName(id))
return if (file != null) {
CoverResult.Hit(FileCoverImpl(id, file))
} else {
@ -38,21 +42,21 @@ open class FileCovers(private val appFiles: AppFiles, private val coverFormat: C
protected fun getFileName(id: String) = "$id.${coverFormat.extension}"
}
class MutableFileCovers(
private val appFiles: AppFiles,
class MutableInternalCovers(
private val appFS: AppFS,
private val coverFormat: CoverFormat,
private val coverIdentifier: CoverIdentifier
) : FileCovers(appFiles, coverFormat), MutableCovers<FileCover> {
) : InternalCovers(appFS, coverFormat), MutableCovers<FileCover> {
override suspend fun create(file: DeviceFile, metadata: Metadata): CoverResult<FileCover> {
val data = metadata.cover ?: return CoverResult.Miss()
val id = coverIdentifier.identify(data)
val coverFile = appFiles.write(getFileName(id)) { coverFormat.transcodeInto(data, it) }
val coverFile = appFS.write(getFileName(id)) { coverFormat.transcodeInto(data, it) }
return CoverResult.Hit(FileCoverImpl(id, coverFile))
}
override suspend fun cleanup(excluding: Collection<Cover>) {
val used = excluding.mapTo(mutableSetOf()) { getFileName(it.id) }
appFiles.deleteWhere { it !in used }
appFS.deleteWhere { it !in used }
}
}

View file

@ -28,7 +28,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
interface AppFiles {
interface AppFS {
suspend fun find(name: String): AppFile?
suspend fun write(name: String, block: suspend (OutputStream) -> Unit): AppFile
@ -36,9 +36,9 @@ interface AppFiles {
suspend fun deleteWhere(block: (String) -> Boolean)
companion object {
suspend fun at(dir: File): AppFiles {
suspend fun at(dir: File): AppFS {
withContext(Dispatchers.IO) { check(dir.exists() && dir.isDirectory) }
return AppFilesImpl(dir)
return AppFSImpl(dir)
}
}
}
@ -49,7 +49,7 @@ interface AppFile {
suspend fun open(): InputStream?
}
private class AppFilesImpl(private val dir: File) : AppFiles {
private class AppFSImpl(private val dir: File) : AppFS {
private val fileMutexes = mutableMapOf<String, Mutex>()
private val mapMutex = Mutex()

View file

@ -30,16 +30,37 @@ import kotlinx.coroutines.flow.flow
import org.oxycblt.musikr.fs.MusicLocation
import org.oxycblt.musikr.fs.Path
internal interface DeviceFiles {
internal interface DeviceFS {
fun explore(locations: Flow<MusicLocation>, ignoreHidden: Boolean = true): Flow<DeviceNode>
companion object {
fun from(context: Context): DeviceFiles = DeviceFilesImpl(context.contentResolverSafe)
fun from(context: Context): DeviceFS = DeviceFSImpl(context.contentResolverSafe)
}
}
sealed interface DeviceNode {
val uri: Uri
val path: Path
}
data class DeviceDirectory(
override val uri: Uri,
override val path: Path,
val parent: DeviceDirectory?,
var children: Flow<DeviceNode>
) : DeviceNode
data class DeviceFile(
override val uri: Uri,
override val path: Path,
val modifiedMs: Long,
val mimeType: String,
val size: Long,
val parent: DeviceDirectory
) : DeviceNode
@OptIn(ExperimentalCoroutinesApi::class)
private class DeviceFilesImpl(private val contentResolver: ContentResolver) : DeviceFiles {
private class DeviceFSImpl(private val contentResolver: ContentResolver) : DeviceFS {
override fun explore(locations: Flow<MusicLocation>, ignoreHidden: Boolean): Flow<DeviceNode> =
locations.flatMapMerge { location ->
// Create a root directory for each location

View file

@ -1,44 +0,0 @@
/*
* Copyright (c) 2024 Auxio Project
* DeviceFile.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.musikr.fs.device
import android.net.Uri
import kotlinx.coroutines.flow.Flow
import org.oxycblt.musikr.fs.Path
sealed interface DeviceNode {
val uri: Uri
val path: Path
}
data class DeviceDirectory(
override val uri: Uri,
override val path: Path,
val parent: DeviceDirectory?,
var children: Flow<DeviceNode>
) : DeviceNode
data class DeviceFile(
override val uri: Uri,
override val path: Path,
val modifiedMs: Long,
val mimeType: String,
val size: Long,
val parent: DeviceDirectory
) : DeviceNode

View file

@ -22,7 +22,7 @@ import org.oxycblt.musikr.Album
import org.oxycblt.musikr.Artist
import org.oxycblt.musikr.Music
import org.oxycblt.musikr.Song
import org.oxycblt.musikr.cover.CoverCollection
import org.oxycblt.musikr.covers.CoverCollection
import org.oxycblt.musikr.tag.Date
import org.oxycblt.musikr.tag.interpret.PreAlbum
import org.oxycblt.musikr.util.update

View file

@ -23,7 +23,7 @@ import org.oxycblt.musikr.Artist
import org.oxycblt.musikr.Genre
import org.oxycblt.musikr.Music
import org.oxycblt.musikr.Song
import org.oxycblt.musikr.cover.CoverCollection
import org.oxycblt.musikr.covers.CoverCollection
import org.oxycblt.musikr.tag.interpret.PreArtist
import org.oxycblt.musikr.util.update

View file

@ -22,7 +22,7 @@ import org.oxycblt.musikr.Artist
import org.oxycblt.musikr.Genre
import org.oxycblt.musikr.Music
import org.oxycblt.musikr.Song
import org.oxycblt.musikr.cover.CoverCollection
import org.oxycblt.musikr.covers.CoverCollection
import org.oxycblt.musikr.tag.interpret.PreGenre
import org.oxycblt.musikr.util.update

View file

@ -20,7 +20,7 @@ package org.oxycblt.musikr.model
import org.oxycblt.musikr.Playlist
import org.oxycblt.musikr.Song
import org.oxycblt.musikr.cover.CoverCollection
import org.oxycblt.musikr.covers.CoverCollection
import org.oxycblt.musikr.playlist.interpret.PrePlaylistInfo
import org.oxycblt.musikr.tag.Name

View file

@ -33,13 +33,13 @@ import kotlinx.coroutines.flow.merge
import org.oxycblt.musikr.Storage
import org.oxycblt.musikr.cache.Cache
import org.oxycblt.musikr.cache.CacheResult
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.cover.CoverResult
import org.oxycblt.musikr.cover.Covers
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.CoverResult
import org.oxycblt.musikr.covers.Covers
import org.oxycblt.musikr.fs.MusicLocation
import org.oxycblt.musikr.fs.device.DeviceDirectory
import org.oxycblt.musikr.fs.device.DeviceFile
import org.oxycblt.musikr.fs.device.DeviceFiles
import org.oxycblt.musikr.fs.device.DeviceFS
import org.oxycblt.musikr.fs.device.DeviceNode
import org.oxycblt.musikr.playlist.db.StoredPlaylists
import org.oxycblt.musikr.playlist.m3u.M3U
@ -50,12 +50,12 @@ internal interface ExploreStep {
companion object {
fun from(context: Context, storage: Storage): ExploreStep =
ExploreStepImpl(
DeviceFiles.from(context), storage.cache, storage.covers, storage.storedPlaylists)
DeviceFS.from(context), storage.cache, storage.covers, storage.storedPlaylists)
}
}
private class ExploreStepImpl(
private val deviceFiles: DeviceFiles,
private val deviceFS: DeviceFS,
private val cache: Cache,
private val covers: Covers<out Cover>,
private val storedPlaylists: StoredPlaylists
@ -64,7 +64,7 @@ private class ExploreStepImpl(
override fun explore(locations: List<MusicLocation>): Flow<Explored> {
val addingMs = System.currentTimeMillis()
return merge(
deviceFiles
deviceFS
.explore(locations.asFlow())
.flattenFilter { it.mimeType.startsWith("audio/") || it.mimeType == M3U.MIME_TYPE }
.distribute(8)

View file

@ -26,9 +26,9 @@ import kotlinx.coroutines.flow.onCompletion
import org.oxycblt.musikr.Storage
import org.oxycblt.musikr.cache.CachedSong
import org.oxycblt.musikr.cache.MutableCache
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.cover.CoverResult
import org.oxycblt.musikr.cover.MutableCovers
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.covers.CoverResult
import org.oxycblt.musikr.covers.MutableCovers
import org.oxycblt.musikr.metadata.MetadataExtractor
import org.oxycblt.musikr.tag.parse.TagParser

View file

@ -18,7 +18,7 @@
package org.oxycblt.musikr.pipeline
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.fs.device.DeviceFile
import org.oxycblt.musikr.metadata.Properties
import org.oxycblt.musikr.playlist.PlaylistFile
@ -44,7 +44,7 @@ internal sealed interface Extracted : PipelineItem {
sealed interface Invalid : Extracted
}
data object InvalidSong : Extracted.Invalid
internal data object InvalidSong : Extracted.Invalid
internal data class RawPlaylist(val file: PlaylistFile) : Explored.Known, Extracted.Valid

View file

@ -21,7 +21,7 @@ package org.oxycblt.musikr.tag.interpret
import android.net.Uri
import java.util.UUID
import org.oxycblt.musikr.Music
import org.oxycblt.musikr.cover.Cover
import org.oxycblt.musikr.covers.Cover
import org.oxycblt.musikr.fs.Format
import org.oxycblt.musikr.fs.Path
import org.oxycblt.musikr.tag.Date