Use File::Share(Dir) for templates
[app-edwardng.git] / lib / App / EdwardNG.pm
index 256cf7d670d7031697918d079edeca7cc0805f8c..4da1968ce2ab082321fc2ea5b334252f2ee6767e 100644 (file)
@@ -8,7 +8,9 @@ our $VERSION = '0.001';
 our @EXPORT = qw/process_message/;
 
 use Email::Sender::Simple qw/sendmail/;
+use File::Share qw/dist_file/;
 use File::Slurp qw/read_file/;
+use File::Spec::Functions qw/rel2abs/;
 use Getopt::Long;
 use MIME::Entity;
 use MIME::Parser;
@@ -32,29 +34,21 @@ sub mg {
 sub first_part{
        my ($ent) = @_;
        return first_part $ent->parts(0) if $ent->parts;
-       $ent->bodyhandle->as_string
+       stringify [$ent->bodyhandle->as_lines]
 }
 
 sub process_message {
-       my ($msg) = @_;
+       my ($in) = @_;
+       my $msg;
        my $parser = MIME::Parser->new;
        $parser->decode_bodies(0);
        $parser->output_to_core(1);
 
-       if (ref $msg eq 'MIME::Entity') {
-               debug 'Got MIME::Entity';
-       } elsif (ref $msg eq 'IO') {
-               debug 'Parsing from filehandle';
-               $msg = $parser->parse($msg)
-       } elsif (ref $msg eq 'SCALAR') {
-               debug 'Parsing from string';
-               $msg = $parser->parse_data($$msg)
-       } elsif (!ref $msg) {
-               debug "Parsing from file $msg";
-               $msg = $parser->parse_open($msg)
-       } else {
-               die "Don't know how to parse $msg"
-       }
+       $msg =                      $in   if     ref $in eq 'MIME::Entity';
+       $msg = $parser->parse      ($in)  if     ref $in eq 'IO';
+       $msg = $parser->parse_data ($in)  if     ref $in eq 'SCALAR';
+       $msg = $parser->parse_open ($in)  unless ref $in;
+       die "Don't know how to parse $in" unless $msg;
 
        if ($msg->mime_type ne 'multipart/signed' && $msg->mime_type ne 'multipart/encrypted') {
                # PGP/Inline requires decoding
@@ -103,13 +97,16 @@ sub run {
                'key=s'         => \$ENV{EDWARDNG_KEY},
                'keydir=s'      => \$ENV{EDWARDNG_KEYDIR},
                'passphrase=s'  => \$ENV{EDWARDNG_PASSPHRASE},
+               'tmpl-path=s'   => \$ENV{EDWARDNG_TMPL_PATH},
                'use-agent!'    => \$ENV{EDWARDNG_USE_AGENT},
        );
+       my $tmpl_path = $ENV{EDWARDNG_TMPL_PATH} // 'en';
 
        my $parser = MIME::Parser->new;
        $parser->decode_bodies(0);
        $parser->output_to_core(1);
        my $in = $parser->parse(\*STDIN);
+       debug 'Received mail from ', $in->get('From');
 
        my ($tmpl, %params);
        try {
@@ -117,10 +114,11 @@ sub run {
        } catch {
                ($tmpl, %params) = (error => message => $_)
        };
+       debug "Result is $tmpl, GnuPG said:\n", $params{message};
 
        $params{plaintext} = first_part $params{decrypted} if $params{decrypted};
 
-       my $tt = Template->new(INCLUDE_PATH => 'tmpl/en');
+       my $tt = Template->new(INCLUDE_PATH => rel2abs $tmpl_path, dist_file 'App-EdwardNG', 'tmpl');
        my $data;
        $tt->process($tmpl, \%params, \$data);
        my $email = MIME::Entity->build(
@@ -129,9 +127,11 @@ sub run {
                Subject => 'Re: ' . $in->get('Subject'),
                Data    => $data);
 
+       my $email_unencrypted = $email->dup;
        my $mg = mg always_trust => 1;
-       $mg->mime_signencrypt($email, $in->get('From') =~ /<(.*)>/) and debug 'Could not encrypt message. GnuPG said ', stringify $mg->{last_message};
-       sendmail $email
+       my $encrypt_failed = $mg->mime_signencrypt($email, $in->get('From') =~ /<(.*)>/);
+       debug 'Could not encrypt message, sending unencrypted. GnuPG said:', "\n", stringify $mg->{last_message} if $encrypt_failed;
+       sendmail $encrypt_failed ? $email_unencrypted : $email
 }
 
 1;
@@ -169,8 +169,6 @@ App::EdwardNG - GnuPG email sign/encrypt testing bot
 
 EdwardNG is a reimplementation of the Edward reply bot referenced in L<https://emailselfdefense.fsf.org/>.
 
-It takes mail messages, checks them for PGP signatures and encryption, then replies appropriately.
-
 This module exports a single function, B<process_message>, which takes a single parameter representing the message. This parameter can be:
 
 =over
This page took 0.011816 seconds and 4 git commands to generate.