inbox/inbox.go
Rama master · réplica de lectura del repositorio original.
package inbox
import (
"os"
"os/signal"
"syscall"
"time"
"github.com/dominicgisler/imap-spam-cleaner/app"
"github.com/dominicgisler/imap-spam-cleaner/database"
"github.com/dominicgisler/imap-spam-cleaner/imap"
"github.com/dominicgisler/imap-spam-cleaner/logx"
"github.com/dominicgisler/imap-spam-cleaner/provider"
"github.com/go-co-op/gocron/v2"
)
func Schedule(ctx app.Context) {
s, err := gocron.NewScheduler()
if err != nil {
logx.Errorf("Could not create scheduler: %v", err)
return
}
for i, inbox := range ctx.Config.Inboxes {
logx.Infof("Scheduling inbox %s (%s)", inbox.Username, inbox.Schedule)
prov, ok := ctx.Config.Providers[inbox.Provider]
if !ok {
logx.Errorf("Invalid provider %s for inbox %d", inbox.Provider, i)
continue
}
if _, err = s.NewJob(
gocron.CronJob(inbox.Schedule, false),
gocron.NewTask(processInbox, ctx, inbox, prov),
gocron.WithSingletonMode(gocron.LimitModeReschedule),
); err != nil {
logx.Errorf("Could not schedule inbox %s (%s): %v", inbox.Username, inbox.Schedule, err)
}
}
s.Start()
ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
sig := <-ch
logx.Debugf("Received %s, shutting down", sig.String())
if err = s.Shutdown(); err != nil {
logx.Errorf("Could not shutdown scheduler: %v ", err)
}
}
func RunAllInboxes(ctx app.Context) {
for i, inbox := range ctx.Config.Inboxes {
logx.Infof("Processing inbox %s", inbox.Username)
prov, ok := ctx.Config.Providers[inbox.Provider]
if !ok {
logx.Errorf("Invalid provider %s for inbox %d", inbox.Provider, i)
continue
}
processInbox(ctx, inbox, prov)
}
}
func processInbox(ctx app.Context, inbox app.Inbox, prov app.Provider) {
var err error
var msgs []imap.Message
var p provider.Provider
var im *imap.Imap
var n int
var run database.Run
logx.Infof("Handling %s", inbox.Username)
run.StartedAt = time.Now()
run.Inbox = inbox.Username
if im, err = imap.New(inbox); err != nil {
logx.Errorf("Could not load imap: %v\n", err)
return
}
if msgs, err = im.LoadMessages(); err != nil {
logx.Errorf("Could not load messages: %v\n", err)
im.Close()
return
}
logx.Infof("Loaded %d messages", len(msgs))
run.MessageCount = len(msgs)
p, err = provider.New(prov.Type)
if err != nil {
logx.Errorf("Could not load provider: %v\n", err)
im.Close()
return
}
if err = p.Init(prov.Config); err != nil {
logx.Errorf("Could not init provider: %v\n", err)
im.Close()
return
}
moved := 0
for _, m := range msgs {
if wl, ok := ctx.Config.Whitelists[inbox.Whitelist]; ok {
trustedSender := false
for _, rgx := range wl {
if rgx.Match([]byte(m.From)) {
trustedSender = true
break
}
}
if trustedSender {
logx.Debugf("Skipping message #%d (%s) because of trusted sender (%s)", m.UID, m.Subject, m.From)
run.SkippedCount++
continue
}
}
if n, err = p.Analyze(m); err != nil {
logx.Errorf("Could not analyze message #%d (%s): %v\n", m.UID, m.Subject, err)
run.FailedCount++
continue
}
logx.Debugf("Spam score of message #%d (%s): %d/100", m.UID, m.Subject, n)
if n >= inbox.MinScore {
if ctx.Options.AnalyzeOnly {
logx.Debugf("Analyze only mode, not moving message #%d (%s)", m.UID, m.Subject)
continue
}
if inbox.MarkRead {
if err = im.MarkRead(m.UID); err != nil {
logx.Errorf("Could not mark message #%d (%s) read: %v\n", m.UID, m.Subject, err)
}
}
if err = im.MoveMessage(m.UID, inbox.Spam); err != nil {
logx.Errorf("Could not move message (%s): %v\n", m.Subject, err)
continue
}
moved++
}
}
logx.Infof("Moved %d messages", moved)
run.MovedCount = moved
im.Close()
if !ctx.Options.AnalyzeOnly {
run.FinishedAt = time.Now()
if err = database.AddRun(&run); err != nil {
logx.Errorf("Could not save run: %v\n", err)
}
}
}