diff options
author | Robin Jarry <robin@jarry.cc> | 2023-01-25 00:34:59 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-01-26 00:21:14 +0100 |
commit | 63f0e0cbc9a5f072d8915717c89d7ab4f4ff94af (patch) | |
tree | b1940dd2d2a07960786b35f51a7278b326a44179 | |
parent | 402a634937573b86694b372cf76ce375df51f79d (diff) | |
download | aerc-63f0e0cbc9a5f072d8915717c89d7ab4f4ff94af.tar.gz |
viewer: allow piping full headers in a filter
Allow defining a .headers special filter command that will be used only
to process email headers (when [viewer].show-headers=true).
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Kt Programs <ktprograms@gmail.com>
-rw-r--r-- | config/aerc.conf | 6 | ||||
-rw-r--r-- | config/filters.go | 3 | ||||
-rw-r--r-- | doc/aerc-config.5.scd | 11 | ||||
-rw-r--r-- | widgets/msgviewer.go | 54 |
4 files changed, 65 insertions, 9 deletions
diff --git a/config/aerc.conf b/config/aerc.conf index 1ce4810e..b09a7ab7 100644 --- a/config/aerc.conf +++ b/config/aerc.conf @@ -437,6 +437,12 @@ message/rfc822=colorize #subject,~Git(hub|lab)=lolcat -f #from,thatguywhodoesnothardwraphismessages=wrap -w 100 | colorize +# This special filter is only used to post-process email headers when +# [viewer].show-headers=true +# By default, headers are piped directly into the pager. +# +#.headers=colorize + [openers] # # Openers allow you to specify the command to use for the :open action on a diff --git a/config/filters.go b/config/filters.go index 0b7a1cb2..113a6de6 100644 --- a/config/filters.go +++ b/config/filters.go @@ -13,6 +13,7 @@ type FilterType int const ( FILTER_MIMETYPE FilterType = iota FILTER_HEADER + FILTER_HEADERS ) type FilterConfig struct { @@ -57,6 +58,8 @@ func parseFilters(file *ini.File) error { if err != nil { return err } + case filter.Filter == ".headers": + filter.Type = FILTER_HEADERS default: filter.Type = FILTER_MIMETYPE } diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd index cc0a5f80..22c3a40a 100644 --- a/doc/aerc-config.5.scd +++ b/doc/aerc-config.5.scd @@ -644,6 +644,10 @@ The following variables are defined in the filter command environment: Note that said email body is converted into UTF-8 before being passed to filters. +If *show-headers* is enabled, only the currently viewed part body is piped into +the filter command. A special _.headers_ filter command can be defined to post +process the full headers. + ## EXAMPLES _text/plain_ @@ -708,6 +712,13 @@ _text/\*_ text/\*=bat -fP --file-name="$AERC_FILENAME" --style=plain ``` +_.headers_ + Colorize email headers when *show-headers* is _true_. + + ``` + .headers=colorize + ``` + _message/delivery-status_ When not being able to deliver the provider might send such emails: diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go index d33e61cc..d2fc0d80 100644 --- a/widgets/msgviewer.go +++ b/widgets/msgviewer.go @@ -689,9 +689,45 @@ func (pv *PartViewer) attemptCopy() { func (pv *PartViewer) writeMailHeaders() { info := pv.msg.MessageInfo() if config.Viewer.ShowHeaders && info.RFC822Headers != nil { - // header need to bypass the filter, else we run into issues - // with the filter messing with newlines etc. - // hence all writes in this block go directly to the pager + var file io.WriteCloser + + for _, f := range config.Filters { + if f.Type != config.FILTER_HEADERS { + continue + } + log.Debugf("<%s> piping headers in filter: %s", + info.Envelope.MessageId, f.Command) + filter := exec.Command("sh", "-c", f.Command) + if pv.filter != nil { + // inherit from filter env + filter.Env = pv.filter.Env + } + + stdin, err := filter.StdinPipe() + if err == nil { + filter.Stdout = pv.pagerin + filter.Stderr = pv.pagerin + err := filter.Start() + if err == nil { + //nolint:errcheck // who cares? + defer filter.Wait() + file = stdin + } else { + log.Errorf( + "failed to start header filter: %v", + err) + } + } else { + log.Errorf("failed to create pipe: %v", err) + } + break + } + if file == nil { + file = pv.pagerin + } else { + defer file.Close() + } + fields := info.RFC822Headers.Fields() for fields.Next() { var value string @@ -702,22 +738,22 @@ func (pv *PartViewer) writeMailHeaders() { } field := fmt.Sprintf( "%s: %s\n", fields.Key(), value) - _, err = pv.pagerin.Write([]byte(field)) + _, err = file.Write([]byte(field)) if err != nil { - log.Errorf("failed to write to stdin of pager: %v", err) + log.Errorf("failed to write headers: %v", err) } } // virtual header if len(info.Labels) != 0 { labels := fmtHeader(info, "Labels", "", "", "", "") - _, err := pv.pagerin.Write([]byte(fmt.Sprintf("Labels: %s\n", labels))) + _, err := file.Write([]byte(fmt.Sprintf("Labels: %s\n", labels))) if err != nil { - log.Errorf("failed to write to stdin of pager: %v", err) + log.Errorf("failed to write to labels: %v", err) } } - _, err := pv.pagerin.Write([]byte{'\n'}) + _, err := file.Write([]byte{'\n'}) if err != nil { - log.Errorf("failed to write to stdin of pager: %v", err) + log.Errorf("failed to write empty line: %v", err) } } } |