You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
1.5 KiB
Go
80 lines
1.5 KiB
Go
package operation
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/aziis98/cabret"
|
|
"github.com/iancoleman/strcase"
|
|
)
|
|
|
|
func init() {
|
|
registerType("categorize", &Categorize{})
|
|
}
|
|
|
|
type Categorize struct {
|
|
Key string
|
|
}
|
|
|
|
func (op *Categorize) Load(config map[string]any) error {
|
|
{
|
|
v, ok := config["key"]
|
|
if !ok {
|
|
return fmt.Errorf(`missing "key" field`)
|
|
}
|
|
key, ok := v.(string)
|
|
if !ok {
|
|
return fmt.Errorf(`expected string but got "%v" of type %T`, v, v)
|
|
}
|
|
|
|
op.Key = key
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (op *Categorize) ProcessList(contents []cabret.Content) ([]cabret.Content, error) {
|
|
key := strcase.ToCamel(op.Key)
|
|
|
|
categories := map[string][]cabret.Content{}
|
|
|
|
for _, content := range contents {
|
|
v, ok := content.Metadata[key]
|
|
if !ok {
|
|
log.Printf(`[operation.Categorize] item has no categories`)
|
|
continue
|
|
}
|
|
|
|
cats, ok := v.([]any)
|
|
if !ok {
|
|
return nil, fmt.Errorf(`expected a list but got "%v" of type %T`, v, v)
|
|
}
|
|
|
|
for _, v := range cats {
|
|
cat, ok := v.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf(`expected a string but got "%v" of type %T`, v, v)
|
|
}
|
|
|
|
log.Printf(`[operation.Categorize] found item with category "%s"`, cat)
|
|
|
|
categories[cat] = append(categories[cat], content)
|
|
}
|
|
}
|
|
|
|
result := []cabret.Content{}
|
|
for name, contents := range categories {
|
|
log.Printf(`[operation.Categorize] generating category with %v item(s)`, len(contents))
|
|
|
|
result = append(result, cabret.Content{
|
|
Type: "metadata-only",
|
|
Metadata: cabret.Map{
|
|
"Category": name,
|
|
"Items": contents,
|
|
},
|
|
})
|
|
}
|
|
|
|
return result, nil
|
|
}
|