package main import ( "encoding/json" "flag" "fmt" "os" "path/filepath" "xinu.tv/email" "github.com/golang/glog" ) var ( saveFile = flag.String("save", "", "filename to store unread status.") loadFile = flag.String("load", "", "filename to load unread status.") maildir = flag.String("maildir", "", "Maildir root") ) type Status struct { Hash string `json:"hash"` Path string `json:"path,omitempthashy"` Unread bool `json:"unread,omitempty"` } type Messages []Status func (m *Messages) hashMail(path string, info os.FileInfo, err error) error { if info.IsDir() { return nil } r, err := os.Open(path) if err != nil { glog.Fatal(err) } headers := []string{"to", "from", "cc", "date", "subject"} h, err := email.Hash(r, headers) if err != nil { glog.Errorln(path, err) return nil } md := email.NewInfo(path) //fmt.Printf("%x %s\n", h.Sum(nil), path) *m = append(*m, Status{ Path: path, Hash: fmt.Sprintf("%x", h.Sum(nil)), Unread: !md.Seen, }) return nil } func (m *Messages) SaveStatus(maildir, saveFile string) error { if err := filepath.Walk(maildir, m.hashMail); err != nil { return err } b, err := json.MarshalIndent(m, "", " ") if err != nil { return err } f, err := os.Create(saveFile) if err != nil { return err } defer f.Close() n, err := f.Write(b) if err != nil { return err } if n != len(b) { return fmt.Errorf("Short write of save status: wrote %d of %d", n, len(b)) } return nil } func main() { defer glog.Flush() flag.Parse() m := Messages{} if *maildir == "" { glog.Fatal("Must specify Maildir with -maildir") } if *saveFile != "" { if err := m.SaveStatus(*maildir, *saveFile); err != nil { glog.Fatal(err) } } }