remove models.Address in favor of go-message Address
We made a new type out of go-message/mail.Address without any real reason. This suddenly made it necessary to convert from one to the other without actually having any benefit whatsoever. This commit gets rid of the additional type
This commit is contained in:
parent
fb67d1f5a3
commit
fc9ccc3000
6 changed files with 58 additions and 57 deletions
|
@ -13,6 +13,7 @@ import (
|
||||||
"git.sr.ht/~sircmpwn/aerc/lib/format"
|
"git.sr.ht/~sircmpwn/aerc/lib/format"
|
||||||
"git.sr.ht/~sircmpwn/aerc/models"
|
"git.sr.ht/~sircmpwn/aerc/models"
|
||||||
"git.sr.ht/~sircmpwn/aerc/widgets"
|
"git.sr.ht/~sircmpwn/aerc/widgets"
|
||||||
|
"github.com/emersion/go-message/mail"
|
||||||
)
|
)
|
||||||
|
|
||||||
type reply struct{}
|
type reply struct{}
|
||||||
|
@ -97,8 +98,8 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
to []*models.Address
|
to []*mail.Address
|
||||||
cc []*models.Address
|
cc []*mail.Address
|
||||||
)
|
)
|
||||||
|
|
||||||
recSet := newAddrSet() // used for de-duping
|
recSet := newAddrSet() // used for de-duping
|
||||||
|
@ -117,7 +118,7 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
// we add our from address, so that we don't self address ourselves
|
// we add our from address, so that we don't self address ourselves
|
||||||
recSet.Add(from)
|
recSet.Add(from)
|
||||||
|
|
||||||
envTos := make([]*models.Address, 0, len(msg.Envelope.To))
|
envTos := make([]*mail.Address, 0, len(msg.Envelope.To))
|
||||||
for _, addr := range msg.Envelope.To {
|
for _, addr := range msg.Envelope.To {
|
||||||
if recSet.Contains(addr) {
|
if recSet.Contains(addr) {
|
||||||
continue
|
continue
|
||||||
|
@ -147,7 +148,7 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
defaults := map[string]string{
|
defaults := map[string]string{
|
||||||
"To": format.FormatAddresses(to),
|
"To": format.FormatAddresses(to),
|
||||||
"Cc": format.FormatAddresses(cc),
|
"Cc": format.FormatAddresses(cc),
|
||||||
"From": from.Format(),
|
"From": format.AddressForHumans(from),
|
||||||
"Subject": subject,
|
"Subject": subject,
|
||||||
"In-Reply-To": msg.Envelope.MessageId,
|
"In-Reply-To": msg.Envelope.MessageId,
|
||||||
}
|
}
|
||||||
|
@ -231,17 +232,17 @@ func newAddrSet() addrSet {
|
||||||
return addrSet(s)
|
return addrSet(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s addrSet) Add(a *models.Address) {
|
func (s addrSet) Add(a *mail.Address) {
|
||||||
s[a.Address] = struct{}{}
|
s[a.Address] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s addrSet) AddList(al []*models.Address) {
|
func (s addrSet) AddList(al []*mail.Address) {
|
||||||
for _, a := range al {
|
for _, a := range al {
|
||||||
s[a.Address] = struct{}{}
|
s[a.Address] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s addrSet) Contains(a *models.Address) bool {
|
func (s addrSet) Contains(a *mail.Address) bool {
|
||||||
_, ok := s[a.Address]
|
_, ok := s[a.Address]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,28 @@ package format
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"mime"
|
"mime"
|
||||||
gomail "net/mail"
|
gomail "net/mail"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"git.sr.ht/~sircmpwn/aerc/models"
|
"git.sr.ht/~sircmpwn/aerc/models"
|
||||||
"github.com/emersion/go-message"
|
"github.com/emersion/go-message"
|
||||||
|
"github.com/emersion/go-message/mail"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseAddress(address string) (*models.Address, error) {
|
func ParseAddress(address string) (*mail.Address, error) {
|
||||||
addrs, err := gomail.ParseAddress(address)
|
addrs, err := gomail.ParseAddress(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return (*models.Address)(addrs), nil
|
return (*mail.Address)(addrs), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseAddressList(s string) ([]*models.Address, error) {
|
func ParseAddressList(s string) ([]*mail.Address, error) {
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
// we don't consider an empty list to be an error
|
// we don't consider an empty list to be an error
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -33,17 +36,35 @@ func ParseAddressList(s string) ([]*models.Address, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addrs := make([]*models.Address, len(list))
|
addrs := make([]*mail.Address, len(list))
|
||||||
for i, a := range list {
|
for i, a := range list {
|
||||||
addrs[i] = (*models.Address)(a)
|
addrs[i] = (*mail.Address)(a)
|
||||||
}
|
}
|
||||||
return addrs, nil
|
return addrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FormatAddresses(l []*models.Address) string {
|
// AddressForHumans formats the address. If the address's name
|
||||||
|
// contains non-ASCII characters it will be quoted but not encoded.
|
||||||
|
// Meant for display purposes to the humans, not for sending over the wire.
|
||||||
|
func AddressForHumans(a *mail.Address) string {
|
||||||
|
if a.Name != "" {
|
||||||
|
if atom.MatchString(a.Name) {
|
||||||
|
return fmt.Sprintf("%s <%s>", a.Name, a.Address)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("\"%s\" <%s>",
|
||||||
|
strings.ReplaceAll(a.Name, "\"", "'"), a.Address)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("<%s>", a.Address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var atom *regexp.Regexp = regexp.MustCompile("^[a-z0-9!#$%7'*+-/=?^_`{}|~ ]+$")
|
||||||
|
|
||||||
|
func FormatAddresses(l []*mail.Address) string {
|
||||||
formatted := make([]string, len(l))
|
formatted := make([]string, len(l))
|
||||||
for i, a := range l {
|
for i, a := range l {
|
||||||
formatted[i] = a.Format()
|
formatted[i] = AddressForHumans(a)
|
||||||
}
|
}
|
||||||
return strings.Join(formatted, ", ")
|
return strings.Join(formatted, ", ")
|
||||||
}
|
}
|
||||||
|
@ -130,7 +151,7 @@ func ParseMessageFormat(format string, timeFmt string, ctx Ctx) (string,
|
||||||
return "", nil,
|
return "", nil,
|
||||||
errors.New("no envelope available for this message")
|
errors.New("no envelope available for this message")
|
||||||
}
|
}
|
||||||
var addr *models.Address
|
var addr *mail.Address
|
||||||
if len(envelope.ReplyTo) == 0 {
|
if len(envelope.ReplyTo) == 0 {
|
||||||
if len(envelope.From) == 0 {
|
if len(envelope.From) == 0 {
|
||||||
return "", nil,
|
return "", nil,
|
||||||
|
@ -171,7 +192,7 @@ func ParseMessageFormat(format string, timeFmt string, ctx Ctx) (string,
|
||||||
return "", nil,
|
return "", nil,
|
||||||
errors.New("found no address for sender")
|
errors.New("found no address for sender")
|
||||||
}
|
}
|
||||||
addr := envelope.From[0].Format()
|
addr := AddressForHumans(envelope.From[0])
|
||||||
retval = append(retval, 's')
|
retval = append(retval, 's')
|
||||||
args = append(args, addr)
|
args = append(args, addr)
|
||||||
case 'F':
|
case 'F':
|
||||||
|
|
|
@ -3,9 +3,6 @@ package models
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
gomail "net/mail"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/emersion/go-message/mail"
|
"github.com/emersion/go-message/mail"
|
||||||
|
@ -127,34 +124,14 @@ func (bs *BodyStructure) PartAtIndex(index []int) (*BodyStructure, error) {
|
||||||
type Envelope struct {
|
type Envelope struct {
|
||||||
Date time.Time
|
Date time.Time
|
||||||
Subject string
|
Subject string
|
||||||
From []*Address
|
From []*mail.Address
|
||||||
ReplyTo []*Address
|
ReplyTo []*mail.Address
|
||||||
To []*Address
|
To []*mail.Address
|
||||||
Cc []*Address
|
Cc []*mail.Address
|
||||||
Bcc []*Address
|
Bcc []*mail.Address
|
||||||
MessageId string
|
MessageId string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Address gomail.Address
|
|
||||||
|
|
||||||
var atom *regexp.Regexp = regexp.MustCompile("^[a-z0-9!#$%7'*+-/=?^_`{}|~ ]+$")
|
|
||||||
|
|
||||||
// String formats the address. If the address's name
|
|
||||||
// contains non-ASCII characters it will be quoted but not encoded.
|
|
||||||
// Meant for display purposes to the humans, not for sending over the wire.
|
|
||||||
func (a *Address) Format() string {
|
|
||||||
if a.Name != "" {
|
|
||||||
if atom.MatchString(a.Name) {
|
|
||||||
return fmt.Sprintf("%s <%s>", a.Name, a.Address)
|
|
||||||
} else {
|
|
||||||
return fmt.Sprintf("\"%s\" <%s>",
|
|
||||||
strings.ReplaceAll(a.Name, "\"", "'"), a.Address)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return fmt.Sprintf("<%s>", a.Address)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// OriginalMail is helper struct used for reply/forward
|
// OriginalMail is helper struct used for reply/forward
|
||||||
type OriginalMail struct {
|
type OriginalMail struct {
|
||||||
Date time.Time
|
Date time.Time
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"git.sr.ht/~sircmpwn/aerc/models"
|
"git.sr.ht/~sircmpwn/aerc/models"
|
||||||
"github.com/emersion/go-message/charset"
|
"github.com/emersion/go-message/charset"
|
||||||
|
"github.com/emersion/go-message/mail"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -59,10 +60,10 @@ func translateEnvelope(e *imap.Envelope) *models.Envelope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func translateAddresses(addrs []*imap.Address) []*models.Address {
|
func translateAddresses(addrs []*imap.Address) []*mail.Address {
|
||||||
var converted []*models.Address
|
var converted []*mail.Address
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
converted = append(converted, &models.Address{
|
converted = append(converted, &mail.Address{
|
||||||
Name: addr.PersonalName,
|
Name: addr.PersonalName,
|
||||||
Address: addr.Address(),
|
Address: addr.Address(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -193,19 +193,19 @@ func parseReceivedHeader(h *mail.Header) (time.Time, error) {
|
||||||
return time.Parse(time.RFC1123Z, dateRe.FindString(guess))
|
return time.Parse(time.RFC1123Z, dateRe.FindString(guess))
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAddressList(h *mail.Header, key string) ([]*models.Address, error) {
|
func parseAddressList(h *mail.Header, key string) ([]*mail.Address, error) {
|
||||||
var converted []*models.Address
|
var converted []*mail.Address
|
||||||
addrs, err := h.AddressList(key)
|
addrs, err := h.AddressList(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if hdr, err := h.Text(key); err == nil {
|
if hdr, err := h.Text(key); err == nil {
|
||||||
return []*models.Address{&models.Address{
|
return []*mail.Address{&mail.Address{
|
||||||
Name: hdr,
|
Name: hdr,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
converted = append(converted, &models.Address{
|
converted = append(converted, &mail.Address{
|
||||||
Name: addr.Name,
|
Name: addr.Name,
|
||||||
Address: addr.Address,
|
Address: addr.Address,
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"git.sr.ht/~sircmpwn/aerc/models"
|
"git.sr.ht/~sircmpwn/aerc/models"
|
||||||
"git.sr.ht/~sircmpwn/aerc/worker/types"
|
"git.sr.ht/~sircmpwn/aerc/worker/types"
|
||||||
|
"github.com/emersion/go-message/mail"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Sort(messageInfos []*models.MessageInfo,
|
func Sort(messageInfos []*models.MessageInfo,
|
||||||
|
@ -20,7 +21,7 @@ func Sort(messageInfos []*models.MessageInfo,
|
||||||
})
|
})
|
||||||
case types.SortCc:
|
case types.SortCc:
|
||||||
sortAddresses(messageInfos, criterion,
|
sortAddresses(messageInfos, criterion,
|
||||||
func(msgInfo *models.MessageInfo) []*models.Address {
|
func(msgInfo *models.MessageInfo) []*mail.Address {
|
||||||
return msgInfo.Envelope.Cc
|
return msgInfo.Envelope.Cc
|
||||||
})
|
})
|
||||||
case types.SortDate:
|
case types.SortDate:
|
||||||
|
@ -29,7 +30,7 @@ func Sort(messageInfos []*models.MessageInfo,
|
||||||
})
|
})
|
||||||
case types.SortFrom:
|
case types.SortFrom:
|
||||||
sortAddresses(messageInfos, criterion,
|
sortAddresses(messageInfos, criterion,
|
||||||
func(msgInfo *models.MessageInfo) []*models.Address {
|
func(msgInfo *models.MessageInfo) []*mail.Address {
|
||||||
return msgInfo.Envelope.From
|
return msgInfo.Envelope.From
|
||||||
})
|
})
|
||||||
case types.SortRead:
|
case types.SortRead:
|
||||||
|
@ -47,7 +48,7 @@ func Sort(messageInfos []*models.MessageInfo,
|
||||||
})
|
})
|
||||||
case types.SortTo:
|
case types.SortTo:
|
||||||
sortAddresses(messageInfos, criterion,
|
sortAddresses(messageInfos, criterion,
|
||||||
func(msgInfo *models.MessageInfo) []*models.Address {
|
func(msgInfo *models.MessageInfo) []*mail.Address {
|
||||||
return msgInfo.Envelope.To
|
return msgInfo.Envelope.To
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -61,10 +62,10 @@ func Sort(messageInfos []*models.MessageInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
func sortAddresses(messageInfos []*models.MessageInfo, criterion *types.SortCriterion,
|
func sortAddresses(messageInfos []*models.MessageInfo, criterion *types.SortCriterion,
|
||||||
getValue func(*models.MessageInfo) []*models.Address) {
|
getValue func(*models.MessageInfo) []*mail.Address) {
|
||||||
sortSlice(criterion, messageInfos, func(i, j int) bool {
|
sortSlice(criterion, messageInfos, func(i, j int) bool {
|
||||||
addressI, addressJ := getValue(messageInfos[i]), getValue(messageInfos[j])
|
addressI, addressJ := getValue(messageInfos[i]), getValue(messageInfos[j])
|
||||||
var firstI, firstJ *models.Address
|
var firstI, firstJ *mail.Address
|
||||||
if len(addressI) > 0 {
|
if len(addressI) > 0 {
|
||||||
firstI = addressI[0]
|
firstI = addressI[0]
|
||||||
}
|
}
|
||||||
|
@ -78,7 +79,7 @@ func sortAddresses(messageInfos []*models.MessageInfo, criterion *types.SortCrit
|
||||||
} else if firstI != nil && firstJ == nil {
|
} else if firstI != nil && firstJ == nil {
|
||||||
return true
|
return true
|
||||||
} else /* firstI != nil && firstJ != nil */ {
|
} else /* firstI != nil && firstJ != nil */ {
|
||||||
getName := func(addr *models.Address) string {
|
getName := func(addr *mail.Address) string {
|
||||||
if addr.Name != "" {
|
if addr.Name != "" {
|
||||||
return addr.Name
|
return addr.Name
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue