120 lines
2.8 KiB
Go
Executable File
120 lines
2.8 KiB
Go
Executable File
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"mime"
|
|
"mime/multipart"
|
|
"net/mail"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitea.inhome.blapointe.com/local-sandbox/contact"
|
|
"gitea.inhome.blapointe.com/local/args"
|
|
)
|
|
|
|
type MultipartReaderReader struct {
|
|
buff []byte
|
|
r *multipart.Reader
|
|
}
|
|
|
|
func (mrr *MultipartReaderReader) Read(b []byte) (int, error) {
|
|
n := copy(b, mrr.buff)
|
|
mrr.buff = mrr.buff[n:]
|
|
for n < len(b) {
|
|
part, err := mrr.r.NextPart()
|
|
if err != nil {
|
|
return n, err
|
|
}
|
|
defer part.Close()
|
|
|
|
mrr.buff, err = io.ReadAll(part)
|
|
if err != nil {
|
|
return n, err
|
|
}
|
|
m := copy(b, mrr.buff)
|
|
mrr.buff = mrr.buff[m:]
|
|
n += m
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func main() {
|
|
emailer := contact.NewEmailer()
|
|
as := args.NewArgSet()
|
|
as.Append(args.STRING, "imap", "imap server:port", "imap.gmail.com:993")
|
|
as.Append(args.STRING, "pop3", "pop3 server:port", "")
|
|
as.Append(args.INT, "n", "limit (<1 for inf)", 10)
|
|
as.Append(args.STRING, "u", "username", emailer.From)
|
|
as.Append(args.STRING, "p", "password", emailer.Password)
|
|
as.Append(args.INT, "b", "dont read more than this many characters", 4096)
|
|
as.Append(args.BOOL, "json", "output as json", false)
|
|
if err := as.Parse(); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
emailer.IMAP = as.Get("imap").GetString()
|
|
emailer.POP3 = as.Get("pop3").GetString()
|
|
emailer.Limit = as.Get("n").GetInt()
|
|
emailer.From = as.GetString("u")
|
|
emailer.Password = as.GetString("p")
|
|
|
|
var msgs <-chan *mail.Message
|
|
var err error
|
|
if emailer.POP3 != "" {
|
|
msgs, err = emailer.ReadPOP3()
|
|
} else {
|
|
msgs, err = emailer.Read()
|
|
}
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
emails := make([]map[string]any, 0, emailer.Limit)
|
|
for msg := range msgs {
|
|
var r io.Reader
|
|
if n := int64(as.GetInt("b")); n >= 0 {
|
|
r = io.LimitReader(msg.Body, n)
|
|
} else if mediaType, params, _ := mime.ParseMediaType(msg.Header.Get("Content-Type")); strings.HasPrefix(mediaType, "multipart/") {
|
|
r = &MultipartReaderReader{
|
|
r: multipart.NewReader(msg.Body, params["boundary"]),
|
|
}
|
|
} else {
|
|
r = msg.Body
|
|
}
|
|
b, _ := ioutil.ReadAll(r)
|
|
s := strings.ReplaceAll(string(b), "\r\n", "\n")
|
|
s = strings.ReplaceAll(string(s), "\n", "\n")
|
|
s = strings.ReplaceAll(string(s), "\r", "\n")
|
|
if !strings.Contains(s, " ") {
|
|
s = "..."
|
|
}
|
|
d, _ := msg.Header.Date()
|
|
d = d.In(time.Local)
|
|
if as.GetBool("json") {
|
|
emails = append(emails, map[string]any{
|
|
"t": d.Format("06-01-02T15:04Z07"),
|
|
"from": msg.Header.Get("From"),
|
|
"subject": msg.Header.Get("Subject"),
|
|
"body": s,
|
|
})
|
|
} else {
|
|
fmt.Printf(
|
|
"@%+v @%+v: \n\t%+v: \n\t%s\n",
|
|
d.Format("06-01-02T15:04Z07"),
|
|
msg.Header.Get("From"),
|
|
msg.Header.Get("Subject"),
|
|
s,
|
|
)
|
|
}
|
|
}
|
|
if as.GetBool("json") {
|
|
enc := json.NewEncoder(os.Stdout)
|
|
enc.SetIndent("", " ")
|
|
enc.Encode(emails)
|
|
}
|
|
}
|