641 lines
17 KiB
Go
Raw Normal View History

2024-02-18 09:58:47 -08:00
package commands
import (
"database/sql"
"encoding/json"
"errors"
"fmt"
2024-02-18 12:17:07 -08:00
"math"
2024-07-06 14:05:01 -07:00
"math/rand"
2024-02-18 09:58:47 -08:00
"os"
"path/filepath"
"time"
"github.com/zmb3/spotify/v2"
_ "modernc.org/sqlite"
)
func (c *Commander) Radio() error {
2024-02-19 17:58:05 -08:00
currentSong, err := c.Client().PlayerCurrentlyPlaying(c.Context)
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
2024-02-19 17:58:05 -08:00
if currentSong.Item != nil {
return c.RadioGivenSong(currentSong.Item.SimpleTrack, currentSong.Progress)
2024-02-18 09:58:47 -08:00
}
2024-02-18 15:04:34 -08:00
_, err = c.activateDevice()
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
2024-02-18 23:33:32 -08:00
tracks, err := c.Client().CurrentUsersTracks(c.Context, spotify.Limit(10))
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
2024-07-06 14:05:01 -07:00
return c.RadioGivenSong(tracks.Tracks[rand.Intn(len(tracks.Tracks))].SimpleTrack, 0)
2024-02-18 09:58:47 -08:00
}
2024-02-18 15:04:34 -08:00
func (c *Commander) RadioFromPlaylist(playlist spotify.SimplePlaylist) error {
total := playlist.Tracks.Total
if total == 0 {
return fmt.Errorf("this playlist is empty")
}
pages := int(math.Ceil(float64(total) / 50))
randomPage := 1
if pages > 1 {
2024-07-06 14:05:01 -07:00
randomPage = rand.Intn(pages-1) + 1
2024-02-18 15:04:34 -08:00
}
2024-02-18 23:33:32 -08:00
playlistPage, err := c.Client().GetPlaylistItems(
2024-02-18 18:51:25 -08:00
c.Context,
playlist.ID,
spotify.Limit(50),
spotify.Offset((randomPage-1)*50),
)
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
pageSongs := playlistPage.Items
2024-07-06 14:05:01 -07:00
rand.Shuffle(len(pageSongs), func(i, j int) { pageSongs[i], pageSongs[j] = pageSongs[j], pageSongs[i] })
2024-02-18 15:04:34 -08:00
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)
}
return c.RadioGivenList(seedIds[:seedCount], playlist.Name)
}
func (c *Commander) RadioFromSavedTracks() error {
2024-02-18 23:33:32 -08:00
savedSongs, err := c.Client().CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(0))
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
if savedSongs.Total == 0 {
return fmt.Errorf("you have no saved songs")
}
pages := int(math.Ceil(float64(savedSongs.Total) / 50))
randomPage := 1
if pages > 1 {
2024-07-06 14:05:01 -07:00
randomPage = rand.Intn(pages-1) + 1
2024-02-18 15:04:34 -08:00
}
2024-02-18 23:33:32 -08:00
trackPage, err := c.Client().CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(randomPage*50))
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
pageSongs := trackPage.Tracks
2024-07-06 14:05:01 -07:00
rand.Shuffle(len(pageSongs), func(i, j int) { pageSongs[i], pageSongs[j] = pageSongs[j], pageSongs[i] })
2024-02-18 15:04:34 -08:00
seedCount := 4
seedIds := []spotify.ID{}
for idx, song := range pageSongs {
if idx >= seedCount {
break
}
seedIds = append(seedIds, song.ID)
}
seedIds = append(seedIds, savedSongs.Tracks[0].ID)
return c.RadioGivenList(seedIds, "Saved Tracks")
}
func (c *Commander) RadioGivenArtist(artist spotify.SimpleArtist) error {
seed := spotify.Seeds{
Artists: []spotify.ID{artist.ID},
}
2024-02-18 23:33:32 -08:00
recomendations, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
recomendationIds := []spotify.ID{}
for _, song := range recomendations.Tracks {
recomendationIds = append(recomendationIds, song.ID)
}
err = c.ClearRadio()
if err != nil {
return err
}
radioPlaylist, db, err := c.GetRadioPlaylist(artist.Name)
if err != nil {
return err
}
queue := []spotify.ID{}
for _, rec := range recomendationIds {
exists, err := c.SongExists(db, rec)
if err != nil {
return err
}
if !exists {
_, err := db.QueryContext(c.Context, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", string(rec)))
if err != nil {
return err
}
queue = append(queue, rec)
}
}
2024-02-18 23:33:32 -08:00
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
2024-02-18 23:33:32 -08:00
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
2024-02-18 15:04:34 -08:00
PlaybackContext: &radioPlaylist.URI,
})
if err != nil {
return err
}
2024-02-18 23:33:32 -08:00
err = c.Client().Repeat(c.Context, "context")
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
for i := 0; i < 4; i++ {
2024-07-06 14:05:01 -07:00
id := rand.Intn(len(recomendationIds)-2) + 1
2024-02-18 15:04:34 -08:00
seed := spotify.Seeds{
Tracks: []spotify.ID{recomendationIds[id]},
}
2024-02-19 17:58:05 -08:00
additionalRecs, err := c.Client().
GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
additionalRecsIds := []spotify.ID{}
2024-02-19 17:58:05 -08:00
for _, song := range additionalRecs.Tracks {
2024-02-18 15:04:34 -08:00
exists, err := c.SongExists(db, song.ID)
if err != nil {
return err
}
if !exists {
_, err = db.QueryContext(c.Context, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", string(song.ID)))
if err != nil {
return err
}
additionalRecsIds = append(additionalRecsIds, song.ID)
}
}
2024-02-18 23:33:32 -08:00
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
}
return nil
}
2024-05-30 15:19:52 -07:00
func (c *Commander) RadioGivenSong(song spotify.SimpleTrack, pos spotify.Numeric) error {
2024-02-18 09:58:47 -08:00
start := time.Now().UnixMilli()
seed := spotify.Seeds{
Tracks: []spotify.ID{song.ID},
}
2024-02-18 23:33:32 -08:00
recomendations, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(99))
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
recomendationIds := []spotify.ID{}
for _, song := range recomendations.Tracks {
recomendationIds = append(recomendationIds, song.ID)
}
err = c.ClearRadio()
if err != nil {
return err
}
radioPlaylist, db, err := c.GetRadioPlaylist(song.Name)
if err != nil {
return err
}
_, err = db.QueryContext(c.Context, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", string(song.ID)))
if err != nil {
return err
}
queue := []spotify.ID{song.ID}
for _, rec := range recomendationIds {
exists, err := c.SongExists(db, rec)
if err != nil {
return err
}
if !exists {
_, err := db.QueryContext(c.Context, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", string(rec)))
if err != nil {
return err
}
queue = append(queue, rec)
}
}
2024-02-18 23:33:32 -08:00
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
delay := time.Now().UnixMilli() - start
if pos != 0 {
2024-05-30 15:19:52 -07:00
pos = pos + spotify.Numeric(delay)
2024-02-18 09:58:47 -08:00
}
2024-02-18 23:33:32 -08:00
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
2024-02-18 09:58:47 -08:00
PlaybackContext: &radioPlaylist.URI,
PositionMs: pos,
})
if err != nil {
if isNoActiveError(err) {
2024-02-18 15:04:34 -08:00
deviceID, err := c.activateDevice()
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
2024-02-18 23:33:32 -08:00
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
2024-02-18 09:58:47 -08:00
PlaybackContext: &radioPlaylist.URI,
DeviceID: &deviceID,
PositionMs: pos,
})
if err != nil {
return err
}
}
}
2024-02-18 23:33:32 -08:00
err = c.Client().Repeat(c.Context, "context")
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
for i := 0; i < 4; i++ {
2024-07-06 14:05:01 -07:00
id := rand.Intn(len(recomendationIds)-2) + 1
2024-02-18 09:58:47 -08:00
seed := spotify.Seeds{
Tracks: []spotify.ID{recomendationIds[id]},
}
2024-02-19 17:58:05 -08:00
additionalRecs, err := c.Client().
GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
additionalRecsIds := []spotify.ID{}
2024-02-19 17:58:05 -08:00
for _, song := range additionalRecs.Tracks {
2024-02-18 09:58:47 -08:00
exists, err := c.SongExists(db, song.ID)
if err != nil {
return err
}
if !exists {
_, err = db.QueryContext(c.Context, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", string(song.ID)))
if err != nil {
return err
}
additionalRecsIds = append(additionalRecsIds, song.ID)
}
}
2024-02-18 23:33:32 -08:00
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
}
return nil
}
func (c *Commander) ClearRadio() error {
radioPlaylist, db, err := c.GetRadioPlaylist("")
if err != nil {
return err
}
2024-02-18 23:33:32 -08:00
err = c.Client().UnfollowPlaylist(c.Context, radioPlaylist.ID)
2024-02-18 09:58:47 -08:00
if err != nil {
return err
}
_, _ = db.Query("DROP TABLE IF EXISTS radio")
configDir, _ := os.UserConfigDir()
2024-02-18 18:51:25 -08:00
os.Remove(filepath.Join(configDir, "gspot/radio.json"))
2024-02-18 23:33:32 -08:00
_ = c.Client().Pause(c.Context)
2024-02-18 09:58:47 -08:00
return nil
}
func (c *Commander) GetRadioPlaylist(name string) (*spotify.FullPlaylist, *sql.DB, error) {
configDir, _ := os.UserConfigDir()
2024-02-18 18:51:25 -08:00
playlistFile, err := os.ReadFile(filepath.Join(configDir, "gspot/radio.json"))
2024-02-18 09:58:47 -08:00
if errors.Is(err, os.ErrNotExist) {
return c.CreateRadioPlaylist(name)
}
if err != nil {
return nil, nil, err
}
var playlist *spotify.FullPlaylist
err = json.Unmarshal(playlistFile, &playlist)
if err != nil {
return nil, nil, err
}
2024-02-18 18:51:25 -08:00
db, err := sql.Open("sqlite", filepath.Join(configDir, "gspot/radio.db"))
2024-02-18 09:58:47 -08:00
if err != nil {
return nil, nil, err
}
return playlist, db, nil
}
func (c *Commander) CreateRadioPlaylist(name string) (*spotify.FullPlaylist, *sql.DB, error) {
// private flag doesnt work
configDir, _ := os.UserConfigDir()
2024-02-18 23:33:32 -08:00
playlist, err := c.Client().
2024-02-18 09:58:47 -08:00
CreatePlaylistForUser(c.Context, c.User.ID, name+" - autoradio", "Automanaged radio playlist", false, false)
if err != nil {
return nil, nil, err
}
raw, err := json.MarshalIndent(playlist, "", " ")
if err != nil {
return nil, nil, err
}
2024-02-18 18:51:25 -08:00
err = os.WriteFile(filepath.Join(configDir, "gspot/radio.json"), raw, 0o600)
2024-02-18 09:58:47 -08:00
if err != nil {
return nil, nil, err
}
2024-02-18 18:51:25 -08:00
db, err := sql.Open("sqlite", filepath.Join(configDir, "gspot/radio.db"))
2024-02-18 09:58:47 -08:00
if err != nil {
return nil, nil, err
}
_, _ = db.QueryContext(c.Context, "DROP TABLE IF EXISTS radio")
_, _ = db.QueryContext(c.Context, "CREATE TABLE IF NOT EXISTS radio (id string PRIMARY KEY)")
return playlist, db, nil
}
func (c *Commander) SongExists(db *sql.DB, song spotify.ID) (bool, error) {
2024-02-19 17:58:05 -08:00
songID := string(song)
2024-02-18 09:58:47 -08:00
sqlStmt := `SELECT id FROM radio WHERE id = ?`
2024-02-19 17:58:05 -08:00
err := db.QueryRow(sqlStmt, songID).Scan(&songID)
2024-02-18 09:58:47 -08:00
if err != nil {
if err != sql.ErrNoRows {
return false, err
}
return false, nil
}
return true, nil
}
2024-02-18 12:17:07 -08:00
func (c *Commander) RefillRadio() error {
2024-02-18 23:33:32 -08:00
status, err := c.Client().PlayerCurrentlyPlaying(c.Context)
2024-02-18 12:17:07 -08:00
if err != nil {
return err
}
2024-08-22 00:17:10 -07:00
paused := false
2024-02-18 12:17:07 -08:00
if !status.Playing {
2024-08-22 00:17:10 -07:00
paused = true
2024-02-18 12:17:07 -08:00
}
2024-02-19 17:58:05 -08:00
toRemove := []spotify.ID{}
2024-02-18 12:17:07 -08:00
radioPlaylist, db, err := c.GetRadioPlaylist("")
if err != nil {
return err
}
2024-02-18 23:33:32 -08:00
playlistItems, err := c.Client().GetPlaylistItems(c.Context, radioPlaylist.ID)
2024-02-18 12:17:07 -08:00
if err != nil {
return fmt.Errorf("orig playlist items: %w", err)
}
2024-08-22 00:17:10 -07:00
if status.PlaybackContext.URI != radioPlaylist.URI || paused {
return c.RadioFromPlaylist(radioPlaylist.SimplePlaylist)
}
2024-02-18 12:17:07 -08:00
page := 0
for {
2024-02-18 23:33:32 -08:00
tracks, err := c.Client().GetPlaylistItems(c.Context, radioPlaylist.ID, spotify.Limit(50), spotify.Offset(page*50))
2024-02-18 12:17:07 -08:00
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
}
2024-02-19 17:58:05 -08:00
toRemove = append(toRemove, track.Track.Track.ID)
2024-02-18 12:17:07 -08:00
}
page++
}
2024-02-19 17:58:05 -08:00
if len(toRemove) > 0 {
2024-02-18 12:17:07 -08:00
var trackGroups []spotify.ID
2024-02-19 17:58:05 -08:00
for idx, item := range toRemove {
2024-02-18 12:17:07 -08:00
if idx%100 == 0 {
2024-02-18 23:33:32 -08:00
_, err = c.Client().RemoveTracksFromPlaylist(c.Context, radioPlaylist.ID, trackGroups...)
2024-02-18 12:17:07 -08:00
trackGroups = []spotify.ID{}
}
trackGroups = append(trackGroups, item)
if err != nil {
return fmt.Errorf("error clearing playlist: %w", err)
}
}
2024-02-18 23:33:32 -08:00
_, err := c.Client().RemoveTracksFromPlaylist(c.Context, radioPlaylist.ID, trackGroups...)
2024-02-18 12:17:07 -08:00
if err != nil {
return err
}
}
2024-05-30 15:19:52 -07:00
toAdd := 500 - (int(playlistItems.Total) - len(toRemove))
2024-02-18 23:33:32 -08:00
playlistItems, err = c.Client().GetPlaylistItems(c.Context, radioPlaylist.ID)
2024-02-18 12:17:07 -08:00
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 {
2024-07-06 14:05:01 -07:00
randomPage = rand.Intn(pages-1) + 1
2024-02-18 12:17:07 -08:00
}
2024-02-18 23:33:32 -08:00
playlistPage, err := c.Client().
2024-02-18 12:17:07 -08:00
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
2024-07-06 14:05:01 -07:00
rand.Shuffle(len(pageSongs), func(i, j int) { pageSongs[i], pageSongs[j] = pageSongs[j], pageSongs[i] })
2024-02-18 12:17:07 -08:00
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,
}
2024-02-18 23:33:32 -08:00
recomendations, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(95))
2024-02-18 12:17:07 -08:00
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 {
2024-02-19 17:58:05 -08:00
if idx > toAdd {
2024-02-18 12:17:07 -08:00
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)
}
2024-02-19 17:58:05 -08:00
toAdd -= len(queue)
2024-02-18 23:33:32 -08:00
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
2024-02-18 12:17:07 -08:00
if err != nil {
return fmt.Errorf("add tracks: %w", err)
}
2024-02-18 23:33:32 -08:00
err = c.Client().Repeat(c.Context, "context")
2024-02-18 12:17:07 -08:00
if err != nil {
return fmt.Errorf("repeat: %w", err)
}
2024-02-19 17:58:05 -08:00
for toAdd > 0 {
2024-07-06 14:05:01 -07:00
id := rand.Intn(len(recomendationIds)-2) + 1
2024-02-18 12:17:07 -08:00
seed := spotify.Seeds{
Tracks: []spotify.ID{recomendationIds[id]},
}
2024-02-19 17:58:05 -08:00
additionalRecs, err := c.Client().
GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
2024-02-18 12:17:07 -08:00
if err != nil {
return fmt.Errorf("get recs: %w", err)
}
additionalRecsIds := []spotify.ID{}
2024-02-19 17:58:05 -08:00
for idx, song := range additionalRecs.Tracks {
2024-02-18 12:17:07 -08:00
exists, err := c.SongExists(db, song.ID)
if err != nil {
return fmt.Errorf("check song existence: %w", err)
}
if !exists {
2024-02-19 17:58:05 -08:00
if idx > toAdd {
2024-02-18 12:17:07 -08:00
break
}
additionalRecsIds = append(additionalRecsIds, song.ID)
queue = append(queue, song.ID)
}
}
2024-02-19 17:58:05 -08:00
toAdd -= len(queue)
2024-02-18 23:33:32 -08:00
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
2024-02-18 12:17:07 -08:00
if err != nil {
return fmt.Errorf("add tracks to playlist: %w", err)
}
}
return nil
}
2024-02-18 15:04:34 -08:00
func (c *Commander) RadioFromAlbum(album spotify.SimpleAlbum) error {
tracks, err := c.AlbumTracks(album.ID, 1)
if err != nil {
return err
}
total := tracks.Total
if total == 0 {
return fmt.Errorf("this playlist is empty")
}
pages := int(math.Ceil(float64(total) / 50))
randomPage := 1
if pages > 1 {
2024-07-06 14:05:01 -07:00
randomPage = rand.Intn(pages-1) + 1
2024-02-18 15:04:34 -08:00
}
albumTrackPage, err := c.AlbumTracks(album.ID, randomPage)
if err != nil {
return err
}
pageSongs := albumTrackPage.Tracks
2024-07-06 14:05:01 -07:00
rand.Shuffle(len(pageSongs), func(i, j int) { pageSongs[i], pageSongs[j] = pageSongs[j], pageSongs[i] })
2024-02-18 15:04:34 -08:00
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.ID)
}
return c.RadioGivenList(seedIds[:seedCount], album.Name)
}
2024-02-19 17:58:05 -08:00
func (c *Commander) RadioGivenList(songs []spotify.ID, name string) error {
2024-02-18 15:04:34 -08:00
seed := spotify.Seeds{
2024-02-19 17:58:05 -08:00
Tracks: songs,
2024-02-18 15:04:34 -08:00
}
2024-02-18 23:33:32 -08:00
recomendations, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(99))
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
recomendationIds := []spotify.ID{}
for _, song := range recomendations.Tracks {
recomendationIds = append(recomendationIds, song.ID)
}
err = c.ClearRadio()
if err != nil {
return err
}
radioPlaylist, db, err := c.GetRadioPlaylist(name)
if err != nil {
return err
}
2024-02-19 17:58:05 -08:00
queue := []spotify.ID{songs[0]}
2024-02-18 15:04:34 -08:00
for _, rec := range recomendationIds {
exists, err := c.SongExists(db, rec)
if err != nil {
return err
}
if !exists {
_, err := db.QueryContext(c.Context, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", string(rec)))
if err != nil {
return err
}
queue = append(queue, rec)
}
}
2024-02-18 23:33:32 -08:00
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
2024-02-18 23:33:32 -08:00
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
2024-02-18 15:04:34 -08:00
PlaybackContext: &radioPlaylist.URI,
})
if err != nil {
if isNoActiveError(err) {
2024-02-19 17:58:05 -08:00
deviceID, err := c.activateDevice()
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
2024-02-18 23:33:32 -08:00
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
2024-02-18 15:04:34 -08:00
PlaybackContext: &radioPlaylist.URI,
2024-02-19 17:58:05 -08:00
DeviceID: &deviceID,
2024-02-18 15:04:34 -08:00
})
if err != nil {
return err
}
}
}
for i := 0; i < 4; i++ {
2024-07-06 14:05:01 -07:00
id := rand.Intn(len(recomendationIds)-2) + 1
2024-02-18 15:04:34 -08:00
seed := spotify.Seeds{
Tracks: []spotify.ID{recomendationIds[id]},
}
2024-02-19 17:58:05 -08:00
additionalRecs, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
additionalRecsIds := []spotify.ID{}
2024-02-19 17:58:05 -08:00
for _, song := range additionalRecs.Tracks {
2024-02-18 15:04:34 -08:00
exists, err := c.SongExists(db, song.ID)
if err != nil {
return err
}
if !exists {
_, err = db.QueryContext(c.Context, fmt.Sprintf("INSERT INTO radio (id) VALUES('%s')", string(song.ID)))
if err != nil {
return err
}
additionalRecsIds = append(additionalRecsIds, song.ID)
}
}
2024-02-18 23:33:32 -08:00
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
2024-02-18 15:04:34 -08:00
if err != nil {
return err
}
}
return nil
}