X-Git-Url: http://git.tpope.net/?p=tpope-extra.git;a=blobdiff_plain;f=perl%2Faway-tpope;h=a82fb848cea1334e2cd173ece5bd96f90ac1365f;hp=dd26efb682f04a53f4d01f43029d174ec93cd643;hb=3c37f39987545e322eb7ea3dd630904d13519672;hpb=f797889ab9eeec92b620e50455ad4392f9ee6d96 diff --git a/perl/away-tpope b/perl/away-tpope index dd26efb..a82fb84 100755 --- a/perl/away-tpope +++ b/perl/away-tpope @@ -3,8 +3,8 @@ # -*- perl -*- vim:set ft=perl sw=4 sts=4: use strict; -use vars qw(%state @ssh $last $pipe $arg); -@ssh=("ssh","-a","-x","-oBatchmode=yes","-oSetupTimeOut=20"); +use vars qw(%state @ssh $last $pipe $arg $slow); +@ssh=("ssh","-a","-x","-oBatchmode=yes","-oSetupTimeOut=20","-qq"); $pipe = "/tmp/.away-tpope"; $arg=shift || ""; @@ -12,7 +12,7 @@ daemonize() if ($arg eq "-d"); daemon() if ($arg eq "-D"); -if($arg eq "activity" || $arg eq "away") { +if($arg eq "activity" || $arg eq "away" || $arg eq "out" || $arg eq "check") { if(exists($ARGV[0])) { die "Daemon not running\n" unless (-p $pipe); my $a = join(" ",@ARGV); @@ -20,7 +20,6 @@ if($arg eq "activity" || $arg eq "away") { open FIFO, ">$pipe"; print FIFO "$arg $a"; } else { - $arg =~ s/^away$/customaway/; load(); print $state{$arg}."\n" if($state{$arg}); } @@ -29,6 +28,7 @@ if($arg eq "activity" || $arg eq "away") { } sub daemon { + die "Daemon already running?\n" if (-e "/tmp/.away-tpope.pid"); open TMP, ">/tmp/.away-tpope.pid"; print TMP "$$\n"; close TMP; @@ -36,15 +36,17 @@ sub daemon { $SIG{'INT'} = \&quit_handler; $SIG{'TERM'} = \&quit_handler; $SIG{'QUIT'} = \&quit_handler; - $SIG{'HUP'} = \&cycle; + $SIG{'HUP'} = \&hup_handler; $SIG{'USR2'} = \&restart_handler; die "Daemon already running\n" if (-r "/tmp/.tpope-away.pid"); unless (-p $pipe) { unlink $pipe; system("mkfifo", $pipe); + chmod 0600, $pipe; } + $last=0; + $slow=1; cycle(); - $last=time; while(1) { main_loop(); } @@ -83,24 +85,38 @@ sub main_loop { custom_activity($read); } elsif($c eq "away") { custom_away($read); + } elsif($c eq "out") { + custom_out($read); + } elsif($c eq "check") { + host_check($read); } else { print "Unknown command: $c\n"; } } - if(time-$last >=300) { - local $SIG{'HUP'} = "IGNORE"; + if(time-$last >= 240) { cycle(); - $last=time; } } sub cycle { - do_phone(); - do_hosts(); + local $SIG{'HUP'} = sub {$last = 1}; + do_chat(); + if((!$last) || $slow++ ) { + do_hosts(); + do_power(); + do_phone(); + $slow=0; + } + eval_chat(); do_schedule(); - process_away(); + do_decision(); save(); do_custom(); + if($last==1) { + $last=0; + } else { + $last=int(time/60)*60; + } } sub ping { @@ -122,13 +138,17 @@ sub do_schedule { my ($begin, $end, $maxend); next unless /(\d\d):(\d\d)-(\d\d):(\d\d) (.*)/; my ($hs,$ms,$he,$me,$ev) = ($1, $2, $3, $4, $5); - $begin = $hs*60+$ms-25; - $maxend = $he*60+$me+5; - $end = ($begin+25)*3/4+($maxend-5)/4; + $ev =~ s/ *\[.*$//; + $begin = $hs*60+$ms-10; + $maxend = $he*60+$me+10; + $end = ($begin+10)*3/4+($maxend-10)/4; if($begin <= $now && $now < $end) { $state{'class'} = $ev; + internal_out("School"); $familiar = 1; last; + } elsif($begin-35<=$now && $now<$end && $state{'phone'} eq "absent") { + internal_out("School"); } elsif (($state{'class'}||'') eq $ev) { $familiar = 1; undef $state{'class'} @@ -138,13 +158,13 @@ sub do_schedule { close(SCHEDULE); undef $state{'class'} unless ($familiar); - open(SCHEDULE, "today --category='!school !private'|"); $familiar = 0; while() { my ($begin, $end, $maxend); next unless /(\d\d):(\d\d)-(\d\d):(\d\d) (.*)/; my ($hs,$ms,$he,$me,$ev) = ($1, $2, $3, $4, $5); + $ev =~ s/ *\[.*$//; $begin = $hs*60+$ms; $maxend = $he*60+$me; $end = ($begin)*3/4+($maxend)/4; @@ -152,7 +172,7 @@ sub do_schedule { $state{'schedule'} = $ev; $familiar = 1; last; - } elsif ($state{'schedule'} eq $ev) { + } elsif (($state{'schedule'}||'') eq $ev) { $familiar = 1; undef $state{'schedule'} if ($now > $maxend || $state{'phone'} eq "present"); @@ -162,51 +182,144 @@ sub do_schedule { undef $state{'schedule'} unless ($familiar); } +sub do_chat { + if(-r ($ENV{'HOME'} . "/.chat")) { + open TMP, $ENV{'HOME'} . "/.chat"; + my $chat = join ("", ); + close TMP; + chomp $chat; + $state{'chat'} = $chat; + } else { + undef $state{'chat'}; + } +} + +sub eval_chat { + if(($state{'chat'}||'') =~ /^(tpope-\d+|jmwaller|arwen|george)$/) { + internal_out("Work",3*60*60); + } elsif(($state{'chat'}||'') eq "accd") { + #internal_out("School",30*60); + } +} + sub do_hosts { - my @livehosts; - foreach my $host ("sarah", "homer", "lisa", "mona") { - push @livehosts, $host if(ping($host)); + my (@check) = ("tobias", "lucille", "lindsay", "buster"); + my (@uphosts, @livehosts, $host, $hostlist); + if(($_[0] || 0) == 1) { + $hostlist=$state{'hosts'}; + $hostlist=~s/0\S* ?//g; + @livehosts = split / /, $hostlist; + } else { + $hostlist=""; + foreach $host (@check) { + push @uphosts, $host if(ping($host)); + } + foreach $host (@uphosts) { + if(is_alive($host)) { + push @livehosts,$host; + $hostlist="$host $hostlist"; + } else { + $hostlist="0$host $hostlist"; + } + } + $hostlist=~s/ $//; + $state{'hosts'}=$hostlist; } - my $alive = ""; - foreach my $host (@livehosts) { - $alive=$host unless(system(@ssh,$host, 'if pidof xscreensaver >/dev/null && DISPLAY=:0.0 xscreensaver-command -version >/dev/null 2>&1; then if DISPLAY=:0.0 xscreensaver-command -time 2>&1 |egrep "non-blanked|no saver status" >/dev/null; then true; else pid=`ps ax|egrep "[0-9]:[0-9][0-9] ssh marge .*(screen.*RR irc|Chat)"|sed -e "s/^ *//"|cut -d" " -f 1`; [ -f "$HOME/.irc.lock" -o -z "$pid" ] || kill $pid; false; fi; else false; fi') >> 8); + if(scalar @livehosts == 0) { + $state{'alive'} = ''; + } elsif(scalar @livehosts > 1 && $state{'chat'}) { + foreach $host (@livehosts) { + if ($host eq $state{'chat'}) { + $state{'alive'} = $host; + return; + } + } + } + $state{'alive'}=$livehosts[0]; +} + +sub is_alive { + my $ret; + eval { + local $SIG{ALRM} = sub { die "alarm\n" }; + alarm(30); + $ret=!(system(@ssh,shift, 'if pidof xscreensaver >/dev/null && DISPLAY=:0.0 xscreensaver-command -version >/dev/null 2>&1; then if DISPLAY=:0.0 xscreensaver-command -time 2>&1 |egrep "non-blanked|no saver status" >/dev/null; then true; else pid=`ps ax|egrep "[0-9]:[0-9][0-9] ssh gob .*(screen.*RR irc|Chat)"|sed -e "s/^ *//"|cut -d" " -f 1`; [ -f "$HOME/.irc.lock" -o -z "$pid" ] || kill $pid; false; fi; else false; fi') >> 8); + alarm(0); + }; + if($@) { + undef $ret; + die unless $@ eq "alarm\n"; } - $state{'alive'} = $alive; + return $ret; } sub do_phone { my $phone; - if(!ping('mona')) { + if(!ping('tobias')) { $phone="unknown"; } else { - my $last_slh=`@ssh mona cat .blue/last_slh 2>/dev/null`; + my $last_slh=`@ssh tobias cat .blue/last_slh 2>/dev/null`; if(!$last_slh) { $phone="unknown"; - } elsif (time-$last_slh < 600) { + } elsif (time-$last_slh < 540) { $phone="present"; } else { $phone="absent"; } } - if($state{'phone'} eq 'absent' && $phone eq 'present') { - custom_away(""); + if(($state{'phone'}||"") ne 'present' && $phone eq 'present') { + custom_out(""); + internal_out(""); } + $state{'phone'} = $phone; } -sub process_away { - if ($state{'customaway'}) { +sub do_power { + open TMP, "upsc milhouse\@localhost 2>/dev/null|"; + my $ups=''; + while() { + chomp; + if(/status: (.*)/i) { + $ups=$1; + } + } + close TMP; + $state{'ups'}=$ups; +} + +sub do_decision { + custom_away("") + if ($state{'customawayexp'} && $state{'customawayexp'}' . $ENV{'HOME'} . "/.away-tpope" || die $!; @@ -250,7 +419,8 @@ sub save { my $val=$state{$k}; next unless($val); $val =~ s/\n/\\n/g; - print CONF "$k=$val\n"; + $val =~ s/"/\\"/g; + print CONF "$k=\"$val\"\n"; } close CONF; if(defined($state{'activity'})) { @@ -274,15 +444,25 @@ sub save { sub load { open CONF, '<' . $ENV{'HOME'} . "/.away-tpope" or return; + undef $state{'customactivity'}; + undef $state{'customaway'}; + undef $state{'customout'}; + undef $state{'internalout'}; while(my $line=) { $line =~ s/\\n/\n/g; - $line =~ s/^([^=]*)=//; + $line =~ s/\\"/"/g; + $line =~ s/"$//; + $line =~ s/^([^=]*)="?//; chomp $line; $state{$1}=$line; } close CONF; } +sub hup_handler { + $last=1; +} + sub restart_handler { alarm 0; unlink $pipe;