#!/usr/bin/perl -w use warnings 'all'; use strict; use LWP::Simple; use XML::Simple; # Monk_Chat_3a.pl # 2002-04-02 Bruce "Util" Gray # Use this as a read-only Chatterbox client and archiver, # and use the PerlMonks Chatterbox nodelet for talking. my $url = 'http://perlmonks.org/index.pl?node=chatterbox+xml+ticker'; my $log = 'PerlMonks_Chat.log'; # Why is there a \r at the end of the XML? # Why is there a \n at the beginning of "\nRendered by the Chatterbox XML Ticker"? #Why does XML::Simple use Cwd.pm, which triggers warnings? # Check that a hash has exactly the keys expected. sub exact { my @hpa = sort keys %{ +shift }; return ("@_" eq "@hpa"); } sub get_valid_messages { my $p_url = shift; my $xml = get($p_url) or warn "Get failed " and return; die unless $xml =~ m{\n\n\r\n$}; die unless $xml =~ m{^<\?xml version="1\.0" encoding="ISO-8859-1"\?>\n\n\n}; # This insures that $hp->{message} is an array of hashes, even if their is only one hash in the array. my $hp = XMLin($xml, forcearray => [ 'message' ]); exact( $_, qw( INFO ) ) and return foreach $hp; # no messages exact( $_, qw( INFO message ) ) or die foreach $hp; exact( $_, qw( content site sitename ) ) or die foreach $hp->{INFO}; exact( $_, qw( author content time user_id ) ) or die foreach @{ $hp->{message} }; my @r; foreach ( @{ $hp->{message} } ) { my %t = %$_; my ($time, $user_id, $author, $content) = @t{ qw( time user_id author content ) }; tr{\t}{} and warn foreach ($time, $user_id, $author, $content); $content =~ s{^\n}{} or die; push @r, [ $time, $user_id, $author, $content ]; } return @r; } my %h; open LOG, ">>$log" or die; select(LOG); $| = 1; select(STDOUT); $| = 1; while(1) { my @msgs = sort { $a->[0] <=> $b->[0] } get_valid_messages($url); foreach (@msgs) { my ($time, $user_id, $author, $content) = @$_; my $key = join("\t", $time, $user_id, $author); if ( $h{$key} ) { die "Ack! '$h{$key}' ne '$content' " if $h{$key} ne $content; } else { $h{$key} = $content; printf LOG "%s\t%6d\t%-15s\t%s\n", $time, $user_id, $author, $content; printf "%-15s\t%s\n", $author, $content; } } sleep 10; } close LOG or die; #??? Never reached. __END__ Notes: need to read last 100 lines of log into hash need to keep only last 100 lines of log in memory? $hp is a pointer to a hash $hp->{message} $hp->{INFO} INFO is a hash message is array of hashes Data format: Rendered by the Chatterbox XML Ticker<;/INFO> its suprising the number of people who shoot themselves in the foot by not realizing about email receipts... considering they are non-standard, I'd say, "No, ir isn't" $hp = { "message" => [ { "user_id" => 143232, "content" => "\nthanks for the info guys. i have never studied system times and whatnot - i'm just trying to get my head around a few results using bechmark.pm", "author" => "wilstephens", "time" => "20020402101542" }, { "user_id" => 18800, "content" => "\nthe [isbn://156592567x|Eagle] book SC", "author" => "jeffa", "time" => "20020402101640" }, ], "INFO" => { "site" =>; "http://perlmonks.org", "content" => "\nRendered by the Chatterbox XML Ticker", "sitename" => "Perl Monks" } };