App-FonBot-Daemon
view release on metacpan or search on metacpan
lib/App/FonBot/Plugin/Email.pm view on Meta::CPAN
use Email::Simple;
use Email::MIME;
use Linux::Inotify2 qw/IN_MOVED_TO/;
use File::Slurp qw/read_file/;
use POE;
use Log::Log4perl qw//;
use File::Glob qw/bsd_glob GLOB_NOSORT/;
use Text::ParseWords qw/shellwords/;
use App::FonBot::Plugin::Common;
use App::FonBot::Plugin::Config qw/$email_batch_seconds $email_from $email_subject/;
##################################################
my $log=Log::Log4perl->get_logger(__PACKAGE__);
my %queues;
my %queue_alarms;
my $session;
my $inotify;
sub init{
return unless $email_from && $email_subject;
$log->info('initializing '.__PACKAGE__);
$session = POE::Session->create(
inline_states => {
_start => \&email_start,
send_message => \&email_send_message,
flush_queue => \&email_flush_queue,
inotify_readable => sub{
$_[HEAP]{inotify}->poll
},
shutdown => sub{
$_[KERNEL]->select_read($inotify)
}
},
);
}
sub fini{
$log->info('finishing '.__PACKAGE__);
POE::Kernel->post($session, 'shutdown')
}
sub email_handle_new{
for my $file (bsd_glob 'Maildir/new/*', GLOB_NOSORT) {
my $email=Email::MIME->new(scalar read_file $file);
#untaint $file
$file =~ /^(.*)$/;
$file = $1;
unlink $file;
return unless defined $email;
my $replyto=$email->header('From');
return unless defined $replyto;
my ($user,$password)=split ' ', $email->header('Subject'), 2;
chomp $password;
$log->debug("Processing email from $user");
eval { pwcheck $user, $password };
if ($@) {
$log->debug("Incorrect credentials in email subject from user $user. Exception: $@");
POE::Kernel->yield(send_message => $replyto, "Incorrect credentials");
return
}
$ok_user_addresses{"$user EMAIL $replyto"}=1;
my $process_email_part = sub {
local *__ANON__ = "process_email_part"; #Name this sub. See http://www.perlmonks.org/?node_id=304883
my $part=$_[0];
return unless $part->content_type =~ /text\/plain/;
my @lines=split '\n', $part->body;
for my $line (@lines) {
last if $line =~ /^--/;
$log->debug("Command received via email from $user: $line");
sendmsg $user, undef, "EMAIL '$replyto'", shellwords $line
}
};
$email->walk_parts($process_email_part);
}
}
sub email_start{
$_[KERNEL]->alias_set('EMAIL');
$_[HEAP]{inotify} = Linux::Inotify2->new;
$_[HEAP]{inotify}->watch('Maildir/new/',IN_MOVED_TO,\&email_handle_new);
open $inotify,'<&=',$_[HEAP]{inotify}->fileno;
$_[KERNEL]->select_read($inotify, 'inotify_readable');
email_handle_new
}
sub email_send_message{
my ($address, $message) = @_[ARG0,ARG1];
$queues{$address}.=$message."\n";
if (defined $queue_alarms{$address}) {
$_[KERNEL]->delay_adjust($queue_alarms{$address}, $email_batch_seconds)
} else {
$queue_alarms{$address}=$_[KERNEL]->delay_set(flush_queue => $email_batch_seconds, $address)
}
}
sub email_flush_queue{
my ($queue) = $_[ARG0];
return unless exists $queues{$queue};
my $email=Email::Simple->create(
header => [
From => $email_from,
To => $queue,
Subject => $email_subject,
],
body => $queues{$queue}
);
( run in 0.646 second using v1.01-cache-2.11-cpan-39bf76dae61 )