diff --git a/internal/piwigo/piwigotools/tree.go b/internal/piwigo/piwigotools/tree.go index 23cb82a..50e7127 100644 --- a/internal/piwigo/piwigotools/tree.go +++ b/internal/piwigo/piwigotools/tree.go @@ -3,17 +3,19 @@ package piwigotools import ( "path/filepath" "sort" + "strings" ) type Tree interface { - AddNode(string) Tree + Add(string) Tree + AddPath(string) Tree FlatView() chan string TreeView() chan string } type node struct { Name string - Children []*node + children map[string]*node } func NewTree() Tree { @@ -22,11 +24,41 @@ func NewTree() Tree { } } -func (t *node) AddNode(name string) Tree { - n := &node{Name: name} - t.Children = append(t.Children, n) +func (t *node) Add(name string) Tree { + if t.children == nil { + t.children = map[string]*node{} + } + n, ok := t.children[name] + if !ok { + n = &node{Name: name} + t.children[name] = n + } return n } +func (t *node) AddPath(path string) Tree { + n := Tree(t) + for _, name := range strings.Split(path, "/") { + n = n.Add(name) + } + return n +} + +func (t *node) Children() []*node { + childs := make([]*node, len(t.children)) + i := 0 + for _, n := range t.children { + childs[i] = n + i++ + } + sort.Slice(childs, func(i, j int) bool { + return childs[i].Name < childs[j].Name + }) + return childs +} + +func (t *node) HasChildren() bool { + return t.children != nil +} func (t *node) FlatView() (out chan string) { out = make(chan string) @@ -35,14 +67,11 @@ func (t *node) FlatView() (out chan string) { var flatten func(string, *node) flatten = func(path string, t *node) { - switch t.Children { - case nil: + switch t.HasChildren() { + case false: out <- path - default: - sort.Slice(t.Children, func(i, j int) bool { - return t.Children[i].Name < t.Children[j].Name - }) - for _, child := range t.Children { + case true: + for _, child := range t.Children() { flatten(filepath.Join(path, child.Name), child) } } @@ -66,9 +95,10 @@ func (t *node) TreeView() (out chan string) { var tree func(string, *node) tree = func(prefix string, t *node) { - for i, st := range t.Children { + children := t.Children() + for i, st := range children { switch i { - case len(t.Children) - 1: + case len(children) - 1: out <- prefix + treeEndChar + st.Name tree(prefix+treeAfterEndChar, st) case 0: @@ -83,7 +113,6 @@ func (t *node) TreeView() (out chan string) { out <- t.Name tree("", t) - }() return out } diff --git a/internal/piwigocli/images_list.go b/internal/piwigocli/images_list.go index 2d5b69a..9b6fafa 100644 --- a/internal/piwigocli/images_list.go +++ b/internal/piwigocli/images_list.go @@ -60,7 +60,6 @@ func (c *ImagesListCommand) Execute(args []string) error { } rootTree := piwigotools.NewTree() - cache := map[string]piwigotools.Tree{} bar := progressbar.Default(1, "listing") for page := 0; ; page++ { @@ -81,29 +80,14 @@ func (c *ImagesListCommand) Execute(args []string) error { for _, image := range resp.Images { for _, cat := range image.Categories { - categoryPath := strings.Split(categories[cat.Id].Name[len(rootCatName):], " / ") - if !filter.MatchString( - filepath.Join( - filepath.Join(categoryPath...), - image.Filename, - ), - ) { + filename := filepath.Join( + strings.ReplaceAll(categories[cat.Id].Name[len(rootCatName):], " / ", "/"), + image.Filename, + ) + if !filter.MatchString(filename) { continue } - curpath := "" - cur := rootTree - for _, path := range categoryPath { - curpath = filepath.Join(curpath, path) - node, ok := cache[curpath] - switch ok { - case true: - cur = node - case false: - cur = cur.AddNode(path) - cache[curpath] = cur - } - } - cur.AddNode(image.Filename) + rootTree.AddPath(filename) } bar.Add(1) }