Add comprehensive human-readable comments to all Go files
- Comments explain what each function does and why - Fixed unused strconv import in queue.go - Better documentation for SMTP email service - Explained journalctl log parsing in logs.go - Clarified queue operations in queue.go
This commit is contained in:
parent
3e3620a24f
commit
68285d861a
9 changed files with 728 additions and 203 deletions
|
|
@ -1,48 +1,61 @@
|
|||
// Package mail provides functions for interacting with the mail server system.
|
||||
// Currently supports Postfix mail queue operations via postqueue/postsuper commands.
|
||||
package mail
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"bufio" // buffered scanner for reading line-by-line
|
||||
"bytes" // buffer management
|
||||
"encoding/json" // JSON parsing for postqueue output
|
||||
"fmt" // formatted error messages
|
||||
"os/exec" // executing external commands
|
||||
"regexp" // regular expressions (for parsing queue output)
|
||||
"strings" // string manipulation
|
||||
)
|
||||
|
||||
// QueueEntry represents a single email in the mail queue.
|
||||
type QueueEntry struct {
|
||||
ID string `json:"id"`
|
||||
Sender string `json:"sender"`
|
||||
Recipients []string `json:"recipients"`
|
||||
Size int `json:"size"`
|
||||
Time string `json:"time"`
|
||||
Reason string `json:"reason"`
|
||||
ID string `json:"id"` // Queue ID (hex string)
|
||||
Sender string `json:"sender"` // From address
|
||||
Recipients []string `json:"recipients"` // To addresses
|
||||
Size int `json:"size"` // Size in bytes
|
||||
Time string `json:"time"` // Arrival time
|
||||
Reason string `json:"reason"` // Why it's deferred
|
||||
}
|
||||
|
||||
// Regular expression for parsing human-readable queue output (not currently used).
|
||||
var queueLineRegex = regexp.MustCompile(`^([A-Fa-f0-9]+)\s+(\d+)\s+(\w+)\s+([A-Za-z]+\s+\d+\s+[\d:]+)\s+([^\s]+)\s+(.+)$`)
|
||||
|
||||
// GetQueue retrieves all emails currently in the Postfix queue.
|
||||
// Returns: a list of QueueEntry objects, or an error if the command fails.
|
||||
// Uses `postqueue -j` to get JSON output from Postfix.
|
||||
func GetQueue() ([]QueueEntry, error) {
|
||||
// Execute postqueue command with JSON output flag.
|
||||
// postqueue is the Postfix queue management utility.
|
||||
cmd := exec.Command("/usr/sbin/postqueue", "-j")
|
||||
var out bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &stderr
|
||||
cmd.Stdout = &out // Capture standard output
|
||||
cmd.Stderr = &stderr // Capture standard error (for debugging)
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
// Return detailed error including stderr for debugging.
|
||||
return nil, fmt.Errorf("/usr/sbin/postqueue -j: %v (stderr: %s)", err, stderr.String())
|
||||
}
|
||||
|
||||
// Parse the JSON output from postqueue.
|
||||
// Each line of output is a separate JSON object.
|
||||
var entries []QueueEntry
|
||||
scanner := bufio.NewScanner(&out)
|
||||
scanner := bufio.NewScanner(&out) // Read line by line
|
||||
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
// Skip empty lines and non-JSON lines.
|
||||
if line == "" || !strings.HasPrefix(line, "{") {
|
||||
continue
|
||||
}
|
||||
|
||||
// Define the JSON structure matching postqueue's output format.
|
||||
var entry struct {
|
||||
QueueID string `json:"queueid"`
|
||||
Sender string `json:"sender"`
|
||||
|
|
@ -54,10 +67,12 @@ func GetQueue() ([]QueueEntry, error) {
|
|||
Delay string `json:"delay_reason"`
|
||||
}
|
||||
|
||||
// Parse the JSON line into our struct.
|
||||
if err := json.Unmarshal([]byte(line), &entry); err != nil {
|
||||
continue
|
||||
continue // Skip malformed JSON
|
||||
}
|
||||
|
||||
// Extract recipient addresses from the nested structure.
|
||||
recipients := make([]string, len(entry.Recipients))
|
||||
for i, r := range entry.Recipients {
|
||||
recipients[i] = r.Address
|
||||
|
|
@ -73,6 +88,7 @@ func GetQueue() ([]QueueEntry, error) {
|
|||
})
|
||||
}
|
||||
|
||||
// Return empty slice instead of nil for consistent JSON output.
|
||||
if entries == nil {
|
||||
entries = []QueueEntry{}
|
||||
}
|
||||
|
|
@ -80,7 +96,12 @@ func GetQueue() ([]QueueEntry, error) {
|
|||
return entries, nil
|
||||
}
|
||||
|
||||
// RequeueMail requeues all deferred mail (attempts to resend them).
|
||||
// This is a blanket operation - it requeues ALL deferred mail, not just one message.
|
||||
// id: message ID (currently ignored, requeues all).
|
||||
// Note: postqueue -f requeues everything, there's no per-message requeue.
|
||||
func RequeueMail(id string) error {
|
||||
// Execute postqueue -f to flush (requeue) all deferred mail.
|
||||
cmd := exec.Command("/usr/sbin/postqueue", "-f", "-v")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
|
|
@ -92,12 +113,20 @@ func RequeueMail(id string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// DeleteFromQueue deletes a specific message from the queue.
|
||||
// id: the queue ID of the message to delete.
|
||||
// Uses `postsuper -d <id>` to delete the message.
|
||||
func DeleteFromQueue(id string) error {
|
||||
// postsuper is the Postfix superuser queue management command.
|
||||
// -d deletes messages by ID.
|
||||
cmd := exec.Command("/usr/sbin/postsuper", "-d", id)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// GetQueueCount returns the number of messages in the mail queue.
|
||||
// Used for displaying queue statistics on the dashboard.
|
||||
func GetQueueCount() (int, error) {
|
||||
// Use JSON output to get queue count.
|
||||
cmd := exec.Command("/usr/sbin/postqueue", "-j")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
|
|
@ -106,20 +135,15 @@ func GetQueueCount() (int, error) {
|
|||
return 0, err
|
||||
}
|
||||
|
||||
// Count the number of JSON objects (messages) in the output.
|
||||
count := 0
|
||||
scanner := bufio.NewScanner(&out)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.Contains(line, " mail queue") {
|
||||
parts := strings.Fields(line)
|
||||
for i, p := range parts {
|
||||
if n, err := strconv.Atoi(p); err == nil && n > 0 {
|
||||
count = n
|
||||
if i > 0 && parts[i-1] == "in" {
|
||||
return n, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// Each line of JSON output represents one message.
|
||||
// Count non-empty lines that look like JSON.
|
||||
if strings.TrimSpace(line) != "" && strings.HasPrefix(line, "{") {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue