package main import ( "flag" "fmt" "log" "net/mail" "os" "path/filepath" "time" "github.com/luksen/maildir" notify "github.com/mqu/go-notify" fsnotify "gopkg.in/fsnotify.v1" ) var ( AppName = os.Args[0] Linger = 2 ) func init() { notify.Init(AppName) } func main() { flag.Parse() watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } done := make(chan bool) go func() { for { select { case event := <-watcher.Events: // 2014/12/12 21:18:08 event: "/home/vbatts/Maildir/INBOX/new/1418437088_0.3432.valse.usersys.redhat.com,U=478874,FMD5=7e33429f656f1e6e9d79b29c3f82c57e:2,": CREATE log.Println("event:", event) if event.Op == fsnotify.Create { func() { //Notify("new msg", filepath.Dir(filepath.Dir(event.Name))) fh, err := os.Open(event.Name) if err != nil { log.Println(err) return } msg, err := mail.ReadMessage(fh) if err != nil { log.Println(err) return } //fmt.Printf("%#v\n", msg.Header) Notify(filepath.Base(filepath.Dir(filepath.Dir(event.Name))), fmt.Sprintf("%s; From %s", msg.Header["Subject"][0], msg.Header["From"][0])) }() } if event.Op&fsnotify.Write == fsnotify.Write { log.Println("modified file:", event.Name) } case err := <-watcher.Errors: log.Println("error:", err) } } }() go func() { if err := Notify(AppName, "running ..."); err != nil { log.Println(err) } }() for _, arg := range flag.Args() { dirs, err := GetMailDirs(arg) if err != nil { log.Fatal(err) } for _, dirPath := range dirs { if err = watcher.Add(filepath.Join(dirPath, "new")); err != nil { log.Fatal(err) } dir := maildir.Dir(dirPath) keys, err := dir.Keys() if err != nil { log.Fatal(err) } u, err := dir.Unseen() if err != nil { log.Fatal(err) } fmt.Println(dir, len(keys), len(u)) } } if flag.NArg() == 0 { close(done) } <-done } func Notify(title, message string) error { hello := notify.NotificationNew(title, message, "mail-message-new") notify.NotificationSetTimeout(hello, 0) if err := notify.NotificationShow(hello); err != nil && len(err.Message()) > 0 { return fmt.Errorf("%s", err.Message()) } time.Sleep(time.Duration(Linger) * time.Second) if err := notify.NotificationClose(hello); err != nil && len(err.Message()) > 0 { return fmt.Errorf("%s", err.Message()) } return nil } func GetMailDirs(root string) ([]string, error) { dirs := []string{} err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err } base := filepath.Base(path) if !info.IsDir() || base == "cur" || base == "new" || base == "tmp" { return filepath.SkipDir } if b, err := IsMaildir(path); err == nil && b { dirs = append(dirs, path) } return nil }) if err != nil { return nil, err } return dirs, nil //return []string{root}, nil } func IsMaildir(path string) (bool, error) { curInfo, err := os.Stat(filepath.Join(path, "cur")) if err != nil { return false, err } tmpInfo, err := os.Stat(filepath.Join(path, "tmp")) if err != nil { return false, err } newInfo, err := os.Stat(filepath.Join(path, "new")) if err != nil { return false, err } return (curInfo != nil && tmpInfo != nil && newInfo != nil), nil }