Support multiple servers and various other notification improvements
This commit is contained in:
parent
0e3f0fe882
commit
9940de3bde
1 changed files with 97 additions and 65 deletions
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/perl
|
||||
# urgent-mail-check.plx
|
||||
#
|
||||
# Copyright (C) 2013, Bradley M. Kuhn
|
||||
# Copyright (C) 2013, 2015, 2016, Bradley M. Kuhn
|
||||
#
|
||||
# This program gives you software freedom; you can copy, modify, convey,
|
||||
# and/or redistribute it under the terms of the GNU General Public License
|
||||
|
@ -26,57 +26,61 @@ use Date::Manip;
|
|||
use Net::IMAP::Client;
|
||||
use File::Spec;
|
||||
use File::Temp;
|
||||
use Encode qw(encode decode);
|
||||
|
||||
if (@ARGV != 2) {
|
||||
print STDERR "usage: <username> <password_file>\n";
|
||||
my $VERBOSE = 0;
|
||||
if (@ARGV != 3) {
|
||||
print STDERR "usage: <server> <username> <password_file>\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my($SERVER, $USERNAME, $PASSWORD_FILE) = @ARGV;
|
||||
|
||||
my $DIR = File::Spec->catdir("$ENV{HOME}", 'tmp', '.urgent-email-displayed');
|
||||
|
||||
chdir($DIR) or die "unable to go to $DIR";
|
||||
|
||||
######################################################################
|
||||
sub ReadRecentUrgentEmailAnnouncements ($) {
|
||||
my($dir) = @_;
|
||||
sub ReadRecentUrgentEmailAnnouncements ($$) {
|
||||
my($dir, $server) = @_;
|
||||
|
||||
my %info;
|
||||
my $file = File::Spec->catfile($dir, 'urgent-email-announce-recent');
|
||||
open(RECENT_ALERTS, "<", $file) or die "unable to open $file for reading: $!";
|
||||
my $file = File::Spec->catfile($dir, $server . '.urgent-email-announce-recent');
|
||||
open(RECENT_ALERTS, '<:encoding(UTF-8)', $file) or die "unable to open $file for reading: $!";
|
||||
my $key;
|
||||
my $data = "";
|
||||
foreach my $line (<RECENT_ALERTS>) {
|
||||
chomp $line;
|
||||
next if $line =~ /^\s*$/;
|
||||
if ($line =~ /^\s*([\d\:\-]+)\s*$/) {
|
||||
my $newKey = $1;
|
||||
$info{$key} = $data if defined $key;
|
||||
$key = $newKey;
|
||||
$data = "";
|
||||
} else {
|
||||
$data .= $line;
|
||||
if ($line =~ /^\s*\"(.*)\"\s*:\s*([\d\:\-]+)\s*$/) {
|
||||
my($key, $date) = ($1, $2);
|
||||
$info{$key} = $date if defined $key;
|
||||
}
|
||||
}
|
||||
close RECENT_ALERTS; die "error($?) reading $file: $!" unless $? == 0;
|
||||
|
||||
$info{$key} = $data if (defined $key); # Grab last one.
|
||||
|
||||
return \%info;
|
||||
}
|
||||
######################################################################
|
||||
sub WriteRecentUrgentEmailAnnouncements ($$) {
|
||||
my($dir, $info) = @_;
|
||||
sub WriteRecentUrgentEmailAnnouncements ($$$) {
|
||||
my($dir, $server, $info) = @_;
|
||||
|
||||
my $file = File::Spec->catfile($dir, 'urgent-email-announce-recent');
|
||||
open(RECENT_ALERTS, ">", $file) or die "unable to open $file for reading: $!";
|
||||
my $file = File::Spec->catfile($dir, $server . '.urgent-email-announce-recent');
|
||||
print STDERR "writing to $file\n" if $VERBOSE;
|
||||
open(RECENT_ALERTS, '>:encoding(UTF-8)', $file) or die "unable to open $file for reading: $!";
|
||||
|
||||
foreach my $key (sort keys %$info) {
|
||||
print RECENT_ALERTS "$key\n$info->{$key}\n";
|
||||
print STDERR "\"$key\": $info->{$key}\n" if $VERBOSE;
|
||||
print RECENT_ALERTS "\"$key\": $info->{$key}\n";
|
||||
}
|
||||
close RECENT_ALERTS; die "error($?) writing $file: $!" unless $? == 0;
|
||||
print STDERR "Closed $file\n" if $VERBOSE;
|
||||
}
|
||||
######################################################################
|
||||
# Test if network is up
|
||||
if (-f "$ENV{HOME}/.shoddy-network") {
|
||||
print "\${color5}Shoddy Network, no urgent email check!\n";
|
||||
exit 0;
|
||||
}
|
||||
system('/bin/ping -q -w 20 -c 5 pine.sfconservancy.org > /dev/null 2>&1');
|
||||
|
||||
if ($? != 0) {
|
||||
|
@ -84,31 +88,30 @@ if ($? != 0) {
|
|||
exit 0;
|
||||
}
|
||||
|
||||
if (not -f $ARGV[1]) {
|
||||
print "\${color5}File $ARGV[1] not readable!\n";
|
||||
if (not -f $PASSWORD_FILE) {
|
||||
print "\${color5}File $PASSWORD_FILE not readable!\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $output = "";
|
||||
my $record = "";
|
||||
my $info = ReadRecentUrgentEmailAnnouncements($DIR);
|
||||
my $info = ReadRecentUrgentEmailAnnouncements($DIR, $SERVER);
|
||||
|
||||
# open a connection to the IMAP server
|
||||
use Net::IMAP::Client;
|
||||
open(PW, "<", $ARGV[1]) or die "unable to open $ARGV[0] to find password!";
|
||||
open(PW, "<", $PASSWORD_FILE) or die "unable to open $PASSWORD_FILE to find password!";
|
||||
|
||||
my %passwords;
|
||||
while (my $line = <PW>) {
|
||||
die "invalid line in password file: $ARGV[1]"
|
||||
die "invalid line in password file: $PASSWORD_FILE"
|
||||
unless $line =~ /^\s*(\S+)\s+(\S+)\s*$/;
|
||||
$passwords{$1} = $2;
|
||||
}
|
||||
close PW;
|
||||
|
||||
my $imap = Net::IMAP::Client->new(
|
||||
server => 'pine.sfconservancy.org',
|
||||
user => $ARGV[0],
|
||||
pass => $passwords{$ARGV[0]},
|
||||
server => $SERVER,
|
||||
user => $USERNAME,
|
||||
pass => $passwords{$USERNAME},
|
||||
ssl => 1, # (use SSL? default no)
|
||||
ssl_verify_peer => 1, # (use ca to verify server, default yes)
|
||||
# ssl_ca_file => '/etc/ssl/certs/certa.pm', # (CA file used for verify server) or
|
||||
|
@ -126,51 +129,80 @@ my $summaries = $imap->get_summaries($messages);
|
|||
|
||||
use Data::Dumper;
|
||||
|
||||
my(%noticeOutput);
|
||||
my $now = ParseDate("now");
|
||||
foreach my $summary (@{$summaries}) {
|
||||
my $now = ParseDate("now");
|
||||
my($who, $subject) = ($summary->{from}->[0]->name, $summary->subject);
|
||||
my $datetime = ParseDate($summary->date);
|
||||
my $ago = Delta_Format(DateCalc($datetime, $now), 0, "%dt days");
|
||||
$ago = Delta_Format(DateCalc($datetime, $now), 0, "%ht hours")
|
||||
if (defined $ago and $ago =~ /0 days/);
|
||||
$ago = Delta_Format(DateCalc($datetime, $now), 0, "%mt minutes")
|
||||
if (defined $ago and $ago =~ /0 hours/);
|
||||
$ago = Delta_Format(DateCalc($datetime, $now), 0, "%st seconds")
|
||||
if (defined $ago and $ago =~ /0 minutes/);
|
||||
my $output = "";
|
||||
my $ago = Delta_Format(DateCalc($datetime, $now), "approx", 0, "%dt days");
|
||||
$ago = Delta_Format(DateCalc($datetime, $now), "approx", 0, "%ht hours")
|
||||
if (defined $ago and $ago =~ /(^|\s+)0\s+day/);
|
||||
$ago = Delta_Format(DateCalc($datetime, $now), "approx", 0, "%mt minutes")
|
||||
if (defined $ago and $ago =~ /(^|\s+)0\s+hour/);
|
||||
$ago = Delta_Format(DateCalc($datetime, $now), "approx", 0, "%st seconds")
|
||||
if (defined $ago and $ago =~ /(^|\s+)0\s+minute/);
|
||||
$ago = "" if not defined $ago;
|
||||
$subject = "" unless defined $subject;
|
||||
|
||||
$subject = (split('\n', $subject))[0];
|
||||
$subject =~ s/^\s*Re\s*:\s*//i;
|
||||
my $record = "$who about $subject";
|
||||
$output .= "\${font Inconsolata:size=13}$ago ago from $record\n";
|
||||
next if not defined $subject or $subject =~ /^\s*$/;
|
||||
$who = "unknown" unless defined $who;
|
||||
my $record = encode('UTF-8', "$who about $subject");
|
||||
|
||||
my $alreadyDone = 0;
|
||||
foreach my $key (keys %$info) {
|
||||
$alreadyDone = (($info->{$key} eq $record) and
|
||||
(Delta_Format(DateCalc($key, $now), 0, "%mt") < 14400));
|
||||
last if $alreadyDone;
|
||||
}
|
||||
unless ($alreadyDone) {
|
||||
$info->{$now} = $record;
|
||||
my $fh = File::Temp->new();
|
||||
$fh->unlink_on_destroy( 1 );
|
||||
my $fname = $fh->filename;
|
||||
print $fh "Urgent email: ";
|
||||
print $fh $record;
|
||||
$fh->close();
|
||||
system("$ENV{HOME}/bin/myosd", $fname);
|
||||
system('/usr/bin/notify-send', '-u', 'critical', '-t', '300000',
|
||||
'Urgent Email', $record);
|
||||
system("$ENV{HOME}/bin/myspeakbyfile", $fname)
|
||||
unless -f "$ENV{HOME}/.silent-running";
|
||||
}
|
||||
$noticeOutput{$record}{output} = $output;
|
||||
$noticeOutput{$record}{datetime} = $datetime;
|
||||
$noticeOutput{$record}{who} = $who;
|
||||
$noticeOutput{$record}{subject} = $subject;
|
||||
}
|
||||
WriteRecentUrgentEmailAnnouncements($DIR, $info);
|
||||
my $olderCount = 0;
|
||||
my $oldestNow = $now;
|
||||
my $SEVEN_DAYS_AGO = DateCalc($now, "-7 days");
|
||||
my $allOutput = "";
|
||||
foreach my $record (sort {$noticeOutput{$a}{datetime} cmp $noticeOutput{$b}{datetime} } keys %noticeOutput ) {
|
||||
my $alreadyDone = (defined $info->{$record} ) ? $info->{$record} : undef;
|
||||
#and (Delta_Format(DateCalc($info->{$record}, $now), "approx", 0, "%ht") < 96));
|
||||
# uncomment above and put into expression if you want reminders on older emails you're ignoring in urgent.
|
||||
$info->{$record} = $now;
|
||||
if ($noticeOutput{$record}{datetime} lt $SEVEN_DAYS_AGO) {
|
||||
$olderCount++;
|
||||
$oldestNow = $alreadyDone if defined $alreadyDone and $alreadyDone lt $oldestNow;
|
||||
next;
|
||||
} else {
|
||||
$allOutput .= $noticeOutput{$record}{output};
|
||||
}
|
||||
next if defined $alreadyDone;
|
||||
|
||||
print "\$hr\n\${font :size=17}Urgent Emails:\n$output\$hr" if ($output ne "");
|
||||
$info->{$record} = $now;
|
||||
my $fh = File::Temp->new();
|
||||
$fh->unlink_on_destroy( 1 );
|
||||
my $fname = $fh->filename;
|
||||
print $fh "Urgent email: ";
|
||||
print $fh $record;
|
||||
$fh->close();
|
||||
# system("$ENV{HOME}/bin/myosd", $fname);
|
||||
system('/usr/bin/notify-send', '-u', 'critical', '-t', '300000',
|
||||
'Urgent Email', $record);
|
||||
system("$ENV{HOME}/bin/myspeakbyfile", $fname)
|
||||
unless -f "$ENV{HOME}/.silent-running";
|
||||
}
|
||||
WriteRecentUrgentEmailAnnouncements($DIR, $SERVER, $info);
|
||||
|
||||
if ($allOutput ne "") {
|
||||
print "\$hr\n\${font :size=17}Urgent Emails:\n$allOutput";
|
||||
print "\${font Inconsolata:size=13}... and $olderCount emails older than 7 days\n" if $olderCount > 0;
|
||||
print "\$hr";
|
||||
}
|
||||
my $hoursSinceNotify = Delta_Format(DateCalc($oldestNow, $now), "approx", 0, "%ht");
|
||||
if ($olderCount > 0 and $hoursSinceNotify > 1) {
|
||||
system('/usr/bin/notify-send', '-u', 'critical', '-t', '300000',
|
||||
'LONG PENDING URGENT EMAIL',
|
||||
"$olderCount urgent emails in folder older than 7 days (last remind: $hoursSinceNotify)");
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Local variables:
|
||||
# compile-command: "perl -c urgent-mail-check.plx"
|
||||
# End:
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue