summaryrefslogtreecommitdiff
path: root/cmd/generate/mailstuff/thread.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/generate/mailstuff/thread.go')
-rw-r--r--cmd/generate/mailstuff/thread.go114
1 files changed, 0 insertions, 114 deletions
diff --git a/cmd/generate/mailstuff/thread.go b/cmd/generate/mailstuff/thread.go
deleted file mode 100644
index 2cdf9a4..0000000
--- a/cmd/generate/mailstuff/thread.go
+++ /dev/null
@@ -1,114 +0,0 @@
-package mailstuff
-
-import (
- "fmt"
- "net/mail"
- "regexp"
- "strings"
-)
-
-type Set[T comparable] map[T]struct{}
-
-func (s Set[T]) Insert(val T) {
- s[val] = struct{}{}
-}
-
-func mapHas[K comparable, V any](m map[K]V, k K) bool {
- _, ok := m[k]
- return ok
-}
-
-func (s Set[T]) Has(val T) bool {
- return mapHas(s, val)
-}
-
-func (s Set[T]) PickOne() T {
- for v := range s {
- return v
- }
- var zero T
- return zero
-}
-
-type MessageID string
-
-type ThreadedMessage struct {
- *mail.Message
- Parent *ThreadedMessage
- Children Set[*ThreadedMessage]
-}
-
-var reReplyID = regexp.MustCompile("<[^> \t\r\n]+>")
-
-func rfc2822parse(msg *mail.Message) *jwzMessage {
- // TODO: This is bad, and needs a real implementation.
- ret := &jwzMessage{
- Subject: msg.Header.Get("Subject"),
- ID: jwzID(msg.Header.Get("Message-ID")),
- }
- refIDs := strings.Fields(msg.Header.Get("References"))
- strings.Fields(msg.Header.Get("References"))
- if replyID := reReplyID.FindString(msg.Header.Get("In-Reply-To")); replyID != "" {
- refIDs = append(refIDs, replyID)
- }
- ret.References = make([]jwzID, len(refIDs))
- for i := range refIDs {
- ret.References[i] = jwzID(refIDs[i])
- }
- return ret
-}
-
-func ThreadMessages(msgs []*mail.Message) (Set[*ThreadedMessage], map[MessageID]*ThreadedMessage) {
- jwzMsgs := make(map[jwzID]*jwzMessage, len(msgs))
- retMsgs := make(map[jwzID]*ThreadedMessage, len(msgs))
- bogusCnt := 0
- for _, msg := range msgs {
- jwzMsg := rfc2822parse(msg)
-
- // RFC 5256:
- //
- // If a message does not contain a Message-ID header
- // line, or the Message-ID header line does not
- // contain a valid Message ID, then assign a unique
- // Message ID to this message.
- //
- // If two or more messages have the same Message ID,
- // then only use that Message ID in the first (lowest
- // sequence number) message, and assign a unique
- // Message ID to each of the subsequent messages with
- // a duplicate of that Message ID.
- for jwzMsg.ID == "" || mapHas(jwzMsgs, jwzMsg.ID) {
- jwzMsg.ID = jwzID(fmt.Sprintf("bogus.%d", bogusCnt))
- bogusCnt++
- }
-
- jwzMsgs[jwzMsg.ID] = jwzMsg
- retMsgs[jwzMsg.ID] = &ThreadedMessage{
- Message: msg,
- }
- }
-
- jwzThreads := jwzThreadMessages(jwzMsgs)
-
- var convertMessage func(*jwzContainer) *ThreadedMessage
- convertMessage = func(in *jwzContainer) *ThreadedMessage {
- var out *ThreadedMessage
- if in.Message == nil {
- out = new(ThreadedMessage)
- } else {
- out = retMsgs[in.Message.ID]
- }
- out.Children = make(Set[*ThreadedMessage], len(in.Children))
- for inChild := range in.Children {
- outChild := convertMessage(inChild)
- out.Children.Insert(outChild)
- outChild.Parent = out
- }
- return out
- }
- retThreads := make(Set[*ThreadedMessage], len(jwzThreads))
- for inThread := range jwzThreads {
- retThreads.Insert(convertMessage(inThread))
- }
- return retThreads, retMsgs
-}