O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


 
Buy the book!
IRC Hacks
By Paul Mutton
July 2004
More Info

HACK
#16
Filter Channel Lists
Even if you've already found a satisfactory IRC network, you may have missed some interesting channels. Discover them in the output from the LIST command
The Code
[Discuss (0) | Link to this hack]

The Code

You can use the skeleton code from the RSS to IRC hack , again using the Net::IRC Perl module . For improved performance, you should precompile the regular expressions that get passed from the command line, as you will be matching them over and over many times. Eventually, you can use printf to pretty-print the matching channels with the columns nicely aligned.

Save the following as filterlist.pl:

#!/usr/bin/perl -w
# filterlist.pl - Filter a list of channels based on given criteria.
# MIT licence, (c) Petr Baudis <pasky@ucw.cz>.

use strict;

### Configuration section.
use vars qw ($nick $server $port);
$nick = 'filtelst';
$server = 'irc.freenode.net';
$port = 6667;

### Preamble.
use Net::IRC;

### Arguments munching and data structures setup.
# Arguments.
use vars qw ($chanre $topicre $userlimit);
($chanre, $topicre, $userlimit) = @ARGV;
$chanre ||= ''; $topicre ||= ''; $userlimit ||= 0;

# Precompile the patterns.
$chanre = qr/$chanre/i;
$topicre = qr/$topicre/i;

# List of matched channels, and maximal length of each field for pretty-printing.
use vars qw (@channels $chanlen $userlen);

# This will eventually print out the channels list when it gets called.
sub list_channels {
  my (@channels) = @_;
  foreach my $chan (@channels) {
    my ($channel, $topic, $usercount) = @$chan;
    printf ("\%-${chanlen}s \%${userlen}d \%s\n", $channel, $usercount, $topic);
  }
}

### Connection initialization.
use vars qw ($irc $conn);
$irc = new Net::IRC;
$conn = $irc->newconn (Nick => $nick, Server => $server, Port => $port,
                       Ircname => 'Channels List Filter');

### The event handlers.
# Connect handler - we immediately try to get the channels list.
sub on_connect {
  my ($self, $event) = @_;
  $self->list ( );
}
$conn->add_handler ('welcome', \&on_connect);

# Received one channel item.
sub on_list {
  my ($self, $event) = @_;
  my (undef, $channel, $usercount, $topic) = $event->args;

  # Filter.
  return unless ($channel =~ $chanre);
  return unless ($topic =~ $topicre);
  return unless ($userlimit == 0
                 or ($userlimit < 0 ? $usercount <= -$userlimit
                            : $usercount >= $userlimit));

  # Enqueue for listing.
  push (@channels, [ $channel, $topic, $usercount ]);

  # Update the pretty-printing skids.
  $^W = 0; # Undefined $chanlen.
  $chanlen = length ($channel) if (length ($channel) > $chanlen);
  $userlen = length ($usercount) if (length ($usercount) > $userlen);
  $^W = 1;
}
$conn->add_handler ('list', \&on_list);

# Received the whole channels list.
sub on_listend {
  my ($self, $event) = @_;
  list_channels (@channels);
  exit;
}
$conn->add_handler ('listend', \&on_listend);

# Fire up the IRC loop.
$irc->start;


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.