Rob Norris
Cricket bot
Scenario:
- You like the cricket.
- There’s live commentary available on the web, but its not in some kind of nice incremental stream, so using it is a bit fiddly.
- You’re in IRC all day long at your desk and on your phone.
Half an hour and some Perl later, this :)
#!/usr/bin/env perl
use 5.016;
use warnings;
use strict;
use AnyEvent;
use AnyEvent::IRC::Client;
use AnyEvent::HTTP;
use HTML::TreeBuilder 5 -weak;
use Digest::SHA1 qw(sha1_hex);
if (@ARGV < 5) {
say "usage: cricinfobot <host> <port> <nick> <channel> <matchid>";
exit 1;
}
my ($HOST, $PORT, $NICK, $CHANNEL, $MATCHID) = @ARGV;
my $URL = "http://www.espncricinfo.com/netstorage/$MATCHID.html";
my $c = AnyEvent->condvar;
my $timer;
my $con = new AnyEvent::IRC::Client;
$con->reg_cb(
registered => sub {
$con->send_srv(JOIN => $CHANNEL);
},
disconnect => sub {
$c->broadcast;
},
);
$con->connect ($HOST, $PORT, { nick => $NICK });
my %seen;
my $check = AnyEvent->timer(interval => 15, cb => sub {
http_get($URL, sub {
my ($body, $hdr) = @_;
if ($hdr->{Status} !~ m/^2/) {
say STDERR "fetch failed: $hdr->{Status}";
return;
}
my $tree = HTML::TreeBuilder->new_from_content($body);
my %new_seen;
for my $elem (reverse $tree->look_down(class => "commsText")) {
my $text = $elem->as_text;
my $checksum = sha1_hex($text);
$new_seen{$checksum} = 1;
$con->send_srv(PRIVMSG => $CHANNEL, $text) if not $seen{$checksum};
}
%seen = %new_seen;
});
});
$c->wait;
$con->disconnect;