aboutsummaryrefslogtreecommitdiff
path: root/worker/notmuch/message.go
diff options
context:
space:
mode:
Diffstat (limited to 'worker/notmuch/message.go')
-rw-r--r--worker/notmuch/message.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/worker/notmuch/message.go b/worker/notmuch/message.go
new file mode 100644
index 0000000..077fb92
--- /dev/null
+++ b/worker/notmuch/message.go
@@ -0,0 +1,123 @@
+//+build notmuch
+
+package notmuch
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+
+ "git.sr.ht/~sircmpwn/aerc/models"
+ "git.sr.ht/~sircmpwn/aerc/worker/lib"
+ "github.com/emersion/go-message"
+ _ "github.com/emersion/go-message/charset"
+ notmuch "github.com/zenhack/go.notmuch"
+)
+
+type Message struct {
+ uid uint32
+ key string
+ msg *notmuch.Message
+}
+
+// NewReader reads a message into memory and returns an io.Reader for it.
+func (m Message) NewReader() (io.Reader, error) {
+ f, err := os.Open(m.msg.Filename())
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ b, err := ioutil.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+ return bytes.NewReader(b), nil
+}
+
+// MessageInfo populates a models.MessageInfo struct for the message.
+func (m Message) MessageInfo() (*models.MessageInfo, error) {
+ return lib.MessageInfo(m)
+}
+
+// NewBodyPartReader creates a new io.Reader for the requested body part(s) of
+// the message.
+func (m Message) NewBodyPartReader(requestedParts []int) (io.Reader, error) {
+ f, err := os.Open(m.msg.Filename())
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ msg, err := message.Read(f)
+ if err != nil {
+ return nil, fmt.Errorf("could not read message: %v", err)
+ }
+ return lib.FetchEntityPartReader(msg, requestedParts)
+}
+
+// MarkRead either adds or removes the maildir.FlagSeen flag from the message.
+func (m Message) MarkRead(seen bool) error {
+ haveUnread := false
+ for _, t := range m.tags() {
+ if t == "unread" {
+ haveUnread = true
+ break
+ }
+ }
+ if (haveUnread && !seen) || (!haveUnread && seen) {
+ // we already have the desired state
+ return nil
+ }
+
+ if haveUnread {
+ err := m.msg.RemoveTag("unread")
+ if err != nil {
+ return err
+ }
+ return nil
+ }
+
+ err := m.msg.AddTag("unread")
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// tags returns the notmuch tags of a message
+func (m Message) tags() []string {
+ ts := m.msg.Tags()
+ var tags []string
+ var tag *notmuch.Tag
+ for ts.Next(&tag) {
+ tags = append(tags, tag.Value)
+ }
+ return tags
+}
+
+func (m Message) ModelFlags() ([]models.Flag, error) {
+ var flags []models.Flag
+ seen := true
+
+ for _, tag := range m.tags() {
+ switch tag {
+ case "replied":
+ flags = append(flags, models.AnsweredFlag)
+ case "flagged":
+ flags = append(flags, models.FlaggedFlag)
+ case "unread":
+ seen = false
+ default:
+ continue
+ }
+ }
+ if seen {
+ flags = append(flags, models.SeenFlag)
+ }
+ return flags, nil
+}
+
+func (m Message) UID() uint32 {
+ return m.uid
+}