imc-vibe/backend/internal/mail/queue.go
2026-03-21 22:41:23 +01:00

123 lines
2.5 KiB
Go

package mail
import (
"bufio"
"bytes"
"encoding/json"
"os/exec"
"regexp"
"strconv"
"strings"
)
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"`
}
var queueLineRegex = regexp.MustCompile(`^([A-Fa-f0-9]+)\s+(\d+)\s+(\w+)\s+([A-Za-z]+\s+\d+\s+[\d:]+)\s+([^\s]+)\s+(.+)$`)
func GetQueue() ([]QueueEntry, error) {
cmd := exec.Command("postqueue", "-p", "-j")
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return nil, err
}
var entries []QueueEntry
scanner := bufio.NewScanner(&out)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" || !strings.HasPrefix(line, "{") {
continue
}
var entry struct {
QueueID string `json:"queueid"`
Sender string `json:"sender"`
Recipients []struct {
Address string `json:"address"`
} `json:"recipients"`
Size int64 `json:"size"`
Arrival string `json:"arrival_timestamp"`
Delay string `json:"delay_reason"`
}
if err := json.Unmarshal([]byte(line), &entry); err != nil {
continue
}
recipients := make([]string, len(entry.Recipients))
for i, r := range entry.Recipients {
recipients[i] = r.Address
}
entries = append(entries, QueueEntry{
ID: entry.QueueID,
Sender: entry.Sender,
Recipients: recipients,
Size: int(entry.Size),
Time: entry.Arrival,
Reason: entry.Delay,
})
}
if entries == nil {
entries = []QueueEntry{}
}
return entries, nil
}
func RequeueMail(id string) error {
cmd := exec.Command("postqueue", "-f", "-v")
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &out
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func DeleteFromQueue(id string) error {
cmd := exec.Command("postsuper", "-d", id)
return cmd.Run()
}
func GetQueueCount() (int, error) {
cmd := exec.Command("postqueue", "-p")
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return 0, err
}
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
}
}
}
}
}
return count, nil
}