Skip to content

Commit 399d720

Browse files
committed
Implement scheduled delivery ("send later" functionality)
1 parent 1609328 commit 399d720

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

script/manitou-mdx

+34-9
Original file line numberDiff line numberDiff line change
@@ -1917,7 +1917,9 @@ sub redirect {
19171917
}
19181918

19191919
sub send_one_mail {
1920-
my ($from, $subject, $mail_id) = @_;
1920+
my ($from, $subject, $mail_id, $job_id) = @_;
1921+
# job_id is set for scheduled messages
1922+
# the job entry is deleted as soon as the message is sent.
19211923
my $decl_charset = getconf("preferred_charset", $from) || 'iso-8859-1';
19221924
my @charsets = split(/\s+/, $decl_charset);
19231925

@@ -2008,6 +2010,11 @@ sub send_one_mail {
20082010
$top->head->replace("Bcc", $bcc);
20092011
}
20102012

2013+
if (defined $job_id) {
2014+
# for scheduled deliveries, replace the Date header with the
2015+
# current date and time
2016+
Manitou::MailFormat::add_date_header($top);
2017+
}
20112018
attach_parts($dbh, $mail_id, $top, getconf("tmpdir"));
20122019

20132020
my @opl;
@@ -2087,10 +2094,10 @@ sub send_one_mail {
20872094
error_log("Local delivery agent error: (\`$cmd\`, exit code=".($?>>8)."): $e");
20882095
}
20892096
else {
2090-
# Set the SENT and ARCHIVED status bits
2091-
my $sths = $dbh->prepare("UPDATE mail SET status=status|(256+32),sender_date=now() WHERE mail_id=?");
2092-
$sths->execute($mail_id);
2093-
$sths->finish;
2097+
# Set the SENT and ARCHIVED status bits. Clear SCHEDULED.
2098+
$dbh->do("UPDATE mail SET status=(status|(256+32))&(~1024),sender_date=now() WHERE mail_id=?",
2099+
{}, $mail_id);
2100+
$dbh->do("DELETE FROM jobs_queue WHERE job_id=?",{}, $job_id) if (defined $job_id);
20942101
$ret=1; # OK
20952102
}
20962103
}
@@ -2129,17 +2136,35 @@ sub get_delivery_agent {
21292136
}
21302137

21312138
sub send_mails {
2132-
my $sth1 = $dbh->prepare("SELECT mail_id FROM mail_status WHERE status=129");
2139+
my $sched_bit=1024; # bitmask for "send later"
2140+
my $sth1 = $dbh->prepare("SELECT mail_id FROM mail_status WHERE (status=129 OR status=129+$sched_bit)");
21332141
$sth1->execute;
21342142
my @res;
2143+
my $sth_job;
21352144
while (@res = $sth1->fetchrow_array) {
21362145
my $mail_id=$res[0];
21372146
next if (exists $hsend_blocked{$mail_id});
2138-
my $sth = $dbh->prepare("SELECT sender,subject FROM mail WHERE mail_id=? AND status=129");
2147+
my $sth = $dbh->prepare("SELECT sender,subject,status FROM mail WHERE mail_id=?");
21392148
$sth->execute($mail_id);
21402149
my @row;
2141-
while (@row = $sth->fetchrow_array) {
2142-
if (send_one_mail($row[0], $row[1], $mail_id)) {
2150+
while (my ($sender,$subject,$status) = $sth->fetchrow_array) {
2151+
my $job_id;
2152+
my $sched_time; # timestamp as seconds since epoch
2153+
if ($status == 129+$sched_bit) {
2154+
if (!defined $sth_job) { # prepare the query only if needed
2155+
$sth_job = $dbh->prepare("SELECT job_id,job_args FROM jobs_queue WHERE mail_id=? AND job_type=?");
2156+
}
2157+
$sth_job->execute($mail_id, "send_mail");
2158+
($job_id, $sched_time) = $sth_job->fetchrow_array;
2159+
# check if the scheduled time is reached
2160+
next if ( ! ($sched_time =~ /^[0-9]+$/ && $sched_time <= time()) );
2161+
}
2162+
elsif ($status != 129) {
2163+
# If the status has changed since the initial fetch (when other messages
2164+
# were sent in the loop), ignore the message.
2165+
next;
2166+
}
2167+
if (send_one_mail($sender, $subject, $mail_id, $job_id)) {
21432168
update_runtime_timestamp("last_sent") if getconf_bool("update_runtime_info", $row[0]);
21442169
notice_log("Sent outgoing message #$mail_id");
21452170
my $nb_blocked = scalar (keys %hsend_blocked);

0 commit comments

Comments
 (0)