summaryrefslogtreecommitdiffstats
path: root/whine.pl
diff options
context:
space:
mode:
Diffstat (limited to 'whine.pl')
-rwxr-xr-xwhine.pl918
1 files changed, 464 insertions, 454 deletions
diff --git a/whine.pl b/whine.pl
index 6343b501f..bfa8df5e6 100755
--- a/whine.pl
+++ b/whine.pl
@@ -37,38 +37,35 @@ my @seen_schedules = ();
# These statement handles should live outside of their functions in order to
# allow the database to keep their SQL compiled.
-my $sth_run_queries =
- $dbh->prepare("SELECT " .
- "query_name, title, onemailperbug " .
- "FROM whine_queries " .
- "WHERE eventid=? " .
- "ORDER BY sortkey");
-my $sth_get_query =
- $dbh->prepare("SELECT query FROM namedqueries " .
- "WHERE userid = ? AND name = ?");
+my $sth_run_queries
+ = $dbh->prepare("SELECT "
+ . "query_name, title, onemailperbug "
+ . "FROM whine_queries "
+ . "WHERE eventid=? "
+ . "ORDER BY sortkey");
+my $sth_get_query = $dbh->prepare(
+ "SELECT query FROM namedqueries " . "WHERE userid = ? AND name = ?");
# get the event that's scheduled with the lowest run_next value
-my $sth_next_scheduled_event = $dbh->prepare(
- "SELECT " .
- " whine_schedules.eventid, " .
- " whine_events.owner_userid, " .
- " whine_events.subject, " .
- " whine_events.body, " .
- " whine_events.mailifnobugs " .
- "FROM whine_schedules " .
- "LEFT JOIN whine_events " .
- " ON whine_events.id = whine_schedules.eventid " .
- "WHERE run_next <= NOW() " .
- "ORDER BY run_next " .
- $dbh->sql_limit(1)
-);
+my $sth_next_scheduled_event
+ = $dbh->prepare("SELECT "
+ . " whine_schedules.eventid, "
+ . " whine_events.owner_userid, "
+ . " whine_events.subject, "
+ . " whine_events.body, "
+ . " whine_events.mailifnobugs "
+ . "FROM whine_schedules "
+ . "LEFT JOIN whine_events "
+ . " ON whine_events.id = whine_schedules.eventid "
+ . "WHERE run_next <= NOW() "
+ . "ORDER BY run_next "
+ . $dbh->sql_limit(1));
# get all pending schedules matching an eventid
-my $sth_schedules_by_event = $dbh->prepare(
- "SELECT id, mailto_type, mailto " .
- "FROM whine_schedules " .
- "WHERE eventid=? AND run_next <= NOW()"
-);
+my $sth_schedules_by_event
+ = $dbh->prepare("SELECT id, mailto_type, mailto "
+ . "FROM whine_schedules "
+ . "WHERE eventid=? AND run_next <= NOW()");
################################################################################
@@ -88,20 +85,25 @@ my $sth_schedules_by_event = $dbh->prepare(
my $fromaddress = Bugzilla->params->{'mailfrom'};
# get the current date and time
-my ($now_sec, $now_minute, $now_hour, $now_day, $now_month, $now_year,
- $now_weekday) = localtime;
+my (
+ $now_sec, $now_minute, $now_hour, $now_day,
+ $now_month, $now_year, $now_weekday
+) = localtime;
+
# Convert year to two digits
$now_year = sprintf("%02d", $now_year % 100);
+
# Convert the month to January being "1" instead of January being "0".
$now_month++;
my @daysinmonth = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
+
# Alter February in case of a leap year. This simple way to do it only
# applies if you won't be looking at February of next year, which whining
# doesn't need to do.
-if (($now_year % 4 == 0) &&
- (($now_year % 100 != 0) || ($now_year % 400 == 0))) {
- $daysinmonth[2] = 29;
+if (($now_year % 4 == 0) && (($now_year % 100 != 0) || ($now_year % 400 == 0)))
+{
+ $daysinmonth[2] = 29;
}
# run_day can contain either a calendar day (1, 2, 3...), a day of the week
@@ -113,67 +115,79 @@ if (($now_year % 4 == 0) &&
#
# We go over each uninitialized schedule record and use its settings to
# determine what the next time it runs should be
-my $sched_h = $dbh->prepare("SELECT id, run_day, run_time " .
- "FROM whine_schedules " .
- "WHERE run_next IS NULL" );
+my $sched_h
+ = $dbh->prepare("SELECT id, run_day, run_time "
+ . "FROM whine_schedules "
+ . "WHERE run_next IS NULL");
$sched_h->execute();
while (my ($schedule_id, $day, $time) = $sched_h->fetchrow_array) {
- # fill in some defaults in case they're blank
- $day ||= '0';
- $time ||= '0';
-
- # If this schedule is supposed to run today, we see if it's supposed to be
- # run at a particular hour. If so, we set it for that hour, and if not,
- # it runs at an interval over the course of a day, which means we should
- # set it to run immediately.
- if (&check_today($day)) {
- # Values that are not entirely numeric are intervals, like "30min"
- if ($time !~ /^\d+$/) {
- # set it to now
- $sth = $dbh->prepare( "UPDATE whine_schedules " .
- "SET run_next=NOW() " .
- "WHERE id=?");
- $sth->execute($schedule_id);
- }
- # A time greater than now means it still has to run today
- elsif ($time >= $now_hour) {
- # set it to today + number of hours
- $sth = $dbh->prepare(
- "UPDATE whine_schedules " .
- "SET run_next = " .
- $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'HOUR') .
- " WHERE id = ?");
- $sth->execute($time, $schedule_id);
- }
- # the target time is less than the current time
- else { # set it for the next applicable day
- $day = &get_next_date($day);
- my $run_next = $dbh->sql_date_math('('
- . $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY')
- . ')', '+', '?', 'HOUR');
- $sth = $dbh->prepare("UPDATE whine_schedules " .
- "SET run_next = $run_next
- WHERE id = ?");
- $sth->execute($day, $time, $schedule_id);
- }
+ # fill in some defaults in case they're blank
+ $day ||= '0';
+ $time ||= '0';
+
+ # If this schedule is supposed to run today, we see if it's supposed to be
+ # run at a particular hour. If so, we set it for that hour, and if not,
+ # it runs at an interval over the course of a day, which means we should
+ # set it to run immediately.
+ if (&check_today($day)) {
+
+ # Values that are not entirely numeric are intervals, like "30min"
+ if ($time !~ /^\d+$/) {
+
+ # set it to now
+ $sth = $dbh->prepare(
+ "UPDATE whine_schedules " . "SET run_next=NOW() " . "WHERE id=?");
+ $sth->execute($schedule_id);
}
- # If the schedule is not supposed to run today, we set it to run on the
- # appropriate date and time
- else {
- my $target_date = &get_next_date($day);
- # If configured for a particular time, set it to that, otherwise
- # midnight
- my $target_time = ($time =~ /^\d+$/) ? $time : 0;
-
- my $run_next = $dbh->sql_date_math('('
- . $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY')
- . ')', '+', '?', 'HOUR');
- $sth = $dbh->prepare("UPDATE whine_schedules " .
- "SET run_next = $run_next
- WHERE id = ?");
- $sth->execute($target_date, $target_time, $schedule_id);
+
+ # A time greater than now means it still has to run today
+ elsif ($time >= $now_hour) {
+
+ # set it to today + number of hours
+ $sth
+ = $dbh->prepare("UPDATE whine_schedules "
+ . "SET run_next = "
+ . $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'HOUR')
+ . " WHERE id = ?");
+ $sth->execute($time, $schedule_id);
+ }
+
+ # the target time is less than the current time
+ else { # set it for the next applicable day
+ $day = &get_next_date($day);
+ my $run_next
+ = $dbh->sql_date_math(
+ '(' . $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY') . ')',
+ '+', '?', 'HOUR');
+ $sth = $dbh->prepare(
+ "UPDATE whine_schedules " . "SET run_next = $run_next
+ WHERE id = ?"
+ );
+ $sth->execute($day, $time, $schedule_id);
}
+
+ }
+
+ # If the schedule is not supposed to run today, we set it to run on the
+ # appropriate date and time
+ else {
+ my $target_date = &get_next_date($day);
+
+ # If configured for a particular time, set it to that, otherwise
+ # midnight
+ my $target_time = ($time =~ /^\d+$/) ? $time : 0;
+
+ my $run_next
+ = $dbh->sql_date_math(
+ '(' . $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY') . ')',
+ '+', '?', 'HOUR');
+ $sth = $dbh->prepare(
+ "UPDATE whine_schedules " . "SET run_next = $run_next
+ WHERE id = ?"
+ );
+ $sth->execute($target_date, $target_time, $schedule_id);
+ }
}
$sched_h->finish();
@@ -195,91 +209,85 @@ $sched_h->finish();
# mailifnobugs - send message even if there are no query or query results
sub get_next_event {
- my $event = {};
-
- # Loop until there's something to return
- until (scalar keys %{$event}) {
-
- $dbh->bz_start_transaction();
-
- # Get the event ID for the first pending schedule
- $sth_next_scheduled_event->execute;
- my $fetched = $sth_next_scheduled_event->fetch;
- $sth_next_scheduled_event->finish;
- return undef unless $fetched;
- my ($eventid, $owner_id, $subject, $body, $mailifnobugs) = @{$fetched};
-
- my $owner = Bugzilla::User->new($owner_id);
-
- my $whineatothers = $owner->in_group('bz_canusewhineatothers');
-
- my %user_objects; # Used for keeping track of who has been added
-
- # Get all schedules that match that event ID and are pending
- $sth_schedules_by_event->execute($eventid);
-
- # Add the users from those schedules to the list
- while (my $row = $sth_schedules_by_event->fetch) {
- my ($sid, $mailto_type, $mailto) = @{$row};
-
- # Only bother doing any work if this user has whine permission
- if ($owner->in_group('bz_canusewhines')) {
-
- if ($mailto_type == MAILTO_USER) {
- if (not defined $user_objects{$mailto}) {
- if ($mailto == $owner_id) {
- $user_objects{$mailto} = $owner;
- }
- elsif ($whineatothers) {
- $user_objects{$mailto} = Bugzilla::User->new($mailto);
- }
- }
- }
- elsif ($mailto_type == MAILTO_GROUP) {
- my $sth = $dbh->prepare("SELECT name FROM groups " .
- "WHERE id=?");
- $sth->execute($mailto);
- my $groupname = $sth->fetch->[0];
- my $group_id = Bugzilla::Group::ValidateGroupName(
- $groupname, $owner);
- if ($group_id) {
- my $glist = join(',',
- @{Bugzilla::Group->flatten_group_membership(
- $group_id)});
- $sth = $dbh->prepare("SELECT user_id FROM " .
- "user_group_map " .
- "WHERE group_id IN ($glist)");
- $sth->execute();
- for my $row (@{$sth->fetchall_arrayref}) {
- if (not defined $user_objects{$row->[0]}) {
- $user_objects{$row->[0]} =
- Bugzilla::User->new($row->[0]);
- }
- }
- }
- }
+ my $event = {};
- }
+ # Loop until there's something to return
+ until (scalar keys %{$event}) {
- reset_timer($sid);
- }
+ $dbh->bz_start_transaction();
+
+ # Get the event ID for the first pending schedule
+ $sth_next_scheduled_event->execute;
+ my $fetched = $sth_next_scheduled_event->fetch;
+ $sth_next_scheduled_event->finish;
+ return undef unless $fetched;
+ my ($eventid, $owner_id, $subject, $body, $mailifnobugs) = @{$fetched};
- $dbh->bz_commit_transaction();
-
- # Only set $event if the user is allowed to do whining
- if ($owner->in_group('bz_canusewhines')) {
- my @users = values %user_objects;
- $event = {
- 'eventid' => $eventid,
- 'author' => $owner,
- 'mailto' => \@users,
- 'subject' => $subject,
- 'body' => $body,
- 'mailifnobugs' => $mailifnobugs,
- };
+ my $owner = Bugzilla::User->new($owner_id);
+
+ my $whineatothers = $owner->in_group('bz_canusewhineatothers');
+
+ my %user_objects; # Used for keeping track of who has been added
+
+ # Get all schedules that match that event ID and are pending
+ $sth_schedules_by_event->execute($eventid);
+
+ # Add the users from those schedules to the list
+ while (my $row = $sth_schedules_by_event->fetch) {
+ my ($sid, $mailto_type, $mailto) = @{$row};
+
+ # Only bother doing any work if this user has whine permission
+ if ($owner->in_group('bz_canusewhines')) {
+
+ if ($mailto_type == MAILTO_USER) {
+ if (not defined $user_objects{$mailto}) {
+ if ($mailto == $owner_id) {
+ $user_objects{$mailto} = $owner;
+ }
+ elsif ($whineatothers) {
+ $user_objects{$mailto} = Bugzilla::User->new($mailto);
+ }
+ }
}
+ elsif ($mailto_type == MAILTO_GROUP) {
+ my $sth = $dbh->prepare("SELECT name FROM groups " . "WHERE id=?");
+ $sth->execute($mailto);
+ my $groupname = $sth->fetch->[0];
+ my $group_id = Bugzilla::Group::ValidateGroupName($groupname, $owner);
+ if ($group_id) {
+ my $glist = join(',', @{Bugzilla::Group->flatten_group_membership($group_id)});
+ $sth = $dbh->prepare(
+ "SELECT user_id FROM " . "user_group_map " . "WHERE group_id IN ($glist)");
+ $sth->execute();
+ for my $row (@{$sth->fetchall_arrayref}) {
+ if (not defined $user_objects{$row->[0]}) {
+ $user_objects{$row->[0]} = Bugzilla::User->new($row->[0]);
+ }
+ }
+ }
+ }
+
+ }
+
+ reset_timer($sid);
+ }
+
+ $dbh->bz_commit_transaction();
+
+ # Only set $event if the user is allowed to do whining
+ if ($owner->in_group('bz_canusewhines')) {
+ my @users = values %user_objects;
+ $event = {
+ 'eventid' => $eventid,
+ 'author' => $owner,
+ 'mailto' => \@users,
+ 'subject' => $subject,
+ 'body' => $body,
+ 'mailifnobugs' => $mailifnobugs,
+ };
}
- return $event;
+ }
+ return $event;
}
# Run the queries for each event
@@ -293,38 +301,38 @@ sub get_next_event {
# mailifnobugs (send message even if there are no query or query results)
while (my $event = get_next_event) {
- my $eventid = $event->{'eventid'};
-
- # We loop for each target user because some of the queries will be using
- # subjective pronouns
- $dbh = Bugzilla->switch_to_shadow_db();
- for my $target (@{$event->{'mailto'}}) {
- my $args = {
- 'subject' => $event->{'subject'},
- 'body' => $event->{'body'},
- 'eventid' => $event->{'eventid'},
- 'author' => $event->{'author'},
- 'recipient' => $target,
- 'from' => $fromaddress,
- };
-
- # run the queries for this schedule
- my $queries = run_queries($args);
-
- # If mailifnobugs is false, make sure there is something to output
- if (!$event->{'mailifnobugs'}) {
- my $there_are_bugs = 0;
- for my $query (@{$queries}) {
- $there_are_bugs = 1 if scalar @{$query->{'bugs'}};
- }
- next unless $there_are_bugs;
- }
+ my $eventid = $event->{'eventid'};
+
+ # We loop for each target user because some of the queries will be using
+ # subjective pronouns
+ $dbh = Bugzilla->switch_to_shadow_db();
+ for my $target (@{$event->{'mailto'}}) {
+ my $args = {
+ 'subject' => $event->{'subject'},
+ 'body' => $event->{'body'},
+ 'eventid' => $event->{'eventid'},
+ 'author' => $event->{'author'},
+ 'recipient' => $target,
+ 'from' => $fromaddress,
+ };
+
+ # run the queries for this schedule
+ my $queries = run_queries($args);
+
+ # If mailifnobugs is false, make sure there is something to output
+ if (!$event->{'mailifnobugs'}) {
+ my $there_are_bugs = 0;
+ for my $query (@{$queries}) {
+ $there_are_bugs = 1 if scalar @{$query->{'bugs'}};
+ }
+ next unless $there_are_bugs;
+ }
- $args->{'queries'} = $queries;
+ $args->{'queries'} = $queries;
- mail($args);
- }
- $dbh = Bugzilla->switch_to_main_db();
+ mail($args);
+ }
+ $dbh = Bugzilla->switch_to_main_db();
}
################################################################################
@@ -350,46 +358,39 @@ while (my $event = get_next_event) {
# - boundary a MIME boundary generated using the process id and time
#
sub mail {
- my $args = shift;
- my $addressee = $args->{recipient};
- # Don't send mail to someone whose bugmail notification is disabled.
- return if $addressee->email_disabled;
+ my $args = shift;
+ my $addressee = $args->{recipient};
+
+ # Don't send mail to someone whose bugmail notification is disabled.
+ return if $addressee->email_disabled;
- my $template = Bugzilla->template_inner($addressee->setting('lang'));
- my $msg = ''; # it's a temporary variable to hold the template output
- $args->{'alternatives'} ||= [];
+ my $template = Bugzilla->template_inner($addressee->setting('lang'));
+ my $msg = ''; # it's a temporary variable to hold the template output
+ $args->{'alternatives'} ||= [];
- # put together the different multipart mime segments
+ # put together the different multipart mime segments
- $template->process("whine/mail.txt.tmpl", $args, \$msg)
- or die($template->error());
- push @{$args->{'alternatives'}},
- {
- 'content' => $msg,
- 'type' => 'text/plain',
- };
- $msg = '';
+ $template->process("whine/mail.txt.tmpl", $args, \$msg)
+ or die($template->error());
+ push @{$args->{'alternatives'}}, {'content' => $msg, 'type' => 'text/plain',};
+ $msg = '';
- $template->process("whine/mail.html.tmpl", $args, \$msg)
- or die($template->error());
- push @{$args->{'alternatives'}},
- {
- 'content' => $msg,
- 'type' => 'text/html',
- };
- $msg = '';
+ $template->process("whine/mail.html.tmpl", $args, \$msg)
+ or die($template->error());
+ push @{$args->{'alternatives'}}, {'content' => $msg, 'type' => 'text/html',};
+ $msg = '';
- # now produce a ready-to-mail mime-encoded message
+ # now produce a ready-to-mail mime-encoded message
- $args->{'boundary'} = "----------" . $$ . "--" . time() . "-----";
+ $args->{'boundary'} = "----------" . $$ . "--" . time() . "-----";
- $template->process("whine/multipart-mime.txt.tmpl", $args, \$msg)
- or die($template->error());
+ $template->process("whine/multipart-mime.txt.tmpl", $args, \$msg)
+ or die($template->error());
- MessageToMTA($msg);
+ MessageToMTA($msg);
- delete $args->{'boundary'};
- delete $args->{'alternatives'};
+ delete $args->{'boundary'};
+ delete $args->{'alternatives'};
}
@@ -397,87 +398,90 @@ sub mail {
# the results to $args or mailing off the template if a query wants individual
# messages for each bug
sub run_queries {
- my $args = shift;
-
- my $return_queries = [];
-
- $sth_run_queries->execute($args->{'eventid'});
- my @queries = ();
- for (@{$sth_run_queries->fetchall_arrayref}) {
- push(@queries,
- {
- 'name' => $_->[0],
- 'title' => $_->[1],
- 'onemailperbug' => $_->[2],
- 'bugs' => [],
- }
- );
+ my $args = shift;
+
+ my $return_queries = [];
+
+ $sth_run_queries->execute($args->{'eventid'});
+ my @queries = ();
+ for (@{$sth_run_queries->fetchall_arrayref}) {
+ push(
+ @queries,
+ {
+ 'name' => $_->[0],
+ 'title' => $_->[1],
+ 'onemailperbug' => $_->[2],
+ 'bugs' => [],
+ }
+ );
+ }
+
+ foreach my $thisquery (@queries) {
+ next unless $thisquery->{'name'}; # named query is blank
+
+ my $savedquery = get_query($thisquery->{'name'}, $args->{'author'});
+ next unless $savedquery; # silently ignore missing queries
+
+ # Execute the saved query
+ my @searchfields = qw(
+ bug_id
+ bug_severity
+ priority
+ rep_platform
+ assigned_to
+ bug_status
+ resolution
+ short_desc
+ );
+
+ # A new Bugzilla::CGI object needs to be created to allow
+ # Bugzilla::Search to execute a saved query. It's exceedingly weird,
+ # but that's how it works.
+ my $searchparams = new Bugzilla::CGI($savedquery);
+ my $search = new Bugzilla::Search(
+ 'fields' => \@searchfields,
+ 'params' => scalar $searchparams->Vars,
+ 'user' => $args->{'recipient'}, # the search runs as the recipient
+ );
+
+ # If a query fails for whatever reason, it shouldn't kill the script.
+ my $data = eval { $search->data };
+ if ($@) {
+ print STDERR get_text('whine_query_failed',
+ {query_name => $thisquery->{'name'}, author => $args->{'author'}, reason => $@})
+ . "\n";
+ next;
}
- foreach my $thisquery (@queries) {
- next unless $thisquery->{'name'}; # named query is blank
-
- my $savedquery = get_query($thisquery->{'name'}, $args->{'author'});
- next unless $savedquery; # silently ignore missing queries
-
- # Execute the saved query
- my @searchfields = qw(
- bug_id
- bug_severity
- priority
- rep_platform
- assigned_to
- bug_status
- resolution
- short_desc
- );
- # A new Bugzilla::CGI object needs to be created to allow
- # Bugzilla::Search to execute a saved query. It's exceedingly weird,
- # but that's how it works.
- my $searchparams = new Bugzilla::CGI($savedquery);
- my $search = new Bugzilla::Search(
- 'fields' => \@searchfields,
- 'params' => scalar $searchparams->Vars,
- 'user' => $args->{'recipient'}, # the search runs as the recipient
- );
- # If a query fails for whatever reason, it shouldn't kill the script.
- my $data = eval { $search->data };
- if ($@) {
- print STDERR get_text('whine_query_failed', { query_name => $thisquery->{'name'},
- author => $args->{'author'},
- reason => $@ }) . "\n";
- next;
- }
-
- foreach my $row (@$data) {
- my $bug = {};
- for my $field (@searchfields) {
- my $fieldname = $field;
- $fieldname =~ s/^bugs\.//; # No need for bugs.whatever
- $bug->{$fieldname} = shift @$row;
- }
-
- if ($thisquery->{'onemailperbug'}) {
- $args->{'queries'} = [
- {
- 'name' => $thisquery->{'name'},
- 'title' => $thisquery->{'title'},
- 'bugs' => [ $bug ],
- },
- ];
- mail($args);
- delete $args->{'queries'};
- }
- else { # It belongs in one message with any other lists
- push @{$thisquery->{'bugs'}}, $bug;
- }
- }
- if (!$thisquery->{'onemailperbug'} && @{$thisquery->{'bugs'}}) {
- push @{$return_queries}, $thisquery;
- }
+ foreach my $row (@$data) {
+ my $bug = {};
+ for my $field (@searchfields) {
+ my $fieldname = $field;
+ $fieldname =~ s/^bugs\.//; # No need for bugs.whatever
+ $bug->{$fieldname} = shift @$row;
+ }
+
+ if ($thisquery->{'onemailperbug'}) {
+ $args->{'queries'} = [
+ {
+ 'name' => $thisquery->{'name'},
+ 'title' => $thisquery->{'title'},
+ 'bugs' => [$bug],
+ },
+ ];
+ mail($args);
+ delete $args->{'queries'};
+ }
+ else { # It belongs in one message with any other lists
+ push @{$thisquery->{'bugs'}}, $bug;
+ }
+ }
+ if (!$thisquery->{'onemailperbug'} && @{$thisquery->{'bugs'}}) {
+ push @{$return_queries}, $thisquery;
}
+ }
- return $return_queries;
+ return $return_queries;
}
# get_query gets the namedquery. It's similar to LookupNamedQuery (in
@@ -485,12 +489,12 @@ sub run_queries {
# individual named queries might go away without the whine_queries that point
# to them being removed.
sub get_query {
- my ($name, $user) = @_;
- my $qname = $name;
- $sth_get_query->execute($user->id, $qname);
- my $fetched = $sth_get_query->fetch;
- $sth_get_query->finish;
- return $fetched ? $fetched->[0] : '';
+ my ($name, $user) = @_;
+ my $qname = $name;
+ $sth_get_query->execute($user->id, $qname);
+ my $fetched = $sth_get_query->fetch;
+ $sth_get_query->finish;
+ return $fetched ? $fetched->[0] : '';
}
# check_today gets a run day from the schedule and sees if it matches today
@@ -502,25 +506,23 @@ sub get_query {
# - 'MF' for every weekday
sub check_today {
- my $run_day = shift;
-
- if (($run_day eq 'MF')
- && ($now_weekday > 0)
- && ($now_weekday < 6)) {
- return 1;
- }
- elsif (
- length($run_day) == 3 &&
- index("SunMonTueWedThuFriSat", $run_day)/3 == $now_weekday) {
- return 1;
- }
- elsif (($run_day eq 'All')
- || (($run_day eq 'last') &&
- ($now_day == $daysinmonth[$now_month] ))
- || ($run_day eq $now_day)) {
- return 1;
- }
- return 0;
+ my $run_day = shift;
+
+ if (($run_day eq 'MF') && ($now_weekday > 0) && ($now_weekday < 6)) {
+ return 1;
+ }
+ elsif (length($run_day) == 3
+ && index("SunMonTueWedThuFriSat", $run_day) / 3 == $now_weekday)
+ {
+ return 1;
+ }
+ elsif (($run_day eq 'All')
+ || (($run_day eq 'last') && ($now_day == $daysinmonth[$now_month]))
+ || ($run_day eq $now_day))
+ {
+ return 1;
+ }
+ return 0;
}
# reset_timer sets the next time a whine is supposed to run, assuming it just
@@ -529,95 +531,101 @@ sub check_today {
# reset_timer does not lock the whine_schedules table. Anything that calls it
# should do that itself.
sub reset_timer {
- my $schedule_id = shift;
-
- # Schedules may not be executed more than once for each invocation of
- # whine.pl -- there are legitimate circumstances that can cause this, like
- # a set of whines that take a very long time to execute, so it's done
- # quietly.
- if (grep($_ == $schedule_id, @seen_schedules)) {
- null_schedule($schedule_id);
- return;
- }
- push @seen_schedules, $schedule_id;
-
- $sth = $dbh->prepare( "SELECT run_day, run_time FROM whine_schedules " .
- "WHERE id=?" );
- $sth->execute($schedule_id);
- my ($run_day, $run_time) = $sth->fetchrow_array;
-
- # It may happen that the run_time field is NULL or blank due to
- # a bug in editwhines.cgi when this field was initially 0.
- $run_time ||= 0;
-
- my $run_today = 0;
- my $minute_offset = 0;
-
- # If the schedule is to run today, and it runs many times per day,
- # it shall be set to run immediately.
- $run_today = &check_today($run_day);
- if (($run_today) && ($run_time !~ /^\d+$/)) {
- # The default of 60 catches any bad value
- my $minute_interval = 60;
- if ($run_time =~ /^(\d+)min$/i) {
- $minute_interval = $1;
- }
-
- # set the minute offset to the next interval point
- $minute_offset = $minute_interval - ($now_minute % $minute_interval);
- }
- elsif (($run_today) && ($run_time > $now_hour)) {
- # timed event for later today
- # (This should only happen if, for example, an 11pm scheduled event
- # didn't happen until after midnight)
- $minute_offset = (60 * ($run_time - $now_hour)) - $now_minute;
- }
- else {
- # it's not something that runs later today.
- $minute_offset = 0;
-
- # Set the target time if it's a specific hour
- my $target_time = ($run_time =~ /^\d+$/) ? $run_time : 0;
-
- my $nextdate = &get_next_date($run_day);
- my $run_next = $dbh->sql_date_math('('
- . $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY')
- . ')', '+', '?', 'HOUR');
- $sth = $dbh->prepare("UPDATE whine_schedules " .
- "SET run_next = $run_next
- WHERE id = ?");
- $sth->execute($nextdate, $target_time, $schedule_id);
- return;
+ my $schedule_id = shift;
+
+ # Schedules may not be executed more than once for each invocation of
+ # whine.pl -- there are legitimate circumstances that can cause this, like
+ # a set of whines that take a very long time to execute, so it's done
+ # quietly.
+ if (grep($_ == $schedule_id, @seen_schedules)) {
+ null_schedule($schedule_id);
+ return;
+ }
+ push @seen_schedules, $schedule_id;
+
+ $sth = $dbh->prepare(
+ "SELECT run_day, run_time FROM whine_schedules " . "WHERE id=?");
+ $sth->execute($schedule_id);
+ my ($run_day, $run_time) = $sth->fetchrow_array;
+
+ # It may happen that the run_time field is NULL or blank due to
+ # a bug in editwhines.cgi when this field was initially 0.
+ $run_time ||= 0;
+
+ my $run_today = 0;
+ my $minute_offset = 0;
+
+ # If the schedule is to run today, and it runs many times per day,
+ # it shall be set to run immediately.
+ $run_today = &check_today($run_day);
+ if (($run_today) && ($run_time !~ /^\d+$/)) {
+
+ # The default of 60 catches any bad value
+ my $minute_interval = 60;
+ if ($run_time =~ /^(\d+)min$/i) {
+ $minute_interval = $1;
}
- if ($minute_offset > 0) {
- # Scheduling is done in terms of whole minutes.
-
- my $next_run = $dbh->selectrow_array(
- 'SELECT ' . $dbh->sql_date_math('NOW()', '+', '?', 'MINUTE'),
- undef, $minute_offset);
- $next_run = format_time($next_run, "%Y-%m-%d %R", "UTC");
-
- $sth = $dbh->prepare("UPDATE whine_schedules " .
- "SET run_next = ? WHERE id = ?");
- $sth->execute($next_run, $schedule_id);
- } else {
- # The minute offset is zero or less, which is not supposed to happen.
- # complain to STDERR
- null_schedule($schedule_id);
- print STDERR "Error: bad minute_offset for schedule ID $schedule_id\n";
- }
+ # set the minute offset to the next interval point
+ $minute_offset = $minute_interval - ($now_minute % $minute_interval);
+ }
+ elsif (($run_today) && ($run_time > $now_hour)) {
+
+ # timed event for later today
+ # (This should only happen if, for example, an 11pm scheduled event
+ # didn't happen until after midnight)
+ $minute_offset = (60 * ($run_time - $now_hour)) - $now_minute;
+ }
+ else {
+ # it's not something that runs later today.
+ $minute_offset = 0;
+
+ # Set the target time if it's a specific hour
+ my $target_time = ($run_time =~ /^\d+$/) ? $run_time : 0;
+
+ my $nextdate = &get_next_date($run_day);
+ my $run_next
+ = $dbh->sql_date_math(
+ '(' . $dbh->sql_date_math('CURRENT_DATE', '+', '?', 'DAY') . ')',
+ '+', '?', 'HOUR');
+ $sth = $dbh->prepare(
+ "UPDATE whine_schedules " . "SET run_next = $run_next
+ WHERE id = ?"
+ );
+ $sth->execute($nextdate, $target_time, $schedule_id);
+ return;
+ }
+
+ if ($minute_offset > 0) {
+
+ # Scheduling is done in terms of whole minutes.
+
+ my $next_run
+ = $dbh->selectrow_array(
+ 'SELECT ' . $dbh->sql_date_math('NOW()', '+', '?', 'MINUTE'),
+ undef, $minute_offset);
+ $next_run = format_time($next_run, "%Y-%m-%d %R", "UTC");
+
+ $sth
+ = $dbh->prepare("UPDATE whine_schedules " . "SET run_next = ? WHERE id = ?");
+ $sth->execute($next_run, $schedule_id);
+ }
+ else {
+ # The minute offset is zero or less, which is not supposed to happen.
+ # complain to STDERR
+ null_schedule($schedule_id);
+ print STDERR "Error: bad minute_offset for schedule ID $schedule_id\n";
+ }
}
# null_schedule is used to safeguard against infinite loops. Schedules with
# run_next set to NULL will not be available to get_next_event until they are
# rescheduled, which only happens when whine.pl starts.
sub null_schedule {
- my $schedule_id = shift;
- $sth = $dbh->prepare("UPDATE whine_schedules " .
- "SET run_next = NULL " .
- "WHERE id=?");
- $sth->execute($schedule_id);
+ my $schedule_id = shift;
+ $sth = $dbh->prepare(
+ "UPDATE whine_schedules " . "SET run_next = NULL " . "WHERE id=?");
+ $sth->execute($schedule_id);
}
# get_next_date determines the difference in days between now and the next
@@ -626,56 +634,58 @@ sub null_schedule {
# It takes a run_day argument (see check_today, above, for an explanation),
# and returns an integer, representing a number of days.
sub get_next_date {
- my $day = shift;
+ my $day = shift;
- my $add_days = 0;
+ my $add_days = 0;
- if ($day eq 'All') {
- $add_days = 1;
+ if ($day eq 'All') {
+ $add_days = 1;
+ }
+ elsif ($day eq 'last') {
+
+ # next_date should contain the last day of this month, or next month
+ # if it's today
+ if ($daysinmonth[$now_month] == $now_day) {
+ my $month = $now_month + 1;
+ $month = 1 if $month > 12;
+ $add_days = $daysinmonth[$month] + 1;
}
- elsif ($day eq 'last') {
- # next_date should contain the last day of this month, or next month
- # if it's today
- if ($daysinmonth[$now_month] == $now_day) {
- my $month = $now_month + 1;
- $month = 1 if $month > 12;
- $add_days = $daysinmonth[$month] + 1;
- }
- else {
- $add_days = $daysinmonth[$now_month] - $now_day;
- }
+ else {
+ $add_days = $daysinmonth[$now_month] - $now_day;
}
- elsif ($day eq 'MF') { # any day Monday through Friday
- if ($now_weekday < 5) { # Sun-Thurs
- $add_days = 1;
- }
- elsif ($now_weekday == 5) { # Friday
- $add_days = 3;
- }
- else { # it's 6, Saturday
- $add_days = 2;
- }
+ }
+ elsif ($day eq 'MF') { # any day Monday through Friday
+ if ($now_weekday < 5) { # Sun-Thurs
+ $add_days = 1;
+ }
+ elsif ($now_weekday == 5) { # Friday
+ $add_days = 3;
}
- elsif ($day !~ /^\d+$/) { # A specific day of the week
+ else { # it's 6, Saturday
+ $add_days = 2;
+ }
+ }
+ elsif ($day !~ /^\d+$/) { # A specific day of the week
# The default is used if there is a bad value in the database, in
# which case we mark it to a less-popular day (Sunday)
- my $day_num = 0;
+ my $day_num = 0;
- if (length($day) == 3) {
- $day_num = (index("SunMonTueWedThuFriSat", $day)/3) or 0;
- }
+ if (length($day) == 3) {
+ $day_num = (index("SunMonTueWedThuFriSat", $day) / 3) or 0;
+ }
- $add_days = $day_num - $now_weekday;
- if ($add_days <= 0) { # it's next week
- $add_days += 7;
- }
+ $add_days = $day_num - $now_weekday;
+ if ($add_days <= 0) { # it's next week
+ $add_days += 7;
}
- else { # it's a number, so we set it for that calendar day
- $add_days = $day - $now_day;
- # If it's already beyond that day this month, set it to the next one
- if ($add_days <= 0) {
- $add_days += $daysinmonth[$now_month];
- }
+ }
+ else { # it's a number, so we set it for that calendar day
+ $add_days = $day - $now_day;
+
+ # If it's already beyond that day this month, set it to the next one
+ if ($add_days <= 0) {
+ $add_days += $daysinmonth[$now_month];
}
- return $add_days;
+ }
+ return $add_days;
}