87 lines
1.9 KiB
Go
87 lines
1.9 KiB
Go
// backend/internal/usermap.go
|
|
package internal
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// StringOrList allows both a single string ("Stein_90s")
|
|
// and a list of strings (["Stein_90s","Home Videos"]) in YAML.
|
|
type StringOrList []string
|
|
|
|
func (s *StringOrList) UnmarshalYAML(value *yaml.Node) error {
|
|
switch value.Kind {
|
|
case yaml.ScalarNode:
|
|
var str string
|
|
if err := value.Decode(&str); err != nil {
|
|
return err
|
|
}
|
|
*s = StringOrList{str}
|
|
return nil
|
|
case yaml.SequenceNode:
|
|
var list []string
|
|
if err := value.Decode(&list); err != nil {
|
|
return err
|
|
}
|
|
*s = StringOrList(list)
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("expected string or list, got kind=%v", value.Kind)
|
|
}
|
|
}
|
|
|
|
type UserMap struct {
|
|
// Maps Jellyfin username -> one or more relative media subdirs
|
|
Map map[string]StringOrList `yaml:"map"`
|
|
}
|
|
|
|
func LoadUserMap(path string) (*UserMap, error) {
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var m UserMap
|
|
if err := yaml.Unmarshal(b, &m); err != nil {
|
|
return nil, err
|
|
}
|
|
return &m, nil
|
|
}
|
|
|
|
// Resolve returns the first configured library for the user (back-compat).
|
|
func (m *UserMap) Resolve(username string) (string, error) {
|
|
roots, err := m.ResolveAll(username)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return roots[0], nil
|
|
}
|
|
|
|
// ResolveAll returns all configured libraries for the user.
|
|
func (m *UserMap) ResolveAll(username string) ([]string, error) {
|
|
v, ok := m.Map[username]
|
|
if !ok || len(v) == 0 {
|
|
return nil, fmt.Errorf("no mapping for user %q", username)
|
|
}
|
|
out := make([]string, 0, len(v))
|
|
for _, dir := range v {
|
|
dir = strings.TrimSpace(dir)
|
|
if dir == "" {
|
|
continue
|
|
}
|
|
clean := filepath.Clean(dir)
|
|
if clean == "." || clean == "/" {
|
|
continue
|
|
}
|
|
out = append(out, clean)
|
|
}
|
|
if len(out) == 0 {
|
|
return nil, fmt.Errorf("no valid mapping for user %q", username)
|
|
}
|
|
return out, nil
|
|
}
|