#!/usr/bin/perl
-
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Author: Steven Schubiger <stsc@refcnt.org>
-# Last modified: Thu Jan 31 11:12:22 CET 2013
+# Last modified: Wed 09 Jun 2021 01:19:17 PM CEST
use strict;
use warnings;
use constant true => 1;
use constant false => 0;
+use DateTime ();
use DBI ();
+use Encode qw(decode encode);
use File::Basename ();
use File::Spec ();
use FindBin qw($Bin);
use LUGS::Events::Parser ();
use Mail::Sendmail qw(sendmail);
use Text::Wrap::Smart::XS qw(fuzzy_wrap);
+use URI ();
use WWW::Mechanize ();
-my $VERSION = '0.41';
+my $VERSION = '0.53';
#-----------------------
# Start of configuration
events_url => 'http://www.lugs.ch/lugs/termine/termine.txt',
form_url => 'http://lists.lugs.ch/reminder.cgi',
mail_from => 'reminder@lugs.ch',
+ mail_admin => 'stsc@refcnt.org',
dbase_name => '<hidden>',
dbase_user => '<hidden>',
dbase_pass => '<hidden>',
+ sleep_secs => 300,
+ max_tries => 48,
};
#---------------------
#---------------------
my $dbh = DBI->connect("dbi:mysql(RaiseError=>1):$Config->{dbase_name}", $Config->{dbase_user}, $Config->{dbase_pass});
-my $file = File::Basename::basename($Config->{events_url});
+my $file = File::Spec->catfile('tmp', (URI->new($Config->{events_url})->path_segments)[-1]);
my ($test, $run) = (false, false);
sub fetch_and_write_events
{
my $mech = WWW::Mechanize->new;
- my $http = $mech->get($Config->{events_url});
- open(my $fh, '>', $file) or die "Cannot open $file: $!\n";
- print {$fh} $http->content;
- close($fh);
+ my ($http, $retry, $tries);
+ $http = undef;
+
+ do {
+ $retry = false;
+ $tries++;
+ eval {
+ $http = $mech->get($Config->{events_url});
+ } or do {
+ warn "[${\scalar localtime}] $@";
+ $retry = ($tries < $Config->{max_tries}) ? true : false;
+ sleep $Config->{sleep_secs} if $retry;
+ };
+ } while ($retry);
+
+ if (defined $http) {
+ open(my $fh, '>', $file) or die "Cannot open $file for writing: $!\n";
+ print {$fh} $http->content;
+ close($fh);
+ }
+ else {
+ my $script = File::Basename::basename($0);
+ warn "[${\scalar localtime}] $script not entirely run, no http content\n";
+ my $message = <<"MSG";
+hello,
+
+This is lreminder [<$Config->{mail_from}>].
+
+Could not run $script entirely, no http content.
+Please re-run manually with `$0 --run' today.
+
+thanks,
+MSG
+ sendmail(
+ From => $Config->{mail_from},
+ To => $Config->{mail_admin},
+ Subject => 'LUGS Reminder - warning: timeout',
+ Message => $message,
+ ) or die "Cannot send mail: $Mail::Sendmail::error";
+ exit;
+ }
}
sub init
{
- my ($parser, $month_days, $current) = @_;
+ my ($parser) = @_;
$$parser = LUGS::Events::Parser->new($file, {
filter_html => true,
rewrite => '$TEXT - $HREF',
fields => [ qw(location more) ],
} ],
- 'br' => [ {
- rewrite => '',
- fields => [ qw(more) ],
- } ],
},
+ purge_tags => [ qw(location responsible more) ],
strip_text => [ 'mailto:' ],
});
unlink $file;
-
- %$month_days = (
- 1 => 31, 7 => 31,
- 2 => 28, 8 => 31,
- 3 => 31, 9 => 30,
- 4 => 30, 10 => 31,
- 5 => 31, 11 => 30,
- 6 => 30, 12 => 31,
- );
-
- %$current = do {
- my @time = (localtime)[3..5];
- $time[1]++;
- $time[2] += 1900;
- map { $_ => shift @time } qw(day month year);
- };
}
sub process_events
{
- my ($parser, %month_days, %current);
- init(\$parser, \%month_days, \%current);
+ my $parser;
+ init(\$parser);
while (my $event = $parser->next_event) {
my %event = (
my $subscriptions = $sth{subscriptions}->fetchrow_hashref;
next unless $subscriptions->{$event{color}};
- my %notify = %current;
+ my $notify = DateTime->now(time_zone => 'Europe/Zurich');
$subscriber->{notify} ||= 0;
- my $day = $current{day} + $subscriber->{notify};
- my $days_in_month = $month_days{$current{month}};
+ $notify->add(days => $subscriber->{notify});
- if ($day > $days_in_month) {
- $notify{day} = $day - $days_in_month;
- $notify{month}++;
- }
- else {
- $notify{day} += $subscriber->{notify};
- }
-
- if ($event{year} == $notify{year}
- && $event{month} == $notify{month}
- && $event{day} == $notify{day}
+ if ($event{year} == $notify->year
+ && $event{month} == $notify->month
+ && $event{day} == $notify->day
) {
send_mail($event, $subscriber->{mail});
}
my $month_name = $month_names{$month};
-my $message = (<<MSG);
+my $message = (<<"MSG");
Wann:\t$wday, $simple_day. $month_name $year, $time Uhr
Was :\t$title
Wo :\t$location
MSG
if ($run) {
+ $title = decode('UTF-8', $title);
sendmail(
- From => $Config->{mail_from},
- To => $mail_subscriber,
- Subject => "LUGS Reminder - $title",
- Message => $message,
- ) or die $Mail::Sendmail::error;
+ From => $Config->{mail_from},
+ To => $mail_subscriber,
+ Subject => encode('MIME-Q', "LUGS Reminder - $title"),
+ Message => $message,
+ 'Content-Type' => 'text/plain; charset="UTF-8"',
+ ) or die "Cannot send mail: $Mail::Sendmail::error";
}
elsif ($test) {
printf "[%s] <$mail_subscriber> ($color)\n", scalar localtime;
my $modified = localtime((stat($0))[9]);
$modified =~ s/(?<=\b) (?:\d{2}\:?){3} (?=\b)//x;
- $modified =~ s/\s+/ /g;
+ $modified =~ s/\s{2,}/ /g;
- my $info = <<EOT;
+ my $info = <<"EOT";
--
running $script v$VERSION - last modified: $modified
EOT