mirror of
https://git.sr.ht/~rjarry/aerc
synced 2026-03-02 18:23:33 +01:00
Currently, names of recipients in From, To, Cc and Bcc headers are (almost) always wrapped in quotes. Even if they are pure ASCII and contain one upper case letter. E.g.: From: "Foo" <foo@baz.org> There is no valid reason to add these quotes unless the name contains special characters as specified by RFC 5322, section 3.2.3: specials = "(" / ")" / ; Special characters that do "<" / ">" / ; not appear in atext "[" / "]" / ":" / ";" / "@" / "\" / "," / "." / DQUOTE Adapt the check accordingly. Link: https://datatracker.ietf.org/doc/html/rfc5322#section-3.2.3 Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
89 lines
2.1 KiB
Go
89 lines
2.1 KiB
Go
package format
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
|
|
"github.com/emersion/go-message/mail"
|
|
)
|
|
|
|
const rfc5322specials string = `()<>[]:;@\,."`
|
|
|
|
// AddressForHumans formats the address.
|
|
// Meant for display purposes to the humans, not for sending over the wire.
|
|
func AddressForHumans(a *mail.Address) string {
|
|
if a.Name != "" {
|
|
if strings.ContainsAny(a.Name, rfc5322specials) {
|
|
return fmt.Sprintf("\"%s\" <%s>",
|
|
strings.ReplaceAll(a.Name, "\"", "'"), a.Address)
|
|
} else {
|
|
return fmt.Sprintf("%s <%s>", a.Name, a.Address)
|
|
}
|
|
} else {
|
|
return fmt.Sprintf("<%s>", a.Address)
|
|
}
|
|
}
|
|
|
|
// FormatAddresses formats a list of addresses into a human readable string
|
|
func FormatAddresses(l []*mail.Address) string {
|
|
formatted := make([]string, len(l))
|
|
for i, a := range l {
|
|
formatted[i] = AddressForHumans(a)
|
|
}
|
|
return strings.Join(formatted, ", ")
|
|
}
|
|
|
|
// CompactPath reduces a directory path into a compact form. The directory
|
|
// name will be split with the provided separator and each part will be reduced
|
|
// to the first letter in its name: INBOX/01_WORK/PROJECT will become
|
|
// I/W/PROJECT.
|
|
func CompactPath(name string, sep rune) (compact string) {
|
|
parts := strings.Split(name, string(sep))
|
|
for i, part := range parts {
|
|
if i == len(parts)-1 {
|
|
compact += part
|
|
} else {
|
|
if len(part) != 0 {
|
|
r := part[0]
|
|
for i := 0; i < len(part)-1; i++ {
|
|
if unicode.IsLetter(rune(part[i])) {
|
|
r = part[i]
|
|
break
|
|
}
|
|
}
|
|
compact += fmt.Sprintf("%c%c", r, sep)
|
|
} else {
|
|
compact += fmt.Sprintf("%c", sep)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func DummyIfZeroDate(date time.Time, format string, todayFormat string,
|
|
thisWeekFormat string, thisYearFormat string,
|
|
) string {
|
|
if date.IsZero() {
|
|
return strings.Repeat("?", len(format))
|
|
}
|
|
year := date.Year()
|
|
day := date.YearDay()
|
|
now := time.Now()
|
|
thisYear := now.Year()
|
|
thisDay := now.YearDay()
|
|
if year == thisYear {
|
|
if day == thisDay && todayFormat != "" {
|
|
return date.Format(todayFormat)
|
|
}
|
|
if day > thisDay-7 && thisWeekFormat != "" {
|
|
return date.Format(thisWeekFormat)
|
|
}
|
|
if thisYearFormat != "" {
|
|
return date.Format(thisYearFormat)
|
|
}
|
|
}
|
|
return date.Format(format)
|
|
}
|