refactor ParseMessageFormat to use a ctx object

This commit is contained in:
Reto Brunner 2020-10-14 08:42:26 +02:00
parent b6bcf89784
commit 75cbf76732
3 changed files with 74 additions and 60 deletions

View file

@ -37,9 +37,12 @@ func (trig *TriggersConfig) ExecNewEmail(account *AccountConfig,
err := trig.ExecTrigger(trig.NewEmail, err := trig.ExecTrigger(trig.NewEmail,
func(part string) (string, error) { func(part string) (string, error) {
formatstr, args, err := format.ParseMessageFormat( formatstr, args, err := format.ParseMessageFormat(
account.From, part, conf.Ui.TimestampFormat,
part, format.Ctx{
conf.Ui.TimestampFormat, account.Name, 0, msg, false) FromAddress: account.From,
AccountName: account.Name,
MsgInfo: msg},
)
if err != nil { if err != nil {
return "", err return "", err
} }

View file

@ -48,20 +48,26 @@ func FormatAddresses(l []*models.Address) string {
return strings.Join(formatted, ", ") return strings.Join(formatted, ", ")
} }
func ParseMessageFormat( type Ctx struct {
fromAddress string, FromAddress string
format string, timestampformat string, AccountName string
accountName string, number int, msg *models.MessageInfo, MsgNum int
marked bool) (string, MsgInfo *models.MessageInfo
MsgIsMarked bool
}
func ParseMessageFormat(format string, timeFmt string, ctx Ctx) (string,
[]interface{}, error) { []interface{}, error) {
retval := make([]byte, 0, len(format)) retval := make([]byte, 0, len(format))
var args []interface{} var args []interface{}
accountFromAddress, err := ParseAddress(fromAddress) accountFromAddress, err := ParseAddress(ctx.FromAddress)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
envelope := ctx.MsgInfo.Envelope
var c rune var c rune
for i, ni := 0, 0; i < len(format); { for i, ni := 0, 0; i < len(format); {
ni = strings.IndexByte(format[i:], '%') ni = strings.IndexByte(format[i:], '%')
@ -108,80 +114,80 @@ func ParseMessageFormat(
case '%': case '%':
retval = append(retval, '%') retval = append(retval, '%')
case 'a': case 'a':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
if len(msg.Envelope.From) == 0 { if len(envelope.From) == 0 {
return "", nil, return "", nil,
errors.New("found no address for sender") errors.New("found no address for sender")
} }
addr := msg.Envelope.From[0] addr := envelope.From[0]
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, addr.Address) args = append(args, addr.Address)
case 'A': case 'A':
if msg.Envelope == nil { if envelope == nil {
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 *models.Address
if len(msg.Envelope.ReplyTo) == 0 { if len(envelope.ReplyTo) == 0 {
if len(msg.Envelope.From) == 0 { if len(envelope.From) == 0 {
return "", nil, return "", nil,
errors.New("found no address for sender or reply-to") errors.New("found no address for sender or reply-to")
} else { } else {
addr = msg.Envelope.From[0] addr = envelope.From[0]
} }
} else { } else {
addr = msg.Envelope.ReplyTo[0] addr = envelope.ReplyTo[0]
} }
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, addr.Address) args = append(args, addr.Address)
case 'C': case 'C':
retval = append(retval, 'd') retval = append(retval, 'd')
args = append(args, number) args = append(args, ctx.MsgNum)
case 'd': case 'd':
date := msg.Envelope.Date date := envelope.Date
if date.IsZero() { if date.IsZero() {
date = msg.InternalDate date = ctx.MsgInfo.InternalDate
} }
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, args = append(args,
dummyIfZeroDate(date.Local(), timestampformat)) dummyIfZeroDate(date.Local(), timeFmt))
case 'D': case 'D':
date := msg.Envelope.Date date := envelope.Date
if date.IsZero() { if date.IsZero() {
date = msg.InternalDate date = ctx.MsgInfo.InternalDate
} }
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, args = append(args,
dummyIfZeroDate(date.Local(), timestampformat)) dummyIfZeroDate(date.Local(), timeFmt))
case 'f': case 'f':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
if len(msg.Envelope.From) == 0 { if len(envelope.From) == 0 {
return "", nil, return "", nil,
errors.New("found no address for sender") errors.New("found no address for sender")
} }
addr := msg.Envelope.From[0].Format() addr := envelope.From[0].Format()
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, addr) args = append(args, addr)
case 'F': case 'F':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
if len(msg.Envelope.From) == 0 { if len(envelope.From) == 0 {
return "", nil, return "", nil,
errors.New("found no address for sender") errors.New("found no address for sender")
} }
addr := msg.Envelope.From[0] addr := envelope.From[0]
var val string var val string
if addr.Name == accountFromAddress.Name && len(msg.Envelope.To) != 0 { if addr.Name == accountFromAddress.Name && len(envelope.To) != 0 {
addr = msg.Envelope.To[0] addr = envelope.To[0]
} }
if addr.Name != "" { if addr.Name != "" {
@ -194,25 +200,25 @@ func ParseMessageFormat(
case 'g': case 'g':
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, strings.Join(msg.Labels, ", ")) args = append(args, strings.Join(ctx.MsgInfo.Labels, ", "))
case 'i': case 'i':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, msg.Envelope.MessageId) args = append(args, envelope.MessageId)
case 'n': case 'n':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
if len(msg.Envelope.From) == 0 { if len(envelope.From) == 0 {
return "", nil, return "", nil,
errors.New("found no address for sender") errors.New("found no address for sender")
} }
addr := msg.Envelope.From[0] addr := envelope.From[0]
var val string var val string
if addr.Name != "" { if addr.Name != "" {
val = addr.Name val = addr.Name
@ -222,53 +228,53 @@ func ParseMessageFormat(
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, val) args = append(args, val)
case 'r': case 'r':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
addrs := FormatAddresses(msg.Envelope.To) addrs := FormatAddresses(envelope.To)
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, addrs) args = append(args, addrs)
case 'R': case 'R':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
addrs := FormatAddresses(msg.Envelope.Cc) addrs := FormatAddresses(envelope.Cc)
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, addrs) args = append(args, addrs)
case 's': case 's':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, msg.Envelope.Subject) args = append(args, envelope.Subject)
case 't': case 't':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
if len(msg.Envelope.To) == 0 { if len(envelope.To) == 0 {
return "", nil, return "", nil,
errors.New("found no address for recipient") errors.New("found no address for recipient")
} }
addr := msg.Envelope.To[0] addr := envelope.To[0]
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, addr.Address) args = append(args, addr.Address)
case 'T': case 'T':
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, accountName) args = append(args, ctx.AccountName)
case 'u': case 'u':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
if len(msg.Envelope.From) == 0 { if len(envelope.From) == 0 {
return "", nil, return "", nil,
errors.New("found no address for sender") errors.New("found no address for sender")
} }
addr := msg.Envelope.From[0] addr := envelope.From[0]
mailbox := addr.Address // fallback if there's no @ sign mailbox := addr.Address // fallback if there's no @ sign
if split := strings.SplitN(addr.Address, "@", 2); len(split) == 2 { if split := strings.SplitN(addr.Address, "@", 2); len(split) == 2 {
mailbox = split[1] mailbox = split[1]
@ -276,15 +282,15 @@ func ParseMessageFormat(
retval = append(retval, 's') retval = append(retval, 's')
args = append(args, mailbox) args = append(args, mailbox)
case 'v': case 'v':
if msg.Envelope == nil { if envelope == nil {
return "", nil, return "", nil,
errors.New("no envelope available for this message") errors.New("no envelope available for this message")
} }
if len(msg.Envelope.From) == 0 { if len(envelope.From) == 0 {
return "", nil, return "", nil,
errors.New("found no address for sender") errors.New("found no address for sender")
} }
addr := msg.Envelope.From[0] addr := envelope.From[0]
// check if message is from current user // check if message is from current user
if addr.Name != "" { if addr.Name != "" {
retval = append(retval, 's') retval = append(retval, 's')
@ -300,7 +306,7 @@ func ParseMessageFormat(
seen := false seen := false
recent := false recent := false
answered := false answered := false
for _, flag := range msg.Flags { for _, flag := range ctx.MsgInfo.Flags {
if flag == models.SeenFlag { if flag == models.SeenFlag {
seen = true seen = true
} else if flag == models.RecentFlag { } else if flag == models.RecentFlag {
@ -328,7 +334,7 @@ func ParseMessageFormat(
readReplyFlag = "O" // message is old readReplyFlag = "O" // message is old
} }
} }
if marked { if ctx.MsgIsMarked {
markedFlag = "*" markedFlag = "*"
} }
retval = append(retval, '4', 's') retval = append(retval, '4', 's')
@ -339,7 +345,7 @@ func ParseMessageFormat(
case 'l': case 'l':
// TODO: number of lines in the message // TODO: number of lines in the message
retval = append(retval, 'd') retval = append(retval, 'd')
args = append(args, msg.Size) args = append(args, ctx.MsgInfo.Size)
case 'e': case 'e':
// TODO: current message number in thread // TODO: current message number in thread
fallthrough fallthrough

View file

@ -150,9 +150,14 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
ctx.Fill(0, row, ctx.Width(), 1, ' ', style) ctx.Fill(0, row, ctx.Width(), 1, ' ', style)
fmtStr, args, err := format.ParseMessageFormat( fmtStr, args, err := format.ParseMessageFormat(
ml.aerc.SelectedAccount().acct.From, uiConfig.IndexFormat, uiConfig.TimestampFormat,
uiConfig.IndexFormat, format.Ctx{
uiConfig.TimestampFormat, "", i, msg, store.IsMarked(uid)) FromAddress: ml.aerc.SelectedAccount().acct.From,
AccountName: ml.aerc.SelectedAccount().Name(),
MsgInfo: msg,
MsgNum: i,
MsgIsMarked: store.IsMarked(uid),
})
if err != nil { if err != nil {
ctx.Printf(0, row, style, "%v", err) ctx.Printf(0, row, style, "%v", err)
} else { } else {