This commit is contained in:
parent
a4b6f7bc40
commit
1b7090084f
@ -235,6 +235,15 @@ func Run(c *commands.Commander, s fx.Shutdowner) {
|
|||||||
},
|
},
|
||||||
Category: "Radio",
|
Category: "Radio",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "refillradio",
|
||||||
|
Usage: "Refills the radio queue with similar songs",
|
||||||
|
Aliases: []string{"rr"},
|
||||||
|
Action: func(cCtx *cli.Context) error {
|
||||||
|
return c.RefillRadio()
|
||||||
|
},
|
||||||
|
Category: "Radio",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "status",
|
Name: "status",
|
||||||
Usage: "Prints the current status",
|
Usage: "Prints the current status",
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
@ -211,3 +212,159 @@ func (c *Commander) SongExists(db *sql.DB, song spotify.ID) (bool, error) {
|
|||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commander) RefillRadio() error {
|
||||||
|
status, err := c.Client.PlayerCurrentlyPlaying(c.Context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !status.Playing {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
to_remove := []spotify.ID{}
|
||||||
|
radioPlaylist, db, err := c.GetRadioPlaylist("")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if status.PlaybackContext.URI != radioPlaylist.URI {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
playlistItems, err := c.Client.GetPlaylistItems(c.Context, radioPlaylist.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("orig playlist items: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
page := 0
|
||||||
|
for {
|
||||||
|
tracks, err := c.Client.GetPlaylistItems(c.Context, radioPlaylist.ID, spotify.Limit(50), spotify.Offset(page*50))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tracks: %w", err)
|
||||||
|
}
|
||||||
|
if len(tracks.Items) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for _, track := range tracks.Items {
|
||||||
|
if track.Track.Track.ID == status.Item.ID {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
to_remove = append(to_remove, track.Track.Track.ID)
|
||||||
|
}
|
||||||
|
page++
|
||||||
|
}
|
||||||
|
if len(to_remove) > 0 {
|
||||||
|
var trackGroups []spotify.ID
|
||||||
|
for idx, item := range to_remove {
|
||||||
|
if idx%100 == 0 {
|
||||||
|
_, err = c.Client.RemoveTracksFromPlaylist(c.Context, radioPlaylist.ID, trackGroups...)
|
||||||
|
trackGroups = []spotify.ID{}
|
||||||
|
}
|
||||||
|
trackGroups = append(trackGroups, item)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error clearing playlist: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := c.Client.RemoveTracksFromPlaylist(c.Context, radioPlaylist.ID, trackGroups...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
to_add := 500 - (playlistItems.Total - len(to_remove))
|
||||||
|
playlistItems, err = c.Client.GetPlaylistItems(c.Context, radioPlaylist.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("playlist items: %w", err)
|
||||||
|
}
|
||||||
|
total := playlistItems.Total
|
||||||
|
pages := int(math.Ceil(float64(total) / 50))
|
||||||
|
randomPage := 1
|
||||||
|
if pages > 1 {
|
||||||
|
randomPage = frand.Intn(pages-1) + 1
|
||||||
|
}
|
||||||
|
playlistPage, err := c.Client.
|
||||||
|
GetPlaylistItems(c.Context, radioPlaylist.ID, spotify.Limit(50), spotify.Offset((randomPage-1)*50))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("playlist page: %w", err)
|
||||||
|
}
|
||||||
|
pageSongs := playlistPage.Items
|
||||||
|
frand.Shuffle(len(pageSongs), func(i, j int) { pageSongs[i], pageSongs[j] = pageSongs[j], pageSongs[i] })
|
||||||
|
seedCount := 5
|
||||||
|
if len(pageSongs) < seedCount {
|
||||||
|
seedCount = len(pageSongs)
|
||||||
|
}
|
||||||
|
seedIds := []spotify.ID{}
|
||||||
|
for idx, song := range pageSongs {
|
||||||
|
if idx >= seedCount {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
seedIds = append(seedIds, song.Track.Track.ID)
|
||||||
|
}
|
||||||
|
seed := spotify.Seeds{
|
||||||
|
Tracks: seedIds,
|
||||||
|
}
|
||||||
|
recomendations, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(95))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
recomendationIds := []spotify.ID{}
|
||||||
|
for _, song := range recomendations.Tracks {
|
||||||
|
exists, err := c.SongExists(db, song.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("err check song existnce: %w", err)
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
recomendationIds = append(recomendationIds, song.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queue := []spotify.ID{}
|
||||||
|
for idx, rec := range recomendationIds {
|
||||||
|
if idx > to_add {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_, err = db.QueryContext(c.Context, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", rec.String()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
queue = append(queue, rec)
|
||||||
|
}
|
||||||
|
to_add -= len(queue)
|
||||||
|
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("add tracks: %w", err)
|
||||||
|
}
|
||||||
|
err = c.Client.Repeat(c.Context, "context")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("repeat: %w", err)
|
||||||
|
}
|
||||||
|
for to_add > 0 {
|
||||||
|
id := frand.Intn(len(recomendationIds)-2) + 1
|
||||||
|
seed := spotify.Seeds{
|
||||||
|
Tracks: []spotify.ID{recomendationIds[id]},
|
||||||
|
}
|
||||||
|
additional_recs, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get recs: %w", err)
|
||||||
|
}
|
||||||
|
additionalRecsIds := []spotify.ID{}
|
||||||
|
for idx, song := range additional_recs.Tracks {
|
||||||
|
exists, err := c.SongExists(db, song.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("check song existence: %w", err)
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
if idx > to_add {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
additionalRecsIds = append(additionalRecsIds, song.ID)
|
||||||
|
queue = append(queue, song.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
to_add -= len(queue)
|
||||||
|
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("add tracks to playlist: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user