diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicModule.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicModule.kt index 37eb96878..c276ca414 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicModule.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicModule.kt @@ -28,7 +28,6 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Singleton import org.oxycblt.musikr.cache.Cache import org.oxycblt.musikr.playlist.db.StoredPlaylists -import org.oxycblt.musikr.track.Tracker @Module @InstallIn(SingletonComponent::class) @@ -43,8 +42,6 @@ interface MusicModule { class MusikrShimModule { @Singleton @Provides fun cache(@ApplicationContext context: Context) = Cache.from(context) - @Singleton @Provides fun tracker(@ApplicationContext context: Context) = Tracker.from(context) - @Singleton @Provides fun storedPlaylists(@ApplicationContext context: Context) = StoredPlaylists.from(context) diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt index 5f1e1fb4a..159a31ca8 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt @@ -42,7 +42,6 @@ import org.oxycblt.musikr.cache.WriteOnlyCache import org.oxycblt.musikr.playlist.db.StoredPlaylists import org.oxycblt.musikr.tag.interpret.Naming import org.oxycblt.musikr.tag.interpret.Separators -import org.oxycblt.musikr.track.Tracker import timber.log.Timber as L /** @@ -216,7 +215,6 @@ class MusicRepositoryImpl constructor( @ApplicationContext private val context: Context, private val cache: Cache, - private val tracker: Tracker, private val storedPlaylists: StoredPlaylists, private val musicSettings: MusicSettings ) : MusicRepository { @@ -367,7 +365,7 @@ constructor( val newRevision = currentRevision?.takeIf { withCache } ?: UUID.randomUUID() val cache = if (withCache) cache else WriteOnlyCache(cache) val covers = MutableRevisionedStoredCovers(context, newRevision) - val storage = Storage(cache, tracker, covers, storedPlaylists) + val storage = Storage(cache, covers, storedPlaylists) val interpretation = Interpretation(nameFactory, separators) val newLibrary = diff --git a/musikr/src/main/java/org/oxycblt/musikr/Config.kt b/musikr/src/main/java/org/oxycblt/musikr/Config.kt index 7158f9446..22ec833dd 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/Config.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/Config.kt @@ -23,11 +23,9 @@ import org.oxycblt.musikr.cover.MutableStoredCovers import org.oxycblt.musikr.playlist.db.StoredPlaylists import org.oxycblt.musikr.tag.interpret.Naming import org.oxycblt.musikr.tag.interpret.Separators -import org.oxycblt.musikr.track.Tracker data class Storage( val cache: Cache, - val tracker: Tracker, val storedCovers: MutableStoredCovers, val storedPlaylists: StoredPlaylists ) diff --git a/musikr/src/main/java/org/oxycblt/musikr/graph/MusicGraph.kt b/musikr/src/main/java/org/oxycblt/musikr/graph/MusicGraph.kt index 21e0f12f9..d08a979ce 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/graph/MusicGraph.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/graph/MusicGraph.kt @@ -24,7 +24,7 @@ import org.oxycblt.musikr.playlist.interpret.PrePlaylist import org.oxycblt.musikr.tag.interpret.PreAlbum import org.oxycblt.musikr.tag.interpret.PreArtist import org.oxycblt.musikr.tag.interpret.PreGenre -import org.oxycblt.musikr.track.TrackedSong +import org.oxycblt.musikr.tag.interpret.PreSong import org.oxycblt.musikr.util.unlikelyToBeNull internal data class MusicGraph( @@ -35,7 +35,7 @@ internal data class MusicGraph( val playlistVertex: Set ) { interface Builder { - fun add(trackedSong: TrackedSong) + fun add(preSong: PreSong) fun add(prePlaylist: PrePlaylist) @@ -54,8 +54,7 @@ private class MusicGraphBuilderImpl : MusicGraph.Builder { private val genreVertices = mutableMapOf() private val playlistVertices = mutableSetOf() - override fun add(trackedSong: TrackedSong) { - val preSong = trackedSong.preSong + override fun add(preSong: PreSong) { val uid = preSong.uid if (songVertices.containsKey(uid)) { return @@ -89,7 +88,7 @@ private class MusicGraphBuilderImpl : MusicGraph.Builder { val songVertex = SongVertex( - trackedSong, + preSong, albumVertex, songArtistVertices.toMutableList(), songGenreVertices.toMutableList()) @@ -312,7 +311,7 @@ private class MusicGraphBuilderImpl : MusicGraph.Builder { } internal class SongVertex( - val trackedSong: TrackedSong, + val preSong: PreSong, var albumVertex: AlbumVertex, var artistVertices: MutableList, var genreVertices: MutableList diff --git a/musikr/src/main/java/org/oxycblt/musikr/model/LibraryFactory.kt b/musikr/src/main/java/org/oxycblt/musikr/model/LibraryFactory.kt index d3ed34b53..bffe06b0c 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/model/LibraryFactory.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/model/LibraryFactory.kt @@ -75,7 +75,7 @@ private class LibraryFactoryImpl() : LibraryFactory { } private class SongVertexCore(private val vertex: SongVertex) : SongCore { - override val trackedSong = vertex.trackedSong + override val preSong = vertex.preSong override fun resolveAlbum() = vertex.albumVertex.tag as Album diff --git a/musikr/src/main/java/org/oxycblt/musikr/model/SongImpl.kt b/musikr/src/main/java/org/oxycblt/musikr/model/SongImpl.kt index b77e90195..2747edd1d 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/model/SongImpl.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/model/SongImpl.kt @@ -22,10 +22,10 @@ import org.oxycblt.musikr.Album import org.oxycblt.musikr.Artist import org.oxycblt.musikr.Genre import org.oxycblt.musikr.Song -import org.oxycblt.musikr.track.TrackedSong +import org.oxycblt.musikr.tag.interpret.PreSong internal interface SongCore { - val trackedSong: TrackedSong + val preSong: PreSong fun resolveAlbum(): Album @@ -40,7 +40,7 @@ internal interface SongCore { * @author Alexander Capehart (OxygenCobalt) */ internal class SongImpl(private val handle: SongCore) : Song { - private val preSong = handle.trackedSong.preSong + private val preSong = handle.preSong override val uid = preSong.uid override val name = preSong.name @@ -56,7 +56,7 @@ internal class SongImpl(private val handle: SongCore) : Song { override val sampleRateHz = preSong.sampleRateHz override val replayGainAdjustment = preSong.replayGainAdjustment override val lastModified = preSong.lastModified - override val dateAdded = handle.trackedSong.dateAdded + override val dateAdded = preSong.dateAdded override val cover = preSong.cover override val album: Album get() = handle.resolveAlbum() diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt index 65b94b4e4..2ccc992be 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt @@ -19,12 +19,10 @@ package org.oxycblt.musikr.pipeline import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.buffer import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.flattenMerge import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge @@ -37,7 +35,6 @@ import org.oxycblt.musikr.model.LibraryFactory import org.oxycblt.musikr.playlist.db.StoredPlaylists import org.oxycblt.musikr.playlist.interpret.PlaylistInterpreter import org.oxycblt.musikr.tag.interpret.TagInterpreter -import org.oxycblt.musikr.track.Tracker internal interface EvaluateStep { suspend fun evaluate(extractedMusic: Flow): MutableLibrary @@ -46,17 +43,14 @@ internal interface EvaluateStep { fun new(storage: Storage, interpretation: Interpretation): EvaluateStep = EvaluateStepImpl( TagInterpreter.new(interpretation), - storage.tracker, PlaylistInterpreter.new(interpretation), storage.storedPlaylists, LibraryFactory.new()) } } -@OptIn(ExperimentalCoroutinesApi::class) private class EvaluateStepImpl( private val tagInterpreter: TagInterpreter, - private val tracker: Tracker, private val playlistInterpreter: PlaylistInterpreter, private val storedPlaylists: StoredPlaylists, private val libraryFactory: LibraryFactory @@ -75,13 +69,6 @@ private class EvaluateStepImpl( .map { wrap(it, tagInterpreter::interpret) } .flowOn(Dispatchers.Default) .buffer(Channel.UNLIMITED) - val trackDistributedFlow = preSongs.distribute(8) - val trackedSongs = - merge( - trackDistributedFlow.manager, - trackDistributedFlow.flows - .map { flow -> flow.map { wrap(it, tracker::track) } } - .flattenMerge()) val prePlaylists = filterFlow.left .map { wrap(it, playlistInterpreter::interpret) } @@ -91,7 +78,7 @@ private class EvaluateStepImpl( val graphBuild = merge( filterFlow.manager, - trackedSongs.onEach { wrap(it, graphBuilder::add) }, + preSongs.onEach { wrap(it, graphBuilder::add) }, prePlaylists.onEach { wrap(it, graphBuilder::add) }) graphBuild.collect() val graph = graphBuilder.build() diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/PipelineException.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/PipelineException.kt index 8a2525fc8..1f6efc892 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/PipelineException.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/PipelineException.kt @@ -22,7 +22,6 @@ import org.oxycblt.musikr.fs.DeviceFile import org.oxycblt.musikr.playlist.PlaylistFile import org.oxycblt.musikr.playlist.interpret.PrePlaylist import org.oxycblt.musikr.tag.interpret.PreSong -import org.oxycblt.musikr.track.TrackedSong class PipelineException(val processing: WhileProcessing, val error: Exception) : Exception() { override val cause = error @@ -47,11 +46,6 @@ sealed interface WhileProcessing { override fun toString() = "Pre Song @ ${preSong.path}" } - class ATrackedSong internal constructor(private val trackedSong: TrackedSong) : - WhileProcessing { - override fun toString() = "Tracked Song @ ${trackedSong.preSong.path}" - } - class APrePlaylist internal constructor(private val prePlaylist: PrePlaylist) : WhileProcessing { override fun toString() = "Pre Playlist @ ${prePlaylist.name}" @@ -86,13 +80,6 @@ internal suspend fun wrap(song: PreSong, block: suspend (PreSong) -> R): R = throw PipelineException(WhileProcessing.APreSong(song), e) } -internal suspend fun wrap(song: TrackedSong, block: suspend (TrackedSong) -> R): R = - try { - block(song) - } catch (e: Exception) { - throw PipelineException(WhileProcessing.ATrackedSong(song), e) - } - internal suspend fun wrap(playlist: PrePlaylist, block: suspend (PrePlaylist) -> R): R = try { block(playlist) diff --git a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/PreMusic.kt b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/PreMusic.kt index ae109e556..ba6c28da4 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/PreMusic.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/PreMusic.kt @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package org.oxycblt.musikr.tag.interpret import android.net.Uri @@ -47,27 +47,27 @@ internal data class PreSong( val sampleRateHz: Int, val replayGainAdjustment: ReplayGainAdjustment, val lastModified: Long, + val dateAdded: Long, val cover: Cover?, val preAlbum: PreAlbum, val preArtists: List, val preGenres: List ) { - val uid = - musicBrainzId?.let { Music.UID.musicBrainz(Music.UID.Item.SONG, it) } - ?: Music.UID.auxio(Music.UID.Item.SONG) { - // Song UIDs are based on the raw data without parsing so that they remain - // consistent across music setting changes. Parents are not held up to the - // same standard since grouping is already inherently linked to settings. - update(rawName) - update(preAlbum.rawName) - update(date) + val uid = musicBrainzId?.let { Music.UID.musicBrainz(Music.UID.Item.SONG, it) } + ?: Music.UID.auxio(Music.UID.Item.SONG) { + // Song UIDs are based on the raw data without parsing so that they remain + // consistent across music setting changes. Parents are not held up to the + // same standard since grouping is already inherently linked to settings. + update(rawName) + update(preAlbum.rawName) + update(date) - update(track) - update(disc?.number) + update(track) + update(disc?.number) - update(preArtists.map { artist -> artist.rawName }) - update(preAlbum.preArtists.map { artist -> artist.rawName }) - } + update(preArtists.map { artist -> artist.rawName }) + update(preAlbum.preArtists.map { artist -> artist.rawName }) + } } internal data class PreAlbum( diff --git a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/TagInterpreter.kt b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/TagInterpreter.kt index b9b4b297b..b6f07df30 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/TagInterpreter.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/TagInterpreter.kt @@ -65,6 +65,8 @@ private class TagInterpreterImpl(private val interpretation: Interpretation) : T size = song.file.size, format = Format.infer(song.file.mimeType, song.properties.mimeType), lastModified = song.file.lastModified, + // TODO: Figure out what to do with date added + dateAdded = song.file.lastModified, musicBrainzId = song.tags.musicBrainzId?.toUuidOrNull(), name = interpretation.naming.name(song.tags.name, song.tags.sortName), rawName = song.tags.name, diff --git a/musikr/src/main/java/org/oxycblt/musikr/track/Tracker.kt b/musikr/src/main/java/org/oxycblt/musikr/track/Tracker.kt deleted file mode 100644 index acf5e0aad..000000000 --- a/musikr/src/main/java/org/oxycblt/musikr/track/Tracker.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2024 Auxio Project - * Tracker.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 . - */ - -package org.oxycblt.musikr.track - -import android.content.Context -import org.oxycblt.musikr.tag.interpret.PreSong - -abstract class Tracker { - internal abstract suspend fun track(preSong: PreSong): TrackedSong - - companion object { - fun from(context: Context): Tracker = - TrackerImpl(TrackerDatabase.from(context).trackedSongsDao()) - } -} - -internal data class TrackedSong(val preSong: PreSong, val dateAdded: Long) - -private class TrackerImpl(private val dao: TrackedSongsDao) : Tracker() { - override suspend fun track(preSong: PreSong): TrackedSong { - val currentTime = System.currentTimeMillis() - val entity = TrackedSongEntity(uid = preSong.uid.toString(), dateAdded = currentTime) - dao.insertSong(entity) - val trackedEntity = dao.selectSong(preSong.uid.toString()) - return TrackedSong(preSong = preSong, dateAdded = trackedEntity?.dateAdded ?: currentTime) - } -} diff --git a/musikr/src/main/java/org/oxycblt/musikr/track/TrackerDatabase.kt b/musikr/src/main/java/org/oxycblt/musikr/track/TrackerDatabase.kt deleted file mode 100644 index e30676141..000000000 --- a/musikr/src/main/java/org/oxycblt/musikr/track/TrackerDatabase.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2024 Auxio Project - * TrackerDatabase.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 . - */ - -package org.oxycblt.musikr.track - -import android.content.Context -import androidx.room.Dao -import androidx.room.Database -import androidx.room.Entity -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.PrimaryKey -import androidx.room.Query -import androidx.room.Room -import androidx.room.RoomDatabase - -@Database(entities = [TrackedSongEntity::class], version = 1, exportSchema = false) -internal abstract class TrackerDatabase : RoomDatabase() { - abstract fun trackedSongsDao(): TrackedSongsDao - - companion object { - fun from(context: Context) = - Room.databaseBuilder( - context.applicationContext, TrackerDatabase::class.java, "tracked_songs.db") - .fallbackToDestructiveMigration() - .build() - } -} - -@Entity internal data class TrackedSongEntity(@PrimaryKey val uid: String, val dateAdded: Long) - -@Dao -internal interface TrackedSongsDao { - @Query("SELECT * FROM TrackedSongEntity WHERE uid = :uid") - suspend fun selectSong(uid: String): TrackedSongEntity? - - @Insert(onConflict = OnConflictStrategy.IGNORE) - suspend fun insertSong(trackedSong: TrackedSongEntity) -}