A very simple IRC client which uses POE::Wheel::ReadLine for user input.
use strict;
use warnings;
use Getopt::Long;
use POE qw(Component::IRC::State Wheel::ReadLine);
use Data::Dumper;
$Data::Dumper::Indent = 1;
my $nick;
my $user;
my $server;
my $port;
my $ircname;
my $password;
my $current_channel;
GetOptions(
"nick=s" => \$nick,
"server=s" => \$server,
"user=s" => \$user,
"port=s" => \$port,
"pass=s" => \$password,
"ircname=s" => \$ircname,
);
die unless $nick and $server;
print "$nick $server\n";
my $irc = POE::Component::IRC::State->spawn(
Nick => $nick,
Server => $server,
Port => $port,
Ircname => $ircname,
Username => $user,
Password => $password
);
print STDOUT $irc->version(), "\n";
POE::Session->create(package_states =>
['main' => [qw(_start _stop got_input parse_input _default irc_public)],],);
$poe_kernel->run();
exit 0;
sub _start {
my $heap = $_[HEAP];
$heap->{readline_wheel} =
POE::Wheel::ReadLine->new(InputEvent => 'got_input');
$heap->{readline_wheel}->get("> ");
$irc->yield(register => 'all');
undef;
}
sub _stop {
delete $_[HEAP]->{readline_wheel};
$irc->yield(unregister => 'all');
$irc->yield('shutdown');
undef;
}
sub got_input {
my ($heap, $kernel, $input, $exception) = @_[HEAP, KERNEL, ARG0, ARG1];
if (defined $input) {
$heap->{readline_wheel}->addhistory($input);
#$heap->{readline_wheel}->put("I heard $input");
$kernel->yield('parse_input' => $input);
}
elsif ($exception eq 'interrupt') {
$heap->{readline_wheel}->put("Goodbye.");
delete $heap->{readline_wheel};
$irc->yield(unregister => 'all');
$irc->yield('shutdown');
return;
}
else {
$heap->{readline_wheel}->put("\tException: $exception");
if ($exception eq 'eot') {
$irc->yield(unregister => 'all');
$irc->yield('shutdown');
delete($heap->{readline_wheel});
}
}
$heap->{readline_wheel}->get("> ") if ($heap->{readline_wheel});
undef;
}
sub parse_input {
my ($kernel, $heap, $input) = @_[KERNEL, HEAP, ARG0];
# Parse input
if ($input =~ /^\//) {
$input =~ s/^\///;
my (@args) = split(/ /, $input);
my ($cmd) = shift @args;
SWITCH: {
if ($cmd eq 'connect') {
if ($irc->connected()) {
$heap->{readline_wheel}->put("Already connected");
last SWITCH;
}
$heap->{readline_wheel}->put("Connecting");
$irc->yield('connect');
last SWITCH;
}
if ($cmd eq 'dump_state') {
unless (@args) {
$heap->{readline_wheel}->put($_)
for split /\n/, Dumper($irc->{STATE});
}
else {
open my $fh, ">", $args[0] or return;
print $fh Dumper($irc->{STATE});
}
last SWITCH;
}
if ($cmd eq 'sl' or $cmd eq 'quote') {
$irc->yield($cmd => join(' ', @args));
}
else {
$irc->yield($cmd => @args);
}
$heap->{readline_wheel}->put($cmd . " " . join(' ', @args));
}
}
undef;
}
sub _default {
my ($event, $args) = @_[ARG0 .. $#_];
my (@output);
my $arg_number = 0;
foreach (@$args) {
SWITCH: {
if (ref($_) eq 'ARRAY') {
push(@output, "[", join(", ", @$_), "]");
last SWITCH;
}
if (ref($_) eq 'HASH') {
push(@output, "{", join(", ", %$_), "}");
last SWITCH;
}
push(@output, "'$_'");
}
$arg_number++;
}
$_[HEAP]->{readline_wheel}->put("$event " . join(' ', @output))
if (defined($_[HEAP]->{readline_wheel}));
return 0; # Don't handle signals.
}
sub irc_public {
my ($kernel, $heap, $who, $where, $what) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2];
my ($nick) = (split /!/, $who)[0];
my ($chan) = $where->[0];
$heap->{readline_wheel}->put($chan . ':<' . $nick . '> ' . $what);
undef;
}