music: cleanup
Clean up parts of the music loader.
This commit is contained in:
parent
77d01a0c97
commit
a9a6d1ccc1
3 changed files with 26 additions and 16 deletions
|
@ -372,7 +372,6 @@ constructor(
|
|||
// Do the initial query of the cache and media databases in parallel.
|
||||
logD("Starting MediaStore query")
|
||||
val mediaStoreQueryJob = worker.scope.tryAsync { mediaStoreExtractor.query() }
|
||||
val userLibraryQueryJob = worker.scope.tryAsync { userLibraryFactory.query() }
|
||||
val cache =
|
||||
if (withCache) {
|
||||
logD("Reading cache")
|
||||
|
@ -431,6 +430,7 @@ constructor(
|
|||
logD("Discovered ${rawSongs.size} songs, starting finalization")
|
||||
emitLoading(IndexingProgress.Indeterminate)
|
||||
logD("Starting UserLibrary query")
|
||||
val userLibraryQueryJob = worker.scope.tryAsync { userLibraryFactory.query() }
|
||||
if (cache == null || cache.invalidated) {
|
||||
logD("Writing cache [why=${cache?.invalidated}]")
|
||||
cacheRepository.writeCache(rawSongs)
|
||||
|
|
|
@ -97,6 +97,14 @@ interface DeviceLibrary {
|
|||
|
||||
/** Constructs a [DeviceLibrary] implementation in an asynchronous manner. */
|
||||
interface Factory {
|
||||
/**
|
||||
* Creates a new [DeviceLibrary] instance asynchronously based on the incoming stream of
|
||||
* [RawSong] instances.
|
||||
*
|
||||
* @param rawSongs A stream of [RawSong] instances to process.
|
||||
* @param processedSongs A stream of [RawSong] instances that will have been processed by
|
||||
* the instance.
|
||||
*/
|
||||
suspend fun create(
|
||||
rawSongs: Channel<RawSong>,
|
||||
processedSongs: Channel<RawSong>
|
||||
|
@ -123,8 +131,11 @@ class DeviceLibraryFactoryImpl @Inject constructor(private val musicSettings: Mu
|
|||
// causing severe issues elsewhere.
|
||||
if (songGrouping.containsKey(song.uid)) {
|
||||
logW(
|
||||
"Duplicate song found: ${song.path} in " +
|
||||
"Duplicate song found: ${song.path} " +
|
||||
"collides with ${unlikelyToBeNull(songGrouping[song.uid]).path}")
|
||||
// We still want to say that we "processed" the song so that the user doesn't
|
||||
// get confused at why the bar was only partly filled by the end of the loading
|
||||
// process.
|
||||
processedSongs.send(rawSong)
|
||||
continue
|
||||
}
|
||||
|
@ -140,9 +151,9 @@ class DeviceLibraryFactoryImpl @Inject constructor(private val musicSettings: Mu
|
|||
// use for album information to ensure consistent metadata and UIDs. Fall back to
|
||||
// the name otherwise.
|
||||
val trackLower =
|
||||
song.track != null && (prioritized.track == null || song.track < prioritized.track)
|
||||
val nameLower =
|
||||
song.name < prioritized.name
|
||||
song.track != null &&
|
||||
(prioritized.track == null || song.track < prioritized.track)
|
||||
val nameLower = song.name < prioritized.name
|
||||
if (trackLower || nameLower) {
|
||||
albumBody.raw = PrioritizedRaw(song.rawAlbum, song)
|
||||
}
|
||||
|
@ -192,8 +203,7 @@ class DeviceLibraryFactoryImpl @Inject constructor(private val musicSettings: Mu
|
|||
|
||||
// Now that all songs are processed, also process albums and group them into their
|
||||
// respective artists.
|
||||
val albums =
|
||||
albumGrouping.values.map { AlbumImpl(it.raw.inner, musicSettings, it.music) }
|
||||
val albums = albumGrouping.values.map { AlbumImpl(it.raw.inner, musicSettings, it.music) }
|
||||
for (album in albums) {
|
||||
for (rawArtist in album.rawArtists) {
|
||||
val key = RawArtist.Key(rawArtist)
|
||||
|
@ -204,13 +214,14 @@ class DeviceLibraryFactoryImpl @Inject constructor(private val musicSettings: Mu
|
|||
// Immediately replace any songs that initially held the priority position.
|
||||
is SongImpl -> body.raw = PrioritizedRaw(rawArtist, album)
|
||||
is AlbumImpl -> {
|
||||
// Album information from later dates is prioritized, as it is more likely to
|
||||
// Album information from later dates is prioritized, as it is more
|
||||
// likely to
|
||||
// contain the "modern" name of the artist if the information really is
|
||||
// in-consistent. Fall back to the name otherwise.
|
||||
val dateEarlier =
|
||||
album.dates != null && (prioritized.dates == null || album.dates < prioritized.dates)
|
||||
val nameLower =
|
||||
album.name < prioritized.name
|
||||
album.dates != null &&
|
||||
(prioritized.dates == null || album.dates < prioritized.dates)
|
||||
val nameLower = album.name < prioritized.name
|
||||
if (dateEarlier || nameLower) {
|
||||
body.raw = PrioritizedRaw(rawArtist, album)
|
||||
}
|
||||
|
@ -228,8 +239,7 @@ class DeviceLibraryFactoryImpl @Inject constructor(private val musicSettings: Mu
|
|||
// Artists and genres do not need to be grouped and can be processed immediately.
|
||||
val artists =
|
||||
artistGrouping.values.map { ArtistImpl(it.raw.inner, musicSettings, it.music) }
|
||||
val genres =
|
||||
genreGrouping.values.map { GenreImpl(it.raw.inner, musicSettings, it.music) }
|
||||
val genres = genreGrouping.values.map { GenreImpl(it.raw.inner, musicSettings, it.music) }
|
||||
|
||||
return DeviceLibraryImpl(songGrouping.values, albums, artists, genres)
|
||||
}
|
||||
|
@ -259,7 +269,7 @@ class DeviceLibraryImpl(
|
|||
override fun hashCode() = songs.hashCode()
|
||||
override fun toString() =
|
||||
"DeviceLibrary(songs=${songs.size}, albums=${albums.size}, " +
|
||||
"artists=${artists.size}, genres=${genres.size})"
|
||||
"artists=${artists.size}, genres=${genres.size})"
|
||||
|
||||
override fun findSong(uid: Music.UID): Song? = songUidMap[uid]
|
||||
override fun findAlbum(uid: Music.UID): Album? = albumUidMap[uid]
|
||||
|
|
|
@ -36,9 +36,9 @@ import org.oxycblt.auxio.util.logE
|
|||
* is also not backed by library information, rather an app database with in-memory caching. It is
|
||||
* generally not expected to create this yourself, and instead rely on MusicRepository.
|
||||
*
|
||||
* TODO: Communicate errors
|
||||
*
|
||||
* @author Alexander Capehart
|
||||
*
|
||||
* TODO: Communicate errors
|
||||
*/
|
||||
interface UserLibrary {
|
||||
/** The current user-defined playlists. */
|
||||
|
|
Loading…
Reference in a new issue