Skip to content

Instantly share code, notes, and snippets.

@adriano66
Forked from dullgiulio/mailq-parser.php
Last active July 16, 2021 09:45
Show Gist options
  • Select an option

  • Save adriano66/c0530a55e108c566dd83a78686b62437 to your computer and use it in GitHub Desktop.

Select an option

Save adriano66/c0530a55e108c566dd83a78686b62437 to your computer and use it in GitHub Desktop.
Interactive mailq
<?php
class EmailData {
private $id;
private $recipients = [];
private $sender;
private $size;
private $date;
private $failed;
private $error;
private function __construct() {
}
public static function fromArray($data) {
$emailData = new static();
$emailData->id = $data['id'];
$emailData->size = $data['size'];
$emailData->date = $data['date'];
$emailData->sender = $data['sender'];
$emailData->failed = $data['failed'];
$emailData->recipients = $data['recipients'] ?? [];
return $emailData;
}
public function setFailedStatus($status) {
$this->failed = $status;
}
public function setError($error) {
$this->error = $error;
}
public function getSender() {
return $this->sender;
}
public function getReciepientsString() {
return implode(';', $this->recipients);
}
public function getId() {
return $this->id;
}
public function addRecipient(string $recipient) {
$this->recipients[] = $recipient;
}
}
function printMessage($message) {
echo '===' . PHP_EOL;
echo $message . PHP_EOL;
}
function runInteractivePostQ() {
$emails = getMailQueue();
if (empty($emails)) {
printMessage('Nothing to process. Bye!');
return;
}
foreach ($emails as $emailData) {
printMessage(<<<MENU
Email from: {$emailData->getSender()}
Email to: {$emailData->getReciepientsString()}
0) Exit
1) Skip
2) Send email
MENU
);
$action = readline("Select option: ");
if (empty($action)) {
return;
}
printMessage(selectOption($action, $emailData));
}
printMessage('Everything processed. Bye!');
}
function selectOption($option, EmailData $emailData) {
switch ($option) {
case '1':
return 'Skipping';
case '2':
return sendMail($emailData);
}
}
function sendMail(EmailData $emailData) {
$recipients = $emailData->getReciepientsString();
$message = "Sending email: {$emailData->getId()}, to {$recipients}" . PHP_EOL;
$message .= shell_exec("postqueue -v -i {$emailData->getId()}");
return $message;
}
/**
* @return EmailData[]
*/
function getMailQueue() {
$emailsList = shell_exec("postqueue -p");
$emails = mailQParser($emailsList);
return $emails;
}
/**
* @return EmailData[]
*/
function mailQParser($emailsList) {
$results = [];
$mailq = explode(PHP_EOL, trim($emailsList));
array_shift($mailq);
array_pop($mailq);
foreach ($mailq as $line) {
if (trim($line) === '') {
continue;
}
$line = trim($line);
// This could be much better so easily (eg: insert months, remove duplications, etc.)
$res = preg_match('/^([A-Z0-9]{1,20})\s+([1-9][0-9]*)\s+((Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+[A-Za-z]{3}\s+[0-9]{2}\s+[0-9]{2}\:[0-9]{2}\:[0-9]{2})\s+([^ ]+)\s*$/', $line, $matches);
if ($res) {
$id = $matches[1];
$current_object = EmailData::fromArray([
'id' => $matches[1],
'size' => (int) $matches[2],
'date' => strftime($matches[3]),
'sender' => $matches[5],
'failed' => FALSE,
'recipients' => [],
]);
}
else {
// Parse error lines and recipients in lines following the message ID.
if (!empty($current_object)) {
if (strpos(">$line", '(') == 1) {
$current_object->setFailedStatus(TRUE);
$current_object->setError($line);
}
else {
$current_object->addRecipient($line);
}
}
}
if (isset($id, $current_object)) {
$results[$id] = $current_object;
}
}
return $results;
}
runInteractivePostQ();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment