Skip to content

Commit 21fa5de

Browse files
committed
Implement queue ordering by song request weight
1 parent 2728344 commit 21fa5de

23 files changed

+328
-210
lines changed

database/migration.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"gorm.io/gorm"
99
)
1010

11-
const targetDatabaseVersion = 35
11+
const targetDatabaseVersion = 41
1212

1313
func migrateIfNecessary(db *gorm.DB) {
1414
logger.Info("Connection acquired. Checking database version")

database/model/songRequest.go

+7-14
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,11 @@ package model
22

33
type SongRequest struct {
44
BaseModel
5-
SessionId uint `json:"session_id"`
6-
UserId *uint `json:"user_id"`
7-
SpotifyTrackId string `json:"spotify_track_id"`
8-
TrackMetadata TrackMetadata `gorm:"foreignKey:spotify_track_id;references:spotify_track_id" json:"track_metadata"`
9-
Status SongRequestStatus `json:"status"`
5+
SessionId uint `json:"session_id"`
6+
SpotifyTrackId string `json:"spotify_track_id"`
7+
TrackMetadata TrackMetadata `gorm:"foreignKey:spotify_track_id;references:spotify_track_id" json:"track_metadata"`
8+
Played bool `json:"-"`
9+
Locked bool `json:"-"`
10+
RequestedBy string `json:"requested_by"`
11+
Weight int64 `json:"-"`
1012
}
11-
12-
type SongRequestStatus string
13-
14-
const (
15-
StatusPlayed SongRequestStatus = "PLAYED"
16-
StatusCurrentlyPlaying SongRequestStatus = "CURRENTLY_PLAYING"
17-
StatusUpNext SongRequestStatus = "UP_NEXT"
18-
StatusInQueue SongRequestStatus = "IN_QUEUE"
19-
)

listeningSession/fallbackPlaylist.go

+45-21
Original file line numberDiff line numberDiff line change
@@ -58,38 +58,41 @@ func SetFallbackPlaylistShuffle(session model.SimpleListeningSession, user model
5858
return nil
5959
}
6060

61-
func addFallbackTrackIfNecessary(session model.FullListeningSession, upNextRequest *model.SongRequest) (trackAdded bool, error *SpotifeteError) {
61+
func addFallbackTrackIfNecessary(session model.FullListeningSession, queue []model.SongRequest) (updatedQueue []model.SongRequest, error *SpotifeteError) {
62+
6263
if session.FallbackPlaylistId == nil {
63-
return false, nil
64+
return queue, nil
6465
}
6566

66-
if upNextRequest != nil {
67-
return false, nil
68-
}
67+
for i := len(queue); i < 2; i++ {
68+
addedRequest, spotifeteError := addFallbackTrack(session)
69+
if spotifeteError != nil {
70+
return queue, spotifeteError
71+
}
6972

70-
spotifeteError := addFallbackTrack(session)
71-
if spotifeteError != nil {
72-
return false, spotifeteError
73+
queue = append(queue, addedRequest)
7374
}
7475

75-
return true, nil
76+
return queue, nil
7677
}
7778

78-
func addFallbackTrack(session model.FullListeningSession) (error *SpotifeteError) {
79+
func addFallbackTrack(session model.FullListeningSession) (addedRequest model.SongRequest, error *SpotifeteError) {
80+
7981
fallbackTrackId, spotifeteError := findNextFallbackTrack(session)
8082
if spotifeteError != nil {
81-
return spotifeteError
83+
return model.SongRequest{}, spotifeteError
8284
}
8385

84-
_, spotifeteError = RequestSong(session, fallbackTrackId)
86+
addedRequest, spotifeteError = RequestSong(session, fallbackTrackId, "Fallback-Playlist")
8587
if spotifeteError != nil {
86-
return spotifeteError
88+
return model.SongRequest{}, spotifeteError
8789
}
8890

89-
return nil
91+
return addedRequest, nil
9092
}
9193

9294
func findNextFallbackTrack(session model.FullListeningSession) (nextFallbackTrackId string, spotifeteError *SpotifeteError) {
95+
9396
playableTracks, spotifeteError := getPlayablePlaylistTracks(*session.FallbackPlaylistId, session.Owner)
9497
if spotifeteError != nil {
9598
return "", spotifeteError
@@ -109,10 +112,17 @@ func findNextFallbackTrack(session model.FullListeningSession) (nextFallbackTrac
109112
}
110113

111114
func doFindNextFallbackTrack(playableTracks *[]spotify.FullTrack, session model.FullListeningSession) (nextFallbackTrackId string, spotifeteError *SpotifeteError) {
112-
currentlyPlayingRequest := GetCurrentlyPlayingRequest(session.SimpleListeningSession)
115+
116+
queue, err := GetFullQueue(session.SimpleListeningSession)
117+
if err != nil {
118+
return "", nil
119+
}
113120

114121
for i := 0; i < 10_000; i++ {
115-
fallbackTrack := findPossibleFallbackTrackFromPlayableTracks(*playableTracks, session.SimpleListeningSession, currentlyPlayingRequest, 0)
122+
fallbackTrack, err := findPossibleFallbackTrackFromPlayableTracks(*playableTracks, session.SimpleListeningSession, queue, 0)
123+
if err != nil {
124+
return "", NewInternalError("could not find possible fallback tracks", err)
125+
}
116126
if fallbackTrack != nil {
117127
return *fallbackTrack, nil
118128
}
@@ -124,7 +134,7 @@ func doFindNextFallbackTrack(playableTracks *[]spotify.FullTrack, session model.
124134
return "", NewInternalError(fmt.Sprintf("No track found in fallback playlist for session %d that has been played less than 10,000 times. Aborting and removing fallback playlist.", session.ID), nil)
125135
}
126136

127-
func findPossibleFallbackTrackFromPlayableTracks(playableTracks []spotify.FullTrack, session model.SimpleListeningSession, currentlyPlayingRequest *model.SongRequest, maximumPlays int64) (possibleFallbackTrackId *string) {
137+
func findPossibleFallbackTrackFromPlayableTracks(playableTracks []spotify.FullTrack, session model.SimpleListeningSession, queue []model.SongRequest, maximumPlays int64) (possibleFallbackTrackId *string, err error) {
128138
if session.FallbackPlaylistShuffle {
129139
rand.Seed(time.Now().UnixNano())
130140
rand.Shuffle(
@@ -136,14 +146,28 @@ func findPossibleFallbackTrackFromPlayableTracks(playableTracks []spotify.FullTr
136146

137147
for _, track := range playableTracks {
138148
trackId := track.ID.String()
139-
if currentlyPlayingRequest == nil || currentlyPlayingRequest.SpotifyTrackId != trackId {
140-
playCount := getTrackPlayCount(session, trackId)
149+
if !queueContainsTrack(queue, trackId) {
150+
playCount, err := getTrackPlayCount(session, trackId)
151+
if err != nil {
152+
return nil, err
153+
}
141154

142155
if playCount <= maximumPlays {
143-
return &trackId
156+
return &trackId, nil
144157
}
145158
}
146159
}
147160

148-
return nil
161+
return nil, nil
162+
}
163+
164+
func queueContainsTrack(queue []model.SongRequest, trackId string) bool {
165+
166+
for _, trackInQueue := range queue {
167+
if trackInQueue.SpotifyTrackId == trackId {
168+
return true
169+
}
170+
}
171+
172+
return false
149173
}

0 commit comments

Comments
 (0)