diff --git a/imap/mailbox.go b/imap/mailbox.go index ad47f1c..f207d8e 100644 --- a/imap/mailbox.go +++ b/imap/mailbox.go @@ -44,7 +44,7 @@ func (mbox *mailbox) Info() (*imap.MailboxInfo, error) { func (mbox *mailbox) Status(items []imap.StatusItem) (*imap.MailboxStatus, error) { status := imap.NewMailboxStatus(mbox.name, items) status.Flags = mbox.flags - status.PermanentFlags = []string{imap.SeenFlag, imap.AnsweredFlag, imap.FlaggedFlag, imap.DeletedFlag, imap.DraftFlag} + status.PermanentFlags = []string{imap.SeenFlag, imap.FlaggedFlag, imap.DeletedFlag} status.UnseenSeqNum = 0 // TODO for _, name := range items { @@ -346,8 +346,62 @@ func (mbox *mailbox) CreateMessage(flags []string, date time.Time, body imap.Lit return errNotYetImplemented // TODO } -func (mbox *mailbox) UpdateMessagesFlags(uid bool, seqSet *imap.SeqSet, operation imap.FlagsOp, flags []string) error { - return errNotYetImplemented // TODO +func (mbox *mailbox) fromSeqSet(isUID bool, seqSet *imap.SeqSet) ([]string, error) { + var apiIDs []string + err := mbox.db.ForEach(func(seqNum, uid uint32, apiID string) error { + var id uint32 + if isUID { + id = uid + } else { + id = seqNum + } + + if seqSet.Contains(id) { + apiIDs = append(apiIDs, apiID) + } + return nil + }) + return apiIDs, err +} + +func (mbox *mailbox) UpdateMessagesFlags(uid bool, seqSet *imap.SeqSet, op imap.FlagsOp, flags []string) error { + if err := mbox.init(); err != nil { + return err + } + + apiIDs, err := mbox.fromSeqSet(uid, seqSet) + if err != nil { + return err + } + + // TODO: imap.SetFlags should remove currently set flags + + for _, flag := range flags { + var err error + switch flag { + case imap.SeenFlag: + switch op { + case imap.SetFlags, imap.AddFlags: + err = mbox.u.c.MarkMessagesRead(apiIDs) + case imap.RemoveFlags: + err = mbox.u.c.MarkMessagesUnread(apiIDs) + } + case imap.FlaggedFlag: + switch op { + case imap.SetFlags, imap.AddFlags: + err = mbox.u.c.LabelMessages(protonmail.LabelStarred, apiIDs) + case imap.RemoveFlags: + err = mbox.u.c.UnlabelMessages(protonmail.LabelStarred, apiIDs) + } + case imap.DeletedFlag: + // TODO + } + if err != nil { + return err + } + } + + return nil } func (mbox *mailbox) CopyMessages(uid bool, seqSet *imap.SeqSet, dest string) error { diff --git a/protonmail/messages.go b/protonmail/messages.go index a7c3c20..8b27642 100644 --- a/protonmail/messages.go +++ b/protonmail/messages.go @@ -292,6 +292,63 @@ func (c *Client) UpdateDraftMessage(msg *Message) (*Message, error) { return respData.Message, nil } +func (c *Client) doMessages(action string, ids []string) error { + reqData := struct { + IDs []string + }{ids} + req, err := c.newJSONRequest(http.MethodPut, "/messages/"+action, &reqData) + if err != nil { + return err + } + + // TODO: the response contains one response per message + return c.doJSON(req, nil) +} + +func (c *Client) MarkMessagesRead(ids []string) error { + return c.doMessages("read", ids) +} + +func (c *Client) MarkMessagesUnread(ids []string) error { + return c.doMessages("unread", ids) +} + +func (c *Client) DeleteMessages(ids []string) error { + return c.doMessages("delete", ids) +} + +func (c *Client) UndeleteMessages(ids []string) error { + return c.doMessages("undelete", ids) +} + +func (c *Client) LabelMessages(labelID string, ids []string) error { + reqData := struct { + LabelID string + IDs []string + }{labelID, ids} + req, err := c.newJSONRequest(http.MethodPut, "/messages/label", &reqData) + if err != nil { + return err + } + + // TODO: the response contains one response per message + return c.doJSON(req, nil) +} + +func (c *Client) UnlabelMessages(labelID string, ids []string) error { + reqData := struct { + LabelID string + IDs []string + }{labelID, ids} + req, err := c.newJSONRequest(http.MethodPut, "/messages/unlabel", &reqData) + if err != nil { + return err + } + + // TODO: the response contains one response per message + return c.doJSON(req, nil) +} + type MessageKeyPacket struct { ID string KeyPackets string