Files
TTRPG-Spotify-Sync/data/speaker.go

114 lines
2.5 KiB
Go

package data
import (
"context"
"errors"
"emtlabs.com/spotify-sync/api"
log "github.com/sirupsen/logrus"
clientv3 "go.etcd.io/etcd/client/v3"
"gopkg.in/yaml.v3"
)
const speaker_base_key string = "/v1/speaker"
const default_speaker_lease_time int64 = 10
var slog *log.Entry
func initSpeaker() error {
slog = dlog.WithField("data", "speaker")
return nil
}
// buildSpeakerKey returns the key for a given speaker by id
func buildSpeakerKey(id string) string {
return speaker_base_key + "/" + id
}
// GetSpeaker returns a speaker by id
func GetSpeaker(id string) (*api.Speaker, error) {
//set log
l := slog.WithField("method", "get")
l.Debugln("getting current speaker state from db")
ctx := context.Background()
sk := buildSpeakerKey(id)
resp, err := Client.Get(ctx, sk)
if err != nil {
l.Errorln(err)
return nil, err
}
if resp.Count == 0 {
l.Warningln("speaker not available")
return nil, err
} else if resp.Count > 1 {
err = errors.New("multiple speaker available on same path")
l.Errorln(err)
return nil, err
}
//decode playout
speaker := api.Speaker{}
resp_raw := resp.Kvs[0].Value
err = yaml.Unmarshal(resp_raw, &speaker)
if err != nil {
l.Errorln(err)
return nil, err
}
l.Debugln("speaker state in db (", speaker, ")")
return &speaker, nil
}
// SendHeartbeat sends a speaker state to the db
func SendHeartbeat(speaker *api.Speaker) error {
l := slog.WithField("method", "put")
data, err := yaml.Marshal(speaker)
if err != nil {
l.Errorln(err)
return err
}
l.Debugln("sending speaker to db", string(data))
sk := buildSpeakerKey(speaker.Id)
ctx := context.Background()
lease, err := Client.Grant(ctx, default_speaker_lease_time)
if err != nil {
l.Errorln(err)
return err
}
ctx = context.Background()
_, err = Client.KV.Put(ctx, sk, string(data), clientv3.WithLease(lease.ID))
if err != nil {
l.Errorln(err)
return err
}
return nil
}
// GetSpeakers returns a list of all speakers
func GetSpeakers() ([]api.Speaker, error) {
//set log
l := slog.WithField("method", "list")
l.Debugln("list speaker states from db")
ctx := context.Background()
resp, err := Client.Get(ctx, speaker_base_key, clientv3.WithPrefix())
if err != nil {
l.Errorln(err)
return nil, err
}
resp_list := make([]api.Speaker, 0)
//decode speaker
for _, v := range resp.Kvs {
speaker := api.Speaker{}
err = yaml.Unmarshal(v.Value, &speaker)
if err != nil {
l.Warnln(err)
continue
}
resp_list = append(resp_list, speaker)
}
l.Debugln(len(resp_list), " speaker states read from db")
return resp_list, nil
}