File Coverage

blib/lib/App/Bot/BasicBot/Pluggable.pm
Criterion Covered Total %
statement 53 64 82.8
branch 7 12 58.3
condition 3 3 100.0
subroutine 14 16 87.5
pod 1 2 50.0
total 78 97 80.4


line stmt bran cond sub pod time code
1             package App::Bot::BasicBot::Pluggable;
2             $App::Bot::BasicBot::Pluggable::VERSION = '1.10';
3 3     3   147172 use Moose;
  3         914743  
  3         19  
4 3     3   15623 use Config::Find;
  3         43909  
  3         85  
5 3     3   1249 use Bot::BasicBot::Pluggable;
  3         20  
  3         199  
6 3     3   14 use Bot::BasicBot::Pluggable::Store;
  3         3  
  3         54  
7 3     3   10 use Moose::Util::TypeConstraints;
  3         3  
  3         47  
8 3     3   6192 use List::MoreUtils qw(any uniq);
  3         19224  
  3         26  
9 3     3   1468 use Try::Tiny;
  3         4  
  3         152  
10 3     3   13 use Log::Log4perl;
  3         4  
  3         19  
11              
12             with 'MooseX::Getopt::Dashes';
13             with 'MooseX::SimpleConfig';
14              
15             use Module::Pluggable
16 3         22 sub_name => '_available_stores',
17 3     3   147 search_path => 'Bot::BasicBot::Pluggable::Store';
  3         6  
18              
19             subtype 'App::Bot::BasicBot::Pluggable::Channels'
20             => as 'ArrayRef'
21             ## Either it's an empty ArrayRef or all channels start with #
22             => where { @{$_} ? any { /^#/ } @{$_} : 1 };
23              
24             coerce 'App::Bot::BasicBot::Pluggable::Channels'
25             => from 'ArrayRef'
26             => via { [ map { /^#/ ? $_ : "#$_" } @{$_} ] };
27              
28             subtype 'App::Bot::BasicBot::Pluggable::Store'
29             => as 'Bot::BasicBot::Pluggable::Store';
30              
31             MooseX::Getopt::OptionTypeMap->add_option_type_to_map(
32             'App::Bot::BasicBot::Pluggable::Store' => '=s%'
33             );
34              
35             coerce 'App::Bot::BasicBot::Pluggable::Store'
36             => from 'Str'
37             => via { Bot::BasicBot::Pluggable::Store->new_from_hashref({ type => 'Str' }) };
38              
39             coerce 'App::Bot::BasicBot::Pluggable::Store'
40             => from 'HashRef'
41             => via { Bot::BasicBot::Pluggable::Store->new_from_hashref( shift ) };
42              
43             has server => ( is => 'rw', isa => 'Str', default => 'localhost' );
44             has nick => ( is => 'rw', isa => 'Str', default => 'basicbot' );
45             has charset => ( is => 'rw', isa => 'Str', default => 'utf8' );
46             has channel => (
47             is => 'rw',
48             isa => 'App::Bot::BasicBot::Pluggable::Channels',
49             coerce => 1,
50             default => sub { [] }
51             );
52             has password => ( is => 'rw', isa => 'Str' );
53             has port => ( is => 'rw', isa => 'Int', default => 6667 );
54             has useipv6 => ( is => 'rw', isa => 'Bool', default => 1 );
55             has localaddr => ( is => 'rw', isa => 'Str' );
56             has bot_class =>
57             ( is => 'rw', isa => 'Str', default => 'Bot::BasicBot::Pluggable' );
58              
59             has list_modules => ( is => 'rw', isa => 'Bool', default => 0 );
60             has list_stores => ( is => 'rw', isa => 'Bool', default => 0 );
61              
62             has store => (
63             is => 'rw',
64             isa => 'App::Bot::BasicBot::Pluggable::Store',
65             coerce => 1,
66             builder => '_create_store'
67             );
68             has settings => (
69             metaclass => 'NoGetopt',
70             is => 'rw',
71             isa => 'HashRef',
72             default => sub { {} }
73             );
74              
75             has loglevel => ( is => 'rw', isa => 'Str', default => 'warn' );
76             has logconfig => ( is => 'rw', isa => 'Str' );
77              
78             has configfile => (
79             is => 'rw',
80             isa => 'Str|Undef',
81             default => Config::Find->find( name => 'bot-basicbot-pluggable.yaml' ),
82             );
83              
84             has bot => (
85             metaclass => 'NoGetopt',
86             is => 'rw',
87             isa => 'Bot::BasicBot::Pluggable',
88             builder => '_create_bot',
89             lazy => 1,
90             );
91              
92             has module => (
93             is => 'rw',
94             isa => 'ArrayRef',
95             default => sub { return [qw( Auth Loader )] }
96             );
97              
98             sub BUILD {
99 3     3 0 6547 my ($self) = @_;
100              
101 3 100       98 if ( $self->password() ) {
102 1         2 $self->module( [ uniq @{ $self->module }, 'Auth' ] );
  1         27  
103             }
104 3         10 $self->_load_modules();
105             }
106              
107             sub _load_modules {
108 3     3   5 my ($self) = @_;
109 3         8 my %settings = %{ $self->settings() };
  3         82  
110 3         15 my $logger = Log::Log4perl->get_logger( ref $self );
111              
112             # Implicit loading of modules via $self->settings
113 3         655 my @modules = uniq @{ $self->module() }, keys %settings;
  3         94  
114 3         112 $self->module( [@modules] );
115              
116 3         7 for my $module_name (@modules) {
117             my $module = try {
118 7     7   406 $self->bot->load($module_name);
119             }
120             catch {
121 0     0   0 $logger->error("$_");
122 7         45 };
123 7 50       89 next if !$module;
124 7 100       15 if ( exists( $settings{$module_name} ) ) {
125 1         2 for my $key ( keys %{ $settings{$module_name} } ) {
  1         4  
126 1         4 $module->set( $key, $settings{$module_name}->{$key} );
127             }
128             }
129 7 100 100     174 if ( $module_name eq 'Auth' and $self->password() ) {
130 1         31 $module->set( 'password_admin', $self->password() );
131             }
132             }
133             }
134              
135             sub _create_store {
136 1     1   328 return Bot::BasicBot::Pluggable::Store->new_from_hashref(
137             { type => 'Memory' } );
138             }
139              
140             sub _create_bot {
141 3     3   6 my ($self) = @_;
142 3         89 my $class = $self->bot_class();
143 3         81 return $class->new(
144             channels => $self->channel(),
145             server => $self->server(),
146             nick => $self->nick(),
147             charset => $self->charset(),
148             port => $self->port(),
149             useipv6 => $self->useipv6(),
150             localaddr => $self->localaddr(),
151             store => $self->store(),
152             loglevel => $self->loglevel(),
153             logconfig => $self->logconfig(),
154             );
155             }
156              
157             sub run {
158 0     0 1   my ($self) = @_;
159              
160 0 0         if ( $self->list_modules() ) {
161 0           print "$_\n" for $self->bot->available_modules;
162 0           exit 0;
163             }
164              
165 0 0         if ( $self->list_stores() ) {
166 0           for ( $self->_available_stores ) {
167 0           s/Bot::BasicBot::Pluggable::Store:://;
168 0           print "$_\n";
169             }
170 0           exit 0;
171             }
172 0           $self->bot->run();
173             }
174              
175             1;
176              
177             __END__
178              
179             =head1 NAME
180              
181             App::Bot::BasicBot::Pluggable - Base class for bot applications
182              
183             =head1 VERSION
184              
185             version 1.10
186              
187             =head1 SYNOPSIS
188              
189             my bot = App::Bot::BasicBot::Pluggable( modules => [ 'Karma' ] )
190             $bot->run();
191              
192             =head1 DESCRIPTION
193              
194             This module is basically intended as base class for
195             L<Bot::BasicBot::Pluggable> frontends. It's attributes can be set
196             by command line options or a configuration file.
197              
198             =head1 ATTRIBUTES
199              
200             All subsequently listed attributes are documented in the manpage
201             of L<bot-basicbot-pluggable>. Just replace all dashes with underscores.
202              
203             =over 4
204              
205             =item server
206              
207             =item nick
208              
209             =item charset
210              
211             =item password
212              
213             =item port
214              
215             =item list_modules
216              
217             =item list_stores
218              
219             =item loglevel
220              
221             =item logconfig
222              
223             =item configfile
224              
225             =item module
226              
227             =back
228              
229             =head1 METHODS
230              
231             =head2 run
232              
233             If list_modules or list_stores are set to a true value, the according
234             list is printed to stdout. Otherwise the run method of the bot
235             specified by the bot_class method is called.
236              
237             =head1 AUTHOR
238              
239             Mario Domgoergen <mdom@cpan.org>
240              
241             =head1 LICENSE
242              
243             This program is free software; you can redistribute it
244             and/or modify it under the same terms as Perl itself