From b812dd932aaec17dc81dbd80d902291edfa5ca93 Mon Sep 17 00:00:00 2001 From: Michael Weiss Date: Sun, 2 Aug 2020 15:21:29 +0200 Subject: scripts/mailing-list-member-retirement: Add an initial PoC Can read fsi.mbox (228 MiB) but lacks features (e.g. limiting the parsing to messages of the past year) and it would be nice to indicate which messages couldn't be read. But it basically works :) --- scripts/mailing-list-member-retirement/main.go | 80 ++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 scripts/mailing-list-member-retirement/main.go (limited to 'scripts/mailing-list-member-retirement/main.go') diff --git a/scripts/mailing-list-member-retirement/main.go b/scripts/mailing-list-member-retirement/main.go new file mode 100644 index 0000000..7ce7867 --- /dev/null +++ b/scripts/mailing-list-member-retirement/main.go @@ -0,0 +1,80 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "log" + "os" + "strings" + "github.com/emersion/go-mbox" + "github.com/emersion/go-message/mail" + _ "github.com/emersion/go-message/charset" +) + +// Prints the email addresses (one per line) of all senders by parsing an MBOX. + +func main() { + mboxNamePtr := flag.String("mbox", "test.mbox", "MBOX to read") + flag.Parse() + PrintAllMboxSenders(*mboxNamePtr) +} + +func PrintAllMboxSenders(fileName string) { + f, err := os.Open(fileName) + if err != nil { + log.Fatal(err) + } + defer func() { + if err = f.Close(); err != nil { + log.Fatal(err) + } + }() + fr := bufio.NewReader(f) + mr := mbox.NewReader(fr) + for { + r, err := mr.NextMessage() + if err == io.EOF { + break + } else if err != nil { + log.Fatal(err) + } + PrintMessageSender(r) + } +} + +func PrintMessageSender(r io.Reader) { + mr, err := mail.CreateReader(r) + if err != nil { + if err.Error() == "charset \"cp-850\": ianaindex: invalid encoding name" { + fmt.Fprintf(os.Stderr, "Ignored a mail due to an invalid charset\n") + return // TODO: Print message ID + } + log.Fatal(err) + } + + addr, err := mr.Header.AddressList("From") + if err != nil { + if strings.Contains(err.Error(), "invalid utf-8 in quoted-string") { + addr := strings.TrimPrefix(err.Error(), "mail: missing word in phrase: mail: invalid utf-8 in quoted-string: ") + fmt.Fprintf(os.Stderr, "Ignored due to invalid UTF-8 encoding: %v\n", addr) + return + } else if err.Error() == "mail: missing @ in addr-spec" { + fmt.Fprintf(os.Stderr, "Ignored a sender due to missing @\n") + return // TODO: Print invalid address + } else if err.Error() == "mail: no angle-addr" { + fmt.Fprintf(os.Stderr, "Ignored a mail due to no angle-address\n") + return // TODO: Print message ID + } + log.Fatal(err) + } else if len(addr) != 1 { + if len(addr) == 0 { + fmt.Fprintf(os.Stderr, "Ignored a mail due to a missing sender\n") + return // TODO: Print message ID + } + fmt.Fprintf(os.Stderr, "A mail has an unexpected number of senders: %v\n", len(addr)) + return // TODO: Print message ID + } + fmt.Println(addr[0].Address) +} -- cgit v1.2.3