package main import ( "encoding/json" "fmt" "log" "strings" "time" "github.com/boltdb/bolt" "github.com/sergi/go-diff/diffmatchpatch" ) var db *bolt.DB var open bool // Open to create the database and open func Open(filename string) error { var err error config := &bolt.Options{Timeout: 30 * time.Second} db, err = bolt.Open(filename, 0600, config) if err != nil { fmt.Println("Opening BoltDB timed out") log.Fatal(err) } open = true return nil } // Close database func Close() { open = false db.Close() } // Data for storing in DB type CowyoData struct { Title string CurrentText string Diffs []string Timestamps []string } func hasPassword(title string) (bool, error) { title = strings.ToLower(title) if !open { return false, fmt.Errorf("db must be opened before loading!") } hasPassword := false err := db.View(func(tx *bolt.Tx) error { var err error b := tx.Bucket([]byte("datas")) if b == nil { return fmt.Errorf("db must be opened before loading!") } k := []byte(title) val := b.Get(k) if val == nil { return nil } var p CowyoData err = p.decode(val) if err != nil { return err } for _, line := range strings.Split(p.CurrentText, "\n") { if strings.Contains(line, "<") == true && strings.Contains(line, ">") == true && strings.Contains(line, "user") == true && strings.Contains(line, "password") == true && strings.Contains(line, "public") == true { hasPassword = true } } return nil }) if err != nil { fmt.Printf("Could not get CowyoData: %s", err) return false, err } return hasPassword, nil } func getCurrentText(title string) string { title = strings.ToLower(title) currentText := "" if !open { return currentText } err := db.View(func(tx *bolt.Tx) error { var err error b := tx.Bucket([]byte("datas")) if b == nil { return fmt.Errorf("db must be opened before loading!") } k := []byte(title) val := b.Get(k) if val == nil { return nil } var p CowyoData err = p.decode(val) if err != nil { return err } currentText = p.CurrentText return nil }) if err != nil { fmt.Printf("Could not get CowyoData: %s", err) } return currentText } func (p *CowyoData) load(title string) error { title = strings.ToLower(title) if !open { return fmt.Errorf("db must be opened before loading!") } err := db.View(func(tx *bolt.Tx) error { var err error b := tx.Bucket([]byte("datas")) if b == nil { return nil } k := []byte(title) val := b.Get(k) if val == nil { // make new one p.Title = title p.CurrentText = "" p.Diffs = []string{} p.Timestamps = []string{} return nil } err = p.decode(val) if err != nil { return err } return nil }) if err != nil { fmt.Printf("Could not get CowyoData: %s", err) return err } return nil } func (p *CowyoData) save(newText string) error { if !open { return fmt.Errorf("db must be opened before saving") } err := db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte("datas")) if err != nil { return fmt.Errorf("create bucket: %s", err) } // find diffs dmp := diffmatchpatch.New() diffs := dmp.DiffMain(p.CurrentText, newText, true) delta := dmp.DiffToDelta(diffs) p.CurrentText = newText p.Timestamps = append(p.Timestamps, time.Now().String()) p.Diffs = append(p.Diffs, delta) enc, err := p.encode() if err != nil { return fmt.Errorf("could not encode CowyoData: %s", err) } err = bucket.Put([]byte(p.Title), enc) return err }) return err } func (p *CowyoData) encode() ([]byte, error) { enc, err := json.Marshal(p) if err != nil { return nil, err } return enc, nil } func (p *CowyoData) decode(data []byte) error { err := json.Unmarshal(data, &p) if err != nil { return err } return nil }