GunRunMaps/send_aac_maps.pl

218 lines
8.9 KiB
Perl
Executable File

#!/usr/bin/perl
# Debug level 0: Send email
# Debug level 1: Send email to myself
# Debug level 2: Print names and email addresses
use strict;
use warnings;
use Text::CSV;
use Email::MIME::CreateHTML;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP;
use Email::Sender::Transport::SMTPS;
use Email::Sender::Transport::SMTP::TLS;
use Term::ReadKey;
use File::Basename;
use Try::Tiny;
use Data::Dumper;
my $map_dir = '/home/tim/Documents/Projects/2019/Gun Run/Maps/';
my $email_csv = "$map_dir/GIS Base Map/marshals_by_position.csv";
my $pdf_dir = "$map_dir/GIS Base Map/Marshals/";
my $debug = 2;
my @emails;
if ($debug == 2) {
print "WARNING: Printing names. Not sending emails!\n";
} elsif ($debug == 1) {
print "WARNING: Sending emails to a TEST address.\n";
} elsif ($debug == 0) {
print "Sending emails to...\n";
} else {
print "ERROR: Invalid debug value\n";
}
my $password;
if (-f "$map_dir/password_store") {
open(my $fh, '<:encoding(UTF-8)', "$map_dir/password_store") or die "Could not open password store: $!";
while (my $row = <$fh>) {
chomp($password = $row);
}
close($fh)
} else {
print "Please type your email password: ";
#chomp($password = <STDIN>);
ReadMode('noecho');
chomp($password = ReadLine(0));
print "\n";
ReadMode('normal');
}
my $csv = Text::CSV->new ( { binary => 1 } ) or die "Cannot use CSV: ".Text::CSV->error_diag ();
open my $ifh, "<", $email_csv or die "Could not read $email_csv: $!";
$csv->column_names($csv->getline( $ifh ));
while ( my $row = $csv->getline( $ifh ) ) {
my $person = {
"position" => $row->[0],
"club" => $row->[1],
"first_name" => $row->[2],
"name" => $row->[4],
"email" => $row->[6],
};
$person->{"name"} =~ s/ +$//g if $person->{"name"};
$person->{"name"} =~ s/ +/ /g if $person->{"name"};
$person->{"first_name"} =~ s/ +$//g if $person->{"first_name"};
$person->{"first_name"} =~ s/ +/ /g if $person->{"first_name"};
$person->{"email"} =~ s/,//g if $person->{"email"};
push @emails, $person;
}
$csv->eof or $csv->error_diag();
close $ifh;
#@emails = sort { $a->{"position"} cmp $b->{"position"} } @emails;
if ($ARGV[0]) {
my $pos = $ARGV[0];
@emails = grep { $_->{"position"} =~ /^$pos$/ } @emails;
}
#print Dumper(@emails);
foreach my $person (@emails) {
next unless $$person{"name"} and $$person{"email"};
next unless $$person{"club"} =~ /^(AAC)$/;
next if $$person{"position"} =~ /\D/;
my $salutation = $$person{"first_name"};
my $name = $$person{"name"};
my $email = $$person{"email"};
my $club = $$person{"club"};
next unless $email =~ /@/;
my $position = $$person{"position"};
my $position_time;
if ($position =~ /^(10\d|110)$/) {
$position_time = "4:45AM";
} else {
$position_time = "5:45AM";
}
# if ($position =~ /^(26|27)$/i) {
# warn "NOTE: Skipped position $position";
# next;
# }
foreach my $m (split(/[, ]+/, $email)) {
$m = "$name <$m>";
printf "%-4s %-15s %15s\n", $$person{"position"}, $salutation, $m if ($debug >= 0);
$m = 'Timothy Allen <tim@allen.org.za>' if ($debug == 1);
my $pdf = $pdf_dir . $club . '_marshal_map_' . $position . '.pdf';
my $jpg = $pdf_dir . $club . '_marshal_map_' . $position . '.jpg';
my $parking = $map_dir . '/Gun Run 2019 - P9 Marshal Parking.pdf';
my $directions = $map_dir . '/Gun Run 2019 - P9 Parking Access.pdf';
my $pdf_filename = basename($pdf);
my $jpg_filename = basename($jpg);
die "No PDF at $pdf_filename" unless -e $pdf;
die "No JPG at $jpg_filename" unless -e $jpg;
my $html = qq(
<html><head>
</head>
<body>
<p>
Dear $salutation
</p>
<p>
I believe that many marshals didn't receive their maps, so I'm re-sending to everyone. If you received your map before, please accept my apologies, along with the attached voucher for parking in P9! I've also attached a map that shows you how to get to P9: turn off Helen Suzman by the Virgin Active, turn right at the T-junction, and pass through the gate at the end of the road, onto the field in Green Point Park. Please note that you will need to <b>print</b> the map (security won't accept an image on your phone).
</p>
<p>
Also attached to this email is a map that gives your marshalling position. <b>You are in position $position on the map.</b> It's important to be in place by <b>$position_time</b> on the day, as the police and traffic officials will be conducting spot checks at that point, and if any marshal is not in position, they may call off the race or delay it.
</p>
<p>
If you have any trouble opening the attachment, the map is available online as a <a href="http://node.org.za/GunRun2019/$club/$pdf_filename">PDF document</a> and an <a href="http://node.org.za/GunRun2019/$club/$jpg_filename">image</a>.
</p>
<p>
In addition, there is a complete <a href="https://node.org.za/GunRun2019/Gun%20Run%202019%20-%20Routes.pdf">route map</a> and a map of <a href="https://node.org.za/GunRun2019/Gun%20Run%202019%20-%20Marshal%20Plan.pdf">all marshal positions</a>. All <a href="http://node.org.za/GunRun2019/">other maps</a> (including cones and fencing; road closures; and directions to the start) are available as well.
</p>
<p>
You'll notice the map has several phone numbers on it&mdash;if in doubt, please call the Venue Operations Centre (VOC) in case of any emergency, as you'll get a faster response than by calling your captain or myself.
</p>
<p>
It can get quite cold in the mornings at this time of year; please be sure to bring something warm (wear it <i>under</i> your bib, please!), as well as sunscreen and a hat. You may also wish to bring water or coffee and something to eat, and even something to sit on. Please do encourage the runners as they run past you!
</p>
<p>
Regards,
</p>
<p>
Tim
</p>
</body>
</html>
);
my $plain_text = qq(Dear $salutation
I believe that many marshals didn't receive their maps, so I'm re-sending to everyone. If you received your map before, please accept my apologies, along with the attached voucher for parking in P9! I've also attached a map that shows you how to get to P9: turn off Helen Suzman by the Virgin Active, turn right at the T-junction, and pass through the gate at the end of the road, onto the field in Green Point Park. Please note that you will need to print the map (security won't accept an image on your phone).
Attached to this email is a map that gives your marshalling position. You are in position $position. It's important to be in place by $position_time on the day, as the police and traffic officials will be conducting spot checks at that point, and if any marshal is not in position, they may call off the race or delay it.
If you have any trouble opening the attachment, the map is available online as a PDF document at <http://node.org.za/GunRun2019/$club/$pdf_filename> and as an image at <http://node.org.za/GunRun2019/$club/$jpg_filename>.
In addition, there is a complete route map at <https://node.org.za/GunRun2019/Gun%20Run%202019%20-%20Routes.pdf> and a map of all marshal positions at <https://node.org.za/GunRun2019/Gun%20Run%202019%20-%20Marshal%20Plan.pdf>. All other maps (including cones and fencing; road closures; and directions to the start) are available as well at <https://node.org.za/GunRun2019/>.
You'll notice the map has several phone numbers on it -- if in doubt, please call the Venue Operations Centre (VOC) in case of any emergency, as you'll get a faster response than by calling your captain or myself.
It can get quite cold in the mornings at this time of year; please be sure to bring something warm (wear it under your bib, please!), as well as sunscreen and a hat. You may also wish to bring water or coffee and something to eat, and even something to sit on. Please do encourage the runners as they run past you!
Regards,
Tim
);
$pdf_filename =~ s/^.*?_//;
my %objects = (
"$pdf_filename" => $pdf,
"Gun_Run_2019_-_P9_Marshal_Parking.pdf" => $parking,
"Gun_Run_2019_-_P9_Parking_Access.pdf" => $directions,
);
my $mail = Email::MIME->create_html(
header => [
From => 'Timothy Allen <tim@allen.org.za>',
Subject => 'Your Gun Run 2019 marshalling position (with parking voucher)',
To => $m,
],
body => $html,
text_body => $plain_text,
objects => \%objects,
);
my $g_transport = Email::Sender::Transport::SMTP::TLS->new(
host => 'smtp.gmail.com',
username => 'trallen@gmail.com',
password => $password,
);
my $t_transport = Email::Sender::Transport::SMTP::TLS->new(
host => 'mail.treehouse.org.za',
username => 'tim',
password => $password,
);
try {
# sendmail($mail, { transport => $g_transport }) if ($debug <= 1);
sendmail($mail, { transport => $t_transport }) if ($debug <= 1);
} catch {
warn "\n\nError sending email for position $position\n\n";
warn $_;
};
}
sleep 2 if ($debug < 1);
last if ($debug == 1);
}
# vim: set expandtab shiftwidth=4 softtabstop=4 :