diff options
Diffstat (limited to 'cmd/generate/mailstuff/thread.go')
-rw-r--r-- | cmd/generate/mailstuff/thread.go | 114 |
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 -} |