X-Git-Url: http://git.tpope.net/?p=tpope-extra.git;a=blobdiff_plain;f=perl%2Faway-tpope;h=a82fb848cea1334e2cd173ece5bd96f90ac1365f;hp=e5b7479b163e2b958026c4d3fbe1cf8e5a8bbde4;hb=3c37f39987545e322eb7ea3dd630904d13519672;hpb=2b0aae2fc868670054a23914fd3ff1844bd97d53 diff --git a/perl/away-tpope b/perl/away-tpope index e5b7479..a82fb84 100755 --- a/perl/away-tpope +++ b/perl/away-tpope @@ -3,16 +3,16 @@ # -*- perl -*- vim:set ft=perl sw=4 sts=4: use strict; -use vars qw(%state @ssh $last $pipe); -@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"; -my $arg=shift || ""; +$arg=shift || ""; 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,14 +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(); } @@ -82,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 { + local $SIG{'HUP'} = sub {$last = 1}; + do_chat(); + if((!$last) || $slow++ ) { + do_hosts(); + do_power(); + do_phone(); + $slow=0; + } + eval_chat(); do_schedule(); - do_hosts(); - do_phone(); - process_away(); + do_decision(); save(); do_custom(); + if($last==1) { + $last=0; + } else { + $last=int(time/60)*60; + } } sub ping { @@ -112,90 +129,197 @@ sub ping { } sub do_schedule { - my @now=localtime(time); - my $now=$now[3]*60+$now[2]; + my @now=localtime; + my $now=$now[2]*60+$now[1]; + my $familiar = 0; open(SCHEDULE, "today --category=school|"); 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); - $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 ($state{'class'} eq $ev && $now > $maxend) { - $state{'class'} = ''; + } elsif($begin-35<=$now && $now<$end && $state{'phone'} eq "absent") { + internal_out("School"); + } elsif (($state{'class'}||'') eq $ev) { + $familiar = 1; + undef $state{'class'} + if ($now > $maxend || $state{'phone'} eq "present"); } } 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; if($begin <= $now && $now < $end) { $state{'schedule'} = $ev; + $familiar = 1; last; - } elsif ($state{'schedule'} eq $ev && $now > $maxend) { - $state{'schedule'} = ''; + } elsif (($state{'schedule'}||'') eq $ev) { + $familiar = 1; + undef $state{'schedule'} + if ($now > $maxend || $state{'phone'} eq "present"); } } close(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'} = $alive; + $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"; + } + 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 $!; @@ -239,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'})) { @@ -263,15 +444,34 @@ 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; + unlink "/tmp/.away-tpope.pid"; + save(); + exec($0,$arg) || die $!; + print "Restarting $0 $arg...\n"; +} + sub quit_handler { unlink $pipe; unlink "/tmp/.away-tpope.pid";