diff options
Diffstat (limited to 'worker')
-rw-r--r-- | worker/imap/flags.go | 32 | ||||
-rw-r--r-- | worker/imap/worker.go | 2 | ||||
-rw-r--r-- | worker/maildir/message.go | 20 | ||||
-rw-r--r-- | worker/maildir/worker.go | 35 | ||||
-rw-r--r-- | worker/notmuch/message.go | 33 | ||||
-rw-r--r-- | worker/notmuch/worker.go | 27 | ||||
-rw-r--r-- | worker/types/messages.go | 6 |
7 files changed, 155 insertions, 0 deletions
diff --git a/worker/imap/flags.go b/worker/imap/flags.go index 17c9393c..26250866 100644 --- a/worker/imap/flags.go +++ b/worker/imap/flags.go @@ -44,6 +44,38 @@ func (imapw *IMAPWorker) handleDeleteMessages(msg *types.DeleteMessages) { } } +func (imapw *IMAPWorker) handleAnsweredMessages(msg *types.AnsweredMessages) { + item := imap.FormatFlagsOp(imap.AddFlags, true) + flags := []interface{}{imap.AnsweredFlag} + if !msg.Answered { + item = imap.FormatFlagsOp(imap.RemoveFlags, true) + flags = []interface{}{imap.AnsweredFlag} + } + uids := toSeqSet(msg.Uids) + emitErr := func(err error) { + imapw.worker.PostMessage(&types.Error{ + Message: types.RespondTo(msg), + Error: err, + }, nil) + } + if err := imapw.client.UidStore(uids, item, flags, nil); err != nil { + emitErr(err) + return + } + imapw.worker.PostAction(&types.FetchMessageHeaders{ + Uids: msg.Uids, + }, func(_msg types.WorkerMessage) { + switch m := _msg.(type) { + case *types.Error: + err := fmt.Errorf("handleAnsweredMessages: %v", m.Error) + imapw.worker.Logger.Printf("could not fetch headers: %s", err) + emitErr(err) + case *types.Done: + imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) + } + }) +} + func (imapw *IMAPWorker) handleReadMessages(msg *types.ReadMessages) { item := imap.FormatFlagsOp(imap.AddFlags, true) flags := []interface{}{imap.SeenFlag} diff --git a/worker/imap/worker.go b/worker/imap/worker.go index 45a22690..a43ac49e 100644 --- a/worker/imap/worker.go +++ b/worker/imap/worker.go @@ -175,6 +175,8 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { w.handleDeleteMessages(msg) case *types.ReadMessages: w.handleReadMessages(msg) + case *types.AnsweredMessages: + w.handleAnsweredMessages(msg) case *types.CopyMessages: w.handleCopyMessages(msg) case *types.AppendMessage: diff --git a/worker/maildir/message.go b/worker/maildir/message.go index 9d622b45..5c6c9307 100644 --- a/worker/maildir/message.go +++ b/worker/maildir/message.go @@ -53,6 +53,26 @@ func (m Message) SetFlags(flags []maildir.Flag) error { return m.dir.SetFlags(m.key, flags) } +// MarkReplied either adds or removes the maildir.FlagReplied flag from the +// message. +func (m Message) MarkReplied(answered bool) error { + flags, err := m.Flags() + if err != nil { + return fmt.Errorf("could not read previous flags: %v", err) + } + if answered { + flags = append(flags, maildir.FlagReplied) + return m.SetFlags(flags) + } + var newFlags []maildir.Flag + for _, flag := range flags { + if flag != maildir.FlagReplied { + newFlags = append(newFlags, flag) + } + } + return m.SetFlags(newFlags) +} + // MarkRead either adds or removes the maildir.FlagSeen flag from the message. func (m Message) MarkRead(seen bool) error { flags, err := m.Flags() diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go index dbdb9252..f14672e5 100644 --- a/worker/maildir/worker.go +++ b/worker/maildir/worker.go @@ -195,6 +195,8 @@ func (w *Worker) handleMessage(msg types.WorkerMessage) error { return w.handleDeleteMessages(msg) case *types.ReadMessages: return w.handleReadMessages(msg) + case *types.AnsweredMessages: + return w.handleAnsweredMessages(msg) case *types.CopyMessages: return w.handleCopyMessages(msg) case *types.AppendMessage: @@ -438,6 +440,39 @@ func (w *Worker) handleDeleteMessages(msg *types.DeleteMessages) error { return nil } +func (w *Worker) handleAnsweredMessages(msg *types.AnsweredMessages) error { + for _, uid := range msg.Uids { + m, err := w.c.Message(*w.selected, uid) + if err != nil { + w.worker.Logger.Printf("could not get message: %v", err) + w.err(msg, err) + continue + } + if err := m.MarkReplied(msg.Answered); err != nil { + w.worker.Logger.Printf( + "could not mark message as answered: %v", err) + w.err(msg, err) + continue + } + info, err := m.MessageInfo() + if err != nil { + w.worker.Logger.Printf("could not get message info: %v", err) + w.err(msg, err) + continue + } + + w.worker.PostMessage(&types.MessageInfo{ + Message: types.RespondTo(msg), + Info: info, + }, nil) + + w.worker.PostMessage(&types.DirectoryInfo{ + Info: w.getDirectoryInfo(w.selectedName), + }, nil) + } + return nil +} + func (w *Worker) handleReadMessages(msg *types.ReadMessages) error { for _, uid := range msg.Uids { m, err := w.c.Message(*w.selected, uid) diff --git a/worker/notmuch/message.go b/worker/notmuch/message.go index ec1adb9b..3fd2fb62 100644 --- a/worker/notmuch/message.go +++ b/worker/notmuch/message.go @@ -64,6 +64,39 @@ func (m *Message) NewBodyPartReader(requestedParts []int) (io.Reader, error) { return lib.FetchEntityPartReader(msg, requestedParts) } +// MarkAnswered either adds or removes the "replied" tag from the message. +func (m *Message) MarkAnswered(answered bool) error { + haveReplied := false + tags, err := m.Tags() + if err != nil { + return err + } + for _, t := range tags { + if t == "replied" { + haveReplied = true + break + } + } + if haveReplied == answered { + // we already have the desired state + return nil + } + + if haveAnswered { + err := m.RemoveTag("replied") + if err != nil { + return err + } + return nil + } + + err = m.AddTag("replied") + if err != nil { + return err + } + return nil +} + // MarkRead either adds or removes the maildir.FlagSeen flag from the message. func (m *Message) MarkRead(seen bool) error { haveUnread := false diff --git a/worker/notmuch/worker.go b/worker/notmuch/worker.go index 9929648d..b2262698 100644 --- a/worker/notmuch/worker.go +++ b/worker/notmuch/worker.go @@ -363,6 +363,33 @@ func (w *worker) handleFetchFullMessages(msg *types.FetchFullMessages) error { return nil } +func (w *worker) handleAnsweredMessages(msg *types.AnsweredMessages) error { + for _, uid := range msg.Uids { + m, err := w.msgFromUid(uid) + if err != nil { + w.w.Logger.Printf("could not get message: %v", err) + w.err(msg, err) + continue + } + if err := m.MarkAnswered(msg.Answered); err != nil { + w.w.Logger.Printf("could not mark message as answered: %v", err) + w.err(msg, err) + continue + } + err = w.emitMessageInfo(m, msg) + if err != nil { + w.w.Logger.Printf(err.Error()) + w.err(msg, err) + continue + } + } + if err := w.emitDirectoryInfo(w.currentQueryName); err != nil { + w.w.Logger.Printf(err.Error()) + } + w.done(msg) + return nil +} + func (w *worker) handleReadMessages(msg *types.ReadMessages) error { for _, uid := range msg.Uids { m, err := w.msgFromUid(uid) diff --git a/worker/types/messages.go b/worker/types/messages.go index f1ef36ea..475a7aa3 100644 --- a/worker/types/messages.go +++ b/worker/types/messages.go @@ -120,6 +120,12 @@ type ReadMessages struct { Uids []uint32 } +type AnsweredMessages struct { + Message + Answered bool + Uids []uint32 +} + type CopyMessages struct { Message Destination string |