File Coverage

blib/lib/Adam.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Adam;
2             our $VERSION = '0.09';
3 1     1   15704 use MooseX::POE;
  0            
  0            
4             use namespace::autoclean;
5              
6             use POE::Component::IRC::Common qw( :ALL );
7             use POE qw(
8             Component::IRC::State
9             Component::IRC::Plugin::PlugMan
10             Component::IRC::Plugin::Connector
11             Component::IRC::Plugin::ISupport
12             Component::IRC::Plugin::NickReclaim
13             Component::IRC::Plugin::BotAddressed
14             Component::IRC::Plugin::AutoJoin
15             );
16              
17             use MooseX::Aliases;
18             use Adam::Logger::Default;
19              
20             with qw(
21             MooseX::SimpleConfig
22             MooseX::Getopt
23             );
24              
25             has logger => (
26             does => 'Adam::Logger::API',
27             is => 'ro',
28             traits => ['NoGetopt'],
29             lazy_build => 1,
30             handles => 'Adam::Logger::API',
31             );
32              
33             sub _build_logger { Adam::Logger::Default->new() }
34              
35             has nickname => (
36             isa => 'Str',
37             reader => 'get_nickname',
38             alias => 'nick',
39             traits => ['Getopt'],
40             cmd_flag => 'nickname',
41             required => 1,
42             builder => 'default_nickname',
43             );
44              
45             sub default_nickname { $_[0]->meta->name }
46              
47             has server => (
48             isa => 'Str',
49             reader => 'get_server',
50             traits => ['Getopt'],
51             cmd_flag => 'server',
52             required => 1,
53             builder => 'default_server',
54             );
55              
56             sub default_server { 'irc.perl.org' }
57              
58             has port => (
59             isa => 'Int',
60             reader => 'get_port',
61             traits => ['Getopt'],
62             cmd_flag => 'port',
63             required => 1,
64             builder => 'default_port',
65             );
66              
67             sub default_port { 6667 }
68              
69             has channels => (
70             isa => 'ArrayRef',
71             reader => 'get_channels',
72             traits => ['Getopt'],
73             cmd_flag => 'channels',
74             builder => 'default_channels',
75             auto_deref => 1,
76             );
77              
78             sub default_channels { [] }
79              
80             has owner => (
81             isa => 'Str',
82             accessor => 'get_owner',
83             traits => ['Getopt'],
84             cmd_flag => 'owner',
85             builder => 'default_owner',
86             );
87              
88             sub default_owner { 'perigrin!~perigrin@217.168.150.167' }
89              
90             has username => (
91             isa => 'Str',
92             accessor => 'get_username',
93             traits => ['Getopt'],
94             cmd_flag => 'username',
95             builder => 'default_username',
96             );
97              
98             sub default_username { 'adam' }
99              
100             has password => (
101             isa => 'Str',
102             accessor => 'get_password',
103             traits => ['Getopt'],
104             cmd_flag => 'password',
105             builder => 'default_password',
106             );
107              
108             sub default_password { '' }
109              
110             has flood => (
111             isa => 'Bool',
112             reader => 'can_flood',
113             traits => ['Getopt'],
114             cmd_flag => 'flood',
115             builder => 'default_flood',
116             );
117              
118             sub default_flood { 0 }
119              
120             has plugins => (
121             isa => 'HashRef',
122             traits => [ 'Hash', 'NoGetopt' ],
123             lazy => 1,
124             auto_deref => 1,
125             builder => 'default_plugins',
126             handles => {
127             plugin_names => 'keys',
128             get_plugin => 'get',
129             has_plugins => 'count'
130             }
131             );
132              
133             sub core_plugins {
134             return {
135             'Core_Connector' => 'POE::Component::IRC::Plugin::Connector',
136             'Core_BotAddressed' => 'POE::Component::IRC::Plugin::BotAddressed',
137             'Core_AutoJoin' => POE::Component::IRC::Plugin::AutoJoin->new(
138             Channels => { map { $_ => '' } @{ $_[0]->get_channels } },
139             ),
140             'Core_NickReclaim' =>
141             POE::Component::IRC::Plugin::NickReclaim->new( poll => 30 ),
142             };
143             }
144              
145             sub custom_plugins { {} }
146              
147             sub default_plugins {
148             return { %{ $_[0]->core_plugins }, %{ $_[0]->custom_plugins } };
149             }
150              
151             has plugin_manager => (
152             isa => 'POE::Component::IRC::Plugin::PlugMan',
153             is => 'ro',
154             lazy_build => 1,
155             );
156              
157             sub _build_plugin_manager {
158             POE::Component::IRC::Plugin::PlugMan->new(
159             botowner => $_[0]->get_owner,
160             debug => 1
161             );
162             }
163              
164             before 'START' => sub {
165             my ($self) = @_;
166             $self->plugin_add( 'PlugMan' => $self->plugin_manager );
167             };
168              
169             has poco_irc_args => (
170             isa => 'HashRef',
171             accessor => 'get_poco_irc_args',
172             traits => [ 'Hash', 'Getopt' ],
173             cmd_flag => 'extra_args',
174             builder => 'default_poco_irc_args',
175             );
176              
177             sub default_poco_irc_args {
178             {};
179             }
180              
181             has poco_irc_options => (
182             isa => 'HashRef',
183             accessor => 'get_poco_irc_options',
184             traits => [ 'Hash', 'Getopt' ],
185             cmd_flag => 'extra_args',
186             builder => 'default_poco_irc_options',
187             );
188              
189             sub default_poco_irc_options { { trace => 0 } }
190              
191             has _irc => (
192             isa => 'POE::Component::IRC',
193             accessor => 'irc',
194             lazy_build => 1,
195             handles => {
196             irc_session_id => 'session_id',
197             server_name => 'server_name',
198             plugin_add => 'plugin_add',
199             }
200             );
201              
202             sub _build__irc {
203             my $self = shift;
204             POE::Component::IRC::State->spawn(
205             Nick => $self->get_nickname,
206             Server => $self->get_server,
207             Port => $self->get_port,
208             Ircname => $self->get_nickname,
209             Options => $self->get_poco_irc_options,
210             Flood => $self->can_flood,
211             Username => $self->get_username,
212             Password => $self->get_password,
213             %{ $self->get_poco_irc_args },
214             );
215             }
216              
217             sub privmsg {
218             my $self = shift;
219             POE::Kernel->post( $self->irc_session_id => privmsg => @_ );
220             }
221              
222             sub START {
223             my ( $self, $heap ) = @_[ OBJECT, HEAP ];
224             $poe_kernel->post( $self->irc_session_id => register => 'all' );
225             $poe_kernel->post( $self->irc_session_id => connect => {} );
226             $self->info( 'connecting to ' . $self->get_server . ':' . $self->get_port );
227             return;
228             }
229              
230             sub load_plugin {
231             my ( $self, $name, $plugin ) = @_;
232             $self->plugin_manager->load( $name => $plugin, bot => $self );
233             }
234              
235             event irc_plugin_add => sub {
236             my ( $self, $desc, $plugin ) = @_[ OBJECT, ARG0, ARG1 ];
237             $self->info("loaded plugin: $desc");
238             if ( $desc eq 'PlugMan' ) {
239             $self->debug("loading other plugins");
240             for my $name ( sort $self->plugin_names ) {
241             $self->debug("loading $name");
242             $plugin = $self->get_plugin($name);
243             $self->load_plugin( $name => $plugin );
244             }
245             }
246             };
247              
248             event irc_connected => sub {
249             my ( $self, $sender ) = @_[ OBJECT, SENDER ];
250             $self->info( "connected to " . $self->get_server . ':' . $self->get_port );
251             return;
252             };
253              
254             # We registered for all events, this will produce some debug info.
255             sub DEFAULT {
256             my ( $self, $event, $args ) = @_[ OBJECT, ARG0 .. $#_ ];
257             my @output = ("$event: ");
258              
259             foreach my $arg (@$args) {
260             if ( ref($arg) eq ' ARRAY ' ) {
261             push( @output, "[" . join( " ,", @$arg ) . "]" );
262             }
263             else {
264             push( @output, "'$arg' " );
265             }
266             }
267             $self->debug( join ' ', @output );
268             return 0;
269             }
270              
271             sub run {
272             $_[0]->new_with_options unless blessed $_[0];
273             POE::Kernel->run;
274             }
275              
276             1; # Magic true value required at end of module
277              
278             __END__
279              
280             =head1 NAME
281              
282             Adam - The patriarch of IRC Bots
283              
284             =head1 VERSION
285              
286             This documentation refers to version 0.05.
287              
288             =head1 SYNOPSIS
289              
290             See the Synopsis in L<Moses|Moses>. Adam is not meant to be used directly.
291              
292             =head1 DESCRIPTION
293              
294             The Adam class implements a basic L<POE::Component::IRC|POE::Component::IRC>
295             bot based on L<Moose|Moose> and L<MooseX::POE|MooseX::POE>.
296              
297             =head1 ATTRIBUTES
298              
299             =head2 nickname (Str)
300              
301             The IRC nickname for the bot, it will default to the package name.
302              
303             =head2 server (Str)
304              
305             The IRC server to connect to.
306              
307             =head2 port (Int)
308              
309             The port for the IRC server, defaults to 6667
310              
311             =head2 username(Str)
312              
313             The username which we should use
314              
315             =head2 password(Str)
316              
317             The server password which we shoulduse
318              
319             =head2 channels (ArrayRef[Str])
320              
321             IRC channels to connect to.
322              
323             =head2 owner (Str)
324              
325             The hostmask of the ower of the bot. The owner can control the bot's plugins
326             through IRC using the <POE::Component::IRC::Plugin::Plugman|Plugman>
327             interface.
328              
329             =head2 flood (Bool)
330              
331             Disable flood protection. Defaults to False.
332              
333             =head2 plugins (HashRef)
334              
335             A list of plugins associated with the IRC bot. See L<Moses::Plugin> for more
336             details.
337              
338             =head2 extra_args (HashRef)
339              
340             A list of extra arguments to pass to the irc constructor.
341              
342             =head1 METHODS
343              
344             =head2 privmsg (Str $who, Str $what)
345              
346             Send message C<$what> as a private message to C<$who>, a channel or nick.
347              
348             =head2 run ()
349              
350             Start the IRC bot. This method also works as a Class Method and will
351             instanciate the bot if called as such.
352              
353             =head1 DEPENDENCIES
354              
355             L<MooseX::POE|MooseX::POE>, L<namespace::autoclean|namespace::autoclean>,
356             L<MooseX::Alias|MooseX::Alias>, L<POE::Component::IRC|POE::Component::IRC>,
357             L<MooseX::Getopt|MooseX::Getopt>,
358             L<MooseX::SimpleConfig|MooseX::SimpleConfig>,
359             L<MooseX::LogDispatch|MooseX::LogDispatch>
360              
361             =head1 BUGS AND LIMITATIONS
362              
363             None known currently, please email the author if you find any.
364              
365             =head1 AUTHOR
366              
367             Chris Prather (chris@prather.org)
368              
369             =head1 LICENCE
370              
371             Copyright 2007-2009 by Chris Prather.
372              
373             This software is free. It is licensed under the same terms as Perl itself.
374              
375             =cut