2023-08-25 20:44:44 +00:00
|
|
|
package morningalarm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"math/rand"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/zmb3/spotify/v2"
|
|
|
|
)
|
|
|
|
|
2023-09-05 19:01:24 +00:00
|
|
|
type headerTransport struct {
|
|
|
|
baseTransport http.RoundTripper
|
|
|
|
headers map[string]string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
|
|
for key, value := range t.headers {
|
|
|
|
req.Header.Set(key, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
return t.baseTransport.RoundTrip(req)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ma *MorningAlarm) setupSpotifyWithProxy() {
|
|
|
|
client := &http.Client{
|
|
|
|
Transport: &headerTransport{
|
|
|
|
baseTransport: http.DefaultTransport,
|
|
|
|
headers: map[string]string{
|
|
|
|
"X-API-KEY": ma.config.OAuthProxyAPIKey,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
ma.sp = spotify.New(client, spotify.WithBaseURL(ma.config.OAuthProxyURL))
|
|
|
|
}
|
|
|
|
|
2023-08-25 20:44:44 +00:00
|
|
|
// playWakeUpMusic plays the playlist specified in the config at the specified device.
|
|
|
|
// Returns true if the playback was started successfully.
|
|
|
|
// Returns error if any error occurred.
|
|
|
|
// Can still return an error even if the playback was started successfully.
|
|
|
|
func (ma *MorningAlarm) playWakeUpMusic() (bool, error) {
|
|
|
|
playContextURI := spotify.URI("spotify:playlist:" + ma.config.PlaylistID)
|
2023-09-25 23:07:01 +00:00
|
|
|
|
|
|
|
devID, err := ma.getDeviceIDFromName(ma.config.DeviceName)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
deviceID := spotify.ID(devID)
|
2023-08-25 20:44:44 +00:00
|
|
|
|
|
|
|
playlist, err := ma.sp.GetPlaylistItems(context.Background(), spotify.ID(ma.config.PlaylistID))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return true, err
|
|
|
|
}
|
|
|
|
|
|
|
|
randomTrackIndex := rand.Intn(playlist.Total)
|
|
|
|
|
|
|
|
err = ma.sp.PlayOpt(context.Background(), &spotify.PlayOptions{
|
|
|
|
PlaybackContext: &playContextURI,
|
|
|
|
DeviceID: &deviceID,
|
|
|
|
PlaybackOffset: &spotify.PlaybackOffset{Position: randomTrackIndex},
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return true, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ma.sp.ShuffleOpt(context.Background(), true, &spotify.PlayOptions{
|
|
|
|
DeviceID: &deviceID,
|
|
|
|
})
|
|
|
|
|
|
|
|
return true, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ma *MorningAlarm) getAvailableDevices() ([]Device, error) {
|
|
|
|
devices, err := ma.sp.PlayerDevices(context.Background())
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var availableDevices []Device
|
|
|
|
for _, device := range devices {
|
|
|
|
if !device.Restricted {
|
|
|
|
availableDevices = append(availableDevices, Device{
|
|
|
|
ID: string(device.ID),
|
|
|
|
Name: device.Name,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return availableDevices, nil
|
|
|
|
}
|
2023-09-25 23:07:01 +00:00
|
|
|
|
|
|
|
func (ma *MorningAlarm) getDeviceIDFromName(name string) (string, error) {
|
|
|
|
dev, err := ma.getAvailableDevices()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, device := range dev {
|
|
|
|
if device.Name == name {
|
|
|
|
return device.ID, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", fmt.Errorf("device with name %s not found", name)
|
|
|
|
}
|