diff --git a/configuration.go b/configuration.go new file mode 100644 index 0000000..b757b15 --- /dev/null +++ b/configuration.go @@ -0,0 +1,18 @@ +package main + +type MailBoxConfiguration struct { + Server string + Port int + User string + Password string + SSL string +} +type BlogConfiguration struct { + Title string + MailBox string + WWWRoot string +} +type Configuration struct { + MailBoxes map[string]MailBoxConfiguration + Blogs map[string]BlogConfiguration +} diff --git a/imap_handler.go b/imap_handler.go index 4982fa1..88c2daf 100644 --- a/imap_handler.go +++ b/imap_handler.go @@ -1,18 +1,23 @@ package main import ( + "bytes" + "io" "log" "mime" + "github.com/emersion/go-imap/v2" "github.com/emersion/go-imap/v2/imapclient" "github.com/emersion/go-message/charset" + "github.com/emersion/go-message/mail" ) type MailBox struct { - Server string - User string - Password string - Client *imapclient.Client + Server string + User string + Password string + InBox string + Client *imapclient.Client } func (mb *MailBox) ListMessages() (string, error) { @@ -29,16 +34,71 @@ func (mb *MailBox) Connect() error { log.Println("Error connnecting to", mb.Server, ":", err) return err } - log.Println("Connected") - err = mb.Client.Login(mb.User, mb.Password).Wait() - if err != nil { - log.Fatal("failed to login:", err) - } - log.Println("Logged in") + log.Println("Connected") + err = mb.Client.Login(mb.User, mb.Password).Wait() + if err != nil { + log.Fatal("failed to login:", err) + } + log.Println("Logged in") + mailBoxes, err := mb.Client.List("", "%", nil).Collect() + if err != nil { + log.Fatal("Error listing mailboxes", err) + } + for _, mbox := range mailBoxes { + log.Println("mailbox:", mbox.Mailbox) + } + inbox, err := mb.Client.Select(mb.InBox, nil).Wait() + if err != nil { + log.Fatal("Error selecting mailbox:", mb.InBox, err) + } + log.Println("Inbox has", inbox.NumMessages, "messages") + + for i := uint32(0); i <= inbox.NumMessages; i++ { + seqSet := imap.SeqSetNum(i) + bodySection := &imap.FetchItemBodySection{} + fetchOptions := &imap.FetchOptions{ + Envelope: true, + BodySection: []*imap.FetchItemBodySection{bodySection}, + } + messages, err := mb.Client.Fetch(seqSet, fetchOptions).Collect() + if err != nil { + log.Fatal("Error fetching mails:", err) + } + for _, msg := range messages { + log.Println(msg.Envelope.From) + log.Println(msg.Envelope.To) + log.Println(msg.Envelope.Date) + log.Println(msg.Envelope.Subject) + + section := msg.FindBodySection(bodySection) + ioReader := bytes.NewReader(section) + mailReader, err := mail.CreateReader(ioReader) + if err != nil { + log.Fatalf("failed to create mail reader: %v", err) + } + for { + part, err := mailReader.NextPart() + if err == io.EOF { + log.Println("------------") + break + } else if err != nil { + log.Fatal("Error reading part", err) + } + switch header := part.Header.(type) { + case *mail.AttachmentHeader: + filename, _ := header.Filename() + log.Println("Attachment:", filename) + case *mail.InlineHeader: + body, _ := io.ReadAll(part.Body) + log.Println(string(body)) + } + } + } + } return nil } func (mb *MailBox) Close() { - mb.Client.Close() + mb.Client.Close() } diff --git a/mailblog.go b/mailblog.go index f850b6d..484ecfc 100644 --- a/mailblog.go +++ b/mailblog.go @@ -3,8 +3,9 @@ package main import ( "log" "net/http" - "net/url" + "net/url" "os" + "strings" ) func slash(w http.ResponseWriter, r *http.Request) { @@ -14,16 +15,15 @@ func slash(w http.ResponseWriter, r *http.Request) { func main() { var mb MailBox - - - url, err := url.Parse(os.Getenv("MAILBOX")) - if err != nil { - log.Fatal("Bad parameter MAILBOX:", os.Getenv("MAILBOX"), "(", err, ")") - } + url, err := url.Parse(os.Getenv("MAILBOX")) + if err != nil { + log.Fatal("Bad parameter MAILBOX:", os.Getenv("MAILBOX"), "(", err, ")") + } mb.Server = url.Host - mb.User = os.Getenv("IMAP_USER") - mb.Password = os.Getenv("IMAP_PASSWORD") + mb.User = os.Getenv("IMAP_USER") + mb.Password = os.Getenv("IMAP_PASSWORD") + mb.InBox, _ = strings.CutPrefix(url.Path, "/") err = mb.Connect() if err != nil { log.Fatal(err) @@ -32,11 +32,11 @@ func main() { if err != nil { log.Fatal(err) } - + log.Println(msg) - mb.Close() - return + mb.Close() + return http.HandleFunc("/", slash) http.ListenAndServe("0.0.0.0:8080", nil) }