diff options
author | Patrick Spek <p.spek@tyil.nl> | 2020-03-09 12:48:12 +0100 |
---|---|---|
committer | Patrick Spek <p.spek@tyil.nl> | 2021-08-14 11:59:32 +0200 |
commit | c8123c155b237e6717a500923376918bb0a4c38a (patch) | |
tree | 31d494ba02c8a3b476433a8ea189ce586588c359 /.local/bin/localmail | |
parent | 06683b22c139a8ebf637256fad1a79734d872964 (diff) |
Add Mutt configuration
Diffstat (limited to '.local/bin/localmail')
-rwxr-xr-x | .local/bin/localmail | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/.local/bin/localmail b/.local/bin/localmail new file mode 100755 index 0000000..dc1092a --- /dev/null +++ b/.local/bin/localmail @@ -0,0 +1,198 @@ +#!/usr/bin/env perl + +use v5.16; +use feature qw/say signatures/; +use strict; +use utf8; +use warnings; + +use Data::UUID; +use Email::Simple; +use File::Copy; +use File::Slurp; +use Net::IMAP::Simple; +use Net::SMTP; +use File::Path; +use File::Basename; + +use Data::Dumper; + +use App::Localmail; + +sub main (@args) { + my $action = shift @args; + + return 1 unless defined $action; + + my %actions = ( + fetch => \&fetch, + send => \&send, + ); + + return 2 unless exists $actions{$action}; + + return $actions{$action}(App::Localmail::base_config(), @args); +} + +sub fetch ($config, @args) { + # Get all passwords + App::Localmail::config_passwords($config); + + # Fetch email for each account + my $uuid = Data::UUID->new; + my $maildir = $config->{localmail}{maildir}; + + for my $account (keys %{$config->{accounts}}) { + my $current = $config->{accounts}{$account}{incoming}; + + if (!defined $current->{password}{plain}) { + say "No password for '$account'"; + next; + } + + say "Fetching mail for $account"; + say " Connecting to $current->{server}"; + + my $connection = Net::IMAP::Simple->new( + $current->{server}, + use_ssl => $current->{ssl} // 1, + ); + + if (!$connection) { + say " Failed: ". $Net::IMAP::Simple::errstr."\n"; + next; + } + + if ($current->{starttls}) { + say ' Applying StartTLS'; + $connection->starttls; + } + + say " Authenticating"; + if (!$connection->login($current->{username}, $current->{password}{plain})) { + say ' Failed: '.$connection->errstr."\n"; + next; + } + + say " Fetching mailboxes"; + for my $mbox ($connection->mailboxes) { + $connection->select($mbox); + + my @messages = keys(%{$connection->list}); + my $count = 0; + + say " $mbox (".($#messages + 1).")"; + + for my $message (@messages) { + $count++; + my $current_uuid = fc($uuid->to_string($uuid->create)); + + say " $current_uuid ($count)"; + + open(FH, '>', "$maildir/tmp/$current_uuid.eml") or die $!; + print FH $connection->fetch($message); + close(FH); + + move("$maildir/tmp/$current_uuid.eml", "$maildir/new/$current_uuid.eml"); + $connection->delete($message); + } + + $connection->close; + } + + say " Closing connection"; + $connection->quit; + } + + return 0; +} + +sub send ($config, @args) { + # Get all passwords + App::Localmail::config_passwords($config); + + my $uuid = Data::UUID->new; + my $maildir = $config->{localmail}{maildir}; + + # Create a hash of sender addresses and related accounts + my %senders; + + for my $account (keys %{$config->{accounts}}) { + for my $handler (@{$config->{accounts}{$account}{outgoing}{handles}}) { + $senders{$handler} = $account; + } + } + + # Walk through the queue of emails to send + for my $item (glob("$maildir/queue/*")) { + next unless -d $item; + next unless -f "$item/message.eml"; + + my ($id, $path) = File::Basename::fileparse($item); + + say "Sending $id"; + + my $body = File::Slurp::read_file("$item/message.eml"); + my $email = Email::Simple->new($body); + my $from = $email->header("From"); + my @recipients = File::Slurp::read_file("$item/recipients"); + + if (!exists $senders{$from}) { + say " No account handles mail from '$from'"; + next; + } + + my $current = $config->{accounts}{$senders{$from}}{outgoing}; + + say " Connecting to ".$current->{server}; + + # Send the email + my $connection = Net::SMTP->new( + $current->{server}, + SSL => $current->{ssl}, + Timeout => $current->{timeout} // 5, + ); + + say " Authenticating"; + + if (!$connection->auth($current->{username}, $current->{password}{plain})) { + say " Failed: ".$connection->message; + next; + } + + say " MAIL FROM"; + if (!$connection->mail($from)) { + say " Failed: ".$connection->message; + next; + } + + say " RCPT TO"; + if (!$connection->recipient(@recipients)) { + say " Failed: ".$connection->message; + next; + } + + say " DATA"; + if (!$connection->data($body)) { + say " Failed: ".$connection->message; + next; + } + + $connection->quit; + + say " Sent!"; + + if (open(FH, '>', "$maildir/sent/$id.eml")) { + say " Moving to sentdir"; + + print FH $email->as_string; + close(FH); + + File::Path::rmtree($item); + } + } + + return 0; +} + +exit main(@ARGV); |