File Coverage

lib/Bot/BasicBot/Pluggable/Module.pm
Criterion Covered Total %
statement 56 69 81.1
branch 8 16 50.0
condition 2 6 33.3
subroutine 20 28 71.4
pod 26 26 100.0
total 112 145 77.2


line stmt bran cond sub pod time code
1             package Bot::BasicBot::Pluggable::Module;
2             $Bot::BasicBot::Pluggable::Module::VERSION = '1.20';
3 10     10   41 use warnings;
  10         11  
  10         276  
4 10     10   33 use strict;
  10         10  
  10         6425  
5              
6             sub new {
7 16     16 1 140 my $class = shift;
8 16         47 my %param = @_;
9              
10 16   33     132 my $name = ref($class) || $class;
11 16         89 $name =~ s/^.*:://;
12 16   33     83 $param{Name} ||= $name;
13              
14 16         22 my $self = \%param;
15 16         26 bless $self, $class;
16              
17 16         58 $self->init();
18              
19 16         51 return $self;
20             }
21              
22             sub config {
23 10     10 1 18 my ( $self, $config ) = @_;
24 10         13 for my $var ( keys %{$config} ) {
  10         36  
25 50 50       92 $self->set( $var, $config->{$var} ) unless defined( $self->get($var) );
26             }
27             }
28              
29             sub bot {
30 2698     2698 1 1567 my $self = shift;
31 2698         4245 return $self->{Bot};
32             }
33              
34             sub store {
35 1300     1300 1 826 my $self = shift;
36 1300 50       1228 die "module has no bot" unless $self->bot;
37 1300         1222 return $self->bot->store;
38             }
39              
40             sub get {
41 1188     1188 1 1204 my $self = shift;
42 1188         1312 $self->store->get( $self->{Name}, @_ );
43             }
44              
45             sub set {
46 103     103 1 1607 my $self = shift;
47 103         131 $self->store->set( $self->{Name}, @_ );
48             }
49              
50             sub unset {
51 5     5 1 7 my $self = shift;
52 5         11 $self->store->unset( $self->{Name}, @_ );
53             }
54              
55             sub var {
56 4     4 1 6 my $self = shift;
57 4         6 my $name = shift;
58 4 100       8 if (@_) {
59 1         4 return $self->set( $name, shift );
60             }
61             else {
62 3         7 return $self->get($name);
63             }
64             }
65              
66             sub store_keys {
67 9     9 1 13 my $self = shift;
68 9         17 my $store = $self->store;
69              
70 9 50       22 die "No store set up" unless defined $store;
71 9 50       19 die "Store isn't a ref" unless ref($store);
72              
73 9         47 $store->keys( $self->{Name}, @_ );
74             }
75              
76             sub help {
77 1     1 1 1281 my ( $self, $mess ) = @_;
78 1         6 return "No help for module '$self->{Name}'. This is a bug.";
79             }
80              
81             sub say {
82 0     0 1 0 my $self = shift;
83 0         0 return $self->bot->say(@_);
84             }
85              
86             sub reply {
87 2     2 1 5 my $self = shift;
88 2         4 return $self->bot->reply(@_);
89             }
90              
91             sub tell {
92 0     0 1 0 my ( $self, $target, $body ) = @_;
93 0 0       0 if ( $target =~ /^#/ ) {
94 0         0 $self->say( { channel => $target, body => $body } );
95             }
96             else {
97 0         0 $self->say( { channel => 'msg', body => $body, who => $target } );
98             }
99             }
100              
101             sub said {
102 754     754 1 668 my ( $self, $mess, $pri ) = @_;
103 754 50       4961 $mess->{body} =~ s/(^\s*|\s*$)//g if defined $mess->{body};
104              
105 754         861 my $handler = (qw/ seen admin told fallback /)[$pri];
106              
107 754         1429 return $self->$handler($mess);
108             }
109              
110             sub authed {
111 54     54 1 51 my ( $self, $who ) = @_;
112 54 50       72 if ( $self->bot->module('Auth') ) {
113 0         0 return $self->bot->module('Auth')->authed($who);
114             }
115 54         188 return 0;
116             }
117              
118 4     4 1 5 sub init { undef }
119 0     0 1 0 sub connected { undef }
120 0     0 1 0 sub chanjoin { undef }
121 0     0 1 0 sub chanpart { undef }
122 232     232 1 363 sub seen { undef }
123 211     211 1 331 sub admin { undef }
124 4     4 1 11 sub told { undef }
125 10     10 1 22 sub fallback { undef }
126 0     0 1   sub emoted { undef }
127 0     0 1   sub tick { undef }
128 0     0 1   sub stop { undef }
129              
130             1;
131              
132             __END__
133              
134             =head1 NAME
135              
136             Bot::BasicBot::Pluggable::Module - base module for all BasicBot plugins
137              
138             =head1 VERSION
139              
140             version 1.20
141              
142             =head1 SYNOPSIS
143              
144             You MUST override C<help()>, which MUST return help text for the module.
145              
146             You MUST override at least C<said()>, though it is preferred that you
147             override the more specific C<seen()>, C<admin()>, C<told()> and C<fallback()>
148             for cleaner code without relying on checks against C<$pri>.
149              
150             You MAY override C<chanjoin()>, C<chanpart()>, C<userquit>,
151             C<nick_change>, C<topic>, C<kicked> and C<tick()>.
152              
153             You MAY return a response from C<said()> to the event.
154              
155             =head1 DESCRIPTION
156              
157             =head2 Object Store
158              
159             Every pluggable module gets an object store to save variables in. Access
160             this store using the C<get()> and C<set()> accessors. Do not access the store
161             through any other means - the location of the store, and its method of storage,
162             may change at any time:
163              
164             my $count = $self->get("count");
165             $self->set( count => $count + 1 );
166              
167             Keys that begin "user_" are considered _USER_ variables, and can be changed by
168             administrators in the IRC channel using L<Bot::BasicBot::Pluggable::Module::Vars>.
169             Don't use them as unchecked input data.
170              
171             =head1 METHODS
172              
173             =over 4
174              
175             =item new()
176              
177             Standard C<new> method, blesses a hash into the right class and puts any
178             key/value pairs passed to it into the blessed hash. Calls C<init> to load
179             any internal or user variables you may have set in your module.
180              
181             =item init()
182              
183             Called as part of new class construction. May or may not be after
184             server connection. Override this to do things when your module is added
185             to the bot.
186              
187             =item config($config)
188              
189             Set every key in the hash reference $config to its default value
190             if it is not already defined in the module store. In that case the
191             value from the store is used to initialise the variable. Typically
192             called in the module's init functions.
193              
194             =item start()
195              
196             Indicates that the module is added to the bot, and that the bot is
197             connected to the IRC server. Do things here that need to be done after
198             you're connected.
199              
200             TODO - this method not yet implemented.
201              
202             =item stop()
203              
204             Called just before your module is removed from the bot. Do cleanup here.
205              
206             =item bot()
207              
208             Returns the L<Bot::BasicBot::Pluggable> bot we're running under.
209              
210             =item store
211              
212             Returns L<Bot::BasicBot::Pluggable::Store> subclass used to store variables.
213              
214             =item get($name)
215              
216             Returns the value of a local variable from the object store.
217              
218             =item set($name => $value)
219              
220             Set a local variable into the object store.
221              
222             =item unset($name)
223              
224             Unsets a local variable - removes it from the store, not just C<undef>s it.
225              
226             =item var($name, [$value])
227              
228             C<get()> or C<set()> a local variable from the module store.
229              
230             =item store_keys
231              
232             Returns a list of all keys in the object store.
233              
234             =item connected
235              
236             Called when the bot connects to the server. The return value is meaningless.
237              
238             =item chanjoin($message)
239              
240             Called when a user joins a channel.
241              
242             =item userquit($message)
243              
244             Called when a user client quits. See L<Bot::BasicBot> for a description
245             of the arguments.
246              
247             =item chanpart($message)
248              
249             Called when a user leaves a channel.
250              
251             =item topic($message)
252              
253             Called when the topic of a channel is changed. See L<Bot::BasicBot> for a description
254             of the arguments.
255              
256             =item kicked($message)
257              
258             Called when a user is kicked from a channel. See L<Bot::BasicBot> for a description
259             of the arguments.
260              
261             =item nick_change($message)
262              
263             When a user changes nicks, this will be called. See L<Bot::BasicBot> for a description
264             of the arguments.
265              
266             =item help
267              
268             Called when a user asks for help on a topic and thus should return some useful
269             help text. For L<Bot::BasicBot::Pluggable>, when a user asks the bot 'help',
270             the bot will return a list of modules. Asking the bot 'help <modulename>' will
271             call the C<help> function of that module, passing in the first parameter the
272             message object that represents the question.
273              
274             =item say($message)
275              
276             Passing through L<Bot::BasicBot>, send messages without replying to a C<said()>:
277              
278             $self->say({ who => 'tom', body => 'boo', channel => 'msg' });
279              
280             =item reply($message, $body)
281              
282             Replies to the given message with the given text. Another passthrough to
283             C<Bot::BasicBot>. The message is used to pre-populate the reply, so it'll
284             be in the same channel as the question, directed to the right user, etc.
285              
286             =item tell($nick | $channel, $message)
287              
288             Convenience method to send message to nick (privmsg) or channel (public):
289              
290             $self->tell('tom', "hello there, fool");
291             $self->tell('#sailors', "hello there, sailor");
292              
293             =item said($message, $priority)
294              
295             This method is called whenever the bot sees something said. The first parameter
296             is a L<Bot::BasicBot> 'message' object, as passed to it's 'said' function - see
297             those docs for further details. The second parameter is the priority of the
298             message - all modules will have the 'said' function called up to 4 times, with
299             priorities of 0, 1, 2, and 3. The first module to return a non-null value
300             'claims' the message, and the bot will reply to it with the value returned -
301             unless the value is "1", in which case the message is considered claimed (no
302             other module will see it) but no reply will be issued.
303              
304             The exception to this is the 0 priority, which a module MUST NOT respond to
305             (any response will be ignored).
306             This is so that all modules will at least see all messages. I suggest:
307              
308             sub said {
309             my ($self, $mess, $pri) = @_;
310             my $body = $mess->{body};
311              
312             return unless ($pri == 2); # most common
313              
314             my ($command, $param) = split(/\s+/, $body, 2);
315             $command = lc($command);
316              
317             # do something here
318              
319             return; # allows other modules to see this message, or:
320             return 1; # "eat" the message, no other module sees it, no reply, or:
321             return "OK!"; # "eat" the message and send a reply back to the user
322             }
323              
324             The preferred way, however, is to override one of the separate C<seen()>, C<admin()>,
325             C<told()> and C<fallback()> methods, corresponding to priorities 0, 1, 2 and 3
326             in order - this will lead to nicer code. This approach is new, though, which
327             is why it's not yet used in most of the shipped modules yet. It will eventually
328             become the only thing to do, and I will deprecate C<said()>.
329              
330             =item replied($message,$reply)
331              
332             This method is called every time a module returns an reply. The first
333             argument is the original message and the second is the returned
334             string. The return value of this method is actually discarded, so
335             you can't do anything to prevent the message from being sent. This
336             is mainly meant to log the bots activity.
337              
338             =item seen($message)
339              
340             Like C<said()>; called if you don't override C<said()>, but only for priority 0.
341              
342             As it is called at priority 0, you cannot return a reply from this method.
343              
344             =item admin($message)
345              
346             Like C<said()>; called if you don't override C<said()>, but only for priority 1.
347              
348             =item told($message)
349              
350             Like C<said()>; called if you don't override C<said()>, but only for priority 2.
351              
352             =item fallback($message)
353              
354             Like C<said()>; called if you don't override C<said()>, but only for priority 3.
355              
356             =item emoted($message, $priority)
357              
358             Called when a user emotes something in channel.
359              
360             =item tick
361              
362             Called every five seconds. It is probably worth having a counter and not
363             responding to every single one, assuming you want to respond at all. The
364             return value is ignored.
365              
366             =item authed($who)
367              
368             This is a convenient method that tries to check for the users
369             authentication level via Auth.pm. It is exactly equivalent to
370              
371             $self->bot->module('Auth')
372             and $self->bot->module('Auth')->authed($who);
373              
374             =back
375              
376             =head1 AUTHOR
377              
378             Mario Domgoergen <mdom@cpan.org>
379              
380             This program is free software; you can redistribute it
381             and/or modify it under the same terms as Perl itself.