#!/usr/bin/perl -w use strict; use LWP::UserAgent; use HTTP::Request; use HTML::TokeParser; use File::Spec; use DB_File; use MIME::Entity; use MIME::Tools; use Data::Dumper; my $advogato_url = 'http://www.advogato.com/person/'; my @person_list = qw(blackhole thomasd Skud rachel technik pudge freeside XFire Telsa); my $recipients = "blackhole\@etla.org"; my $cache_file = File::Spec->catfile($ENV{HOME}, '.a2m'); my %history; tie %history, 'DB_File', $cache_file; my $ua = new LWP::UserAgent; $ua->agent("$0 / 0.1 blackhole\@etla.org " . $ua->agent); $ua->env_proxy; my @new_entries; foreach my $person (@person_list) { print "Fetching $person\n"; my $person_url = $advogato_url . $person . "/"; my $request = new HTTP::Request(GET => $person_url); $request->header(Accept => 'text/html'); my $res = $ua->request($request); if (! $res->is_success) { print "$person_url failed: " . $res->status_line . "\n"; next; } my $page = $res->content; my $p = new HTML::TokeParser(\$page); my $find_blockquote_start = 0; my $in_blockquote = 0; my $entry = ''; my $entry_number; my %entries; my $max_entry = 0; while (my $token = $p->get_token) { # look for . if ($token->[0] eq 'S' and exists $token->[2]->{name} and $token->[2]->{name} =~ /^\d+$/ and $token->[1] eq 'a' and (!$in_blockquote)) { $find_blockquote_start = 1; $entry_number = $token->[2]->{name}; } if ($token->[0] eq 'S' and $token->[1] eq 'blockquote' and $find_blockquote_start) { $find_blockquote_start = 0; $in_blockquote = 1; $entry = ''; } if ($in_blockquote and !($token->[0] eq 'E' and $token->[1] eq 'blockquote') and $token->[0] eq 'T') { $entry .= $token->[1]; } if ($in_blockquote and $token->[0] eq 'E' and $token->[1] eq 'blockquote') { $max_entry = $entry_number if $entry_number > $max_entry; $entries{$entry_number} = $entry; $in_blockquote = 0; } } if ((!exists $history{$person}) or $max_entry > $history{$person}) { foreach my $key (sort {$a <=> $b } keys %entries) { if ((!exists $history{$person}) or $key > $history{$person}) { push @new_entries, { person => $person, text => $entries{$key}, index => $key }; } } $history{$person} = $max_entry; } } #MIME::Tools->debugging(1); if (!scalar @new_entries) { exit 0; } my $entity = MIME::Entity->build(Type => 'multipart/mixed', From => 'blackhole@etla.org', To => 'blackhole@etla.org', Subject => 'a2m updates'); $entity->attach(Data => "a2m updates for @person_list"); foreach my $entry (@new_entries) { $entity->attach(Data => "Updates for $entry->{person}:$entry->{index}:\n" . $entry->{text}); } open SENDMAIL, "| /usr/sbin/sendmail -oi -oem $recipients" or die "Couldn't open sendmail: $!"; $entity->print(\*SENDMAIL); close SENDMAIL or die "Couldn't close sendmail: $!";