get client only when needed
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful

This commit is contained in:
abs3nt 2024-02-18 23:33:32 -08:00
parent 86c2c38dfe
commit f6f7d3bd70
Signed by: abs3nt
GPG Key ID: A7BD96A8BAB04C09
30 changed files with 163 additions and 148 deletions

View File

@ -21,7 +21,6 @@ func main() {
fxplus.Context,
cache.NewCache,
commands.NewCommander,
services.NewSpotifyClient,
logger.NewLogger,
),
fx.Invoke(

View File

@ -26,7 +26,7 @@ func (c *Commander) activateDevice() (spotify.ID, error) {
if err != nil {
return "", err
}
err = c.Client.TransferPlayback(c.Context, device.ID, true)
err = c.Client().TransferPlayback(c.Context, device.ID, true)
if err != nil {
return "", err
}

View File

@ -5,7 +5,7 @@ import (
)
func (c *Commander) AlbumTracks(album spotify.ID, page int) (*spotify.SimpleTrackPage, error) {
tracks, err := c.Client.
tracks, err := c.Client().
GetAlbumTracks(c.Context, album, spotify.Limit(50), spotify.Offset((page-1)*50), spotify.Market(spotify.CountryUSA))
if err != nil {
return nil, err
@ -14,5 +14,5 @@ func (c *Commander) AlbumTracks(album spotify.ID, page int) (*spotify.SimpleTrac
}
func (c *Commander) UserAlbums(page int) (*spotify.SavedAlbumPage, error) {
return c.Client.CurrentUsersAlbums(c.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
return c.Client().CurrentUsersAlbums(c.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
}

View File

@ -3,7 +3,7 @@ package commands
import "github.com/zmb3/spotify/v2"
func (c *Commander) ArtistAlbums(artist spotify.ID, page int) (*spotify.SimpleAlbumPage, error) {
albums, err := c.Client.
albums, err := c.Client().
GetArtistAlbums(c.Context, artist, []spotify.AlbumType{1, 2, 3, 4}, spotify.Market(spotify.CountryUSA), spotify.Limit(50), spotify.Offset((page-1)*50))
if err != nil {
return nil, err

View File

@ -3,12 +3,14 @@ package commands
import (
"context"
"log/slog"
"os"
"sync"
"github.com/zmb3/spotify/v2"
"go.uber.org/fx"
"git.asdf.cafe/abs3nt/gspot/src/components/cache"
"git.asdf.cafe/abs3nt/gspot/src/config"
"git.asdf.cafe/abs3nt/gspot/src/services"
)
type CommanderResult struct {
@ -21,33 +23,53 @@ type CommanderParams struct {
fx.In
Context context.Context
Client *spotify.Client
Log *slog.Logger
Cache *cache.Cache
Config *config.Config
}
type Commander struct {
Context context.Context
Client *spotify.Client
User *spotify.PrivateUser
Log *slog.Logger
Cache *cache.Cache
mu sync.RWMutex
cl *spotify.Client
conf *config.Config
}
func NewCommander(p CommanderParams) CommanderResult {
currentUser, err := p.Client.CurrentUser(p.Context)
if err != nil {
slog.Error("COMMANDER", "error getting current user", err)
os.Exit(1)
}
c := &Commander{
Context: p.Context,
Client: p.Client,
User: currentUser,
Log: p.Log,
Cache: p.Cache,
conf: p.Config,
}
return CommanderResult{
Commander: c,
}
}
func (c *Commander) Client() *spotify.Client {
c.mu.Lock()
if c.cl == nil {
c.cl = c.connectClient()
}
c.mu.Unlock()
c.mu.RLock()
defer c.mu.RUnlock()
return c.cl
}
func (c *Commander) connectClient() *spotify.Client {
client, err := services.GetClient(c.conf)
if err != nil {
panic(err)
}
currentUser, err := client.CurrentUser(c.Context)
if err != nil {
panic(err)
}
c.User = currentUser
return client
}

View File

@ -10,7 +10,7 @@ import (
)
func (c *Commander) ListDevices() error {
devices, err := c.Client.PlayerDevices(c.Context)
devices, err := c.Client().PlayerDevices(c.Context)
if err != nil {
return err
}
@ -27,11 +27,11 @@ func PrintDevices(devices []spotify.PlayerDevice) error {
}
func (c *Commander) SetDevice(device spotify.ID) error {
err := c.Client.TransferPlayback(c.Context, device, true)
err := c.Client().TransferPlayback(c.Context, device, true)
if err != nil {
return err
}
devices, err := c.Client.PlayerDevices(c.Context)
devices, err := c.Client().PlayerDevices(c.Context)
if err != nil {
return err
}

View File

@ -10,7 +10,7 @@ func (c *Commander) DownloadCover(path string) error {
path = "cover.png"
}
destinationPath := filepath.Clean(path)
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}

View File

@ -1,9 +1,9 @@
package commands
func (c *Commander) Like() error {
playing, err := c.Client.PlayerCurrentlyPlaying(c.Context)
playing, err := c.Client().PlayerCurrentlyPlaying(c.Context)
if err != nil {
return err
}
return c.Client.AddTracksToLibrary(c.Context, playing.Item.ID)
return c.Client().AddTracksToLibrary(c.Context, playing.Item.ID)
}

View File

@ -3,7 +3,7 @@ package commands
import "fmt"
func (c *Commander) PrintLink() error {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}
@ -12,7 +12,7 @@ func (c *Commander) PrintLink() error {
}
func (c *Commander) PrintLinkContext() error {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}

View File

@ -9,7 +9,7 @@ import (
func (c *Commander) Next(amt int, inqueue bool) error {
if inqueue {
for i := 0; i < amt; i++ {
err := c.Client.Next(c.Context)
err := c.Client().Next(c.Context)
if err != nil {
return err
}
@ -17,14 +17,14 @@ func (c *Commander) Next(amt int, inqueue bool) error {
return nil
}
if amt == 1 {
err := c.Client.Next(c.Context)
err := c.Client().Next(c.Context)
if err != nil {
if isNoActiveError(err) {
deviceId, err := c.activateDevice()
if err != nil {
return err
}
err = c.Client.NextOpt(c.Context, &spotify.PlayOptions{
err = c.Client().NextOpt(c.Context, &spotify.PlayOptions{
DeviceID: &deviceId,
})
if err != nil {
@ -37,7 +37,7 @@ func (c *Commander) Next(amt int, inqueue bool) error {
}
// found := false
// playingIndex := 0
current, err := c.Client.PlayerCurrentlyPlaying(c.Context)
current, err := c.Client().PlayerCurrentlyPlaying(c.Context)
if err != nil {
return err
}
@ -48,7 +48,7 @@ func (c *Commander) Next(amt int, inqueue bool) error {
currentTrackIndex := 0
page := 1
for !found {
playlist, err := c.Client.
playlist, err := c.Client().
GetPlaylistItems(
c.Context,
spotify.ID(strings.Split(string(current.PlaybackContext.URI), ":")[2]),
@ -68,7 +68,7 @@ func (c *Commander) Next(amt int, inqueue bool) error {
page++
}
pos := currentTrackIndex + amt
return c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
return c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &current.PlaybackContext.URI,
PlaybackOffset: &spotify.PlaybackOffset{
Position: &pos,
@ -79,7 +79,7 @@ func (c *Commander) Next(amt int, inqueue bool) error {
currentTrackIndex := 0
page := 1
for !found {
playlist, err := c.Client.
playlist, err := c.Client().
GetAlbumTracks(
c.Context,
spotify.ID(strings.Split(string(current.PlaybackContext.URI), ":")[2]),
@ -99,7 +99,7 @@ func (c *Commander) Next(amt int, inqueue bool) error {
page++
}
pos := currentTrackIndex + amt
return c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
return c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &current.PlaybackContext.URI,
PlaybackOffset: &spotify.PlaybackOffset{
Position: &pos,
@ -107,7 +107,7 @@ func (c *Commander) Next(amt int, inqueue bool) error {
})
default:
for i := 0; i < amt; i++ {
err := c.Client.Next(c.Context)
err := c.Client().Next(c.Context)
if err != nil {
return err
}

View File

@ -9,7 +9,7 @@ import (
func (c *Commander) NowPlaying(force bool) error {
if force {
current, err := c.Client.PlayerCurrentlyPlaying(c.Context)
current, err := c.Client().PlayerCurrentlyPlaying(c.Context)
if err != nil {
return err
}
@ -19,7 +19,7 @@ func (c *Commander) NowPlaying(force bool) error {
return err
}
song, err := c.Cache.GetOrDo("now_playing", func() (string, error) {
current, err := c.Client.PlayerCurrentlyPlaying(c.Context)
current, err := c.Client().PlayerCurrentlyPlaying(c.Context)
if err != nil {
return "", err
}

View File

@ -1,5 +1,5 @@
package commands
func (c *Commander) Pause() error {
return c.Client.Pause(c.Context)
return c.Client().Pause(c.Context)
}

View File

@ -8,14 +8,14 @@ import (
)
func (c *Commander) Play() error {
err := c.Client.Play(c.Context)
err := c.Client().Play(c.Context)
if err != nil {
if isNoActiveError(err) {
deviceID, err := c.activateDevice()
if err != nil {
return err
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
DeviceID: &deviceID,
})
if err != nil {
@ -39,7 +39,7 @@ func (c *Commander) PlayLikedSongs(position int) error {
return err
}
c.Log.Debug("got playlist", "id", playlist.ID)
songs, err := c.Client.CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(position))
songs, err := c.Client().CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(position))
if err != nil {
return err
}
@ -47,12 +47,12 @@ func (c *Commander) PlayLikedSongs(position int) error {
for _, song := range songs.Tracks {
to_add = append(to_add, song.ID)
}
_, err = c.Client.AddTracksToPlaylist(c.Context, playlist.ID, to_add...)
_, err = c.Client().AddTracksToPlaylist(c.Context, playlist.ID, to_add...)
if err != nil {
return err
}
c.Log.Debug("added songs to playlist")
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &playlist.URI,
})
if err != nil {
@ -62,7 +62,7 @@ func (c *Commander) PlayLikedSongs(position int) error {
if err != nil {
return err
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &playlist.URI,
DeviceID: &deviceID,
})
@ -74,7 +74,7 @@ func (c *Commander) PlayLikedSongs(position int) error {
c.Log.Debug("starting loop")
for page := 2; page <= 5; page++ {
c.Log.Debug("doing loop", "page", page)
songs, err := c.Client.CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset((50*(page-1))+position))
songs, err := c.Client().CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset((50*(page-1))+position))
if err != nil {
return err
}
@ -82,7 +82,7 @@ func (c *Commander) PlayLikedSongs(position int) error {
for _, song := range songs.Tracks {
to_add = append(to_add, song.ID)
}
_, err = c.Client.AddTracksToPlaylist(c.Context, playlist.ID, to_add...)
_, err = c.Client().AddTracksToPlaylist(c.Context, playlist.ID, to_add...)
if err != nil {
return err
}
@ -97,20 +97,20 @@ func (c *Commander) PlayUrl(urlString string) error {
return err
}
track_id := strings.Split(url.Path, "/")[2]
err = c.Client.QueueSong(c.Context, spotify.ID(track_id))
err = c.Client().QueueSong(c.Context, spotify.ID(track_id))
if err != nil {
if isNoActiveError(err) {
deviceID, err := c.activateDevice()
if err != nil {
return err
}
err = c.Client.QueueSongOpt(c.Context, spotify.ID(track_id), &spotify.PlayOptions{
err = c.Client().QueueSongOpt(c.Context, spotify.ID(track_id), &spotify.PlayOptions{
DeviceID: &deviceID,
})
if err != nil {
return err
}
err = c.Client.NextOpt(c.Context, &spotify.PlayOptions{
err = c.Client().NextOpt(c.Context, &spotify.PlayOptions{
DeviceID: &deviceID,
})
if err != nil {
@ -121,7 +121,7 @@ func (c *Commander) PlayUrl(urlString string) error {
return err
}
}
err = c.Client.Next(c.Context)
err = c.Client().Next(c.Context)
if err != nil {
return err
}
@ -129,7 +129,7 @@ func (c *Commander) PlayUrl(urlString string) error {
}
func (c *Commander) PlaySongInPlaylist(context *spotify.URI, offset *int) error {
e := c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
e := c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackOffset: &spotify.PlaybackOffset{Position: offset},
PlaybackContext: context,
})
@ -139,7 +139,7 @@ func (c *Commander) PlaySongInPlaylist(context *spotify.URI, offset *int) error
if err != nil {
return err
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackOffset: &spotify.PlaybackOffset{Position: offset},
PlaybackContext: context,
DeviceID: &deviceID,
@ -150,7 +150,7 @@ func (c *Commander) PlaySongInPlaylist(context *spotify.URI, offset *int) error
if err != nil {
return err
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackOffset: &spotify.PlaybackOffset{Position: offset},
PlaybackContext: context,
DeviceID: &deviceID,
@ -160,7 +160,7 @@ func (c *Commander) PlaySongInPlaylist(context *spotify.URI, offset *int) error
}
}
}
err = c.Client.Play(c.Context)
err = c.Client().Play(c.Context)
if err != nil {
return err
}

View File

@ -3,15 +3,15 @@ package commands
import "github.com/zmb3/spotify/v2"
func (c *Commander) Playlists(page int) (*spotify.SimplePlaylistPage, error) {
return c.Client.CurrentUsersPlaylists(c.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
return c.Client().CurrentUsersPlaylists(c.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
}
func (c *Commander) PlaylistTracks(playlist spotify.ID, page int) (*spotify.PlaylistItemPage, error) {
return c.Client.GetPlaylistItems(c.Context, playlist, spotify.Limit(50), spotify.Offset((page-1)*50))
return c.Client().GetPlaylistItems(c.Context, playlist, spotify.Limit(50), spotify.Offset((page-1)*50))
}
func (c *Commander) DeleteTracksFromPlaylist(tracks []spotify.ID, playlist spotify.ID) error {
_, err := c.Client.RemoveTracksFromPlaylist(c.Context, playlist, tracks...)
_, err := c.Client().RemoveTracksFromPlaylist(c.Context, playlist, tracks...)
if err != nil {
return err
}
@ -19,5 +19,5 @@ func (c *Commander) DeleteTracksFromPlaylist(tracks []spotify.ID, playlist spoti
}
func (c *Commander) TrackList(page int) (*spotify.SavedTrackPage, error) {
return c.Client.CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
return c.Client().CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
}

View File

@ -5,14 +5,14 @@ import (
)
func (c *Commander) Previous() error {
err := c.Client.Previous(c.Context)
err := c.Client().Previous(c.Context)
if err != nil {
if isNoActiveError(err) {
deviceId, err := c.activateDevice()
if err != nil {
return err
}
err = c.Client.PreviousOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PreviousOpt(c.Context, &spotify.PlayOptions{
DeviceID: &deviceId,
})
if err != nil {

View File

@ -3,14 +3,14 @@ package commands
import "github.com/zmb3/spotify/v2"
func (c *Commander) QueueSong(id spotify.ID) error {
err := c.Client.QueueSong(c.Context, id)
err := c.Client().QueueSong(c.Context, id)
if err != nil {
if isNoActiveError(err) {
deviceID, err := c.activateDevice()
if err != nil {
return err
}
err = c.Client.QueueSongOpt(c.Context, id, &spotify.PlayOptions{
err = c.Client().QueueSongOpt(c.Context, id, &spotify.PlayOptions{
DeviceID: &deviceID,
})
if err != nil {

View File

@ -16,7 +16,7 @@ import (
)
func (c *Commander) Radio() error {
current_song, err := c.Client.PlayerCurrentlyPlaying(c.Context)
current_song, err := c.Client().PlayerCurrentlyPlaying(c.Context)
if err != nil {
return err
}
@ -27,7 +27,7 @@ func (c *Commander) Radio() error {
if err != nil {
return err
}
tracks, err := c.Client.CurrentUsersTracks(c.Context, spotify.Limit(10))
tracks, err := c.Client().CurrentUsersTracks(c.Context, spotify.Limit(10))
if err != nil {
return err
}
@ -44,7 +44,7 @@ func (c *Commander) RadioFromPlaylist(playlist spotify.SimplePlaylist) error {
if pages > 1 {
randomPage = frand.Intn(pages-1) + 1
}
playlistPage, err := c.Client.GetPlaylistItems(
playlistPage, err := c.Client().GetPlaylistItems(
c.Context,
playlist.ID,
spotify.Limit(50),
@ -70,7 +70,7 @@ func (c *Commander) RadioFromPlaylist(playlist spotify.SimplePlaylist) error {
}
func (c *Commander) RadioFromSavedTracks() error {
savedSongs, err := c.Client.CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(0))
savedSongs, err := c.Client().CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(0))
if err != nil {
return err
}
@ -82,7 +82,7 @@ func (c *Commander) RadioFromSavedTracks() error {
if pages > 1 {
randomPage = frand.Intn(pages-1) + 1
}
trackPage, err := c.Client.CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(randomPage*50))
trackPage, err := c.Client().CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(randomPage*50))
if err != nil {
return err
}
@ -104,7 +104,7 @@ func (c *Commander) RadioGivenArtist(artist spotify.SimpleArtist) error {
seed := spotify.Seeds{
Artists: []spotify.ID{artist.ID},
}
recomendations, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
recomendations, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
if err != nil {
return err
}
@ -134,17 +134,17 @@ func (c *Commander) RadioGivenArtist(artist spotify.SimpleArtist) error {
queue = append(queue, rec)
}
}
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
if err != nil {
return err
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &radioPlaylist.URI,
})
if err != nil {
return err
}
err = c.Client.Repeat(c.Context, "context")
err = c.Client().Repeat(c.Context, "context")
if err != nil {
return err
}
@ -153,7 +153,7 @@ func (c *Commander) RadioGivenArtist(artist spotify.SimpleArtist) error {
seed := spotify.Seeds{
Tracks: []spotify.ID{recomendationIds[id]},
}
additional_recs, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
additional_recs, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
if err != nil {
return err
}
@ -171,7 +171,7 @@ func (c *Commander) RadioGivenArtist(artist spotify.SimpleArtist) error {
additionalRecsIds = append(additionalRecsIds, song.ID)
}
}
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
if err != nil {
return err
}
@ -184,7 +184,7 @@ func (c *Commander) RadioGivenSong(song spotify.SimpleTrack, pos int) error {
seed := spotify.Seeds{
Tracks: []spotify.ID{song.ID},
}
recomendations, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(99))
recomendations, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(99))
if err != nil {
return err
}
@ -218,7 +218,7 @@ func (c *Commander) RadioGivenSong(song spotify.SimpleTrack, pos int) error {
queue = append(queue, rec)
}
}
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
if err != nil {
return err
}
@ -226,7 +226,7 @@ func (c *Commander) RadioGivenSong(song spotify.SimpleTrack, pos int) error {
if pos != 0 {
pos = pos + int(delay)
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &radioPlaylist.URI,
PositionMs: pos,
})
@ -236,7 +236,7 @@ func (c *Commander) RadioGivenSong(song spotify.SimpleTrack, pos int) error {
if err != nil {
return err
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &radioPlaylist.URI,
DeviceID: &deviceID,
PositionMs: pos,
@ -246,7 +246,7 @@ func (c *Commander) RadioGivenSong(song spotify.SimpleTrack, pos int) error {
}
}
}
err = c.Client.Repeat(c.Context, "context")
err = c.Client().Repeat(c.Context, "context")
if err != nil {
return err
}
@ -255,7 +255,7 @@ func (c *Commander) RadioGivenSong(song spotify.SimpleTrack, pos int) error {
seed := spotify.Seeds{
Tracks: []spotify.ID{recomendationIds[id]},
}
additional_recs, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
additional_recs, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
if err != nil {
return err
}
@ -273,7 +273,7 @@ func (c *Commander) RadioGivenSong(song spotify.SimpleTrack, pos int) error {
additionalRecsIds = append(additionalRecsIds, song.ID)
}
}
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
if err != nil {
return err
}
@ -286,14 +286,14 @@ func (c *Commander) ClearRadio() error {
if err != nil {
return err
}
err = c.Client.UnfollowPlaylist(c.Context, radioPlaylist.ID)
err = c.Client().UnfollowPlaylist(c.Context, radioPlaylist.ID)
if err != nil {
return err
}
_, _ = db.Query("DROP TABLE IF EXISTS radio")
configDir, _ := os.UserConfigDir()
os.Remove(filepath.Join(configDir, "gspot/radio.json"))
_ = c.Client.Pause(c.Context)
_ = c.Client().Pause(c.Context)
return nil
}
@ -321,7 +321,7 @@ func (c *Commander) GetRadioPlaylist(name string) (*spotify.FullPlaylist, *sql.D
func (c *Commander) CreateRadioPlaylist(name string) (*spotify.FullPlaylist, *sql.DB, error) {
// private flag doesnt work
configDir, _ := os.UserConfigDir()
playlist, err := c.Client.
playlist, err := c.Client().
CreatePlaylistForUser(c.Context, c.User.ID, name+" - autoradio", "Automanaged radio playlist", false, false)
if err != nil {
return nil, nil, err
@ -359,7 +359,7 @@ func (c *Commander) SongExists(db *sql.DB, song spotify.ID) (bool, error) {
}
func (c *Commander) RefillRadio() error {
status, err := c.Client.PlayerCurrentlyPlaying(c.Context)
status, err := c.Client().PlayerCurrentlyPlaying(c.Context)
if err != nil {
return err
}
@ -376,14 +376,14 @@ func (c *Commander) RefillRadio() error {
return nil
}
playlistItems, err := c.Client.GetPlaylistItems(c.Context, radioPlaylist.ID)
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))
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)
}
@ -402,7 +402,7 @@ func (c *Commander) RefillRadio() error {
var trackGroups []spotify.ID
for idx, item := range to_remove {
if idx%100 == 0 {
_, err = c.Client.RemoveTracksFromPlaylist(c.Context, radioPlaylist.ID, trackGroups...)
_, err = c.Client().RemoveTracksFromPlaylist(c.Context, radioPlaylist.ID, trackGroups...)
trackGroups = []spotify.ID{}
}
trackGroups = append(trackGroups, item)
@ -410,14 +410,14 @@ func (c *Commander) RefillRadio() error {
return fmt.Errorf("error clearing playlist: %w", err)
}
}
_, err := c.Client.RemoveTracksFromPlaylist(c.Context, radioPlaylist.ID, trackGroups...)
_, 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)
playlistItems, err = c.Client().GetPlaylistItems(c.Context, radioPlaylist.ID)
if err != nil {
return fmt.Errorf("playlist items: %w", err)
}
@ -427,7 +427,7 @@ func (c *Commander) RefillRadio() error {
if pages > 1 {
randomPage = frand.Intn(pages-1) + 1
}
playlistPage, err := c.Client.
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)
@ -448,7 +448,7 @@ func (c *Commander) RefillRadio() error {
seed := spotify.Seeds{
Tracks: seedIds,
}
recomendations, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(95))
recomendations, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(95))
if err != nil {
return err
}
@ -474,11 +474,11 @@ func (c *Commander) RefillRadio() error {
queue = append(queue, rec)
}
to_add -= len(queue)
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, 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")
err = c.Client().Repeat(c.Context, "context")
if err != nil {
return fmt.Errorf("repeat: %w", err)
}
@ -487,7 +487,7 @@ func (c *Commander) RefillRadio() error {
seed := spotify.Seeds{
Tracks: []spotify.ID{recomendationIds[id]},
}
additional_recs, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
additional_recs, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
if err != nil {
return fmt.Errorf("get recs: %w", err)
}
@ -506,7 +506,7 @@ func (c *Commander) RefillRadio() error {
}
}
to_add -= len(queue)
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
if err != nil {
return fmt.Errorf("add tracks to playlist: %w", err)
}
@ -552,7 +552,7 @@ func (c *Commander) RadioGivenList(song_ids []spotify.ID, name string) error {
seed := spotify.Seeds{
Tracks: song_ids,
}
recomendations, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(99))
recomendations, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(99))
if err != nil {
return err
}
@ -582,11 +582,11 @@ func (c *Commander) RadioGivenList(song_ids []spotify.ID, name string) error {
queue = append(queue, rec)
}
}
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, queue...)
if err != nil {
return err
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &radioPlaylist.URI,
})
if err != nil {
@ -595,7 +595,7 @@ func (c *Commander) RadioGivenList(song_ids []spotify.ID, name string) error {
if err != nil {
return err
}
err = c.Client.PlayOpt(c.Context, &spotify.PlayOptions{
err = c.Client().PlayOpt(c.Context, &spotify.PlayOptions{
PlaybackContext: &radioPlaylist.URI,
DeviceID: &deviceId,
})
@ -609,7 +609,7 @@ func (c *Commander) RadioGivenList(song_ids []spotify.ID, name string) error {
seed := spotify.Seeds{
Tracks: []spotify.ID{recomendationIds[id]},
}
additional_recs, err := c.Client.GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
additional_recs, err := c.Client().GetRecommendations(c.Context, seed, &spotify.TrackAttributes{}, spotify.Limit(100))
if err != nil {
return err
}
@ -627,7 +627,7 @@ func (c *Commander) RadioGivenList(song_ids []spotify.ID, name string) error {
additionalRecsIds = append(additionalRecsIds, song.ID)
}
}
_, err = c.Client.AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
_, err = c.Client().AddTracksToPlaylist(c.Context, radioPlaylist.ID, additionalRecsIds...)
if err != nil {
return err
}

View File

@ -1,7 +1,7 @@
package commands
func (c *Commander) Repeat() error {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}
@ -10,7 +10,7 @@ func (c *Commander) Repeat() error {
newState = "context"
}
// spotifyd only supports binary value for repeat, context or off, change when/if spotifyd is better
err = c.Client.Repeat(c.Context, newState)
err = c.Client().Repeat(c.Context, newState)
if err != nil {
return err
}

View File

@ -3,7 +3,7 @@ package commands
import "github.com/zmb3/spotify/v2"
func (c *Commander) Search(search string, page int) (*spotify.SearchResult, error) {
result, err := c.Client.
result, err := c.Client().
Search(c.Context, search, spotify.SearchTypeAlbum|spotify.SearchTypeArtist|spotify.SearchTypeTrack|spotify.SearchTypePlaylist, spotify.Limit(50), spotify.Offset((page-1)*50))
if err != nil {
return nil, err

View File

@ -1,7 +1,7 @@
package commands
func (c *Commander) Seek(fwd bool) error {
current, err := c.Client.PlayerCurrentlyPlaying(c.Context)
current, err := c.Client().PlayerCurrentlyPlaying(c.Context)
if err != nil {
return err
}
@ -9,7 +9,7 @@ func (c *Commander) Seek(fwd bool) error {
if !fwd {
newPos = current.Progress - 5000
}
err = c.Client.Seek(c.Context, newPos)
err = c.Client().Seek(c.Context, newPos)
if err != nil {
return err
}
@ -17,7 +17,7 @@ func (c *Commander) Seek(fwd bool) error {
}
func (c *Commander) SetPosition(pos int) error {
err := c.Client.Seek(c.Context, pos)
err := c.Client().Seek(c.Context, pos)
if err != nil {
return err
}

View File

@ -1,11 +1,11 @@
package commands
func (c *Commander) Shuffle() error {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}
err = c.Client.Shuffle(c.Context, !state.ShuffleState)
err = c.Client().Shuffle(c.Context, !state.ShuffleState)
if err != nil {
return err
}

View File

@ -10,7 +10,7 @@ import (
func (c *Commander) Status() error {
state, err := c.Cache.GetOrDo("state", func() (string, error) {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return "", err
}

View File

@ -1,12 +1,12 @@
package commands
func (c *Commander) TogglePlay() error {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}
if state.Playing {
return c.Client.Pause(c.Context)
return c.Client().Pause(c.Context)
}
return c.Client.Play(c.Context)
return c.Client().Play(c.Context)
}

View File

@ -1,9 +1,9 @@
package commands
func (c *Commander) UnLike() error {
playing, err := c.Client.PlayerCurrentlyPlaying(c.Context)
playing, err := c.Client().PlayerCurrentlyPlaying(c.Context)
if err != nil {
return err
}
return c.Client.RemoveTracksFromLibrary(c.Context, playing.Item.ID)
return c.Client().RemoveTracksFromLibrary(c.Context, playing.Item.ID)
}

View File

@ -1,7 +1,7 @@
package commands
func (c *Commander) ChangeVolume(amount int) error {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}
@ -12,7 +12,7 @@ func (c *Commander) ChangeVolume(amount int) error {
if newVolume < 0 {
newVolume = 0
}
return c.Client.Volume(c.Context, newVolume)
return c.Client().Volume(c.Context, newVolume)
}
func (c *Commander) Mute() error {
@ -24,7 +24,7 @@ func (c *Commander) UnMute() error {
}
func (c *Commander) ToggleMute() error {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}

View File

@ -7,7 +7,7 @@ import (
)
func (c *Commander) PrintYoutubeLink() error {
state, err := c.Client.PlayerState(c.Context)
state, err := c.Client().PlayerState(c.Context)
if err != nil {
return err
}

View File

@ -35,7 +35,7 @@ func (m *mainModel) LoadMoreItems() {
main_updates <- m
return
case "artists":
artists, err := m.commands.Client.CurrentUsersFollowedArtists(
artists, err := m.commands.Client().CurrentUsersFollowedArtists(
m.commands.Context,
spotify.Limit(50),
spotify.Offset((page)*50),

View File

@ -602,7 +602,7 @@ func Tick() tea.Cmd {
}
func (m *mainModel) TickPlayback() {
playing, _ := m.commands.Client.PlayerCurrentlyPlaying(m.commands.Context)
playing, _ := m.commands.Client().PlayerCurrentlyPlaying(m.commands.Context)
if playing != nil && playing.Playing && playing.Item != nil {
if currentlyPlaying == nil || currentlyPlaying.Item == nil ||
currentlyPlaying.Item.ID != playing.Item.ID {
@ -617,7 +617,7 @@ func (m *mainModel) TickPlayback() {
select {
case <-ticker.C:
m.commands.Log.Debug("TICKING PLAYBACK")
playing, _ := m.commands.Client.PlayerCurrentlyPlaying(m.commands.Context)
playing, _ := m.commands.Client().PlayerCurrentlyPlaying(m.commands.Context)
if playing != nil && playing.Playing && playing.Item != nil {
if currentlyPlaying == nil || currentlyPlaying.Item == nil ||
currentlyPlaying.Item.ID != playing.Item.ID {
@ -673,21 +673,21 @@ func (m *mainModel) getContext(playing *spotify.CurrentlyPlaying) (string, error
switch context.Type {
case "album":
m.commands.Log.Debug("ALBUM CONTEXT")
album, err := m.commands.Client.GetAlbum(m.commands.Context, spotify.ID(id))
album, err := m.commands.Client().GetAlbum(m.commands.Context, spotify.ID(id))
if err != nil {
return "", err
}
return album.Name, nil
case "playlist":
m.commands.Log.Debug("PLAYLIST CONTEXT")
playlist, err := m.commands.Client.GetPlaylist(m.commands.Context, spotify.ID(id))
playlist, err := m.commands.Client().GetPlaylist(m.commands.Context, spotify.ID(id))
if err != nil {
return "", err
}
return playlist.Name, nil
case "artist":
m.commands.Log.Debug("ARTIST CONTEXT")
artist, err := m.commands.Client.GetArtist(m.commands.Context, spotify.ID(id))
artist, err := m.commands.Client().GetArtist(m.commands.Context, spotify.ID(id))
if err != nil {
return "", err
}

View File

@ -16,7 +16,7 @@ const regex = `<.*?>`
func DeviceView(commands *commands.Commander) ([]list.Item, error) {
items := []list.Item{}
devices, err := commands.Client.PlayerDevices(commands.Context)
devices, err := commands.Client().PlayerDevices(commands.Context)
if err != nil {
return nil, err
}
@ -32,7 +32,7 @@ func DeviceView(commands *commands.Commander) ([]list.Item, error) {
func QueueView(commands *commands.Commander) ([]list.Item, error) {
items := []list.Item{}
tracks, err := commands.Client.GetQueue(commands.Context)
tracks, err := commands.Client().GetQueue(commands.Context)
if err != nil {
return nil, err
}
@ -63,7 +63,7 @@ func QueueView(commands *commands.Commander) ([]list.Item, error) {
func PlaylistView(commands *commands.Commander, playlist spotify.SimplePlaylist) ([]list.Item, error) {
items := []list.Item{}
playlistItems, err := commands.Client.GetPlaylistItems(
playlistItems, err := commands.Client().GetPlaylistItems(
commands.Context,
playlist.ID,
spotify.Limit(50),
@ -89,7 +89,7 @@ func PlaylistView(commands *commands.Commander, playlist spotify.SimplePlaylist)
func ArtistsView(commands *commands.Commander) ([]list.Item, error) {
items := []list.Item{}
artists, err := commands.Client.CurrentUsersFollowedArtists(commands.Context, spotify.Limit(50), spotify.Offset(0))
artists, err := commands.Client().CurrentUsersFollowedArtists(commands.Context, spotify.Limit(50), spotify.Offset(0))
if err != nil {
return nil, err
}
@ -145,7 +145,7 @@ func SearchView(commands *commands.Commander, search string) ([]list.Item, *Sear
func AlbumsView(commands *commands.Commander) ([]list.Item, error) {
items := []list.Item{}
albums, err := commands.Client.CurrentUsersAlbums(commands.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
albums, err := commands.Client().CurrentUsersAlbums(commands.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
if err != nil {
return nil, err
}
@ -249,7 +249,7 @@ func SearchTracksView(tracks *spotify.FullTrackPage) ([]list.Item, error) {
func SavedTracksView(commands *commands.Commander) ([]list.Item, error) {
items := []list.Item{}
tracks, err := commands.Client.CurrentUsersTracks(commands.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
tracks, err := commands.Client().CurrentUsersTracks(commands.Context, spotify.Limit(50), spotify.Offset((page-1)*50))
if err != nil {
return nil, err
}
@ -275,22 +275,22 @@ func MainView(c *commands.Commander) ([]list.Item, error) {
var albums *spotify.SavedAlbumPage
wg.Go(func() (err error) {
saved_items, err = c.Client.CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(0))
saved_items, err = c.Client().CurrentUsersTracks(c.Context, spotify.Limit(50), spotify.Offset(0))
return
})
wg.Go(func() (err error) {
playlists, err = c.Client.CurrentUsersPlaylists(c.Context, spotify.Limit(50), spotify.Offset(0))
playlists, err = c.Client().CurrentUsersPlaylists(c.Context, spotify.Limit(50), spotify.Offset(0))
return
})
wg.Go(func() (err error) {
artists, err = c.Client.CurrentUsersFollowedArtists(c.Context, spotify.Limit(50), spotify.Offset(0))
artists, err = c.Client().CurrentUsersFollowedArtists(c.Context, spotify.Limit(50), spotify.Offset(0))
return
})
wg.Go(func() (err error) {
albums, err = c.Client.CurrentUsersAlbums(c.Context, spotify.Limit(50), spotify.Offset(0))
albums, err = c.Client().CurrentUsersAlbums(c.Context, spotify.Limit(50), spotify.Offset(0))
return
})

View File

@ -13,18 +13,12 @@ import (
"github.com/zmb3/spotify/v2"
spotifyauth "github.com/zmb3/spotify/v2/auth"
"go.uber.org/fx"
"golang.org/x/exp/slog"
"golang.org/x/oauth2"
"git.asdf.cafe/abs3nt/gspot/src/config"
)
type SpotifyClientResult struct {
fx.Out
Client *spotify.Client
}
var (
auth *spotifyauth.Authenticator
ch = make(chan *spotify.Client)
@ -38,9 +32,9 @@ func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error)
return fn(req)
}
func NewSpotifyClient(conf *config.Config) (c SpotifyClientResult, err error) {
func GetClient(conf *config.Config) (c *spotify.Client, err error) {
if conf.ClientId == "" || (conf.ClientSecret == "" && conf.ClientSecretCmd == "") || conf.Port == "" {
return SpotifyClientResult{}, fmt.Errorf("INVALID CONFIG")
return nil, fmt.Errorf("INVALID CONFIG")
}
if conf.ClientSecretCmd != "" {
args := strings.Fields(conf.ClientSecretCmd)
@ -83,13 +77,13 @@ func NewSpotifyClient(conf *config.Config) (c SpotifyClientResult, err error) {
authFilePath := filepath.Join(configDir, "gspot/auth.json")
authFile, err := os.Open(authFilePath)
if err != nil {
return SpotifyClientResult{}, err
return nil, err
}
defer authFile.Close()
tok := &oauth2.Token{}
err = json.NewDecoder(authFile).Decode(tok)
if err != nil {
return SpotifyClientResult{}, err
return nil, err
}
authCtx := context.WithValue(context.Background(), oauth2.HTTPClient, &http.Client{
Transport: roundTripperFunc(func(r *http.Request) (*http.Response, error) {
@ -101,17 +95,17 @@ func NewSpotifyClient(conf *config.Config) (c SpotifyClientResult, err error) {
client := spotify.New(authClient)
new_token, err := client.Token()
if err != nil {
return SpotifyClientResult{}, err
return nil, err
}
out, err := json.MarshalIndent(new_token, "", " ")
if err != nil {
return SpotifyClientResult{}, err
return nil, err
}
err = os.WriteFile(authFilePath, out, 0o600)
if err != nil {
return SpotifyClientResult{}, fmt.Errorf("failed to save auth")
return nil, fmt.Errorf("failed to save auth")
}
return SpotifyClientResult{Client: client}, nil
return client, nil
}
// first start an HTTP server
http.HandleFunc("/callback", completeAuth)
@ -136,10 +130,10 @@ func NewSpotifyClient(conf *config.Config) (c SpotifyClientResult, err error) {
// use the client to make calls that require authorization
user, err := client.CurrentUser(context.Background())
if err != nil {
return SpotifyClientResult{}, err
return nil, err
}
slog.Info("AUTH", "You are logged in as:", user.ID)
return SpotifyClientResult{Client: client}, nil
return client, nil
}
func completeAuth(w http.ResponseWriter, r *http.Request) {