App-BCVI-NotifyClient

 view release on metacpan or  search on metacpan

lib/App/BCVI/NotifyClient.pm  view on Meta::CPAN

package App::BCVI::NotifyClient;

use warnings;
use strict;

our $VERSION = '2.00';

use POSIX qw(setsid);

my $default_idle_time     = 20;  # seconds
my $default_poll_interval =  5;  # seconds

sub send_command {
    my($self, @args) = @_;

    my $command = $self->opt('command') || $self->default_command();

    if($command eq 'notify') {
        # Check for TTY monitoring options; handle them and exit
        $self->_notify_handle_tty_monitoring(@args);
        # Otherwise drop through for default handling
    }

    return $self->SUPER::send_command(@args);
}


sub _notify_handle_tty_monitoring {
    my($self, @args) = @_;

    my %opt = $self->_notify_get_options(@args) or return;
    $opt{tty} ||= $self->_notify_current_tty;

    if($opt{idle}) {
        print "Starting background process to monitor $opt{tty} for $opt{idle} second idle period\n";
        print "Kill monitor with: bnotify --kill\n";
        $opt{output} = $default_poll_interval;
        $self->_notify_fork_bg_tty_monitor(sub {
            while(1) {
                $self->_notify_wait_for_idle(\%opt);
                $self->SUPER::send_command("terminal is idle");
                $self->_notify_exit if $opt{once};
                $self->_notify_wait_for_output(\%opt);
            }
        });
    }
    elsif($opt{output}) {
        print "Starting background process to monitor $opt{tty} for output\n";
        print "Kill monitor with: bnotify --kill\n";
        $opt{idle} = $default_idle_time;
        $self->_notify_fork_bg_tty_monitor(sub {
            $self->_notify_wait_for_idle(\%opt);
            while(1) {
                $self->_notify_wait_for_output(\%opt);
                $self->SUPER::send_command("output received");
                $self->_notify_exit if $opt{once};
                $self->_notify_wait_for_idle(\%opt);
            }
        });
    }
    elsif($opt{kill}) {
        $self->App::BCVI::Server::kill_current_listener();
        exit;
    }
}


sub _notify_wait_for_idle {
    my($self, $opt) = @_;

    my $sleep_time = $opt->{idle};
    while(1) {
        sleep($sleep_time);
        my $mtime = $self->_notify_tty_mtime($opt);
        my $idle = time() - $mtime;
        $sleep_time = $opt->{idle} - $idle;
        return if $sleep_time <= 0;
    }
}


sub _notify_wait_for_output {
    my($self, $opt) = @_;

    my $mtime = $self->_notify_tty_mtime($opt);
    while(1) {
        sleep($opt->{output});
        return if $self->_notify_tty_mtime($opt) != $mtime;
    }
}


sub _notify_tty_mtime {
    my($self, $opt) = @_;

    my @stat = stat($opt->{tty}) or die "stat($opt->{tty}): $!";
    return $stat[9];
}


sub _notify_current_tty {
    my $tty = readlink("/proc/self/fd/0");
    if(!$tty) {
        chomp( $tty = `tty` );
    }
    die "Unable to determine TTY\n" unless $tty;
    return $tty;
}


sub _notify_get_options {
    my($self, @args) = @_;

    local(@ARGV) = @args;
    my %opt = ();



( run in 0.687 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )