From c610c3cd9dd47c400e52c1858e987f5f32a7a45b Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Sun, 7 Jul 2019 22:43:58 -0400 Subject: Factor IMAP-specific structs out of UI models Before, we were using several IMAP-specific concepts to represent information being displayed in the UI. Factor these structures out of the IMAP package to make it easier for other backends to provide the required information. --- models/models.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 4 deletions(-) (limited to 'models/models.go') diff --git a/models/models.go b/models/models.go index cff05b1..28d256c 100644 --- a/models/models.go +++ b/models/models.go @@ -1,13 +1,37 @@ package models import ( + "bytes" + "fmt" "io" + "regexp" + "strings" "time" - "github.com/emersion/go-imap" "github.com/emersion/go-message/mail" ) +// Flag is an abstraction around the different flags which can be present in +// different email backends and represents a flag that we use in the UI. +type Flag int + +const ( + // SeenFlag marks a message as having been seen previously + SeenFlag Flag = iota + + // RecentFlag marks a message as being recent + RecentFlag + + // AnsweredFlag marks a message as having been replied to + AnsweredFlag + + // DeletedFlag marks a message as having been deleted + DeletedFlag + + // FlaggedFlag marks a message with a user flag + FlaggedFlag +) + type Directory struct { Name string Attributes []string @@ -30,9 +54,9 @@ type DirectoryInfo struct { // A MessageInfo holds information about the structure of a message type MessageInfo struct { - BodyStructure *imap.BodyStructure - Envelope *imap.Envelope - Flags []string + BodyStructure *BodyStructure + Envelope *Envelope + Flags []Flag InternalDate time.Time RFC822Headers *mail.Header Size uint32 @@ -50,3 +74,59 @@ type FullMessage struct { Reader io.Reader Uid uint32 } + +type BodyStructure struct { + MIMEType string + MIMESubType string + Params map[string]string + Description string + Encoding string + Parts []*BodyStructure + Disposition string + DispositionParams map[string]string +} + +type Envelope struct { + Date time.Time + Subject string + From []*Address + ReplyTo []*Address + To []*Address + Cc []*Address + Bcc []*Address + MessageId string +} + +type Address struct { + Name string + Mailbox string + Host string +} + +var atom *regexp.Regexp = regexp.MustCompile("^[a-z0-9!#$%7'*+-/=?^_`{}|~ ]+$") + +func (a Address) Format() string { + if a.Name != "" { + if atom.MatchString(a.Name) { + return fmt.Sprintf("%s <%s@%s>", a.Name, a.Mailbox, a.Host) + } else { + return fmt.Sprintf("\"%s\" <%s@%s>", + strings.ReplaceAll(a.Name, "\"", "'"), + a.Mailbox, a.Host) + } + } else { + return fmt.Sprintf("<%s@%s>", a.Mailbox, a.Host) + } +} + +// FormatAddresses formats a list of addresses, separating each by a comma +func FormatAddresses(addrs []*Address) string { + val := bytes.Buffer{} + for i, addr := range addrs { + val.WriteString(addr.Format()) + if i != len(addrs)-1 { + val.WriteString(", ") + } + } + return val.String() +} -- cgit v1.2.3