95 lines
1.7 KiB
Go
95 lines
1.7 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|