aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Magorsch <arzano@gentoo.org>2020-06-19 15:51:41 +0200
committerMax Magorsch <arzano@gentoo.org>2020-06-19 15:51:41 +0200
commit21181c518cf41828917d36005b726f9452fde657 (patch)
tree38fab1b3c86a41383e48be6b2686d92efd86db62 /pkg/models/message.go
downloadarchives-21181c518cf41828917d36005b726f9452fde657.tar.gz
archives-21181c518cf41828917d36005b726f9452fde657.tar.bz2
archives-21181c518cf41828917d36005b726f9452fde657.zip
Initial version
Signed-off-by: Max Magorsch <arzano@gentoo.org>
Diffstat (limited to 'pkg/models/message.go')
-rw-r--r--pkg/models/message.go155
1 files changed, 155 insertions, 0 deletions
diff --git a/pkg/models/message.go b/pkg/models/message.go
new file mode 100644
index 0000000..17bbb9d
--- /dev/null
+++ b/pkg/models/message.go
@@ -0,0 +1,155 @@
+package models
+
+import (
+ "mime"
+ "net/mail"
+ "strings"
+ "time"
+)
+
+type Message struct {
+ Id string `pg:",pk"`
+ Filename string
+
+ Headers map[string][]string
+ Body map[string]string
+ Attachments []Attachment
+
+ Lists []string
+ Date time.Time
+
+ //Search types.ValueAppender // tsvector
+
+ Comment string
+ Hidden bool
+
+ //ParentId string
+ //Parent Message -> pg fk?
+}
+
+type Header struct {
+ Name string
+ Content string
+}
+
+type Body struct {
+ ContentType string
+ Content string
+}
+
+type Attachment struct {
+ Filename string
+ Mime string
+ Content string
+}
+
+func (m Message) GetSubject() string {
+ return m.GetHeaderField("Subject")
+}
+
+func (m Message) GetListNameFromSubject() string {
+ subject := m.GetSubject()
+ listName := strings.Split(subject, "]")[0]
+ listName = strings.ReplaceAll(listName, "[", "")
+ listName = strings.ReplaceAll(listName, "Re:", "")
+ listName = strings.TrimSpace(listName)
+ return listName
+}
+
+func (m Message) GetAuthorName() string {
+ addr, err := mail.ParseAddress(m.GetHeaderField("From"))
+ if err != nil {
+ return ""
+ }
+ return addr.Name
+}
+
+func (m Message) GetMessageId() string {
+ messageId := m.GetHeaderField("Message-Id")
+ messageId = strings.ReplaceAll(messageId, "<", "")
+ messageId = strings.ReplaceAll(messageId, ">", "")
+ messageId = strings.ReplaceAll(messageId, "\"", "")
+ return messageId
+}
+
+func (m Message) GetInReplyTo() string {
+ inReplyTo := m.GetHeaderField("In-Reply-To")
+ inReplyTo = strings.ReplaceAll(inReplyTo, "<", "")
+ inReplyTo = strings.ReplaceAll(inReplyTo, ">", "")
+ inReplyTo = strings.ReplaceAll(inReplyTo, " ", "")
+ return inReplyTo
+}
+
+func (m Message) GetHeaderField(key string) string {
+ subject, found := m.Headers[key]
+ if !found {
+ return ""
+ }
+ header := strings.Join(subject, " ")
+ if strings.Contains(header, "=?") {
+ dec := new(mime.WordDecoder)
+ decodedHeader, err := dec.DecodeHeader(header)
+ if err != nil {
+ return ""
+ }
+ return decodedHeader
+ }
+ return header
+}
+
+func (m Message) HasHeaderField(key string) bool {
+ _, found := m.Headers[key]
+ return found
+}
+
+func (m Message) GetBody() string {
+ // Get text/plain body
+ for contentType, content := range m.Body {
+ if strings.Contains(contentType, "text/plain") {
+ return content
+ }
+ }
+
+ // If text/plain is not present, fall back to html
+ for contentType, content := range m.Body {
+ if strings.Contains(contentType, "text/html") {
+ return content
+ }
+ }
+
+ // If neither text/plain nor text/html is available return nothing
+ return ""
+}
+
+func (m Message) HasAttachments() bool {
+ for key, _ := range m.Body {
+ if !(strings.Contains(key, "text/plain") || strings.Contains(key, "text/plain")) {
+ return true
+ }
+ }
+ return false
+}
+
+func (m Message) GetAttachments() []Attachment {
+ var attachments []Attachment
+ for key, content := range m.Body {
+ if !(strings.Contains(key, "text/plain") || strings.Contains(key, "text/plain")) {
+ attachments = append(attachments, Attachment{
+ Filename: getAttachmentFileName(key),
+ Mime: strings.Split(key, ";")[0],
+ Content: content,
+ })
+ }
+ }
+ return attachments
+}
+
+// utility methods
+
+func getAttachmentFileName(contentTypeHeader string) string {
+ parts := strings.Split(contentTypeHeader, "name=")
+ if len(parts) < 2 {
+ return "unknown"
+ }
+ return strings.ReplaceAll(parts[1], "\"", "")
+}