msgviewer: simplify attemptCopy
No functional changes, simply extract more complex stuff into sub functions to help readability.
This commit is contained in:
parent
bc9d6fc187
commit
01885e2448
1 changed files with 80 additions and 66 deletions
|
@ -562,75 +562,89 @@ 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 {
|
||||||
if pv.filter != nil {
|
return
|
||||||
stdout, _ := pv.filter.StdoutPipe()
|
}
|
||||||
stderr, _ := pv.filter.StderrPipe()
|
if pv.filter != nil {
|
||||||
pv.filter.Start()
|
pv.copyFilterOutToPager() //delayed until we write to the sink
|
||||||
ch := make(chan interface{})
|
}
|
||||||
go func() {
|
go func() {
|
||||||
_, err := io.Copy(pv.pagerin, stdout)
|
pv.writeMailHeaders()
|
||||||
if err != nil {
|
if pv.part.MIMEType == "text" {
|
||||||
pv.err = err
|
// if the content is plain we can strip ansi control chars
|
||||||
pv.Invalidate()
|
pv.copySourceToSinkStripAnsi()
|
||||||
}
|
} else {
|
||||||
stdout.Close()
|
// if it's binary we have to rely on the filter to be sane
|
||||||
ch <- nil
|
io.Copy(pv.sink, pv.source)
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
_, err := io.Copy(pv.pagerin, stderr)
|
|
||||||
if err != nil {
|
|
||||||
pv.err = err
|
|
||||||
pv.Invalidate()
|
|
||||||
}
|
|
||||||
stderr.Close()
|
|
||||||
ch <- nil
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
<-ch
|
|
||||||
<-ch
|
|
||||||
pv.filter.Wait()
|
|
||||||
pv.pagerin.Close()
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
go func() {
|
pv.sink.Close()
|
||||||
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) writeMailHeaders() {
|
||||||
scanner := bufio.NewScanner(pv.source)
|
info := pv.msg.MessageInfo()
|
||||||
for scanner.Scan() {
|
if pv.showHeaders && info.RFC822Headers != nil {
|
||||||
text := scanner.Text()
|
// header need to bypass the filter, else we run into issues
|
||||||
text = ansi.ReplaceAllString(text, "")
|
// with the filter messing with newlines etc.
|
||||||
io.WriteString(pv.sink, text+"\n")
|
// hence all writes in this block go directly to the pager
|
||||||
}
|
fields := info.RFC822Headers.Fields()
|
||||||
} else {
|
for fields.Next() {
|
||||||
io.Copy(pv.sink, pv.source)
|
var value string
|
||||||
|
var err error
|
||||||
|
if value, err = fields.Text(); err != nil {
|
||||||
|
// better than nothing, use the non decoded version
|
||||||
|
value = fields.Value()
|
||||||
}
|
}
|
||||||
pv.sink.Close()
|
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()
|
||||||
|
stderr, _ := pv.filter.StderrPipe()
|
||||||
|
pv.filter.Start()
|
||||||
|
ch := make(chan interface{})
|
||||||
|
go func() {
|
||||||
|
_, err := io.Copy(pv.pagerin, stdout)
|
||||||
|
if err != nil {
|
||||||
|
pv.err = err
|
||||||
|
pv.Invalidate()
|
||||||
|
}
|
||||||
|
stdout.Close()
|
||||||
|
ch <- nil
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
_, err := io.Copy(pv.pagerin, stderr)
|
||||||
|
if err != nil {
|
||||||
|
pv.err = err
|
||||||
|
pv.Invalidate()
|
||||||
|
}
|
||||||
|
stderr.Close()
|
||||||
|
ch <- nil
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
<-ch
|
||||||
|
<-ch
|
||||||
|
pv.filter.Wait()
|
||||||
|
pv.pagerin.Close()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pv *PartViewer) copySourceToSinkStripAnsi() {
|
||||||
|
scanner := bufio.NewScanner(pv.source)
|
||||||
|
for scanner.Scan() {
|
||||||
|
text := scanner.Text()
|
||||||
|
text = ansi.ReplaceAllString(text, "")
|
||||||
|
io.WriteString(pv.sink, text+"\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue