From db391da4b8c34715acaee0ce520f438b682cacc8 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Mon, 25 Nov 2024 16:34:02 -0700 Subject: [PATCH] music: implement genre linking --- .../stack/interpret/linker/Contribution.kt | 18 +++++++ .../stack/interpret/linker/GenreLinker.kt | 50 +++++++++++++++++-- .../music/stack/interpret/prepare/PreMusic.kt | 2 +- 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/org/oxycblt/auxio/music/stack/interpret/linker/Contribution.kt diff --git a/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/linker/Contribution.kt b/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/linker/Contribution.kt new file mode 100644 index 000000000..badef6647 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/linker/Contribution.kt @@ -0,0 +1,18 @@ +package org.oxycblt.auxio.music.stack.interpret.linker + +class Contribution { + private val map = mutableMapOf() + + val candidates: Collection get() = map.keys + + fun contribute(key: T) { + map[key] = map.getOrDefault(key, 0) + 1 + } + + fun contribute(keys: Collection) { + keys.forEach { contribute(it) } + } + + fun resolve() = map.maxByOrNull { it.value }?.key ?: error("Nothing was contributed") + +} \ No newline at end of file diff --git a/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/linker/GenreLinker.kt b/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/linker/GenreLinker.kt index 1b9e5e0cb..7c9cfaf64 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/linker/GenreLinker.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/linker/GenreLinker.kt @@ -2,16 +2,60 @@ package org.oxycblt.auxio.music.stack.interpret.linker import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.transform import org.oxycblt.auxio.music.stack.interpret.model.GenreImpl import org.oxycblt.auxio.music.stack.interpret.model.SongImpl +import org.oxycblt.auxio.music.stack.interpret.prepare.PreGenre import org.oxycblt.auxio.music.stack.interpret.prepare.PreSong -class GenreLinker { - fun register(preSong: Flow): Flow = emptyFlow() - fun resolve(): Collection = setOf() +class GenreTree { + private val tree = mutableMapOf() + + fun register(preSong: Flow): Flow = preSong.map { + val genreLinks = it.preGenres.map { genre -> + val nameKey = genre.rawName?.lowercase() + val link = tree.getOrPut(nameKey) { GenreLink(GenreNode(Contribution())) } + link.node.contributors.contribute(genre) + link + } + LinkedSong(it, MultiGenreLink(genreLinks)) + } + + fun resolve() = + tree.values.map { it.node.resolve() } data class LinkedSong( val preSong: PreSong, val genres: Linked, SongImpl> ) + + private class MultiGenreLink( + val links: List> + ) : Linked, SongImpl> { + override fun resolve(child: SongImpl): List { + return links.map { it.resolve(child) }.distinct() + } + } + + private data class GenreLink( + var node: GenreNode + ) : Linked { + override fun resolve(child: SongImpl): GenreImpl { + return requireNotNull(node.genreImpl) { "Link" } + } + } + + private class GenreNode( + val contributors: Contribution + ) { + var genreImpl: GenreImpl? = null + private set + + fun resolve(): GenreImpl { + val impl = GenreImpl(contributors.resolve()) + genreImpl = impl + return impl + } + } } diff --git a/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/prepare/PreMusic.kt b/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/prepare/PreMusic.kt index a405ff2ef..ffa5c5ff9 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/prepare/PreMusic.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/stack/interpret/prepare/PreMusic.kt @@ -16,7 +16,7 @@ import java.util.UUID data class PreSong( val musicBrainzId: UUID?, val name: Name, - val rawName: String?, + val rawName: String, val track: Int?, val disc: Disc?, val date: Date?,