File Coverage

blib/lib/POE/Filter/IRC/P10.pm
Criterion Covered Total %
statement 26 47 55.3
branch 12 38 31.5
condition 0 6 0.0
subroutine 6 8 75.0
pod 4 4 100.0
total 48 103 46.6


line stmt bran cond sub pod time code
1             # $Id: Filter-IRC.pm,v 1.3 1999/12/12 11:48:07 dennis Exp $
2             #
3             # POE::Filter::IRC, by Dennis Taylor
4             # Modified for P10 Protocol by Chris Williams
5             #
6             # This module may be used, modified, and distributed under the same
7             # terms as Perl itself. Please see the license that came with your Perl
8             # distribution for details.
9             #
10              
11             package POE::Filter::IRC::P10;
12              
13 1     1   47 use strict;
  1         3  
  1         34  
14 1     1   5 use Carp;
  1         1  
  1         51  
15 1     1   5 use vars qw($VERSION);
  1         2  
  1         882  
16              
17             $VERSION = '0.998';
18              
19             # Create a new, empty POE::Filter::IRC object.
20             sub new {
21 2     2 1 4 my $class = shift;
22 2         5 my %args = @_;
23              
24 2         9 bless {}, $class;
25             }
26              
27              
28             # Set/clear the 'debug' flag.
29             sub debug {
30 0     0 1 0 my $self = shift;
31 0 0       0 $self->{'debug'} = $_[0] if @_;
32 0         0 return $self->{'debug'};
33             }
34              
35              
36             # For each line of raw IRC input data that we're fed, spit back the
37             # appropriate IRC events.
38             sub get {
39 2     2 1 4 my ($self, $raw) = @_;
40 2         4 my $events = [];
41 2         84 my %token2cmd = ('AC' => 'ACCOUNT', 'AD' => 'ADMIN', 'LL' => 'ASLL', 'A' => 'AWAY', 'B' => 'BURST', 'CM' => 'CLEARMODE', 'CLOSE' => 'CLOSE', 'CN' => 'CNOTICE', 'CO' => 'CONNECT', 'CP' => 'CPRIVMSG', 'C' => 'CREATE', 'DE' => 'DESTRUCT', 'DS' => 'DESYNCH', 'DIE' => 'DIE', 'DNS' => 'DNS', 'EB' => 'END_OF_BURST', 'EA' => 'EOB_ACK', 'Y' => 'ERROR', 'GET' => 'GET', 'GL' => 'GLINE', 'HASH' => 'HASH', 'HELP' => 'HELP', 'F' => 'INFO', 'I' => 'INVITE', 'ISON' => 'ISON', 'J' => 'JOIN', 'JU' => 'JUPE', 'K' => 'KICK', 'D' => 'KILL', 'LI' => 'LINKS', 'LIST' => 'LIST', 'LU' => 'LUSERS', 'MAP' => 'MAP', 'M' => 'MODE', 'MO' => 'MOTD', 'E' => 'NAMES', 'N' => 'NICK', 'O' => 'NOTICE', 'OPER' => 'OPER', 'OM' => 'OPMODE', 'L' => 'PART', 'PA' => 'PASS', 'G' => 'PING', 'Z' => 'PONG', 'POST' => 'POST', 'P' => 'PRIVMSG', 'PRIVS' => 'PRIVS', 'PROTO' => 'PROTO', 'Q' => 'QUIT', 'REHASH' => 'REHASH', 'RESET' => 'RESET', 'RESTART' => 'RESTART', 'RI' => 'RPING', 'RO' => 'RPONG', 'S' => 'SERVER', 'SET' => 'SET', 'SE' => 'SETTIME', 'U' => 'SILENCE', 'SQ' => 'SQUIT', 'R' => 'STATS', 'TI' => 'TIME', 'T' => 'TOPIC', 'TR' => 'TRACE', 'UP' => 'UPING', 'USER' => 'USER', 'USERHOST' => 'USERHOST', 'USERIP' => 'USERIP', 'V' => 'VERSION', 'WC' => 'WALLCHOPS', 'WA' => 'WALLOPS', 'WU' => 'WALLUSERS', 'WV' => 'WALLVOICES', 'H' => 'WHO', 'W' => 'WHOIS', 'X' => 'WHOWAS');
42              
43 2         6 foreach my $line (@$raw) {
44 2 50       10 warn "<<< $line\n" if $self->{'debug'};
45 2 50       14 next unless $line =~ /\S/;
46              
47 2 50       40 if ($line =~ /^(\S+) G (.+)$/) {
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
48 0         0 push @$events, { name => 'ping', args => [$1] };
49              
50             # PRIVMSG and NOTICE
51             } elsif ($line =~ /^(\S+) +(P|O) +(\S+) +(.+)$/) {
52 0 0 0     0 if ($2 eq 'O') {
    0 0        
53 0         0 push @$events, { name => 'notice',
54             args => [$1, [split /,/, $3], _decolon( $4 )] };
55              
56             # Using tr/// to count characters here tickles a bug in 5.004. Suck.
57             } elsif (index( $3, '#' ) >= 0 or index( $3, '&' ) >= 0
58             or index( $3, '+' ) >= 0) {
59 0         0 push @$events, { name => 'public',
60             args => [$1, [split /,/, $3], _decolon( $4 )] };
61              
62             } else {
63             # Need a fix here for nick\@server format i think
64 0         0 push @$events, { name => 'msg',
65             args => [$1, [split /,/, $3], _decolon( $4 )] };
66             }
67              
68             # Numeric events
69             } elsif ($line =~ /^(\S+) +(\d+) +(\S+) +(.+)$/) {
70 0         0 push @$events, { name => $2, args => [$1, _decolon( $4 )] };
71              
72             # MODE... just split the args and pass them wholesale.
73             } elsif ($line =~ /^(\S+) +(M|OM) +(\S+) +(.+)$/) {
74 0         0 push @$events, { name => lc $token2cmd{$2}, args => [$1, $3, split(/\s+/, $4)] };
75              
76             } elsif ($line =~ /^(\S+) +K +(\S+) +(\S+) +(.+)$/) {
77 0         0 push @$events, { name => 'kick', args => [$1, $2, $3, _decolon( $4 )] };
78              
79             } elsif ($line =~ /^(\S+) +T +(\S+) +(.+)$/) {
80 0         0 push @$events, { name => 'topic', args => [$1, $2, _decolon( $3 )] };
81              
82             } elsif ($line =~ /^(\S+) +I +(\S+) +(.+)$/) {
83 0         0 push @$events, { name => 'invite', args => [$1, $2, _decolon( $3 )] };
84              
85             } elsif ($line =~ /^SERVER +(.+)$/) {
86 0         0 push @$events, { name => 'server_link', args => [ split(/ /,$1,8), _decolon( substr($1,index($1," :")) ) ] };
87              
88             # NICK, QUIT, JOIN, PART, possibly more?
89             } elsif ($line =~ /^(\S+) +(\S+) +(.+)$/) {
90 2 50       7 unless (grep {$_ eq lc $2} qw(n j q l z r eb b s sq w ac cm gl c ds d)) {
  34         69  
91 0         0 warn "*** ACCIDENTAL MATCH: $2\n";
92 0         0 warn "*** Accident line: $line\n";
93             }
94 2         10 push @$events, { name => lc $token2cmd{$2}, args => [$1, _decolon( $3 )] };
95              
96             # We'll call this 'snotice' (server notice), for lack of a better name.
97             } elsif ($line =~ /^NOTICE +\S+ +(.+)$/) {
98 0         0 push @$events, { name => 'snotice', args => [_decolon( $1 )] };
99              
100             # Eeek.
101             } elsif ($line =~ /^ERROR +(.+)$/) {
102              
103             # If nothing matches, barf and keep reading. Seems reasonable.
104             # I'll reuse the famous "Funky parse case!" error from Net::IRC,
105             # just for a sense of historical continuity.
106             } elsif ($line =~ /^(\S+) +(EB|EA)/) {
107 0         0 push @$events, { name => lc $token2cmd{$2}, args => [_decolon( $1 )] };
108             } elsif ($line =~ /^PASS +(\S+)$/) {
109 0         0 push @$events, { name => 'pass', args => [_decolon( $1 )] };
110             } else {
111 0         0 warn "*** Funky parse case!\nFunky line: \"$line\"\n";
112             }
113             }
114              
115 2         20 return $events;
116             }
117              
118              
119             # Strips superfluous colons from the beginning of text chunks. I can't
120             # believe that this ludicrous protocol can handle ":foo" and ":foo bar"
121             # in a totally different manner.
122             sub _decolon ($) {
123 2     2   5 my $line = shift;
124              
125             # This is very, very, wrong.
126             # if ($line =~ /^:.*\s.*$/) {
127             # $line = substr $line, 1;
128             # }
129              
130 2         5 $line =~ s/^://;
131 2         19 return $line;
132             }
133              
134              
135             # This sub is so useless to implement that I won't even bother.
136             sub put {
137 0     0 1   croak "Call to unimplemented subroutine POE::Filter::IRC->put()";
138             }
139              
140              
141             1;
142              
143              
144             __END__