Implement automatic learning after predefined duration

master
Carlo Strub 7 years ago
parent 44c158d2ef
commit 2216b2a929

@ -250,18 +250,12 @@ func (m *Mail) cleanWordlist() (w []string, err error) {
return w, err
}
// LoadMails creates missing directories and then loads all mails from a given
// slice of Maildirs
// LoadMails loads all mails from a given slice of Maildirs
func LoadMails(d []Maildir) (mails map[Maildir][]*Mail, err error) {
mails = make(map[Maildir][]*Mail)
// create missing directories and write index
for _, val := range d {
err := val.CreateDirs()
if err != nil {
return mails, err
}
var m []*Mail
m, err = val.Index()
if err != nil {
@ -273,3 +267,17 @@ func LoadMails(d []Maildir) (mails map[Maildir][]*Mail, err error) {
return mails, nil
}
// LoadMaildirs creates Maildirs and required directories, if missing
func LoadMaildirs(d []Maildir) (err error) {
// create missing directories and write index
for _, val := range d {
err := val.CreateDirs()
if err != nil {
return err
}
}
return nil
}

@ -6,7 +6,9 @@ import (
"os/signal"
"strings"
"syscall"
"time"
"github.com/boltdb/bolt"
"github.com/fsnotify/fsnotify"
log "github.com/sirupsen/logrus"
@ -45,6 +47,9 @@ func main() {
var pidfile *string
pidfile = new(string)
var learnafter *string
learnafter = new(string)
app.Flags = []cli.Flag{
cli.StringSliceFlag{
@ -60,6 +65,13 @@ func main() {
Usage: "Location of PID file",
Destination: pidfile,
},
cli.StringFlag{
Name: "learn",
Value: "12h",
EnvVar: "SISYPHUS_DURATION",
Usage: "Time interval between to learn cycles",
Destination: learnafter,
},
}
app.Commands = []cli.Command{
@ -122,12 +134,12 @@ func main() {
maildirs = append(maildirs, sisyphus.Maildir(val))
}
// Load all mails
mails, err := sisyphus.LoadMails(maildirs)
// Create missing Maildirs
err := sisyphus.LoadMaildirs(maildirs)
if err != nil {
log.WithFields(log.Fields{
"err": err,
}).Fatal("Cannot load mails")
}).Fatal("Cannot load maildirs")
}
// Open all databases
@ -139,21 +151,18 @@ func main() {
}
defer sisyphus.CloseDatabases(dbs)
// Learn at startup
for _, d := range maildirs {
db := dbs[d]
m := mails[d]
for _, val := range m {
err := val.Learn(db, d)
// Learn at startup and regular intervals
go func() {
for {
duration, err := time.ParseDuration(*learnafter)
if err != nil {
log.WithFields(log.Fields{
"err": err,
"mail": val.Key,
}).Warning("Cannot learn mail")
log.Fatal("Cannot parse duration for learning intervals.")
}
learn(maildirs, dbs)
time.Sleep(duration)
}
}
log.Info("All mails learned")
}()
// Classify whenever a mail arrives in "new"
watcher, err := fsnotify.NewWatcher()
@ -253,3 +262,28 @@ func main() {
app.Run(os.Args)
}
func learn(maildirs []sisyphus.Maildir, dbs map[sisyphus.Maildir]*bolt.DB) {
mails, err := sisyphus.LoadMails(maildirs)
if err != nil {
log.WithFields(log.Fields{
"err": err,
}).Fatal("Cannot load mails")
}
for _, d := range maildirs {
db := dbs[d]
m := mails[d]
for _, val := range m {
err := val.Learn(db, d)
if err != nil {
log.WithFields(log.Fields{
"err": err,
"mail": val.Key,
}).Warning("Cannot learn mail")
}
}
}
log.Info("All mails learned")
return
}

Loading…
Cancel
Save