--- /dev/null
+#! /usr/bin/perl
+#
+
+use strict;
+use warnings;
+use YAML::Syck;
+use Template;
+use Text::Wrap;
+use FileHandle;
+use Getopt::Long;
+
+use Text::CSV_XS;
+use MIME::Entity;
+
+my $dir = undef;
+my $vars = "";
+my $template = "";
+my $send = 0;
+my $verbose = 0;
+
+GetOptions(
+ 'dir=s' => \$dir,
+ 'v|vars=s' => \$vars,
+ 't|template=s' => \$template,
+ 'verbose' => \$verbose,
+ 's|send' => \$send,
+);
+
+if (defined $dir) {
+ $vars = "$dir/merge.csv"
+ if $vars eq '' && -f "$dir/merge.csv";
+ $template = "$dir/merge.yml"
+ if $template eq '' && -f "$dir/merge.yml";
+}
+
+die "Sorry, where is the variables file?"
+ unless -f $vars;
+die "Sorry, where is the template file?"
+ unless -f $template;
+
+my $csv = Text::CSV_XS->new();
+my $tt = Template->new();
+
+my $tmplData = undef;
+eval { $tmplData = LoadFile("$template") };
+
+if ($@) {
+ die "Failed to load query file $template: $@";
+}
+
+for ('subject', 'body', 'from') {
+ if (! defined $tmplData->{$_}) {
+ die "$template missing required field $_\n";
+ }
+}
+
+
+my $IN = new FileHandle;
+open($IN, $vars)
+ || die "Failed to open $vars for reading: $!\n";
+
+my $headers = $csv->getline($IN);
+die "Nothing in $vars!" unless @$headers;
+$csv->column_names(@$headers);
+
+while (my $cols = $csv->getline_hr($IN) ) {
+ last unless %$cols;
+
+ if ($verbose) {
+ print "Template variables:\n";
+ for my $key (sort keys %$cols) {
+ print "$key: $cols->{$key}\n";
+ }
+ print "\n";
+ }
+
+ my $out;
+ if (! $tt->process(\$tmplData->{'body'}, $cols, \$out)) {
+ warn "Failed to process template: $tt->error()";
+ warn "Template: $tmplData->{'body'}\n"
+ if $verbose;
+
+ next;
+ }
+
+ if ($verbose) {
+ print "Subject: $tmplData->{'subject'}\n";
+ print "From: $tmplData->{'from'}\n";
+ print $out;
+ print "\n\n";
+ }
+
+ if ($send) {
+ print "Sending to $cols->{'email'}" .
+ ($tmplData->{'bcc'} ? " bcc $tmplData->{'bcc'} " : '') . "\n";
+
+ my @emails = ( $cols->{'email'} );
+
+ my $mail = MIME::Entity->build(
+ To => \@emails,
+ From => $tmplData->{'from'},
+ Subject => $tmplData->{'subject'},
+ Bcc => $tmplData->{'bcc'},
+ Encoding=> "quoted-printable",
+ Data => $out
+ );
+
+ $mail->send('sendmail');
+ } else {
+ print "Want to send to $cols->{'email'}" .
+ ($tmplData->{'bcc'} ? " bcc $tmplData->{'bcc'} " : '') . "\n";
+ }
+}
+
+close $IN;