msgviewer: simplify attemptCopy

No functional changes, simply extract more complex stuff into
sub functions to help readability.
This commit is contained in:
Reto Brunner 2020-07-28 09:51:36 +02:00
parent bc9d6fc187
commit 01885e2448

View file

@ -562,8 +562,53 @@ func (pv *PartViewer) SetSource(reader io.Reader) {
} }
func (pv *PartViewer) attemptCopy() { func (pv *PartViewer) attemptCopy() {
if pv.source != nil && pv.pager != nil && pv.pager.Process != nil { if pv.source == nil || pv.pager == nil || pv.pager.Process == nil {
return
}
if pv.filter != nil { if pv.filter != nil {
pv.copyFilterOutToPager() //delayed until we write to the sink
}
go func() {
pv.writeMailHeaders()
if pv.part.MIMEType == "text" {
// if the content is plain we can strip ansi control chars
pv.copySourceToSinkStripAnsi()
} else {
// if it's binary we have to rely on the filter to be sane
io.Copy(pv.sink, pv.source)
}
pv.sink.Close()
}()
}
func (pv *PartViewer) writeMailHeaders() {
info := pv.msg.MessageInfo()
if pv.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
fields := info.RFC822Headers.Fields()
for fields.Next() {
var value string
var err error
if value, err = fields.Text(); err != nil {
// better than nothing, use the non decoded version
value = fields.Value()
}
field := fmt.Sprintf(
"%s: %s\n", fields.Key(), value)
pv.pagerin.Write([]byte(field))
}
// virtual header
if len(info.Labels) != 0 {
labels := fmtHeader(info, "Labels", "")
pv.pagerin.Write([]byte(fmt.Sprintf("Labels: %s\n", labels)))
}
pv.pagerin.Write([]byte{'\n'})
}
}
func (pv *PartViewer) copyFilterOutToPager() {
stdout, _ := pv.filter.StdoutPipe() stdout, _ := pv.filter.StdoutPipe()
stderr, _ := pv.filter.StderrPipe() stderr, _ := pv.filter.StderrPipe()
pv.filter.Start() pv.filter.Start()
@ -592,46 +637,15 @@ func (pv *PartViewer) attemptCopy() {
pv.filter.Wait() pv.filter.Wait()
pv.pagerin.Close() pv.pagerin.Close()
}() }()
} }
go func() {
info := pv.msg.MessageInfo()
if pv.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
fields := info.RFC822Headers.Fields()
for fields.Next() {
var value string
var err error
if value, err = fields.Text(); err != nil {
// better than nothing, use the non decoded version
value = fields.Value()
}
field := fmt.Sprintf(
"%s: %s\n", fields.Key(), value)
pv.pagerin.Write([]byte(field))
}
// virtual header
if len(info.Labels) != 0 {
labels := fmtHeader(info, "Labels", "")
pv.pagerin.Write([]byte(fmt.Sprintf("Labels: %s\n", labels)))
}
pv.pagerin.Write([]byte{'\n'})
}
if pv.part.MIMEType == "text" { func (pv *PartViewer) copySourceToSinkStripAnsi() {
scanner := bufio.NewScanner(pv.source) scanner := bufio.NewScanner(pv.source)
for scanner.Scan() { for scanner.Scan() {
text := scanner.Text() text := scanner.Text()
text = ansi.ReplaceAllString(text, "") text = ansi.ReplaceAllString(text, "")
io.WriteString(pv.sink, text+"\n") io.WriteString(pv.sink, text+"\n")
} }
} else {
io.Copy(pv.sink, pv.source)
}
pv.sink.Close()
}()
}
} }
func (pv *PartViewer) Invalidate() { func (pv *PartViewer) Invalidate() {