#!/usr/bin/perl
#
# Author:  Petter Reinholdtsen
# Date:    2005-06-06
# License: GNU Public License v2
#
# Script to send a lot of mails from NUUG
#
# Based on script Mass Mailer v1.1 by ickerne (C) 1998

use warnings;
use strict;
use Getopt::Std;
use Text::CSV_XS;
use Text::Wrap;

sub help {
    print <<EOF;
Usage: $0 [-d] <template> <CSV-fields-file> [<envelope-from>]
  The template should be a complete mail, including headers,
  where <field> will be replaced with the value from the CSV file.

  -d             enable debug output
EOF
    exit 1;
}

my %opts;
getopts("d", \%opts) || help();
my $debug = $opts{d};

my $sendmail="/usr/sbin/sendmail";
my $sum=0;

help() if (2 != scalar @ARGV);

my $templatefile=$ARGV[0];
my $addressfile=$ARGV[1];
my $envelopefrom=$ARGV[2];

sub send_mail {
    my $text = shift;
    if ($debug) {
        print "============\n";
        print "$text\n";
        print "============\n";
    } else {
        if ($envelopefrom) {
            open(SENDMAIL, "|$sendmail -t -f $envelopefrom") or die "Unable to run $sendmail";
        } else {
            open(SENDMAIL, "|$sendmail -t") or die "Unable to run $sendmail";
        }
        print SENDMAIL $text;
        close(SENDMAIL);
    }
}

sub get_template {
    my $templatefile = shift;
    open(TEMPLATE, "<$templatefile") or die "Unable to read from $templatefile";
    my @lines = <TEMPLATE>;
    return join("", @lines);
}

sub update_template {
    my ($text, $mapref) = @_;
    for my $key (keys %{$mapref}) {
        $text =~ s/<$key>/$mapref->{$key}/g;
    }
    return $text;
}

my $template = get_template($templatefile);

my @headers;
my $csv = Text::CSV_XS->new (
    {
        binary => 1,
        sep_char => ';',
    });
open(ADDR, "<", $addressfile) or die "Unable to read from $addressfile";
while (<ADDR>) {
    chomp;
    s/#.*$//;
    next if (m/^\s*$/);
    my $status  = $csv->parse($_);
    if (!$status) {
        print "Parse error: '$_'\n";
    }
    my %map;
    if (@headers) {
        my @columns = $csv->fields();
        for my $header (@headers) {
            $map{$header} = shift @columns;
        }
    } else {
        @headers = $csv->fields();
        next;
    }
    $sum++;
    my $text = update_template($template, \%map );
    send_mail($text);
}
print "$sum mail(s) sent.\n"
