diff options
Diffstat (limited to 'pkg/email')
| -rw-r--r-- | pkg/email/lore/parse.go | 30 | ||||
| -rw-r--r-- | pkg/email/lore/parse_test.go | 143 | ||||
| -rw-r--r-- | pkg/email/lore/read.go | 19 |
3 files changed, 107 insertions, 85 deletions
diff --git a/pkg/email/lore/parse.go b/pkg/email/lore/parse.go index 9d1a010f5..d71e2a362 100644 --- a/pkg/email/lore/parse.go +++ b/pkg/email/lore/parse.go @@ -20,7 +20,7 @@ type Thread struct { MessageID string Type dashapi.DiscussionType BugIDs []string - Messages []*email.Email + Messages []*Email } // Series represents a single patch series sent over email. @@ -35,19 +35,19 @@ type Series struct { type Patch struct { Seq int - *email.Email + *Email } // Threads extracts individual threads from a list of emails. -func Threads(emails []*email.Email) []*Thread { +func Threads(emails []*Email) []*Thread { return listThreads(emails, 0) } -func listThreads(emails []*email.Email, maxDepth int) []*Thread { +func listThreads(emails []*Email, maxDepth int) []*Thread { ctx := &parseCtx{ maxDepth: maxDepth, - messages: map[string]*email.Email{}, - next: map[*email.Email][]*email.Email{}, + messages: map[string]*Email{}, + next: map[*Email][]*Email{}, } for _, email := range emails { ctx.record(email) @@ -57,7 +57,7 @@ func listThreads(emails []*email.Email, maxDepth int) []*Thread { } // PatchSeries is similar to Threads, but returns only the patch series submitted to the mailing lists. -func PatchSeries(emails []*email.Email) []*Series { +func PatchSeries(emails []*Email) []*Series { var ret []*Series // Normally, all following series patches are sent in response to the first email sent. // So there's no sense to look at deeper replies. @@ -180,17 +180,17 @@ func parsePatchSubject(subject string) (PatchSubject, bool) { type parseCtx struct { maxDepth int threads []*Thread - messages map[string]*email.Email - next map[*email.Email][]*email.Email + messages map[string]*Email + next map[*Email][]*Email } -func (c *parseCtx) record(msg *email.Email) { +func (c *parseCtx) record(msg *Email) { c.messages[msg.MessageID] = msg } func (c *parseCtx) process() { // List messages for which we dont't have ancestors. - nodes := []*email.Email{} + nodes := []*Email{} for _, msg := range c.messages { if msg.InReplyTo == "" || c.messages[msg.InReplyTo] == nil { nodes = append(nodes, msg) @@ -220,15 +220,15 @@ func (c *parseCtx) process() { } } -func (c *parseCtx) visit(msg *email.Email, thread *Thread, depth int) { +func (c *parseCtx) visit(msg *Email, thread *Thread, depth int) { var oldInfo *email.OldThreadInfo if thread != nil { oldInfo = &email.OldThreadInfo{ ThreadType: thread.Type, } } - msgType := DiscussionType(msg) - switch email.NewMessageAction(msg, msgType, oldInfo) { + msgType := DiscussionType(msg.Email) + switch email.NewMessageAction(msg.Email, msgType, oldInfo) { case email.ActionIgnore: thread = nil case email.ActionAppend: @@ -238,7 +238,7 @@ func (c *parseCtx) visit(msg *email.Email, thread *Thread, depth int) { MessageID: msg.MessageID, Subject: msg.Subject, Type: msgType, - Messages: []*email.Email{msg}, + Messages: []*Email{msg}, } c.threads = append(c.threads, thread) } diff --git a/pkg/email/lore/parse_test.go b/pkg/email/lore/parse_test.go index 0480729ff..743ffc976 100644 --- a/pkg/email/lore/parse_test.go +++ b/pkg/email/lore/parse_test.go @@ -6,7 +6,6 @@ package lore import ( "fmt" "sort" - "strings" "testing" "time" @@ -116,29 +115,35 @@ Bug report`, Subject: "Thread A", MessageID: "<A-Base>", Type: dashapi.DiscussionMention, - Messages: []*email.Email{ + Messages: []*Email{ { - MessageID: "<A-Base>", - Subject: "Thread A", - Date: time.Date(2017, time.May, 7, 19, 54, 0, 0, zone), - Author: "a@user.com", - Cc: []string{"a@user.com"}, + Email: &email.Email{ + MessageID: "<A-Base>", + Subject: "Thread A", + Date: time.Date(2017, time.May, 7, 19, 54, 0, 0, zone), + Author: "a@user.com", + Cc: []string{"a@user.com"}, + }, }, { - MessageID: "<A-Child-1>", - Subject: "Re: Thread A", - Date: time.Date(2017, time.May, 7, 19, 55, 0, 0, zone), - Author: "b@user.com", - Cc: []string{"a@user.com", "b@user.com"}, - InReplyTo: "<A-Base>", + Email: &email.Email{ + MessageID: "<A-Child-1>", + Subject: "Re: Thread A", + Date: time.Date(2017, time.May, 7, 19, 55, 0, 0, zone), + Author: "b@user.com", + Cc: []string{"a@user.com", "b@user.com"}, + InReplyTo: "<A-Base>", + }, }, { - MessageID: "<A-Child-1-1>", - Subject: "Re: Re: Thread A", - Date: time.Date(2017, time.May, 7, 19, 56, 0, 0, zone), - Author: "c@user.com", - Cc: []string{"a@user.com", "b@user.com", "c@user.com"}, - InReplyTo: "<A-Child-1>", + Email: &email.Email{ + MessageID: "<A-Child-1-1>", + Subject: "Re: Re: Thread A", + Date: time.Date(2017, time.May, 7, 19, 56, 0, 0, zone), + Author: "c@user.com", + Cc: []string{"a@user.com", "b@user.com", "c@user.com"}, + InReplyTo: "<A-Child-1>", + }, }, }, }, @@ -147,32 +152,38 @@ Bug report`, MessageID: "<Bug>", Type: dashapi.DiscussionReport, BugIDs: []string{"4564456"}, - Messages: []*email.Email{ + Messages: []*Email{ { - MessageID: "<Bug>", - BugIDs: []string{"4564456"}, - Subject: "[syzbot] Some bug", - Date: time.Date(2017, time.May, 7, 19, 57, 0, 0, zone), - Author: "syzbot@bar.com", - OwnEmail: true, + Email: &email.Email{ + MessageID: "<Bug>", + BugIDs: []string{"4564456"}, + Subject: "[syzbot] Some bug", + Date: time.Date(2017, time.May, 7, 19, 57, 0, 0, zone), + Author: "syzbot@bar.com", + OwnEmail: true, + }, }, { - MessageID: "<Bug-Reply1>", - BugIDs: []string{"4564456"}, - Subject: "Re: [syzbot] Some bug", - Date: time.Date(2017, time.May, 7, 19, 58, 0, 0, zone), - Author: "c@user.com", - Cc: []string{"c@user.com"}, - InReplyTo: "<Bug>", + Email: &email.Email{ + MessageID: "<Bug-Reply1>", + BugIDs: []string{"4564456"}, + Subject: "Re: [syzbot] Some bug", + Date: time.Date(2017, time.May, 7, 19, 58, 0, 0, zone), + Author: "c@user.com", + Cc: []string{"c@user.com"}, + InReplyTo: "<Bug>", + }, }, { - MessageID: "<Bug-Reply2>", - BugIDs: []string{"4564456"}, - Subject: "Re: [syzbot] Some bug", - Date: time.Date(2017, time.May, 7, 19, 58, 1, 0, zone), - Author: "d@user.com", - Cc: []string{"d@user.com"}, - InReplyTo: "<Bug>", + Email: &email.Email{ + MessageID: "<Bug-Reply2>", + BugIDs: []string{"4564456"}, + Subject: "Re: [syzbot] Some bug", + Date: time.Date(2017, time.May, 7, 19, 58, 1, 0, zone), + Author: "d@user.com", + Cc: []string{"d@user.com"}, + InReplyTo: "<Bug>", + }, }, }, }, @@ -181,14 +192,16 @@ Bug report`, MessageID: "<Patch>", Type: dashapi.DiscussionPatch, BugIDs: []string{"12345"}, - Messages: []*email.Email{ + Messages: []*Email{ { - MessageID: "<Patch>", - BugIDs: []string{"12345"}, - Subject: "[PATCH] Some bug fixed", - Date: time.Date(2017, time.May, 7, 19, 58, 1, 0, zone), - Author: "e@user.com", - Cc: []string{"e@user.com"}, + Email: &email.Email{ + MessageID: "<Patch>", + BugIDs: []string{"12345"}, + Subject: "[PATCH] Some bug fixed", + Date: time.Date(2017, time.May, 7, 19, 58, 1, 0, zone), + Author: "e@user.com", + Cc: []string{"e@user.com"}, + }, }, }, }, @@ -197,29 +210,29 @@ Bug report`, MessageID: "<Sub-Discussion>", Type: dashapi.DiscussionMention, BugIDs: []string{"4564456"}, - Messages: []*email.Email{ + Messages: []*Email{ { - MessageID: "<Sub-Discussion>", - InReplyTo: "<Unknown>", - Date: time.Date(2017, time.May, 7, 19, 57, 0, 0, zone), - BugIDs: []string{"4564456"}, - Cc: []string{"person@email.com"}, - Subject: "Another bug discussion", - Author: "person@email.com", + Email: &email.Email{ + MessageID: "<Sub-Discussion>", + InReplyTo: "<Unknown>", + Date: time.Date(2017, time.May, 7, 19, 57, 0, 0, zone), + BugIDs: []string{"4564456"}, + Cc: []string{"person@email.com"}, + Subject: "Another bug discussion", + Author: "person@email.com", + }, }, }, }, "<Sub-Discussion-Bot>": nil, } - emails := []*email.Email{} + var emails []*Email for _, m := range messages { - msg, err := email.Parse(strings.NewReader(m), []string{"syzbot@bar.com"}, - []string{}, []string{"bar.com"}) + msg, err := emailFromRaw([]byte(m), []string{"syzbot@bar.com"}, []string{"bar.com"}) if err != nil { t.Fatal(err) } - msg.Body = "" msg.RawCc = nil emails = append(emails, msg) } @@ -418,9 +431,9 @@ Content-Type: text/plain Bug report`, } - emails := []*email.Email{} + var emails []*Email for _, m := range messages { - msg, err := email.Parse(strings.NewReader(m), nil, nil, nil) + msg, err := emailFromRaw([]byte(m), nil, nil) if err != nil { t.Fatal(err) } @@ -437,7 +450,7 @@ Bug report`, Patches: []Patch{ { Seq: 1, - Email: &email.Email{Subject: "[PATCH] Small patch"}, + Email: &Email{Email: &email.Email{Subject: "[PATCH] Small patch"}}, }, }, }, @@ -448,11 +461,11 @@ Bug report`, Patches: []Patch{ { Seq: 1, - Email: &email.Email{Subject: "[PATCH v2 01/02] First patch"}, + Email: &Email{Email: &email.Email{Subject: "[PATCH v2 01/02] First patch"}}, }, { Seq: 2, - Email: &email.Email{Subject: "[PATCH v2 02/02] Second patch"}, + Email: &Email{Email: &email.Email{Subject: "[PATCH v2 02/02] Second patch"}}, }, }, }, @@ -463,7 +476,7 @@ Bug report`, Patches: []Patch{ { Seq: 1, - Email: &email.Email{Subject: "[PATCH 01/03] Series"}, + Email: &Email{Email: &email.Email{Subject: "[PATCH 01/03] Series"}}, }, }, }, diff --git a/pkg/email/lore/read.go b/pkg/email/lore/read.go index d4e68cf33..90a462d9a 100644 --- a/pkg/email/lore/read.go +++ b/pkg/email/lore/read.go @@ -36,19 +36,28 @@ func ReadArchive(repo vcs.Repo, afterCommit string, afterTime time.Time) ([]Emai return ret, nil } -func (er *EmailReader) Parse(emails, domains []string) (*email.Email, error) { +type Email struct { + *email.Email + HasPatch bool +} + +func (er *EmailReader) Parse(emails, domains []string) (*Email, error) { body, err := er.Read() if err != nil { return nil, err } + return emailFromRaw(body, emails, domains) +} + +func emailFromRaw(body []byte, emails, domains []string) (*Email, error) { msg, err := email.Parse(bytes.NewReader(body), emails, nil, domains) if err != nil { return nil, err } + ret := &Email{Email: msg} // Keep memory consumption low. - msg.Body = "" - msg.Patch = "" - // TODO: We definitely don't care about the patch here. Add an option to avoid extracting it? + ret.Body = "" + ret.Patch = "" // TODO: If emails/domains are nil, we also don't need to parse the body at all. - return msg, nil + return ret, nil } |
