navidrome/model/smartplaylist.go

107 lines
1.9 KiB
Go

package model
import (
"encoding/json"
"errors"
)
type SmartPlaylist struct {
RuleGroup
Order string `json:"order,omitempty"`
Limit int `json:"limit,omitempty"`
}
type RuleGroup struct {
Combinator string `json:"combinator"`
Rules Rules `json:"rules"`
}
type Rules []IRule
type IRule interface {
Fields() []string
}
type Rule struct {
Field string `json:"field"`
Operator string `json:"operator"`
Value interface{} `json:"value,omitempty"`
}
func (r Rule) Fields() []string {
return []string{r.Field}
}
func (rg RuleGroup) Fields() []string {
var result []string
unique := map[string]struct{}{}
for _, r := range rg.Rules {
for _, f := range r.Fields() {
if _, added := unique[f]; !added {
result = append(result, f)
unique[f] = struct{}{}
}
}
}
return result
}
func (rs *Rules) UnmarshalJSON(data []byte) error {
var rawRules []json.RawMessage
if err := json.Unmarshal(data, &rawRules); err != nil {
return err
}
rules := make(Rules, len(rawRules))
for i, rawRule := range rawRules {
var r Rule
if err := json.Unmarshal(rawRule, &r); err == nil && r.Field != "" {
rules[i] = r
continue
}
var g RuleGroup
if err := json.Unmarshal(rawRule, &g); err == nil && g.Combinator != "" {
rules[i] = g
continue
}
return errors.New("Invalid json. Neither a Rule nor a RuleGroup: " + string(rawRule))
}
*rs = rules
return nil
}
var SmartPlaylistFields = []string{
"title",
"album",
"artist",
"albumartist",
"albumartwork",
"tracknumber",
"discnumber",
"year",
"size",
"compilation",
"dateadded",
"datemodified",
"discsubtitle",
"comment",
"lyrics",
"sorttitle",
"sortalbum",
"sortartist",
"sortalbumartist",
"albumtype",
"albumcomment",
"catalognumber",
"filepath",
"filetype",
"duration",
"bitrate",
"bpm",
"channels",
"genre",
"loved",
"lastplayed",
"playcount",
"rating",
}