2017-05-10 03:45:11 +00:00
|
|
|
package sisyphus
|
|
|
|
|
|
|
|
import (
|
2017-05-18 19:21:46 +00:00
|
|
|
log "github.com/sirupsen/logrus"
|
2017-05-10 03:45:11 +00:00
|
|
|
|
|
|
|
"github.com/boltdb/bolt"
|
|
|
|
"github.com/retailnext/hllpp"
|
|
|
|
)
|
|
|
|
|
2017-05-14 21:16:04 +00:00
|
|
|
// learnWordlist adds the mail key to the respective word's list
|
|
|
|
func (m *Mail) learnWordlist(w string, db *bolt.DB) error {
|
2017-05-10 03:45:11 +00:00
|
|
|
wordKey := "Good"
|
|
|
|
if m.Junk {
|
|
|
|
wordKey = "Junk"
|
|
|
|
}
|
|
|
|
|
2017-05-14 21:16:04 +00:00
|
|
|
err := db.Update(func(tx *bolt.Tx) (err error) {
|
|
|
|
b := tx.Bucket([]byte("Wordlists"))
|
|
|
|
|
|
|
|
bucket := b.Bucket([]byte(wordKey))
|
|
|
|
wordRaw := bucket.Get([]byte(w))
|
|
|
|
var word *hllpp.HLLPP
|
|
|
|
if len(wordRaw) == 0 {
|
|
|
|
word = hllpp.New()
|
|
|
|
} else {
|
|
|
|
word, err = hllpp.Unmarshal(wordRaw)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2017-05-10 03:45:11 +00:00
|
|
|
}
|
2017-05-14 21:16:04 +00:00
|
|
|
}
|
2017-05-10 03:45:11 +00:00
|
|
|
|
2017-05-14 21:16:04 +00:00
|
|
|
word.Add([]byte(m.Key))
|
2017-05-10 03:45:11 +00:00
|
|
|
|
2017-05-14 21:16:04 +00:00
|
|
|
err = bucket.Put([]byte(w), word.Marshal())
|
2017-05-10 03:45:11 +00:00
|
|
|
|
2017-05-14 21:16:04 +00:00
|
|
|
return err
|
|
|
|
})
|
2017-05-10 03:45:11 +00:00
|
|
|
|
2017-05-14 21:16:04 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// learnStatistics adds the mail key to the respective word's list
|
|
|
|
func (m *Mail) learnStatistics(db *bolt.DB) error {
|
|
|
|
err := db.Update(func(tx *bolt.Tx) (err error) {
|
2017-05-10 03:45:11 +00:00
|
|
|
p := tx.Bucket([]byte("Statistics"))
|
|
|
|
|
|
|
|
key := "ProcessedGood"
|
|
|
|
if m.Junk {
|
|
|
|
key = "ProcessedJunk"
|
|
|
|
}
|
|
|
|
|
|
|
|
keyRaw := p.Get([]byte(key))
|
|
|
|
var counter *hllpp.HLLPP
|
|
|
|
if len(keyRaw) == 0 {
|
|
|
|
counter = hllpp.New()
|
|
|
|
} else {
|
|
|
|
counter, err = hllpp.Unmarshal(keyRaw)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
counter.Add([]byte(m.Key))
|
|
|
|
|
|
|
|
err = p.Put([]byte(key), counter.Marshal())
|
|
|
|
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
2017-05-14 21:16:04 +00:00
|
|
|
|
|
|
|
// Learn adds the the mail key to the list of words using hyper log log algorithm.
|
2017-06-05 13:33:32 +00:00
|
|
|
func (m *Mail) Learn(db *bolt.DB, dir Maildir) (err error) {
|
2017-05-14 21:16:04 +00:00
|
|
|
|
2017-05-23 20:43:17 +00:00
|
|
|
log.WithFields(log.Fields{
|
2017-06-05 13:33:32 +00:00
|
|
|
"dir": string(dir),
|
2017-05-23 20:43:17 +00:00
|
|
|
"mail": m.Key,
|
|
|
|
}).Info("Learn mail")
|
2017-05-14 21:16:04 +00:00
|
|
|
|
2017-06-05 13:33:32 +00:00
|
|
|
err = m.Load(dir)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-05-14 21:16:04 +00:00
|
|
|
list, err := m.cleanWordlist()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Learn words
|
|
|
|
for _, val := range list {
|
2017-09-17 17:17:43 +00:00
|
|
|
err = m.learnWordlist(val, db)
|
2017-05-14 21:16:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the statistics counter
|
|
|
|
err = m.learnStatistics(db)
|
2017-09-16 22:56:17 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = m.Unload(dir)
|
2017-05-14 21:16:04 +00:00
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|