File Coverage

blib/lib/Net/IRC2/Connection.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             #
2             # Copyright 2005, Karl Y. Pradene All rights reserved.
3             #
4             #
5              
6             package Net::IRC2::Connection ;
7              
8 1     1   6 use strict; use warnings ;
  1     1   2  
  1         34  
  1         6  
  1         2  
  1         26  
9 1     1   6 use Exporter ;
  1         2  
  1         36  
10 1     1   1147 use IO::Socket::INET () ;
  1         30267  
  1         26  
11 1     1   1806 use Net::IRC2::Parser ;
  0            
  0            
12              
13             our @ISA = qw( Exporter ) ;
14             our @EXPORT_OK = qw( new ) ;
15             our @Export = qw( new ) ;
16              
17             use vars qw( $VERSION $DEBUG ) ;
18             $VERSION = '0.23' ;
19             $DEBUG = 0 ;
20              
21              
22             sub new {
23             my $class = shift ;
24             my $self = bless { @_ } ;
25              
26             $self->split_uri if exists $self->{'uri'} ;
27             my $sock = $self->socket( IO::Socket::INET->new( PeerAddr => $self->server ,
28             PeerPort => $self->port ,
29             Proto => 'tcp' )
30             ) or ( warn "Can't bind : $@\n" and return undef ) ;
31             $sock->send( 'PASS ' . $self->pass . "\n" .
32             'NICK ' . $self->nick . "\n" .
33             'USER ' . $self->user . ' foo.bar.quux ' .
34             $self->server . ' :' . $self->realname . "\n" ) ;
35             $self->parser( new Net::IRC2::Parser ) ;
36             return $self }
37              
38             sub start {
39             my $self = shift ;
40             1 while $self->do_one_loop }
41              
42             sub do_one_loop {
43             my $self = shift;
44             my ( $sock, $parser ) = ( $self->socket, $self->parser );
45             my $line = <$sock>;
46             my $event = $parser->message( $line ) or warn "\nParse error\n$line|\n" and return 1 ;
47             $self->pong( $event->trailing ) if $event->command eq 'PING' ;
48             $event->polish_up;
49             $event->{'_parent'} = $self ;
50             $self->chans( scalar $event->trailing ) if $event->command eq 'JOIN' ;
51             if ( defined $self->{ 'callback' }{ $event->command } ) {
52             &{ $self->{ 'callback' }{ $event->command } } ( $self, $event ) ;
53             } elsif ( defined $self->{ 'callback' }{ 'WaterGate' } ) {
54             &{ $self->{ 'callback' }{ 'WaterGate' } } ( $self, $event ) }
55             no strict 'refs' ;
56             &{'cb'.$event->command}($self, $event) if defined &{'cb'.$event->command} ;
57             return $event }
58              
59             sub split_uri {
60             # http://www.w3.org/Addressing/draft-mirashi-url-irc-01.txt
61             # http://www.mozilla.org/projects/rt-messaging/chatzilla/irc-urls.html
62             # irc:[[(/[][]|)]]
63             # http://www.gbiv.com/protocols/uri/rfc/rfc3986.html
64             # irc://nick!user@server:port/
65             my $self = shift ;
66             if ( exists $self->{'uri'} ) {
67             $self->{'uri'} =~ m|^irc://(.+?)!(.+?)@(.+?):(\d+)/| ;
68             $self->nick($1); $self->user($2); $self->server($3); $self->port($4) }
69             }
70             sub sl {
71             shift->socket->send( "@_\n" ) }
72              
73              
74             ##############
75             # Commands IRC #
76             ##############
77              
78             { my ( $code, $name ) = q{ sub { shift->sl( 'COMMAND' . " @_" ) } } ;
79             no strict 'refs' ;
80             foreach $name qw( mode privmsg notice part whois join pong ) {
81             $_ = $code ; s/COMMAND/$name/ ; *{$name} = eval } }
82              
83             ############
84             # Accessor #
85             ############
86             sub nick { return $_[0]->{ 'nick' } = $_[1] || $_[0]->{ 'nick' }
87             || $ENV{'USER'} || 'nonick' }
88             sub pass { return $_[0]->{'password'} = $_[1] || $_[0]->{'password'} || '2 young 2 die' }
89             sub port { return $_[0]->{ 'port' } = $_[1] || $_[0]->{ 'port' } || 6667 }
90             sub user { return $_[0]->{ 'user' } = $_[1] || $_[0]->{ 'user' } || 'void' }
91             sub realname { return $_[0]->{'realname'} = $_[1] || $_[0]->{'realname'} || 'use Net::IRC2' }
92             sub server { return $_[0]->{ 'server' } = $_[1] || $_[0]->{ 'server' } || 'localhost' }
93             sub socket { return $_[0]->{ 'socket' } = $_[1] || $_[0]->{ 'socket' } }
94             sub parser { return $_[0]->{ 'parser' } = $_[1] || $_[0]->{ 'parser' } }
95             sub grammar { return $_[0]->{'grammar' } = $_[1] || $_[0]->{'grammar' } }
96             sub callback { return $_[0]->{'callback'} = $_[1] if ref $_[1] eq 'CODE' ;
97             return &{$_[0]->{'callback'}}( $_[1] ) if ref $_[1] eq 'Net::IRC2::Events' }
98              
99             sub parent { return $_[0]->{'_parent' } }
100             sub chans { return push ( @{shift->{'chans'}}, shift ) }
101              
102             sub last_sl { return $_[0]->{'last_sl' } = $_[1] || $_[0]->{'last_sl' } }
103              
104             sub add_default_handler { $_[0]->add_handler( [ 'WaterGate' ], $_[1] ) }
105              
106             sub add_handler {
107             my ( $self, $commands, $callback ) = @_ ;
108             $commands = [ $commands ] unless ref $commands eq 'ARRAY' ;
109             ( map { $self->{'callback'}{$_} = $callback } @$commands ) }
110              
111             *add_global_handler = \&Net::IRC2::add_handler;
112              
113             # sub dispatch { }
114              
115             1;
116              
117              
118             __END__