plapkit/pluralkit.go
2024-06-26 20:18:54 -04:00

131 lines
2.9 KiB
Go

package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/hashicorp/golang-lru/v2/expirable"
)
var (
pkApi = NewPluralKit()
)
type PluralKitSwitch struct {
Members []*PluralKitMember
}
type PluralKitSwitches struct {
Members []string
}
type PluralKitMember struct {
UUID string `json:"uuid"`
Name string `json:"name"`
}
type PluralKit struct {
Client http.Client
Cache *expirable.LRU[string, *PluralKitMember]
BaseURL string
}
func NewPluralKit() PluralKit {
return PluralKit{
BaseURL: "https://api.pluralkit.me/v2",
Client: http.Client{Timeout: time.Second * 30},
Cache: expirable.NewLRU[string, *PluralKitMember](20, nil, time.Hour),
}
}
func (pk *PluralKit) GetMember(id string) (*PluralKitMember, error) {
cached, ok := pk.Cache.Get(id)
if ok {
return cached, nil
}
resp, err := pk.Client.Get(fmt.Sprintf("%s/members/%s", pk.BaseURL, id))
if err != nil {
return nil, fmt.Errorf("fetching pluralkit member %s failed: %w", id, err)
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("pluralkit did not find member %s", id)
}
var member PluralKitMember
err = json.NewDecoder(resp.Body).Decode(&member)
if err != nil {
return nil, fmt.Errorf("malformed json: %w", err)
}
pk.Cache.Add(id, &member)
return &member, nil
}
func (pk *PluralKit) GetSwitch(systemID string, switchID string) (*PluralKitSwitch, error) {
resp, err := pk.Client.Get(fmt.Sprintf("%s/systems/%s/switches/%s", pk.BaseURL, systemID, switchID))
if err != nil {
return nil, fmt.Errorf("fetching pluralkit system %s switch %s failed: %w", systemID, switchID, err)
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("pluralkit did not find system %s switch %s", systemID, switchID)
}
var sw PluralKitSwitch
err = json.NewDecoder(resp.Body).Decode(&sw)
if err != nil {
return nil, fmt.Errorf("malformed json: %w", err)
}
for _, member := range sw.Members {
pk.Cache.Add(member.UUID, member)
}
return &sw, nil
}
func (pk *PluralKit) GetSwitches(systemID string) (*PluralKitSwitches, error) {
resp, err := pk.Client.Get(fmt.Sprintf("%s/systems/%s/switches", pk.BaseURL, systemID))
if err != nil {
return nil, fmt.Errorf("fetching pluralkit system %s failed: %w", systemID, err)
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("pluralkit did not find system %s", systemID)
}
var sw []PluralKitSwitches
err = json.NewDecoder(resp.Body).Decode(&sw)
if err != nil {
return nil, fmt.Errorf("malformed json: %w", err)
}
return &sw[0], nil
}
func populateSwitches() {
sysID := os.Getenv("PK_SYSTEM_ID")
switches, err := pkApi.GetSwitches(sysID)
if err != nil {
log.Fatalln("failed to prepopulate switches.", err)
}
members := make([]*PluralKitMember, len(switches.Members))
for idx, id := range switches.Members {
m, err := pkApi.GetMember(id)
if err != nil {
log.Fatalln("failed to get member.", err)
}
members[idx] = m
}
promCountSwitches(sysID, members)
}