diff --git a/cmd/rofi.go b/cmd/rofi.go index 1aff750..436954e 100644 --- a/cmd/rofi.go +++ b/cmd/rofi.go @@ -6,6 +6,7 @@ package cmd import ( "errors" "fmt" + "sort" "strings" "git.bullercodeworks.com/brian/keepass-cli/models" @@ -55,15 +56,33 @@ func runRofi(cmd *cobra.Command, args []string) error { path = append(path, strings.Split(args[i], "/")...) } + var freqs *models.Frequencies if len(path) == 0 || argIsPw { list := db.GetAllEntriesFromRoot() + var printList []string for i := range list { - fmt.Println(strings.Join(list[i], "/")) + printList = append(printList, strings.Join(list[i], "/")) + } + + freqs, err = models.LoadFrequencies() + if err == nil { + sort.Slice(printList, func(i, j int) bool { + return freqs.GetTimes(printList[i]) > freqs.GetTimes(printList[j]) + }) + } + for i := range printList { + fmt.Println(printList[i]) } } else { if entry, entryErr := db.FindEntryFromRoot(path); entryErr != nil { return entryErr } else { + freqPath := strings.Join(path, "/") + freqs, err = models.LoadFrequencies() + if err == nil { + freqs.IncrementEntry(freqPath) + freqs.Save() + } return util.WriteToClipboard(entry.GetPassword()) } } diff --git a/cmd/test.go b/cmd/test.go index 51cb981..b916ac8 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -4,6 +4,7 @@ Copyright © 2024 Brian Buller package cmd import ( + "git.bullercodeworks.com/brian/keepass-cli/models" "github.com/spf13/cobra" ) @@ -19,6 +20,7 @@ func init() { } func runTestCmd(cmd *cobra.Command, args []string) error { + models.LoadFrequencies() /* var db *models.KeePassDB pass, err := util.PromptUserForPassword("Master Password") diff --git a/models/frequencies.go b/models/frequencies.go new file mode 100644 index 0000000..e7e627f --- /dev/null +++ b/models/frequencies.go @@ -0,0 +1,99 @@ +package models + +import ( + "bytes" + "io/ioutil" + "strconv" + "strings" + + "github.com/spf13/viper" +) + +type EntryFrequency struct { + Times int + Entry string +} + +func (ef *EntryFrequency) ToBytes() []byte { + var ret []byte + ret = append(ret, []byte(strconv.Itoa(ef.Times))...) + ret = append(ret, byte('\t')) + ret = append(ret, []byte(ef.Entry)...) + return ret +} + +func FromBytes(bts []byte) (*EntryFrequency, error) { + fields := bytes.Split(bts, []byte{'\t'}) + times, err := strconv.Atoi(string(fields[0])) + if err != nil { + return nil, err + } + return &EntryFrequency{ + Times: times, + Entry: string(fields[1]), + }, nil +} + +type Frequencies struct { + Entries []*EntryFrequency +} + +func LoadFrequencies() (*Frequencies, error) { + fl := viper.ConfigFileUsed() + fl = fl[:strings.LastIndex(fl, "/")+1] + "freq" + req := &Frequencies{} + b, err := ioutil.ReadFile(fl) + if err != nil { + err = req.Save() + if err != nil { + return nil, err + } + return req, nil + } + lines := bytes.Split(b, []byte{'\n'}) + for i := range lines { + var ef *EntryFrequency + ef, err = FromBytes(lines[i]) + if err == nil { + req.AddEntry(ef) + } + } + return req, nil +} + +func (f *Frequencies) AddEntry(ef *EntryFrequency) { + f.Entries = append(f.Entries, ef) +} + +func (f *Frequencies) GetTimes(entry string) int { + for i := range f.Entries { + if f.Entries[i].Entry == entry { + return f.Entries[i].Times + } + } + return 0 +} + +func (f *Frequencies) IncrementEntry(entry string) { + for i := range f.Entries { + if f.Entries[i].Entry == entry { + f.Entries[i].Times++ + return + } + } + f.Entries = append(f.Entries, &EntryFrequency{ + Times: 1, + Entry: entry, + }) +} + +func (f *Frequencies) Save() error { + fl := viper.ConfigFileUsed() + fl = fl[:strings.LastIndex(fl, "/")+1] + "freq" + var b []byte + for _, e := range f.Entries { + b = append(b, e.ToBytes()...) + b = append(b, byte('\n')) + } + return ioutil.WriteFile(fl, b, 0600) +}