Expose session/last-used user and device IP on player rows. Filter retrieve_player_list by users, merge GET /Devices when include_offline is set, and resolve spoken names to HA media_player entities via player_links (device_id or IP). PlayNow still requires a live session.
97 lines
2.2 KiB
Go
97 lines
2.2 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// SplitCSV splits a comma-separated list, trimming blanks.
|
|
func SplitCSV(s string) []string {
|
|
s = strings.TrimSpace(s)
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
if strings.HasPrefix(s, "[") {
|
|
var arr []string
|
|
if err := json.Unmarshal([]byte(s), &arr); err == nil {
|
|
return compactStrings(arr)
|
|
}
|
|
}
|
|
parts := strings.Split(s, ",")
|
|
return compactStrings(parts)
|
|
}
|
|
|
|
func compactStrings(in []string) []string {
|
|
var out []string
|
|
for _, p := range in {
|
|
p = strings.TrimSpace(p)
|
|
if p != "" {
|
|
out = append(out, p)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
type playerLinkWire struct {
|
|
Names flexStrings `json:"names"`
|
|
EmbyDeviceID string `json:"emby_device_id"`
|
|
EmbyDeviceName string `json:"emby_device_name"`
|
|
DeviceIP string `json:"device_ip"`
|
|
HAEntity string `json:"ha_entity"`
|
|
HASource string `json:"ha_source"`
|
|
Users flexStrings `json:"users"`
|
|
}
|
|
|
|
type flexStrings []string
|
|
|
|
func (f *flexStrings) UnmarshalJSON(b []byte) error {
|
|
b = bytesTrim(b)
|
|
if len(b) == 0 || string(b) == "null" {
|
|
return nil
|
|
}
|
|
if b[0] == '[' {
|
|
var a []string
|
|
if err := json.Unmarshal(b, &a); err != nil {
|
|
return err
|
|
}
|
|
*f = compactStrings(a)
|
|
return nil
|
|
}
|
|
var s string
|
|
if err := json.Unmarshal(b, &s); err != nil {
|
|
return err
|
|
}
|
|
*f = SplitCSV(s)
|
|
return nil
|
|
}
|
|
|
|
func bytesTrim(b []byte) []byte {
|
|
return []byte(strings.TrimSpace(string(b)))
|
|
}
|
|
|
|
// ParsePlayerLinks accepts a JSON array of PlayerLink objects.
|
|
func ParsePlayerLinks(s string) ([]PlayerLink, error) {
|
|
s = strings.TrimSpace(s)
|
|
if s == "" || s == "null" || s == "[]" {
|
|
return nil, nil
|
|
}
|
|
var wires []playerLinkWire
|
|
if err := json.Unmarshal([]byte(s), &wires); err != nil {
|
|
return nil, fmt.Errorf("expected JSON array: %w", err)
|
|
}
|
|
out := make([]PlayerLink, 0, len(wires))
|
|
for _, w := range wires {
|
|
out = append(out, PlayerLink{
|
|
Names: []string(w.Names),
|
|
EmbyDeviceID: strings.TrimSpace(w.EmbyDeviceID),
|
|
EmbyDeviceName: strings.TrimSpace(w.EmbyDeviceName),
|
|
DeviceIP: strings.TrimSpace(w.DeviceIP),
|
|
HAEntity: strings.TrimSpace(w.HAEntity),
|
|
HASource: strings.TrimSpace(w.HASource),
|
|
Users: []string(w.Users),
|
|
})
|
|
}
|
|
return out, nil
|
|
}
|