aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2023-06-07 00:57:40 +0200
committerRobin Jarry <robin@jarry.cc>2023-06-07 00:57:40 +0200
commitc0f4b2632045b53f08f1c9f6e1b0e56713ec7ba4 (patch)
tree3809035df3baff5e2ff4858895c6158491ad2ff1
parent9e27c777d4c818dd4a9f265d174686ea988f9955 (diff)
downloadaerc-jmap.tar.gz
aerc-jmap.zip
wipjmap
Signed-off-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--worker/jmap/configure.go18
-rw-r--r--worker/jmap/connect.go10
-rw-r--r--worker/jmap/directories.go3
-rw-r--r--worker/jmap/list.go53
-rw-r--r--worker/jmap/mboxstate.go3
-rw-r--r--worker/jmap/set.go42
-rw-r--r--worker/jmap/worker.go17
7 files changed, 113 insertions, 33 deletions
diff --git a/worker/jmap/configure.go b/worker/jmap/configure.go
index 889ef06e..f423ce4b 100644
--- a/worker/jmap/configure.go
+++ b/worker/jmap/configure.go
@@ -15,8 +15,8 @@ func (w *JMAPWorker) handleConfigure(msg *types.Configure) error {
}
if strings.HasSuffix(u.Scheme, "+oauthbearer") {
- w.oauth = true
- w.query = u.Query()
+ w.config.oauth = true
+ w.config.query = u.Query()
} else {
if u.User == nil {
return fmt.Errorf("user:password not specified")
@@ -29,12 +29,20 @@ func (w *JMAPWorker) handleConfigure(msg *types.Configure) error {
u.RawQuery = ""
u.Fragment = ""
- w.user = u.User
+ w.config.user = u.User
u.User = nil
u.Scheme = "https"
- w.endpoint = u.String()
- w.account = msg.Config
+ w.config.endpoint = u.String()
+ w.config.account = msg.Config
+ switch strings.ToLower(msg.Config.Params["use-labels"]) {
+ case "1", "t", "true", "yes", "y", "on":
+ w.config.useLabels = true
+ }
+ w.config.allMailName = msg.Config.Params["all-mail-name"]
+ if w.config.allMailName == "" {
+ w.config.allMailName = "All mail"
+ }
return nil
}
diff --git a/worker/jmap/connect.go b/worker/jmap/connect.go
index 740dd251..b4ce45ec 100644
--- a/worker/jmap/connect.go
+++ b/worker/jmap/connect.go
@@ -8,14 +8,14 @@ import (
func (w *JMAPWorker) handleConnect(msg *types.Connect) error {
w.w.Debugf("connecting")
- client := &jmap.Client{SessionEndpoint: w.endpoint}
+ client := &jmap.Client{SessionEndpoint: w.config.endpoint}
- if w.oauth {
- pass, _ := w.user.Password()
+ if w.config.oauth {
+ pass, _ := w.config.user.Password()
client.WithAccessToken(pass)
} else {
- user := w.user.Username()
- pass, _ := w.user.Password()
+ user := w.config.user.Username()
+ pass, _ := w.config.user.Password()
client.WithBasicAuth(user, pass)
}
diff --git a/worker/jmap/directories.go b/worker/jmap/directories.go
index dbbb521a..71c0a838 100644
--- a/worker/jmap/directories.go
+++ b/worker/jmap/directories.go
@@ -130,6 +130,9 @@ func (w *JMAPWorker) handleCreateDirectory(msg *types.CreateDirectory) error {
if err != nil {
return err
}
+ if msg.Quiet {
+ return nil
+ }
for _, inv := range resp.Responses {
switch r := inv.Args.(type) {
case *mailbox.SetResponse:
diff --git a/worker/jmap/list.go b/worker/jmap/list.go
index cba3db91..cd11707d 100644
--- a/worker/jmap/list.go
+++ b/worker/jmap/list.go
@@ -11,6 +11,7 @@ import (
func (w *JMAPWorker) handleListDirectories(msg *types.ListDirectories) error {
var req jmap.Request
+ var ids []jmap.ID
w.w.Debugf("listing directories")
@@ -23,8 +24,17 @@ func (w *JMAPWorker) handleListDirectories(msg *types.ListDirectories) error {
for _, inv := range resp.Responses {
switch r := inv.Args.(type) {
case *mailbox.GetResponse:
+ ids = make([]jmap.ID, 0, len(r.List))
for _, mbox := range r.List {
w.mboxes[mbox.ID] = &MailboxState{mbox: mbox}
+ if mbox.Role == "archive" && w.config.useLabels {
+ w.mboxes[""] = &MailboxState{
+ dir: w.config.allMailName,
+ }
+ ids = append(ids, "")
+ } else {
+ ids = append(ids, mbox.ID)
+ }
}
w.mboxState = r.State
}
@@ -34,17 +44,42 @@ func (w *JMAPWorker) handleListDirectories(msg *types.ListDirectories) error {
}
for _, m := range w.mboxes {
+ if m.mbox == nil {
+ w.dir2mbox[m.dir] = ""
+ continue
+ }
m.dir = m.FullPath(w.mboxes)
w.dir2mbox[m.dir] = m.mbox.ID
- w.w.PostMessage(&types.Directory{
- Message: types.RespondTo(msg),
- Dir: &models.Directory{
- Name: m.dir,
- Exists: int(m.mbox.TotalEmails),
- Unseen: int(m.mbox.UnreadEmails),
- Role: jmapRole2aerc[m.mbox.Role],
- },
- }, nil)
+ }
+
+ for _, id := range ids {
+ m := w.mboxes[id]
+ if m.mbox == nil {
+ w.w.PostMessage(&types.Directory{
+ Message: types.RespondTo(msg),
+ Dir: &models.Directory{
+ Name: m.dir,
+ Role: models.AllRole,
+ },
+ }, nil)
+ } else {
+ role := jmapRole2aerc[m.mbox.Role]
+ switch role {
+ case models.ArchiveRole:
+ w.archiveMbox = m.mbox.ID
+ case models.TrashRole:
+ w.trashMbox = m.mbox.ID
+ }
+ w.w.PostMessage(&types.Directory{
+ Message: types.RespondTo(msg),
+ Dir: &models.Directory{
+ Name: m.dir,
+ Exists: int(m.mbox.TotalEmails),
+ Unseen: int(m.mbox.UnreadEmails),
+ Role: role,
+ },
+ }, nil)
+ }
}
go w.monitorChanges()
diff --git a/worker/jmap/mboxstate.go b/worker/jmap/mboxstate.go
index 0ee8bde3..975d18ed 100644
--- a/worker/jmap/mboxstate.go
+++ b/worker/jmap/mboxstate.go
@@ -17,6 +17,9 @@ type MailboxState struct {
}
func (s *MailboxState) FullPath(all map[jmap.ID]*MailboxState) string {
+ if s.mbox == nil {
+ return s.dir
+ }
if s.mbox.ParentID == "" {
return s.mbox.Name
}
diff --git a/worker/jmap/set.go b/worker/jmap/set.go
index d5d4990e..1661f5b1 100644
--- a/worker/jmap/set.go
+++ b/worker/jmap/set.go
@@ -59,36 +59,50 @@ func (w *JMAPWorker) updateFlags(uids []uint32, flags models.Flags, enable bool)
return nil
}
-func (w *JMAPWorker) moveCopy(uids []uint32, destDir string, move bool) error {
+func (w *JMAPWorker) moveCopy(uids []uint32, destDir string, deleteSrc bool) error {
var req jmap.Request
- var dest jmap.ID
+ var destMbox jmap.ID
+ var destroy []jmap.ID
var ok bool
- update := make(map[jmap.ID]jmap.Patch)
+ patches := make(map[jmap.ID]jmap.Patch)
- dest, ok = w.dir2mbox[destDir]
+ destMbox, ok = w.dir2mbox[destDir]
if !ok && destDir != "" {
return fmt.Errorf("unknown destination mailbox")
}
for _, uid := range uids {
+ dest := destMbox
id, ok := w.uidStore.GetKey(uid)
if !ok {
return fmt.Errorf("bug: unknown uid %d", uid)
}
+ mail, ok := w.emails[jmap.ID(id)]
+ if !ok {
+ return fmt.Errorf("bug: unknown message id %s", id)
+ }
patch := jmap.Patch{}
- if dest != "" {
+ if dest == "" {
+ dest = w.fallbackMbox(mail)
+ }
+ if dest != "" && dest != w.selectedMbox {
patch[fmt.Sprintf("mailboxIds/%s", dest)] = true
}
- if move {
+ if deleteSrc {
+ if len(patch) == 0 {
+ destroy = append(destroy, mail.ID)
+ continue
+ }
patch[fmt.Sprintf("mailboxIds/%s", w.selectedMbox)] = nil
}
- update[jmap.ID(id)] = patch
+ patches[jmap.ID(id)] = patch
}
req.Invoke(&email.Set{
Account: w.accountId(),
- Update: update,
+ Update: patches,
+ Destroy: destroy,
})
resp, err := w.client.Do(&req)
@@ -116,3 +130,15 @@ func (w *JMAPWorker) moveCopy(uids []uint32, destDir string, move bool) error {
return nil
}
+
+func (w *JMAPWorker) fallbackMbox(mail *email.Email) jmap.ID {
+ switch {
+ case len(mail.MailboxIDs) > 1:
+ return ""
+ case w.config.useLabels && w.archiveMbox != "":
+ return w.archiveMbox
+ case w.trashMbox != "":
+ return w.trashMbox
+ }
+ return ""
+}
diff --git a/worker/jmap/worker.go b/worker/jmap/worker.go
index f0b3de81..6adc0289 100644
--- a/worker/jmap/worker.go
+++ b/worker/jmap/worker.go
@@ -21,17 +21,22 @@ func init() {
}
type JMAPWorker struct {
- // config
- account *config.AccountConfig
- endpoint string
- oauth bool
- user *url.Userinfo
- query url.Values
+ config struct {
+ account *config.AccountConfig
+ endpoint string
+ oauth bool
+ user *url.Userinfo
+ query url.Values
+ useLabels bool
+ allMailName string
+ }
w *types.Worker
client *jmap.Client
selectedMbox jmap.ID
+ archiveMbox jmap.ID
+ trashMbox jmap.ID
mboxes map[jmap.ID]*MailboxState
dir2mbox map[string]jmap.ID
uidStore *uidstore.Store