add multi-artist support for comma separated artists

This commit is contained in:
2026-03-01 17:18:19 -08:00
parent d73ae51b95
commit 369aae818c
14 changed files with 281 additions and 40 deletions

View File

@@ -1,6 +1,7 @@
package web
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
@@ -35,6 +36,7 @@ type SongData struct {
Username string
Song db.Song
Artist db.Artist
ArtistNames []string
Albums []db.Album
ListenCount int
Times []db.ScrobbleEntry
@@ -48,6 +50,7 @@ type AlbumData struct {
Username string
Album db.Album
Artist db.Artist
ArtistNames []string
ListenCount int
Times []db.ScrobbleEntry
Page int
@@ -169,8 +172,14 @@ func songPageHandler() http.HandlerFunc {
var songIds []int
var albums []db.Album
seenAlbums := make(map[int]bool)
seenArtistIds := make(map[int]bool)
var allArtistIds []int
for _, s := range songs {
songIds = append(songIds, s.Id)
if s.ArtistId > 0 && !seenArtistIds[s.ArtistId] {
seenArtistIds[s.ArtistId] = true
allArtistIds = append(allArtistIds, s.ArtistId)
}
if s.AlbumId > 0 && !seenAlbums[s.AlbumId] {
seenAlbums[s.AlbumId] = true
album, _ := db.GetAlbumById(s.AlbumId)
@@ -178,6 +187,29 @@ func songPageHandler() http.HandlerFunc {
}
}
var artistNames []string
seenArtistIdsMap := make(map[int]bool)
rows, err := db.Pool.Query(context.Background(),
`SELECT DISTINCT artist_ids FROM history WHERE song_id = ANY($1)`,
songIds)
if err == nil {
defer rows.Close()
for rows.Next() {
var artistIds []int
if err := rows.Scan(&artistIds); err == nil {
for _, id := range artistIds {
if !seenArtistIdsMap[id] {
seenArtistIdsMap[id] = true
a, err := db.GetArtistById(id)
if err == nil {
artistNames = append(artistNames, a.Name)
}
}
}
}
}
}
pageStr := r.URL.Query().Get("page")
var pageInt int
if pageStr == "" {
@@ -208,6 +240,7 @@ func songPageHandler() http.HandlerFunc {
Username: username,
Song: song,
Artist: artist,
ArtistNames: artistNames,
Albums: albums,
ListenCount: listenCount,
Times: entries,
@@ -375,10 +408,25 @@ func albumPageHandler() http.HandlerFunc {
return
}
var artistNames []string
seenArtistIds := make(map[int]bool)
for _, e := range entries {
for _, artistId := range e.ArtistIds {
if !seenArtistIds[artistId] {
seenArtistIds[artistId] = true
a, err := db.GetArtistById(artistId)
if err == nil {
artistNames = append(artistNames, a.Name)
}
}
}
}
albumData := AlbumData{
Username: username,
Album: album,
Artist: artist,
ArtistNames: artistNames,
ListenCount: listenCount,
Times: entries,
Page: pageInt,

View File

@@ -25,6 +25,7 @@ type ProfileData struct {
TrackCount int
ArtistCount int
Artists []string
ArtistIdsList [][]int
Titles []string
Times []time.Time
Page int
@@ -93,7 +94,7 @@ func profilePageHandler() http.HandlerFunc {
rows, err := db.Pool.Query(
r.Context(),
"SELECT artist, song_name, timestamp FROM history WHERE user_id = $1 ORDER BY timestamp DESC LIMIT $2 OFFSET $3;",
"SELECT artist_id, song_name, timestamp, artist_ids FROM history WHERE user_id = $1 ORDER BY timestamp DESC LIMIT $2 OFFSET $3;",
userId,
lim,
off,
@@ -106,15 +107,27 @@ func profilePageHandler() http.HandlerFunc {
defer rows.Close()
for rows.Next() {
var artist, title string
var artistId int
var title string
var time pgtype.Timestamptz
err = rows.Scan(&artist, &title, &time)
var artistIds []int
err = rows.Scan(&artistId, &title, &time, &artistIds)
if err != nil {
fmt.Fprintf(os.Stderr, "Scanning history row failed: %v\n", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
profileData.Artists = append(profileData.Artists, artist)
var artistName string
if artistId > 0 {
artist, err := db.GetArtistById(artistId)
if err == nil {
artistName = artist.Name
}
}
profileData.Artists = append(profileData.Artists, artistName)
profileData.ArtistIdsList = append(profileData.ArtistIdsList, artistIds)
profileData.Titles = append(profileData.Titles, title)
profileData.Times = append(profileData.Times, time.Time)
}

View File

@@ -5,6 +5,8 @@ package web
import (
"fmt"
"time"
"muzi/db"
)
// Subtracts two integers
@@ -56,3 +58,18 @@ func formatTimestamp(timestamp time.Time) string {
func formatTimestampFull(timestamp time.Time) string {
return timestamp.Format("Monday 2 Jan 2006, 3:04pm")
}
// GetArtistNames takes artist IDs and returns a slice of artist names
func GetArtistNames(artistIds []int) []string {
if artistIds == nil {
return nil
}
var names []string
for _, id := range artistIds {
artist, err := db.GetArtistById(id)
if err == nil {
names = append(names, artist.Name)
}
}
return names
}

View File

@@ -37,6 +37,7 @@ func init() {
"formatTimestamp": formatTimestamp,
"formatTimestampFull": formatTimestampFull,
"urlquery": url.QueryEscape,
"getArtistNames": GetArtistNames,
}
templates = template.Must(template.New("").Funcs(funcMap).ParseGlob("./templates/*.gohtml"))
}