diff options
Diffstat (limited to 'cmd/generate/forge_pipermail.go')
-rw-r--r-- | cmd/generate/forge_pipermail.go | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/cmd/generate/forge_pipermail.go b/cmd/generate/forge_pipermail.go index e015bb5..56e7ef2 100644 --- a/cmd/generate/forge_pipermail.go +++ b/cmd/generate/forge_pipermail.go @@ -1,12 +1,17 @@ package main import ( + "errors" "fmt" + "net/mail" "net/url" + "os" "regexp" "strconv" "strings" "time" + + "git.lukeshu.com/www/cmd/generate/mailstuff" ) var ( @@ -77,9 +82,20 @@ func (PiperMail) nextMonth(ym string) string { } } -func (PiperMail) messageID(u string) (string, error) { -} +func (p PiperMail) threadLen(thread *mailstuff.ThreadedMessage) int { + if thread == nil { + return 0 + } + ret := 0 + if thread.Message != nil { + ret++ + } + for child := range thread.Children { + ret += p.threadLen(child) + } + return ret +} func (p PiperMail) FetchLastUpdated(urls []string) (time.Time, User, error) { for _, u := range urls { @@ -95,14 +111,14 @@ func (p PiperMail) FetchLastUpdated(urls []string) (time.Time, User, error) { if err != nil { return time.Time{}, User{}, err } - var msgid string + var msgid mailstuff.MessageID for _, line := range strings.Split(htmlStr, "\n") { if m := rePiperMailReply.FindStringSubmatch(line); m != nil { ru, err := url.Parse(m[1]) if err != nil { continue } - if msgid = ru.Query().Get("In-Reply-To"); msgid != "" { + if msgid = mailstuff.MessageID(ru.Query().Get("In-Reply-To")); msgid != "" { break } } @@ -110,9 +126,48 @@ func (p PiperMail) FetchLastUpdated(urls []string) (time.Time, User, error) { if msgid == "" { continue } - mboxStr, err := httpGet(uBase+uYM+".txt.gz", nil) - if err != nil { - return time.Time{}, User{}, err + + var thread *mailstuff.ThreadedMessage + for ym, mbox := uYM, []*mail.Message(nil); true; ym = p.nextMonth(ym) { + lenBefore := p.threadLen(thread) + + mboxStr, err := httpGet(uBase+ym+".txt.gz", nil) + if err != nil && (ym == uYM || !errors.Is(err, os.ErrNotExist)) { + return time.Time{}, User{}, err + } + _mbox, err := mailstuff.ReadMBox(strings.NewReader(mboxStr)) + if err != nil { + return time.Time{}, User{}, err + } + mbox = append(mbox, _mbox...) + _, messages := mailstuff.ThreadMessages(mbox) + thread = messages[msgid] + + if p.threadLen(thread) == lenBefore { + break + } + } + + var retTime time.Time + var retUser User + + var walk func(*mailstuff.ThreadedMessage) + walk = func(msg *mailstuff.ThreadedMessage) { + date, dateErr := msg.Header.Date() + froms, fromErr := msg.Header.AddressList("From") + if dateErr == nil && fromErr == nil && len(froms) > 0 && (retTime.IsZero() || date.After(retTime)) { + retTime = date + retUser.Name = froms[0].Name + if retUser.Name == "" { + retUser.Name = froms[0].Address + } + retUser.URL = "mailto:" + froms[0].Address + } + } + walk(thread) + + if !retTime.IsZero() { + return retTime, retUser, nil } } return time.Time{}, User{}, nil |