aboutsummaryrefslogtreecommitdiff
path: root/.local/bin/localmail
diff options
context:
space:
mode:
authorPatrick Spek <p.spek@tyil.nl>2020-03-09 12:48:12 +0100
committerPatrick Spek <p.spek@tyil.nl>2021-08-14 11:59:32 +0200
commitc8123c155b237e6717a500923376918bb0a4c38a (patch)
tree31d494ba02c8a3b476433a8ea189ce586588c359 /.local/bin/localmail
parent06683b22c139a8ebf637256fad1a79734d872964 (diff)
Add Mutt configuration
Diffstat (limited to '.local/bin/localmail')
-rwxr-xr-x.local/bin/localmail198
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);