Alpha version of my bare-bones, console, read-only Chatterbox client and logger, made available only due to ongoing Monk pain.
This version will not be officially released; Versions 4.x contains fallback code in case XML::Simple is not installed.
Feedback welcome, by email if possible.
#!/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 <bruce.gray@acm.org>
# 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</CHATTER>\n\r\n$};
die unless $xml =~ m{^<\?xml version="1\.0" encoding="ISO-8859-1"\
+?>\n<CHATTER>\n<INFO site="http://perlmonks\.org" sitename="Perl Monk
+s">\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 $conte
+nt;
} else {
$h{$key} = $content;
printf LOG "%s\t%6d\t%-15s\t%s\n", $time, $user_id, $autho
+r, $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:
<?xml version="1.0" encoding="ISO-8859-1"?>
<CHATTER>
<INFO site="http://perlmonks.org" sitename="Perl Monks">
Rendered by the Chatterbox XML Ticker<;/INFO>
<message user_id="108447" author="demerphq" time="20020402094549">
its suprising the number of people who shoot themselves in the foot by
+ not realizing about email receipts...</message>
<message user_id="45366" author="belg4mit" time="20020402094628">
considering they are non-standard, I'd say, "No, ir isn't"</message>
</CHATTER>
$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|Eagl
+e] book SC",
"author" => "jeffa",
"time" => "20020402101640"
},
],
"INFO" => {
"site" =>; "http://perlmonks.org",
"content" => "\nRendered by the Chatterbox XML T
+icker",
"sitename" => "Perl Monks"
}
};
Odd Ball Challenge
Print not printing
Perl Monks User Search
hardcopy printout of perl code
Getting Involved with Perl 6 - an Update
Re: Problem printing contents of file
Why does PerlMonks rock?
Why does PerlMonks rock?
Why does PerlMonks rock?
|