2018-08-23 08:33:18 +00:00
#!/usr/bin/perl
2018-08-23 08:53:02 +00:00
# Debug level 0: Send email
# Debug level 1: Send email to myself
# Debug level 2: Print names and email addresses
2018-08-23 08:33:18 +00:00
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 ;
2018-10-11 12:02:09 +00:00
use Term::ReadKey ;
2018-08-23 08:33:18 +00:00
use File::Basename ;
use Try::Tiny ;
use Data::Dumper ;
2018-10-11 12:02:09 +00:00
my $ map_dir = '/home/tim/Documents/Projects/2018/Gun Run/Maps/' ;
my $ email_csv = "$map_dir/GIS base files and routes/marshals_by_position.csv" ;
my $ pdf_dir = "$map_dir/GIS base files and routes/Marshals/" ;
2018-08-23 08:53:02 +00:00
my $ debug = 1 ;
2018-08-23 08:33:18 +00:00
my @ emails ;
2018-10-11 12:02:09 +00:00
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' ) ;
}
2018-08-23 08:33:18 +00:00
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 ] ,
2018-08-23 08:53:02 +00:00
"first_name" = > $ row - > [ 1 ] ,
"name" = > $ row - > [ 3 ] ,
"club" = > $ row - > [ 4 ] ,
"email" = > $ row - > [ 6 ] ,
2018-08-23 08:33:18 +00:00
} ;
$ person - > { "name" } =~ s/ +$//g if $ person - > { "name" } ;
$ person - > { "name" } =~ s/ +/ /g if $ person - > { "name" } ;
2018-08-23 08:53:02 +00:00
$ person - > { "first_name" } =~ s/ +$//g if $ person - > { "first_name" } ;
$ person - > { "first_name" } =~ s/ +/ /g if $ person - > { "first_name" } ;
2018-08-23 08:33:18 +00:00
$ 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 ;
}
2018-08-23 08:53:02 +00:00
#print Dumper(@emails);
2018-08-23 08:33:18 +00:00
foreach my $ person ( @ emails ) {
next unless $$ person { "name" } and $$ person { "email" } ;
2018-10-11 12:02:09 +00:00
next unless $$ person { "club" } =~ /^(AAC|Walmer( AC)?)$/ ;
next if $$ person { "position" } =~ /\D/ ;
2018-08-23 08:53:02 +00:00
my $ salutation = $$ person { "first_name" } ;
my $ name = $$ person { "name" } ;
2018-08-23 08:33:18 +00:00
my $ email = $$ person { "email" } ;
2018-10-11 08:28:05 +00:00
my $ club = $$ person { "club" } ;
2018-08-23 08:33:18 +00:00
next unless $ email =~ /@/ ;
my $ position = $$ person { "position" } ;
2018-10-11 12:02:09 +00:00
my $ position_time ;
if ( $ position =~ /^10\d$/ ) {
$ position_time = "4:45AM" ;
} else {
$ position_time = "6AM" ;
}
2018-08-23 08:33:18 +00:00
2018-10-11 08:28:05 +00:00
# if ($position =~ /^(26|27)$/i) {
# warn "NOTE: Skipped position $position";
# next;
# }
2018-08-23 08:33:18 +00:00
foreach my $ m ( split ( /[, ]+/ , $ email ) ) {
2018-08-23 08:53:02 +00:00
$ m = "$name <$m>" ;
2018-10-11 08:28:05 +00:00
printf "%-4s %-15s %15s\n" , $$ person { "position" } , $ salutation , $ m if ( $ debug >= 0 ) ;
2018-08-23 08:53:02 +00:00
$ m = 'Timothy Allen <tim@allen.org.za>' if ( $ debug == 1 ) ;
2018-10-11 08:28:05 +00:00
my $ pdf = $ pdf_dir . $ club . '_marshal_map_' . $ position . '.pdf' ;
my $ jpg = $ pdf_dir . $ club . '_marshal_map_' . $ position . '.jpg' ;
2018-08-23 08:53:02 +00:00
my $ pdf_filename = basename ( $ pdf ) ;
my $ jpg_filename = basename ( $ jpg ) ;
die "No PDF at $pdf_filename" unless - e $ pdf ;
2018-10-11 08:28:05 +00:00
die "No JPG at $jpg_filename" unless - e $ jpg ;
2018-08-23 08:53:02 +00:00
2018-08-23 08:33:18 +00:00
my $ html = qq(
<html> <head>
</head>
<body>
<p>
Dear $ salutation
</p>
<p>
Thank you for helping out at this year ' s Gun Run !
</p>
<p>
2018-10-11 12:02:09 +00:00
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 .
2018-08-23 08:33:18 +00:00
</p>
<p>
2018-10-11 08:28:05 +00:00
If you have any trouble opening the attachment , the map is available online as a < a href = "http://node.org.za/GunRun2018/$club/$pdf_filename" > PDF document </a> and an < a href = "http://node.org.za/GunRun2018/$club/$jpg_filename" > image </a> .
2018-08-23 08:33:18 +00:00
</p>
<p>
2018-10-11 12:02:09 +00:00
In addition , there is a complete < a href = "https://node.org.za/GunRun2018/Gun%20Run%202018%20-%20Routes.pdf" > route map </a> and a map of < a href = "https://node.org.za/GunRun2018/Gun%20Run%202018%20-%20Marshal%20Plan%20A3.pdf" > all marshal positions </a> . All < a href = "http://node.org.za/GunRun2018/" > other maps </a> ( including cones and fencing ; road closures ; and directions to the start ) are available as well .
2018-08-23 08:33:18 +00:00
</p>
<p>
2018-08-23 08:53:02 +00:00
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 , Roger , 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 !
2018-08-23 08:33:18 +00:00
</p>
<p>
Regards ,
</p>
<p>
Tim
</p>
</body>
</html>
) ;
2018-08-23 08:53:02 +00:00
2018-08-23 08:33:18 +00:00
my $ plain_text = qq( Dear $salutation
Thank you for helping out at this year ' s Gun Run !
2018-10-11 12:02:09 +00:00
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 .
2018-08-23 08:33:18 +00:00
2018-10-11 08:28:05 +00:00
If you have any trouble opening the attachment , the map is available online as a PDF document at <http://node.org.za/GunRun2017/AAC/$pdf_filename> and as an image at <http://node.org.za/GunRun2017/AAC/$jpg_filename> .
2018-08-23 08:53:02 +00:00
2018-10-11 12:02:09 +00:00
In addition , there is a complete route map at <https://node.org.za/GunRun2018/Gun%20Run%202018%20-%20Routes.pdf> and a map of all marshal positions at <https://node.org.za/GunRun2018/Gun%20Run%202018%20-%20Marshal%20Plan%20A3.pdf> . All other maps ( including cones and fencing ; road closures ; and directions to the start ) are available as well at <https://node.org.za/GunRun2018/> .
2018-08-23 08:53:02 +00:00
2018-08-23 08:33:18 +00:00
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 , Roger , 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
) ;
2018-08-23 08:53:02 +00:00
$ pdf_filename =~ s/^.*?_// ;
my % objects = ( "$pdf_filename" = > $ pdf ) ;
2018-08-23 08:33:18 +00:00
my $ mail = Email::MIME - > create_html (
header = > [
From = > 'Timothy Allen <tim@allen.org.za>' ,
2018-10-11 08:28:05 +00:00
Subject = > 'Your Gun Run 2018 marshalling position' ,
2018-08-23 08:33:18 +00:00
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' ,
2018-10-11 08:28:05 +00:00
password = > $ password ,
2018-08-23 08:33:18 +00:00
) ;
my $ t_transport = Email::Sender::Transport::SMTP::TLS - > new (
host = > 'mail.treehouse.org.za' ,
username = > 'tim' ,
2018-10-11 08:28:05 +00:00
password = > $ password ,
2018-08-23 08:33:18 +00:00
) ;
try {
2018-08-23 08:53:02 +00:00
sendmail ( $ mail , { transport = > $ g_transport } ) if ( $ debug <= 1 ) ;
# sendmail($mail, { transport => $t_transport }) if ($debug <= 1);
2018-08-23 08:33:18 +00:00
} catch {
warn "\n\nError sending email for position $position\n\n" ;
warn $ _ ;
} ;
}
2018-10-11 08:28:05 +00:00
sleep 2 if ( $ debug < 1 ) ;
2018-08-23 08:53:02 +00:00
last if ( $ debug == 1 ) ;
2018-08-23 08:33:18 +00:00
}
2018-10-11 08:28:05 +00:00
# vim: set expandtab shiftwidth=4 softtabstop=4 :