add fzf selection

This commit is contained in:
Celogeek 2022-01-01 23:19:25 +01:00
parent 308017edb7
commit a48caa7fe4
Signed by: celogeek
GPG Key ID: E6B7BDCFC446233A
2 changed files with 78 additions and 2 deletions

View File

@ -4,6 +4,8 @@ import (
"fmt"
"net/url"
"os"
"regexp"
"sort"
"strings"
"github.com/celogeek/piwigo-cli/internal/piwigo"
@ -12,7 +14,8 @@ import (
)
type ImagesTagCommand struct {
Id int `short:"i" long:"id" description:"image id to tag" required:"true"`
Id int `short:"i" long:"id" description:"image id to tag" required:"true"`
ExcludeTags string `short:"x" long:"exclude" description:"exclude tag from selection"`
}
func (c *ImagesTagCommand) Execute(args []string) error {
@ -42,6 +45,10 @@ func (c *ImagesTagCommand) Execute(args []string) error {
return err
}
sort.Slice(tags.Tags, func(i, j int) bool {
return tags.Tags[i].Name < tags.Tags[j].Name
})
img, err := imgDetails.Preview(25)
if err != nil {
return err
@ -61,5 +68,42 @@ func (c *ImagesTagCommand) Execute(args []string) error {
t.SetOutputMirror(os.Stdout)
t.SetStyle(table.StyleLight)
t.Render()
var exclude *regexp.Regexp
if c.ExcludeTags != "" {
exclude = regexp.MustCompile(c.ExcludeTags)
}
sel, err := tags.Tags.Select(exclude)
if err != nil {
return err
}
fmt.Println("Selection:")
selIds := make([]string, len(sel))
for i, s := range sel {
selIds[i] = fmt.Sprint(s.Id)
fmt.Printf(" - %s\n", s.NameWithAgeAt(&imgDetails.DateCreation))
}
fmt.Println("")
fmt.Printf("Confirmed (Y/n)? ")
var answer string
fmt.Scanln(&answer)
switch answer {
case "", "y", "Y":
fmt.Println("Applying changes...")
data := &url.Values{}
data.Set("image_id", fmt.Sprint(c.Id))
data.Set("multiple_value_mode", "replace")
data.Set("tag_ids", strings.Join(selIds, ","))
if err := p.Post("pwg.images.setInfo", data, nil); err != nil {
return err
}
fmt.Println("Done!")
}
return nil
}

View File

@ -2,12 +2,17 @@ package piwigotools
import (
"fmt"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
)
type Tags []*Tag
type Tag struct {
Id int `json:"id"`
Id int `json:"id,string"`
Name string `json:"name"`
LastModified TimeResult `json:"lastmodified"`
Birthdate TimeResult `json:"birthdate"`
@ -31,3 +36,30 @@ func (t *Tag) NameWithAgeAt(createdAt *TimeResult) string {
}
return t.Name
}
func (t Tags) Select(exclude *regexp.Regexp) ([]*Tag, error) {
fzf := "fzf --multi --height=30% --border --layout=reverse -e --bind=esc:clear-query --with-nth 2 --delimiter=\"\t\""
cmd := exec.Command("sh", "-c", fzf)
cmd.Stderr = os.Stderr
in, _ := cmd.StdinPipe()
go func() {
defer in.Close()
for i, tag := range t {
if exclude != nil && exclude.MatchString(tag.Name) {
continue
}
in.Write([]byte(fmt.Sprintf("%d\t%s\n", i, tag.Name)))
}
}()
out, _ := cmd.Output()
rows := strings.Split(string(out), "\n")
selections := make([]*Tag, 0, len(rows))
for _, row := range rows {
i, err := strconv.Atoi(strings.Split(row, "\t")[0])
if err != nil {
continue
}
selections = append(selections, t[i])
}
return selections, nil
}