::::::::::::::::::: blognomic-parser.pl ::::::::::::::::::: #!/usr/bin/perl use HTML::TreeBuilder; use LWP::UserAgent; use HTTP::Request; (print "You must specify the URL-name of a proposal.\n"), exit unless scalar @ARGV == 1; my $proposal = $ARGV[0]; (print "Only [0-9a-zA-Z_-] are accepted in proposal names.\n"), exit unless $proposal =~ /^[0-9a-zA-Z_-]+$/; my $emperor = 'Darth Cliche'; my $agent = LWP::UserAgent->new(); $agent->agent("BlogNomic Bot"); $agent->timeout(20); my $request = HTTP::Request->new(GET => "http://blognomic.com/archive/$proposal/"); my $reply = $agent->request($request); if(!$reply->is_success) { print "Failed to read BlogNomic:", $reply->status_line,"\n"; exit; } my $html = $reply->content; my $tree = HTML::TreeBuilder->new_from_content($html); $tree->elementify(); eval { my %uncounted; my %votes; my $vetoed = 0; my $selfkilled = 0; my $author = $tree->look_down("_tag" => "p", "class" => "post-footer") ->look_down("_tag" => "a")->as_text(); $votes{$author} = 'for'; for my $comment ($tree->look_down("_tag" => "div", "class" => "comment")) { my $commenter = $comment->look_down("_tag" => "h3") ->look_down("_tag" => "a")->as_text(); my $body = $comment->look_down("_tag" => "div", "class" => "commentbody"); my @votes = $body->look_down("_tag" => "img", "src" => qr-^http://blognomic\.com/images/vote/-); my $vote = undef; for my $maybe_vote (@votes) { my $alt = lc $maybe_vote->attr('alt'); next unless $alt; $alt eq 'for' and $vote = 'for'; $alt eq 'against' and $vote = 'against'; $alt eq 'imperial' and $vote = 'deferential'; $alt eq 'veto' and $commenter eq $emperor and $vetoed = 1; } next unless $vote; $vote eq 'against' and $commenter eq $author and $selfkilled = 1; if ($votes{$commenter}) { if ($uncounted{$commenter}) { $uncounted{$commenter} .= ", " . $votes{$commenter}; } else { $uncounted{$commenter} = $votes{$commenter}; } } $votes{$commenter} = $vote; } my @for; my @against; my @deferential; for my $player (keys %votes) { $votes{$player} eq 'for' and push @for, $player; $votes{$player} eq 'against' and push @against, $player; $votes{$player} eq 'deferential' and push @deferential, $player; } print "VETOED! " if $vetoed; print "SELF-KILLED! " if $selfkilled; $" = ", "; my $fortotal = 0; my $againsttotal = 0; my $udeftotal = 0; if (!@deferential) { $fortotal = @for; $againsttotal = @against; @for = ("(nobody)") unless @for; @against = ("(nobody)") unless @against; print "FOR: @for; AGAINST: @against"; } elsif ($votes{$emperor} eq 'for') { print "FOR: @for + (deferential) @deferential; AGAINST: @against"; $fortotal = @for + @deferential; $againsttotal = @against; } elsif ($votes{$emperor} eq 'against') { print "FOR: @for; AGAINST: @against + (deferential) @deferential"; $fortotal = @for; $againsttotal = @against + @deferential; } else { $fortotal = @for; $againsttotal = @against; $udeftotal = @deferential; @for = ("(nobody)") unless @for; @against = ("(nobody)") unless @against; print "FOR: @for; AGAINST: @against; (unresolved) DEFERENTIAL: @deferential"; } print " [$fortotal-$againsttotal"; print "-$udeftotal" if $udeftotal; print "]"; if (%uncounted) { print ". Uncounted votes: "; my $sep = ''; for my $voter (keys %uncounted) { print "$sep$voter (" . $uncounted{$voter}.")"; $sep = ", "; } } print ".\n"; $tree->delete(); exit; }; #print $tree->dump(); #if ($tree && $tree->look_down("_tag" => "b") && # $tree->look_down("_tag" => "b")->as_text eq 'Fatal error') { # print "BlogNomic crashed trying to read the proposal page, try again later.\n"; #} else { print "Unable to parse BlogNomic; is that a proposal?\n"; #} $tree->delete() if $tree; ::::::::::::::: blognomicbot.pl ::::::::::::::: #! /usr/bin/perl -pT $|=1; $x=0; $channel="#nomic"; $p=""; $ENV{LC_ALL}='C'; $ENV{'PATH'} = '/bin:/usr/bin'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; m/^PING (.*\r?\n?)$/ and $_ = $p = "PONG $1\r\nNAMES #nomic\r\nTOPIC #nomic\r\n" and $x=1; m/^:[^ ]* 376/ and $_="${p}JOIN $channel\r\n" and $send = 4997 and $x=1; m/^:[^ ]* 353/ and $l.=$_; m/^:[^ ]* 332/ and $m=$_; m/^:[^ ]* PRIVMSG #nomic :!votes ([a-zA-Z0-9_-]+)\r?\n?$/ and $_="PRIVMSG #nomic :".`perl /home/ais523/blognomic/blognomic-parser.pl $1`."\r\n" and $x=1; if(/^:[^ ]* 366/) { open $fh, '>', 'nomicnames.irc'; print $fh "$l$m"; $ol=$l; $l=""; close $fh; } if(/^:[^ ]* 333/) { open $fh, '>', 'nomicnames.irc'; print $fh "$ol$m"; close $fh; } !defined($global) || !$global and (($global=1),($_="NICK blognomicbot\r\nPASS !!!!!!!!!!\r\nUSER blognomicbot localhost moo.slashnet.org :BlogNomic Bot\r\n"),($x=1)); $x or $_=''; print STDERR $_; ::::::::::::::: blognomicbot.sh ::::::::::::::: tee /dev/stderr < bbotfifo | netcat moo.slashnet.org 6667 | tee /dev/stderr | perl -T blognomicbot.pl > bbotfifo