http://www.perlmonks.org?node_id=138310
Category: IRC
Author/Contact Info Briac Pilpré
Description:

This XChat command grab, parse and print RSS newsfeed from sites defined in a configuration file

Since the configuration file is read each time the command is called, you can add/remove sites without having to reload the script

Usage in XChat:

/rss channel count

'channel' is the name of the RSS channel you want to see, and 'count' is the number of item to display (default 10)

#!/usr/bin/perl -w
use strict;
use LWP::Simple;
use XML::Parser;
use vars qw(%RSS $newsmax %inside $config);

$config = "/home/briac/.xchat/getRSS.conf";

IRC::print("** Loading RSS Alert **\n");
IRC::add_command_handler( "RSS", "rss_command_handler" );

sub rss_command_handler {
    my ( $feed, $count ) = split ( /\s+/, shift () );

    $newsmax = $count || 10;

    do $config;

    # Error checking
    if ( !%RSS ) {
        IRC::print("** Error reading config file\n");
        return 1;
    }
    if ( !$feed ) {
        IRC::print("usage: /rss channel [count]\n");
        IRC::print( "Available channels: " . join (', ', keys %RSS) . 
+"\n" );
        return 1;
    }
    if ( !$RSS{lc($feed)} ) {
        IRC::print("Channel '$feed' unknown.\n");
        IRC::print( "Available channels: " . join (', ', keys %RSS) . 
+"\n" );
        return 1;
    }

    my $xml = get( $RSS{lc($feed)} );
    if ( !$xml ) {
        IRC::print("Can't fetch the RSS\n");
        return 1;
    }

    my $parser = XML::Parser->new( Style => 'Stream' );
    $parser->parse($xml);

    IRC::print("---\n\n");
    return 1;
}

sub StartTag {
    my $elt = $_[1];
    $newsmax-- if $elt eq 'item';
    $inside{$elt}++;
}

sub EndTag {
    my $elt = $_[1];
    IRC::print("\n") if $elt eq 'channel';
    $inside{$elt}--;
}

sub Text {
    return unless /\S/;
    return unless $newsmax >= 0;

    # Channel infos
    IRC::print("> $_")  if ( $inside{channel} && $inside{title} );
    IRC::print(" $_")   if ( $inside{channel} && $inside{description} 
+);
    IRC::print(" ($_)") if ( $inside{channel} && $inside{link} );

    # News Items
    IRC::print("* $_\n")   if ( $inside{item} && $inside{title} );
    IRC::print("    $_\n") if ( $inside{item} && $inside{link} );

}
__END__
# Sample getRSS.conf file
%RSS = (
    slashdot  => 'http://www.slashdot.org/slashdot.rdf',
    useperl   => 'http://use.perl.org/useperl.rdf',
    perlmonks => 'http://www.perlmonks.org/headlines.rdf',
    cpan      => 'http://search.cpan.org/recent.rdf',
    theregister => 'http://www.theregister.co.uk/tonys/slashdot.rdf',
    memepool => 'http://memepool.com/memepool.rss',
);