Implement printing mailqueue in table, restructuring

This commit is contained in:
Jan Philipp Timme 2018-12-31 16:32:23 +01:00
parent d39fb736dc
commit 2a9ae87b2f
2 changed files with 46 additions and 32 deletions

36
main.go
View File

@ -7,6 +7,7 @@ import (
"os"
"os/exec"
"strconv"
"text/tabwriter"
)
import (
@ -41,6 +42,21 @@ func interactiveShell() {
}
func showQueue() {
entries, err := fetchQueueEntries()
if err != nil {
fmt.Printf("Could not fetch queue entries: %s\n", err.Error())
os.Exit(1)
}
pagerReader, pagerWriter := io.Pipe()
pagerDone := make(chan bool)
go launchPager(pagerReader, pagerDone)
printQueueEntries(entries, pagerWriter)
pagerWriter.Close()
// Wait for pager to be closed before continuing the main program
<-pagerDone
}
func fetchQueueEntries() ([]parser.QEntry, error) {
var entries []parser.QEntry
var err error
if settings["mailqCommandArgs"] == "" {
@ -48,24 +64,22 @@ func showQueue() {
} else {
entries, err = readFromCmd(exec.Command(settings["mailqCommand"], settings["mailqCommandArgs"]))
}
if err != nil {
fmt.Printf("Error reading: %s\n", err.Error())
os.Exit(1)
}
reader, writer := io.Pipe()
pagerDone := make(chan bool)
go launchPager(reader, pagerDone)
return entries, err
}
func printQueueEntries(entries []parser.QEntry, writer io.Writer) {
tabWriter := tabwriter.NewWriter(writer, 0, 2, 1, ' ', tabwriter.TabIndent)
fmt.Fprintf(tabWriter, "%s\t%s\t%s\t%s\t%s\t%s\n", "Date", "Id", "Size", "Sender", "#", "First Recipient")
for _, entry := range entries {
_, writeError := fmt.Fprintf(writer, "%s\n", entry.String())
_, writeError := fmt.Fprintf(tabWriter, "%s\t%s\t%d\t%s\t{%d}\t%s\n", entry.Date, entry.Id, entry.Size, entry.Sender, len(entry.Recipients), entry.Recipients[0])
if writeError != nil {
// A writeError is expected once the reader was closed
// This happens when the pager application got terminated
fmt.Printf("Error writing!: %s\n", writeError.Error())
break
}
}
writer.Close()
// Wait for pager to be closed before continuing the main program
<-pagerDone
tabWriter.Flush()
}
func launchPager(reader *io.PipeReader, pagerDone chan<- bool) {

View File

@ -12,35 +12,35 @@ import (
)
type QEntry struct {
id string
status string
date time.Time
size int
sender string
recipients []string
reason string
Id string
Status string
Date time.Time
Size int
Sender string
Recipients []string
Reason string
}
const sortableDateFormat = "2006-01-02 15:04:05"
func (m QEntry) ShortString() string {
return fmt.Sprintf("[%s] %s <%s> -> %d recipients (%d bytes)", m.date.Format(sortableDateFormat), m.id, m.sender, len(m.recipients), m.size)
return fmt.Sprintf("[%s] %s <%s> -> %d recipients (%d bytes)", m.Date.Format(sortableDateFormat), m.Id, m.Sender, len(m.Recipients), m.Size)
}
func (m QEntry) String() string {
var recipientSuffix string
if len(m.recipients) > 1 {
if len(m.Recipients) > 1 {
recipientSuffix = ",..."
}
return fmt.Sprintf("[%s] %s <%s> -> {%d}<%s>%s (%s, %d bytes)", m.date.Format(sortableDateFormat), m.id, m.sender, len(m.recipients), m.recipients[0], recipientSuffix, m.status, m.size)
return fmt.Sprintf("[%s] %s <%s> -> {%d}<%s>%s (%s, %d bytes)", m.Date.Format(sortableDateFormat), m.Id, m.Sender, len(m.Recipients), m.Recipients[0], recipientSuffix, m.Status, m.Size)
}
func (m QEntry) DetailedString() string {
var reasonStr string
if m.reason == "" {
if m.Reason == "" {
reasonStr = "-/-"
}
return fmt.Sprintf("Id: %s\nDate: %s\nStatus: %s\nReason: %s\nSize: %d\nSender: %s\nRecipients: %s", m.id, m.date.Format(sortableDateFormat), m.status, reasonStr, m.size, m.sender, strings.Join(m.recipients, ", "))
return fmt.Sprintf("Id: %s\nDate: %s\nStatus: %s\nReason: %s\nSize: %d\nSender: %s\nRecipients: %s", m.Id, m.Date.Format(sortableDateFormat), m.Status, reasonStr, m.Size, m.Sender, strings.Join(m.Recipients, ", "))
}
func ParseMailQ(dataSource io.Reader) ([]QEntry, error) {
@ -71,26 +71,26 @@ func ParseMailQ(dataSource io.Reader) ([]QEntry, error) {
// Handle line starting next mail in queue
messageId := fields[0]
if strings.HasSuffix(messageId, "*") {
currentMail.status = "active"
currentMail.Status = "active"
} else if strings.HasSuffix(messageId, "!") {
currentMail.status = "hold"
currentMail.Status = "hold"
} else {
currentMail.status = "deferred"
currentMail.Status = "deferred"
}
dateString := strconv.Itoa(time.Now().Year()) + " " + strings.Join(fields[2:6], " ")
mailDate, _ := time.Parse(dateFormat, dateString)
currentMail.id = strings.TrimRight(messageId, "*!")
currentMail.size, _ = strconv.Atoi(fields[1])
currentMail.date = mailDate
currentMail.sender = fields[6]
currentMail.Id = strings.TrimRight(messageId, "*!")
currentMail.Size, _ = strconv.Atoi(fields[1])
currentMail.Date = mailDate
currentMail.Sender = fields[6]
continue
} else if strings.HasPrefix(line, "(") && strings.HasSuffix(line, ")") {
// Handle reason for deferred status (if deferred at all, may be missing)
currentMail.reason = strings.Trim(strings.TrimSpace(line), "()")
currentMail.Reason = strings.Trim(strings.TrimSpace(line), "()")
continue
} else if len(fields) == 1 {
// Handle line with one of the mail recipients
currentMail.recipients = append(currentMail.recipients, fields[0])
currentMail.Recipients = append(currentMail.Recipients, fields[0])
continue
} else if len(fields) == 0 {
// If the next line is empty, make sure to push current mail to list