From d1814742fa888b775fcaea2dfb0e4fdcf8b4ce27 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Wed, 29 Dec 2021 18:24:10 +0100 Subject: [PATCH] tree map list of files, then flatview --- internal/piwigo/piwigotools/tree.go | 53 +++++++++++ internal/piwigocli/images_list.go | 135 ++++++++++++++++------------ 2 files changed, 131 insertions(+), 57 deletions(-) create mode 100644 internal/piwigo/piwigotools/tree.go diff --git a/internal/piwigo/piwigotools/tree.go b/internal/piwigo/piwigotools/tree.go new file mode 100644 index 0000000..447ebd9 --- /dev/null +++ b/internal/piwigo/piwigotools/tree.go @@ -0,0 +1,53 @@ +package piwigotools + +import ( + "path/filepath" + "sort" +) + +type Tree interface { + AddNode(string) Tree + FlatView() chan string +} + +type node struct { + Name string + Children []*node +} + +func NewTree() Tree { + return &node{ + Name: ".", + } +} + +func (t *node) AddNode(name string) Tree { + n := &node{Name: name} + t.Children = append(t.Children, n) + return n +} + +func (t *node) FlatView() (out chan string) { + out = make(chan string) + go func() { + defer close(out) + var flatten func(string, *node) + + flatten = func(path string, t *node) { + switch t.Children { + case nil: + 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 { + flatten(filepath.Join(path, child.Name), child) + } + } + } + + flatten("", t) + }() + return out +} diff --git a/internal/piwigocli/images_list.go b/internal/piwigocli/images_list.go index 43cc3c0..4ff0718 100644 --- a/internal/piwigocli/images_list.go +++ b/internal/piwigocli/images_list.go @@ -3,8 +3,8 @@ package piwigocli import ( "fmt" "net/url" + "path/filepath" "regexp" - "sort" "strings" "github.com/celogeek/piwigo-cli/internal/piwigo" @@ -59,7 +59,9 @@ func (c *ImagesListCommand) Execute(args []string) error { filter = regexp.MustCompile("(?i)" + c.Filter) } - var results []string + rootTree := piwigotools.NewTree() + cache := map[string]piwigotools.Tree{} + bar := progressbar.Default(1, "listing") for page := 0; ; page++ { var resp ImagesListResult @@ -78,16 +80,30 @@ func (c *ImagesListCommand) Execute(args []string) error { } for _, image := range resp.Images { - for _, category := range image.Categories { - cat, ok := categories[category.Id] - if !ok { + for _, cat := range image.Categories { + categoryPath := strings.Split(categories[cat.Id].Name[len(rootCatName):], " / ") + if !filter.MatchString( + filepath.Join( + filepath.Join(categoryPath...), + image.Filename, + ), + ) { continue } - catName := strings.ReplaceAll(cat.Name[len(rootCatName):], " / ", "/") - filename := fmt.Sprintf("%s/%s", catName, image.Filename) - if filter.MatchString(filename) { - results = append(results, filename) + 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) } bar.Add(1) } @@ -98,61 +114,66 @@ func (c *ImagesListCommand) Execute(args []string) error { } bar.Close() - sort.Strings(results) - - if !c.Tree { - for _, r := range results { - fmt.Println(r) - } - return nil + results := rootTree.FlatView() + for filename := range results { + fmt.Println(filename) } - type Tree struct { - Name string - Children []*Tree - } + // sort.Strings(results) - treeMap := make(map[string]*Tree) - treeMap[""] = &Tree{Name: "."} + // if !c.Tree { + // for _, r := range results { + // fmt.Println(r) + // } + // return nil + // } - for _, r := range results { - parentpath := "" - fullpath := "" - for _, s := range strings.Split(r, "/") { - parentpath = fullpath - fullpath += s + "/" - if _, ok := treeMap[fullpath]; ok { - continue - } - treeMap[fullpath] = &Tree{Name: s} - treeMap[parentpath].Children = append(treeMap[parentpath].Children, treeMap[fullpath]) - } - } + // type Tree struct { + // Name string + // Children []*Tree + // } - var treeView func(*Tree, string) - treeLinkChar := "│ " - treeMidChar := "├── " - treeEndChar := "└── " - treeAfterEndChar := " " + // treeMap := make(map[string]*Tree) + // treeMap[""] = &Tree{Name: "."} - treeView = func(t *Tree, prefix string) { - for i, st := range t.Children { - switch i { - case len(t.Children) - 1: - fmt.Println(prefix + treeEndChar + st.Name) - treeView(st, prefix+treeAfterEndChar) - case 0: - fmt.Println(prefix + treeMidChar + st.Name) - treeView(st, prefix+treeLinkChar) - default: - fmt.Println(prefix + treeMidChar + st.Name) - treeView(st, prefix+treeLinkChar) - } - } - } + // for _, r := range results { + // parentpath := "" + // fullpath := "" + // for _, s := range strings.Split(r, "/") { + // parentpath = fullpath + // fullpath += s + "/" + // if _, ok := treeMap[fullpath]; ok { + // continue + // } + // treeMap[fullpath] = &Tree{Name: s} + // treeMap[parentpath].Children = append(treeMap[parentpath].Children, treeMap[fullpath]) + // } + // } - fmt.Println(treeMap[""].Name) - treeView(treeMap[""], "") + // var treeView func(*Tree, string) + // treeLinkChar := "│ " + // treeMidChar := "├── " + // treeEndChar := "└── " + // treeAfterEndChar := " " + + // treeView = func(t *Tree, prefix string) { + // for i, st := range t.Children { + // switch i { + // case len(t.Children) - 1: + // fmt.Println(prefix + treeEndChar + st.Name) + // treeView(st, prefix+treeAfterEndChar) + // case 0: + // fmt.Println(prefix + treeMidChar + st.Name) + // treeView(st, prefix+treeLinkChar) + // default: + // fmt.Println(prefix + treeMidChar + st.Name) + // treeView(st, prefix+treeLinkChar) + // } + // } + // } + + // fmt.Println(treeMap[""].Name) + // treeView(treeMap[""], "") return nil }