diff options
Diffstat (limited to 'lib/App/ImapNotify.pm')
-rw-r--r-- | lib/App/ImapNotify.pm | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/lib/App/ImapNotify.pm b/lib/App/ImapNotify.pm index 4cf5354..0b44f68 100644 --- a/lib/App/ImapNotify.pm +++ b/lib/App/ImapNotify.pm @@ -1,14 +1,16 @@ package App::ImapNotify; -use 5.008001; +use v5.24; use strict; use warnings; our $VERSION = "0.01"; +use App::ImapNotify::ImapClient; +use App::ImapNotify::Notifier; - -1; -__END__ +use Carp; +use Function::Parameters; +use Log::Any qw($log); =encoding utf-8 @@ -22,7 +24,9 @@ App::ImapNotify - It's new $module =head1 DESCRIPTION -App::ImapNotify is ... +App::ImapNotify is a simple notification script using IMAP NOTIFY. Note that it is very simple and +implements a custom IMAP client with very limited features. Mostly a proof of +concept and personal script. =head1 LICENSE @@ -37,3 +41,84 @@ Florian Pritz E<lt>bluewind@xinu.atE<gt> =cut +method new($class: $config, $deps = {}) { + $deps->{imap_client} //= App::ImapNotify::ImapClient->new({$config->%{qw(host port log_id username password keepalive_timeout)}}); + $deps->{notifier} //= App::ImapNotify::Notifier->new(); + return $class->new_no_defaults($config, $deps); +} + +method new_no_defaults($class: $config, $deps = {}) { + my $self = {}; + bless $self, $class; + $self->{config} = $config; + $self->{deps} = $deps; + return $self; +} + +method loop() { + #my $imap = $self->{deps}->{imap_client}->connect($self->{config}->@{qw(host port log_id)}); + #$imap->login($self->{config}->@{qw(username password)}); + my $imap = $self->{deps}->{imap_client}; + $imap->select($self->{config}->{mailboxes}->@[0]); + + $imap->send_command("notify set (selected (MessageExpunge MessageNew (uid body.peek[header.fields (from to subject)]))) (mailboxes (".join(' ', $self->{config}->{mailboxes}->@*).") (MessageNew MessageExpunge MailboxName))"); + + $log->info("Waiting for notify events"); + while (my $line = $imap->readline_timeout()) { + $log->tracef("Got line: '%s'", $line); + if ($line =~ m/^\* .* FETCH /) { + my $message = $imap->handle_fetch($line); + $self->_notify($message); + next; + } + if ($line =~ m/^\* STATUS (?<mailbox>[^ ]+) \(MESSAGES \d+ UIDNEXT (?<uidnext>\d+) UNSEEN \d+\)/) { + $log->debugf("Got status change: '%s'", $line); + my $mailbox = $+{mailbox}; + my $uid = $+{uidnext} - 1; + #$imap2->select($mailbox); + #my $message = $imap2->send_command("uid fetch $uid (body.peek[header.fields (from to subject)])"); + $imap->select($mailbox); + my $message = $imap->send_command("uid fetch $uid (body.peek[header.fields (from to subject)])"); + pop @{$message}; + $self->_notify($message); + next; + } + + next if $line =~ /\* \d+ RECENT/; + next if $line =~ /\* \d+ EXISTS/; + next if $line =~ /\* \d+ EXPUNGE/; + + confess(sprintf("Got unexpected line: '%s'", $line)); + } +} + +method _notify($message) { + $log->debugf("Got data for notification: %s", $message); + my $fields = {}; + my $current_field; + + return if $message->@* == 0; + + for my $line ($message->@*) { + if ($line =~ m/^(?<label>[^\s:]+): (?<value>.*)\r\n$/) { + $current_field = lc($+{label}); + $fields->{$current_field} = $+{value}; + next; + } + + if ($line =~ m/^\s+(.*)$/) { + $fields->{$current_field} .= $1; + } + } + + $log->debugf("Sending notification with data: %s", $fields); + my $notify_heading = sprintf("From: %s", $fields->%*->@{qw(from)}); + my $notify_body = sprintf("Subject: %s", $fields->%*->@{qw(subject)}); + $self->{deps}->{notifier}->notify($notify_heading, $notify_body); +} + + + +1; +__END__ + |