init: pristine aerc 0.20.0 source
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
package jmap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"git.sr.ht/~rjarry/aerc/models"
|
||||
"git.sr.ht/~rockorager/go-jmap"
|
||||
"git.sr.ht/~rockorager/go-jmap/mail"
|
||||
"git.sr.ht/~rockorager/go-jmap/mail/email"
|
||||
"git.sr.ht/~rockorager/go-jmap/mail/mailbox"
|
||||
msgmail "github.com/emersion/go-message/mail"
|
||||
)
|
||||
|
||||
func (w *JMAPWorker) translateMsgInfo(m *email.Email) *models.MessageInfo {
|
||||
env := &models.Envelope{
|
||||
Date: *m.ReceivedAt,
|
||||
Subject: m.Subject,
|
||||
From: translateAddrList(m.From),
|
||||
ReplyTo: translateAddrList(m.ReplyTo),
|
||||
To: translateAddrList(m.To),
|
||||
Cc: translateAddrList(m.CC),
|
||||
Bcc: translateAddrList(m.BCC),
|
||||
MessageId: firstString(m.MessageID),
|
||||
InReplyTo: firstString(m.InReplyTo),
|
||||
}
|
||||
labels := make([]string, 0, len(m.MailboxIDs))
|
||||
for id := range m.MailboxIDs {
|
||||
if dir, ok := w.mbox2dir[id]; ok {
|
||||
labels = append(labels, dir)
|
||||
}
|
||||
}
|
||||
sort.Strings(labels)
|
||||
|
||||
return &models.MessageInfo{
|
||||
Envelope: env,
|
||||
Flags: keywordsToFlags(m.Keywords),
|
||||
Uid: models.UID(m.ID),
|
||||
BodyStructure: translateBodyStructure(m.BodyStructure),
|
||||
RFC822Headers: translateJMAPHeader(m.Headers),
|
||||
Refs: m.References,
|
||||
Labels: labels,
|
||||
Size: uint32(m.Size),
|
||||
InternalDate: *m.ReceivedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func translateJMAPHeader(headers []*email.Header) *msgmail.Header {
|
||||
hdr := new(msgmail.Header)
|
||||
for _, h := range headers {
|
||||
raw := fmt.Sprintf("%s:%s\r\n", h.Name, h.Value)
|
||||
hdr.AddRaw([]byte(raw))
|
||||
}
|
||||
return hdr
|
||||
}
|
||||
|
||||
func flagsToKeywords(flags models.Flags) map[string]bool {
|
||||
kw := make(map[string]bool)
|
||||
if flags.Has(models.SeenFlag) {
|
||||
kw["$seen"] = true
|
||||
}
|
||||
if flags.Has(models.AnsweredFlag) {
|
||||
kw["$answered"] = true
|
||||
}
|
||||
if flags.Has(models.FlaggedFlag) {
|
||||
kw["$flagged"] = true
|
||||
}
|
||||
if flags.Has(models.DraftFlag) {
|
||||
kw["$draft"] = true
|
||||
}
|
||||
return kw
|
||||
}
|
||||
|
||||
func keywordsToFlags(kw map[string]bool) models.Flags {
|
||||
var f models.Flags
|
||||
for k, v := range kw {
|
||||
if v {
|
||||
switch k {
|
||||
case "$seen":
|
||||
f |= models.SeenFlag
|
||||
case "$answered":
|
||||
f |= models.AnsweredFlag
|
||||
case "$flagged":
|
||||
f |= models.FlaggedFlag
|
||||
case "$draft":
|
||||
f |= models.DraftFlag
|
||||
}
|
||||
}
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (w *JMAPWorker) MailboxPath(mbox *mailbox.Mailbox) string {
|
||||
if mbox == nil {
|
||||
return ""
|
||||
}
|
||||
if mbox.ParentID == "" {
|
||||
return mbox.Name
|
||||
}
|
||||
parent, err := w.cache.GetMailbox(mbox.ParentID)
|
||||
if err != nil {
|
||||
w.w.Warnf("MailboxPath/GetMailbox: %s", err)
|
||||
return mbox.Name
|
||||
}
|
||||
return w.MailboxPath(parent) + "/" + mbox.Name
|
||||
}
|
||||
|
||||
var jmapRole2aerc = map[mailbox.Role]models.Role{
|
||||
mailbox.RoleAll: models.AllRole,
|
||||
mailbox.RoleArchive: models.ArchiveRole,
|
||||
mailbox.RoleDrafts: models.DraftsRole,
|
||||
mailbox.RoleInbox: models.InboxRole,
|
||||
mailbox.RoleJunk: models.JunkRole,
|
||||
mailbox.RoleSent: models.SentRole,
|
||||
mailbox.RoleTrash: models.TrashRole,
|
||||
}
|
||||
|
||||
func firstString(s []string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
return s[0]
|
||||
}
|
||||
|
||||
func translateAddrList(addrs []*mail.Address) []*msgmail.Address {
|
||||
res := make([]*msgmail.Address, 0, len(addrs))
|
||||
for _, a := range addrs {
|
||||
res = append(res, &msgmail.Address{Name: a.Name, Address: a.Email})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func translateBodyStructure(part *email.BodyPart) *models.BodyStructure {
|
||||
bs := &models.BodyStructure{
|
||||
Description: part.Name,
|
||||
Encoding: part.Charset,
|
||||
Params: map[string]string{
|
||||
"name": part.Name,
|
||||
"charset": part.Charset,
|
||||
},
|
||||
Disposition: part.Disposition,
|
||||
DispositionParams: map[string]string{
|
||||
"filename": part.Name,
|
||||
},
|
||||
}
|
||||
bs.MIMEType, bs.MIMESubType, _ = strings.Cut(part.Type, "/")
|
||||
for _, sub := range part.SubParts {
|
||||
bs.Parts = append(bs.Parts, translateBodyStructure(sub))
|
||||
}
|
||||
return bs
|
||||
}
|
||||
|
||||
func wrapSetError(err *jmap.SetError) error {
|
||||
var s string
|
||||
if err.Description != nil {
|
||||
s = *err.Description
|
||||
} else {
|
||||
s = err.Type
|
||||
if err.Properties != nil {
|
||||
s += fmt.Sprintf(" %v", *err.Properties)
|
||||
}
|
||||
if s == "invalidProperties: [mailboxIds]" {
|
||||
s = "a message must belong to one or more mailboxes"
|
||||
}
|
||||
}
|
||||
return errors.New(s)
|
||||
}
|
||||
|
||||
func wrapMethodError(err *jmap.MethodError) error {
|
||||
var s string
|
||||
if err.Description != nil {
|
||||
s = *err.Description
|
||||
} else {
|
||||
s = err.Type
|
||||
}
|
||||
return errors.New(s)
|
||||
}
|
||||
Reference in New Issue
Block a user