From: Andrew DeFaria Date: Tue, 18 Aug 2020 11:17:59 +0000 (-0700) Subject: Fixed announceEmail.pl to be less busy X-Git-Url: https://defaria.com/gitweb/?a=commitdiff_plain;h=b4c848b00327fdcc52f3ff1742b71f8bd89dd855;p=clearscm.git Fixed announceEmail.pl to be less busy Turns out announceEmail.pl was looping in MonitorMail. The right way to do this is to call $IMAP->idle to set the call back. After that announceEmail.pl is suspended in idle. When action happens on the IMAP server the callback is called. So MonitorMail gets run to process the callback. But then the callback is gone and needs to be re-established. --- diff --git a/bin/announceEmail.pl b/bin/announceEmail.pl index 31c7596..a0113a1 100755 --- a/bin/announceEmail.pl +++ b/bin/announceEmail.pl @@ -17,7 +17,7 @@ Andrew DeFaria =item Revision -$Revision: 1.1 $ +$Revision: 1.2 $ =item Created: @@ -41,9 +41,10 @@ $Date: 2019/04/04 13:40:10 $ -v|erbose: Verbose mode (Default: -verbose) -de|bug: Turn on debugging (Default: Off) -da|emon: Run in daemon mode (Default: -daemon) - -use|rname: User name to log in with (Default: $USER) + -user|name: 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) + -uses|sl: Whether or not to use SSL to connect (Default: False) =head1 DESCRIPTION @@ -98,6 +99,7 @@ my %opts = ( username => $ENV{USER}, password => $ENV{PASSWORD}, imap => $defaultIMAPServer, + usessl => 0, ); sub interrupted { @@ -114,14 +116,6 @@ sub interrupted { $SIG{USR1} = \&interrupted; -sub debugit($) { - my ($msg) = @_; - - $log->msg($msg) if get_debug; - - return; -} # logit - sub unseenMsgs() { $IMAP->select('inbox') or $log->err("Unable to select inbox: " . get_last_error(), 1); @@ -136,6 +130,7 @@ sub Connect2IMAP() { Server => $opts{imap}, Username => $opts{username}, Password => $opts{password}, + UseSSL => $opts{usessl}, ) or $log->err("Unable to connect to IMAP server $opts{imap}: $@", 1); $log->msg('Connected'); @@ -151,89 +146,84 @@ sub Connect2IMAP() { } # Connect2IMAP sub MonitorMail() { - while () { - # First close and reselect the INBOX to get its current status - debugit "Reconnecting to INBOX"; - $IMAP->close; - $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 - my %newUnseen = unseenMsgs; - - # Now clean out any messages in %unseen that were not in the %newUnseen and - # marked as previously read - for (keys %unseen) { - if (defined $newUnseen{$_}) { - if ($unseen{$_}) { - delete $newUnseen{$_}; - } # if - } else { - delete $unseen{$_} + # First close and reselect the INBOX to get its current status + $IMAP->close; + $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 + my %newUnseen = unseenMsgs; + + # Now clean out any messages in %unseen that were not in the %newUnseen and + # marked as previously read + for (keys %unseen) { + if (defined $newUnseen{$_}) { + if ($unseen{$_}) { + delete $newUnseen{$_}; } # if - } # for + } else { + delete $unseen{$_} + } # if + } # for - debugit "Processing newUnseen"; - for (keys %newUnseen) { - next if $unseen{$_}; + for (keys %newUnseen) { + next if $unseen{$_}; - my $envelope = $IMAP->fetch($_, '(envelope)'); - my $from = $envelope->{$_}{envelope}{From}; - my $subject = $envelope->{$_}{envelope}{Subject}; - $subject //= 'Unknown subject'; + my $envelope = $IMAP->fetch($_, '(envelope)'); + my $from = $envelope->{$_}{envelope}{From}; + my $subject = $envelope->{$_}{envelope}{Subject}; + $subject //= 'Unknown subject'; - # Extract the name only when the email is of the format "name " - if ($from =~ /^"?(.*?)"?\s*\<(\S*)>/) { - $from = $1 if $1 ne ''; - } # if + # Extract the name only when the email is of the format "name " + if ($from =~ /^"?(.*?)"?\s*\<(\S*)>/) { + $from = $1 if $1 ne ''; + } # if - if ($subject =~ /=?\S+?(Q|B)\?(.+)\?=/) { - $subject = decode_base64($2); - } # if + if ($subject =~ /=?\S+?(Q|B)\?(.+)\?=/) { + $subject = decode_base64($2); + } # if - # Google Talk doesn't like # - $subject =~ s/\#//g; + # Google Talk doesn't like # + $subject =~ s/\#//g; - # Now speak it! - debugit "Speaking message from $from"; + # Now speak it! + my $logmsg = "From $from $subject"; - my $logmsg = "From $from $subject"; + my $greeting = $greetings[int rand $#greetings]; + my $msg = "$greeting from $from... " . quotemeta $subject; + $msg =~ s/\"/\\"/g; - my $greeting = $greetings[int rand $#greetings]; - my $msg = "$greeting from $from... " . quotemeta $subject; - $msg =~ s/\"/\\"/g; + # Log it + $log->msg($logmsg); - # Log it - $log->msg($logmsg); - - debugit $logmsg; + my $hour = (localtime)[2]; + # Only announce if after 6 Am. Note this will announce up until + # midnight but that's ok. I want midnight to 6 Am as silent time. + if ($hour > 6) { my $cmd = "/usr/local/bin/gt \"$msg\""; + my ($status, @output) = Execute $cmd; - my $hour = (localtime)[2]; - - # Only announce if after 6 Am. Note this will announce up until - # midnight but that's ok. I want midnight to 6 Am as silent time. - if ($hour > 6) { - my ($status, @output) = Execute $cmd; - - if ($status) { - $log->err("Unable to execute $cmd" . join("\n", @output)); - } # if + if ($status) { + $log->err("Unable to execute $cmd" . join("\n", @output)); } # if + } # if - $unseen{$_} = 1; - } # for - } # while + $unseen{$_} = 1; + } # for - return; + # Re-establish callback + $IMAP->idle(\&MonitorMail); + + # Should not get here + $log->err("Unable to re-establish IDLE callback from IMAP server $opts{imap}", 1); } # MonitorMail END { $IMAP->quit if $IMAP; - $log->msg("$FindBin::Script ending!"); + $log->msg("$FindBin::Script ending unexpectedly!"); } # END ## Main @@ -247,6 +237,7 @@ GetOptions( 'username=s', 'password=s', 'imap=s', + 'usessl', 'sleep', ); @@ -257,7 +248,9 @@ unless ($opts{password}) { $opts{debug} = get_debug; -EnterDaemonMode if $opts{daemon}; +if ($opts{daemon}) { + EnterDaemonMode unless defined $DB::OUT; +} # if $log = Logger->new( path => '/var/log', @@ -277,3 +270,5 @@ my ($status, @output) = Execute $cmd; $IMAP->idle(\&MonitorMail); +# Should not get here +$log->err("Falling off the edge of $0", 1);