reply: use set instead of linear search
This commit is contained in:
parent
b6ef116c36
commit
720733bc6e
1 changed files with 70 additions and 45 deletions
|
@ -64,10 +64,11 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
alias_of_us, err := format.ParseAddressList(conf.Aliases)
|
aliases, err := format.ParseAddressList(conf.Aliases)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
store := widget.Store()
|
store := widget.Store()
|
||||||
if store == nil {
|
if store == nil {
|
||||||
return errors.New("Cannot perform action. Messages still loading")
|
return errors.New("Cannot perform action. Messages still loading")
|
||||||
|
@ -77,61 +78,63 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// figure out the sending from address if we have aliases
|
||||||
|
if len(aliases) != 0 {
|
||||||
|
rec := newAddrSet()
|
||||||
|
rec.AddList(msg.Envelope.To)
|
||||||
|
rec.AddList(msg.Envelope.Cc)
|
||||||
|
// test the from first, it has priority over any present alias
|
||||||
|
if rec.Contains(from) {
|
||||||
|
// do nothing
|
||||||
|
} else {
|
||||||
|
for _, a := range aliases {
|
||||||
|
if rec.Contains(a) {
|
||||||
|
from = a
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
to []*models.Address
|
to []*models.Address
|
||||||
cc []*models.Address
|
cc []*models.Address
|
||||||
)
|
)
|
||||||
if args[0] == "reply" {
|
|
||||||
if len(msg.Envelope.ReplyTo) != 0 {
|
|
||||||
to = msg.Envelope.ReplyTo
|
|
||||||
} else {
|
|
||||||
to = msg.Envelope.From
|
|
||||||
}
|
|
||||||
|
|
||||||
// figure out the sending from address if we have aliases
|
recSet := newAddrSet() // used for de-duping
|
||||||
if len(alias_of_us) != 0 {
|
|
||||||
allRecipients := append(msg.Envelope.To, msg.Envelope.Cc...)
|
|
||||||
outer:
|
|
||||||
for _, addr := range allRecipients {
|
|
||||||
if addr.Address == from.Address {
|
|
||||||
from = addr
|
|
||||||
break
|
|
||||||
}
|
|
||||||
for _, alias := range alias_of_us {
|
|
||||||
if addr.Address == alias.Address {
|
|
||||||
from = addr
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
if len(msg.Envelope.ReplyTo) != 0 {
|
||||||
|
to = msg.Envelope.ReplyTo
|
||||||
|
} else {
|
||||||
|
to = msg.Envelope.From
|
||||||
|
}
|
||||||
|
recSet.AddList(to)
|
||||||
|
|
||||||
isMainRecipient := func(a *models.Address) bool {
|
if replyAll {
|
||||||
for _, ta := range to {
|
// order matters, due to the deduping
|
||||||
if ta.Address == a.Address {
|
// in order of importance, first parse the To, then the Cc header
|
||||||
return true
|
|
||||||
}
|
// we add our from address, so that we don't self address ourselves
|
||||||
|
recSet.Add(from)
|
||||||
|
|
||||||
|
envTos := make([]*models.Address, 0, len(msg.Envelope.To))
|
||||||
|
for _, addr := range msg.Envelope.To {
|
||||||
|
if recSet.Contains(addr) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
return false
|
envTos = append(envTos, addr)
|
||||||
}
|
}
|
||||||
if replyAll {
|
recSet.AddList(envTos)
|
||||||
for _, addr := range msg.Envelope.Cc {
|
to = append(to, envTos...)
|
||||||
//dedupe stuff from the to/from headers
|
|
||||||
if isMainRecipient(addr) || addr.Address == from.Address {
|
for _, addr := range msg.Envelope.Cc {
|
||||||
continue
|
//dedupe stuff from the to/from headers
|
||||||
}
|
if recSet.Contains(addr) {
|
||||||
cc = append(cc, addr)
|
continue
|
||||||
}
|
}
|
||||||
envTos := make([]*models.Address, 0, len(msg.Envelope.To))
|
cc = append(cc, addr)
|
||||||
for _, addr := range msg.Envelope.To {
|
|
||||||
if addr.Address == from.Address {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
envTos = append(envTos, addr)
|
|
||||||
}
|
|
||||||
to = append(to, envTos...)
|
|
||||||
}
|
}
|
||||||
|
recSet.AddList(cc)
|
||||||
}
|
}
|
||||||
|
|
||||||
var subject string
|
var subject string
|
||||||
|
@ -218,3 +221,25 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return addTab()
|
return addTab()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type addrSet map[string]struct{}
|
||||||
|
|
||||||
|
func newAddrSet() addrSet {
|
||||||
|
s := make(map[string]struct{})
|
||||||
|
return addrSet(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s addrSet) Add(a *models.Address) {
|
||||||
|
s[a.Address] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s addrSet) AddList(al []*models.Address) {
|
||||||
|
for _, a := range al {
|
||||||
|
s[a.Address] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s addrSet) Contains(a *models.Address) bool {
|
||||||
|
_, ok := s[a.Address]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue