Refactor, introduce MailQ struct
This commit is contained in:
parent
b164d00e1f
commit
78f9468f0c
26
main.go
26
main.go
|
@ -42,7 +42,7 @@ func interactiveShell() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func showQueue() {
|
func showQueue() {
|
||||||
entries, err := fetchQueueEntries()
|
queue, err := fetchQueue()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Could not fetch queue entries: %s\n", err.Error())
|
fmt.Printf("Could not fetch queue entries: %s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -50,27 +50,25 @@ func showQueue() {
|
||||||
pagerReader, pagerWriter := io.Pipe()
|
pagerReader, pagerWriter := io.Pipe()
|
||||||
pagerDone := make(chan bool)
|
pagerDone := make(chan bool)
|
||||||
go launchPager(pagerReader, pagerDone)
|
go launchPager(pagerReader, pagerDone)
|
||||||
printQueueEntries(entries, pagerWriter)
|
printQueueEntries(queue, pagerWriter)
|
||||||
pagerWriter.Close()
|
pagerWriter.Close()
|
||||||
// Wait for pager to be closed before continuing the main program
|
// Wait for pager to be closed before continuing the main program
|
||||||
<-pagerDone
|
<-pagerDone
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchQueueEntries() ([]parser.QEntry, error) {
|
func fetchQueue() (parser.MailQ, error) {
|
||||||
var entries []parser.QEntry
|
|
||||||
var err error
|
|
||||||
if settings["mailqCommandArgs"] == "" {
|
if settings["mailqCommandArgs"] == "" {
|
||||||
entries, err = readFromCmd(exec.Command(settings["mailqCommand"]))
|
return readFromCmd(exec.Command(settings["mailqCommand"]))
|
||||||
} else {
|
} else {
|
||||||
entries, err = readFromCmd(exec.Command(settings["mailqCommand"], settings["mailqCommandArgs"]))
|
return readFromCmd(exec.Command(settings["mailqCommand"], settings["mailqCommandArgs"]))
|
||||||
}
|
}
|
||||||
return entries, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func printQueueEntries(entries []parser.QEntry, writer io.Writer) {
|
func printQueueEntries(queue parser.MailQ, writer io.Writer) {
|
||||||
|
fmt.Fprintf(writer, "%d entries total (%d active, %d deferred, %d on hold)\n\n", len(queue.Entries), queue.NumActive, queue.NumDeferred, queue.NumHold)
|
||||||
tabWriter := tabwriter.NewWriter(writer, 2, 2, 1, ' ', tabwriter.TabIndent)
|
tabWriter := tabwriter.NewWriter(writer, 2, 2, 1, ' ', tabwriter.TabIndent)
|
||||||
fmt.Fprintf(tabWriter, "| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| \n", "Date", "Id", "Status", "Size", "Sender", "#", "First Recipient", "Reason")
|
fmt.Fprintf(tabWriter, "| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| \n", "Date", "Id", "Status", "Size", "Sender", "#", "First Recipient", "Reason")
|
||||||
for _, entry := range entries {
|
for _, entry := range queue.Entries {
|
||||||
_, writeError := fmt.Fprintf(tabWriter, "| %s\t| %s\t| %s\t| %d\t| %s\t| {%d}\t| %s\t| %s\t \n", entry.Date.Format(parser.SortableDateFormat), entry.Id, entry.Status, entry.Size, entry.Sender, len(entry.Recipients), entry.Recipients[0], entry.Reason)
|
_, writeError := fmt.Fprintf(tabWriter, "| %s\t| %s\t| %s\t| %d\t| %s\t| {%d}\t| %s\t| %s\t \n", entry.Date.Format(parser.SortableDateFormat), entry.Id, entry.Status, entry.Size, entry.Sender, len(entry.Recipients), entry.Recipients[0], entry.Reason)
|
||||||
if writeError != nil {
|
if writeError != nil {
|
||||||
// A writeError is expected once the reader was closed
|
// A writeError is expected once the reader was closed
|
||||||
|
@ -96,17 +94,17 @@ func launchPager(reader *io.PipeReader, pagerDone chan<- bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readFromCmd(cmd *exec.Cmd) ([]parser.QEntry, error) {
|
func readFromCmd(cmd *exec.Cmd) (parser.MailQ, error) {
|
||||||
stdout, err := cmd.StdoutPipe()
|
stdout, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return parser.MailQ{}, err
|
||||||
}
|
}
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return nil, err
|
return parser.MailQ{}, err
|
||||||
}
|
}
|
||||||
result, resultError := parser.ParseMailQ(stdout)
|
result, resultError := parser.ParseMailQ(stdout)
|
||||||
if err := cmd.Wait(); err != nil {
|
if err := cmd.Wait(); err != nil {
|
||||||
return nil, err
|
return parser.MailQ{}, err
|
||||||
}
|
}
|
||||||
return result, resultError
|
return result, resultError
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,14 @@ type QEntry struct {
|
||||||
Reason string
|
Reason string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MailQ struct {
|
||||||
|
NumTotal int
|
||||||
|
NumActive int
|
||||||
|
NumHold int
|
||||||
|
NumDeferred int
|
||||||
|
Entries []QEntry
|
||||||
|
}
|
||||||
|
|
||||||
const SortableDateFormat = "2006-01-02 15:04:05"
|
const SortableDateFormat = "2006-01-02 15:04:05"
|
||||||
|
|
||||||
func (m QEntry) ShortString() string {
|
func (m QEntry) ShortString() string {
|
||||||
|
@ -43,7 +51,7 @@ func (m QEntry) DetailedString() string {
|
||||||
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) {
|
func ParseMailQ(dataSource io.Reader) (MailQ, error) {
|
||||||
const dateFormat = "2006 Mon Jan _2 15:04:05"
|
const dateFormat = "2006 Mon Jan _2 15:04:05"
|
||||||
var messageIdStart = regexp.MustCompile("^[0-9A-Za-z]+[*!]? ")
|
var messageIdStart = regexp.MustCompile("^[0-9A-Za-z]+[*!]? ")
|
||||||
scanner := bufio.NewScanner(dataSource)
|
scanner := bufio.NewScanner(dataSource)
|
||||||
|
@ -52,14 +60,13 @@ func ParseMailQ(dataSource io.Reader) ([]QEntry, error) {
|
||||||
line = scanner.Text()
|
line = scanner.Text()
|
||||||
if strings.HasPrefix(line, "Mail queue is empty") {
|
if strings.HasPrefix(line, "Mail queue is empty") {
|
||||||
// If mail queue is empty, there is nothing to do
|
// If mail queue is empty, there is nothing to do
|
||||||
return []QEntry{}, nil
|
return MailQ{}, nil
|
||||||
} else if strings.HasPrefix(line, "-Queue ID-") == false {
|
} else if strings.HasPrefix(line, "-Queue ID-") == false {
|
||||||
// Abort if input does not look like output from mailq(1)
|
// Abort if input does not look like output from mailq(1)
|
||||||
return nil, errors.New("Sorry, this does not look like output from mailq(1).")
|
return MailQ{}, errors.New("Sorry, this does not look like output from mailq(1).")
|
||||||
}
|
}
|
||||||
|
var queue MailQ
|
||||||
var currentMail QEntry
|
var currentMail QEntry
|
||||||
var queueEntries []QEntry
|
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
// Read input line by line
|
// Read input line by line
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
|
@ -70,12 +77,16 @@ func ParseMailQ(dataSource io.Reader) ([]QEntry, error) {
|
||||||
} else if messageIdStart.MatchString(line) {
|
} else if messageIdStart.MatchString(line) {
|
||||||
// Handle line starting next mail in queue
|
// Handle line starting next mail in queue
|
||||||
messageId := fields[0]
|
messageId := fields[0]
|
||||||
|
queue.NumTotal += 1
|
||||||
if strings.HasSuffix(messageId, "*") {
|
if strings.HasSuffix(messageId, "*") {
|
||||||
|
queue.NumActive += 1
|
||||||
currentMail.Status = "active"
|
currentMail.Status = "active"
|
||||||
} else if strings.HasSuffix(messageId, "!") {
|
} else if strings.HasSuffix(messageId, "!") {
|
||||||
currentMail.Status = "hold"
|
currentMail.Status = "hold"
|
||||||
|
queue.NumHold += 1
|
||||||
} else {
|
} else {
|
||||||
currentMail.Status = "deferred"
|
currentMail.Status = "deferred"
|
||||||
|
queue.NumDeferred += 1
|
||||||
}
|
}
|
||||||
dateString := strconv.Itoa(time.Now().Year()) + " " + strings.Join(fields[2:6], " ")
|
dateString := strconv.Itoa(time.Now().Year()) + " " + strings.Join(fields[2:6], " ")
|
||||||
mailDate, _ := time.Parse(dateFormat, dateString)
|
mailDate, _ := time.Parse(dateFormat, dateString)
|
||||||
|
@ -95,13 +106,13 @@ func ParseMailQ(dataSource io.Reader) ([]QEntry, error) {
|
||||||
} else if len(fields) == 0 {
|
} else if len(fields) == 0 {
|
||||||
// If the next line is empty, make sure to push current mail to list
|
// If the next line is empty, make sure to push current mail to list
|
||||||
// and create a new struct for the next mail to process
|
// and create a new struct for the next mail to process
|
||||||
queueEntries = append(queueEntries, currentMail)
|
queue.Entries = append(queue.Entries, currentMail)
|
||||||
currentMail = QEntry{}
|
currentMail = QEntry{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if scanner.Err() != nil {
|
if scanner.Err() != nil {
|
||||||
// If the scanner failed, let our caller know.
|
// If the scanner failed, let our caller know.
|
||||||
return nil, errors.New("Something went wrong with reading from stdin. Sorry!")
|
return MailQ{}, errors.New("Something went wrong with reading from stdin. Sorry!")
|
||||||
}
|
}
|
||||||
return queueEntries, nil
|
return queue, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue