Fixed typo in pod
[clearscm.git] / bin / announceEmail.pl
index 4eb288a..0fae494 100755 (executable)
@@ -29,7 +29,7 @@ $Date: 2019/04/04 13:40:10 $
 
 =back
 
-=hade1 SYNOPSIS
+=head1 SYNOPSIS
 
  Usage: announceEmail.pl [-usa|ge] [-h|elp] [-v|erbose] [-de|bug] [-da|emon]
                          [-use|rname <username>] [-p|assword <password>]
@@ -44,7 +44,7 @@ $Date: 2019/04/04 13:40:10 $
    -use|rname: User name to log in with (Default: $USER)
    -p|assword: Password to use (Default: prompted)
    -i|map:     IMAP server to talk to (Default: defaria.com)
-   -s|leep:    Number of minutes to sleep inbetween checking mail (Default: 5)
+   -s|leep:    Number of minutes to sleep inbetween checking mail (Default: 1)
 
 =head1 DESCRIPTION
 
@@ -70,12 +70,14 @@ use MIME::Base64;
 use lib "$FindBin::Bin/../lib";
 
 use Display;
+use Logger;
 use Utils;
 
 my $defaultIMAPServer = 'defaria.com';
-my $defaultSleeptime  = 5;
+my $defaultSleeptime  = 1;
 my $IMAP;
 my %unseen;
+my $log;
 
 my %opts = (
   usage    => sub { pod2usage },
@@ -84,10 +86,33 @@ my %opts = (
   debug    => sub { set_debug },
   daemon   => 1,
   username => $ENV{USER},
+  password => $ENV{PASSWORD},
   imap     => $defaultIMAPServer,
   sleep    => $defaultSleeptime,
 );
 
+sub interrupted {
+  if (get_debug) {
+    $log->msg("Turning off debugging");
+    set_debug 0;
+  } else {
+    $log->msg("Turning on debugging");
+    set_debug 1;
+  } # if
+
+  return;
+} # interrupted
+
+$SIG{USR1} = \&interrupted;
+
+sub debugit($) {
+  my ($msg) = @_;
+
+  $log->msg($msg) if get_debug;
+
+  return;
+} # logit
+
 sub unseenMsgs() {
   my %unseenMsgs;
 
@@ -99,20 +124,20 @@ sub unseenMsgs() {
 } # unseenMsgs 
 
 sub Connect2IMAP() {
-  verbose "Connecting to $opts{imap} as $opts{username}";
+  $log->msg("Connecting to $opts{imap} as $opts{username}...", 1);
 
   $IMAP = Net::IMAP::Simple->new($opts{imap}) ||
-    error("Unable to connect to IMAP server $opts{imap}: " . $Net::IMAP::Simple::errstr, 1);
+    $log->err("Unable to connect to IMAP server $opts{imap}: " . $Net::IMAP::Simple::errstr, 1);
 
-  verbose "Connected";
+  $log->msg(' connected');
 
-  verbose "Logging onto $opts{imap} as $opts{username}";
+  $log->msg("Logging onto $opts{imap} as $opts{username}...", 1);
 
   unless ($IMAP->login($opts{username}, $opts{password})) {
-    error("Login to $opts{imap} as $opts{username} failed: " . $IMAP->errstr, 1);
+    $log->err("Login to $opts{imap} as $opts{username} failed: " . $IMAP->errstr, 1);
   } # unless
 
-  verbose "Logged on";
+  $log->msg(' logged on');
 
   # Focus on INBOX only
   $IMAP->select('INBOX');
@@ -120,16 +145,25 @@ sub Connect2IMAP() {
   # Setup %unseen to have each unseen message index set to 0 meaning not read
   # aloud yet
   %unseen = unseenMsgs;
+
+  return;
 } # Connect2IMAP
 
 sub MonitorMail() {
-  verbose "Monitoring email";
+  my $msg = "Now monitoring email for $opts{username}\@$opts{imap}";
+
+  $log->msg($msg);
+
+  my $cmd = "/usr/local/bin/gt \"$msg\"";
+
+  my ($status, @output) = Execute $cmd;
 
   while () {
-    verbose "Looking for unread messages";
     # First close and reselect the INBOX to get its current status
+    debugit "Reconnecting to INBOX";
     $IMAP->close;
-    $IMAP->select('INBOX');
+    $IMAP->select('INBOX')
+      or $log->err("Unable to select INBOX - ". $IMAP->errstr(), 1);
 
     # Go through all of the unseen messages and add them to %unseen if they were
     # not there already from a prior run and read
@@ -147,15 +181,21 @@ sub MonitorMail() {
       } # if
     } # for
 
+    debugit "Processing newUnseen";
     for (keys %newUnseen) {
       next if $unseen{$_};
 
-      my $email = Email::Simple->new(join '', @{$IMAP->top($_)});
+      my @msglines = $IMAP->top($_);
+
+      # What happens at INBOX 0? Does top return empty array?
+      $log->err("Unable to get top for $_ - " . $IMAP->errstr(), 1) unless @msglines;
+
+      my $email = Email::Simple->new(join '', @msglines);
 
       my $from = $email->header('From');
 
       # Extract the name only when the email is of the format "name <email>"
-      if ($from =~ /^(.*)\<(\S*)>/) {
+      if ($from =~ /^"?(.*?)"?\s*\<(\S*)>/) {
         $from = $1 if $1 ne '';
       } # if
 
@@ -165,25 +205,49 @@ sub MonitorMail() {
         $subject = decode_base64($2);
       } # if
 
+      # Google Talk doesn't like #
+      $subject =~ s/\#//g;
+
       # Now speak it!
-      my $msg = "Message from $from... " . quotemeta $subject;
+      debugit "Speaking message from $from";
+      my $logmsg = "From $from $subject";
+
+      $msg = "Message from $from... " . quotemeta $subject;
       $msg =~ s/\"/\\"/g;
 
-      verbose "Announcing $msg";
+      debugit $logmsg;
+
+      $cmd = "/usr/local/bin/gt \"$msg\"";
 
-      Execute "/usr/local/bin/gt \"$msg\"";
+      my $hour = (localtime)[2];
+
+      # Only announce if after 6 Am. Not this will announce up until
+      # midnight but that's ok. I want midnight to 6 Am as silent time.
+      if ($hour > 6) {
+        ($status, @output) = Execute $cmd;
+
+        if ($status) {
+          $log->err("Unable to execute $cmd" . join("\n", @output));
+        } # if
+      } # if
 
       $unseen{$_} = 1;
     } # for
 
-    verbose "Sleeping for $opts{sleep} minutes";
+    debugit "Sleeping for $opts{sleep} minutes";
     sleep 60 * $opts{sleep};
-    verbose "Ah that was refreshing!";
+    debugit "Ah that was refreshing!";
   } # while
+
+  return;
 } # MonitorMail
 
+$SIG{USR2} = \&MonitorMail;
+
 END {
-  $IMAP->quit;
+  $IMAP->quit if $IMAP;
+
+  $log->msg("$FindBin::Script ending!");
 } # END
 
 ## Main
@@ -205,7 +269,16 @@ unless ($opts{password}) {
   $opts{password} = GetPassword;
 } # unless
 
+$opts{debug} = get_debug;
+
 EnterDaemonMode if $opts{daemon};
 
+$log = Logger->new(
+  path        => '/var/log',
+  timestamped => 'yes',
+  append      => 'yes',
+);
+
 Connect2IMAP;
+
 MonitorMail;