package App::Bot::BasicBot::Pluggable;
{
$App::Bot::BasicBot::Pluggable::VERSION = '0.97';
}
use Moose;
use Config::Find;
use Bot::BasicBot::Pluggable;
use Bot::BasicBot::Pluggable::Store;
use Moose::Util::TypeConstraints;
use List::MoreUtils qw(any uniq);
use Try::Tiny;
use Log::Log4perl;
with 'MooseX::Getopt::Dashes';
with 'MooseX::SimpleConfig';
use Module::Pluggable
sub_name => '_available_stores',
search_path => 'Bot::BasicBot::Pluggable::Store';
subtype 'App::Bot::BasicBot::Pluggable::Channels'
=> as 'ArrayRef'
## Either it's an empty ArrayRef or all channels start with #
=> where { @{$_} ? any { /^#/ } @{$_} : 1 };
coerce 'App::Bot::BasicBot::Pluggable::Channels'
=> from 'ArrayRef'
=> via { [ map { /^#/ ? $_ : "#$_" } @{$_} ] };
subtype 'App::Bot::BasicBot::Pluggable::Store'
=> as 'Bot::BasicBot::Pluggable::Store';
MooseX::Getopt::OptionTypeMap->add_option_type_to_map(
'App::Bot::BasicBot::Pluggable::Store' => '=s%'
);
coerce 'App::Bot::BasicBot::Pluggable::Store'
=> from 'Str'
=> via { Bot::BasicBot::Pluggable::Store->new_from_hashref({ type => 'Str' }) };
coerce 'App::Bot::BasicBot::Pluggable::Store'
=> from 'HashRef'
=> via { Bot::BasicBot::Pluggable::Store->new_from_hashref( shift ) };
has server => ( is => 'rw', isa => 'Str', default => 'localhost' );
has nick => ( is => 'rw', isa => 'Str', default => 'basicbot' );
has charset => ( is => 'rw', isa => 'Str', default => 'utf8' );
has channel => (
is => 'rw',
isa => 'App::Bot::BasicBot::Pluggable::Channels',
coerce => 1,
default => sub { [] }
);
has password => ( is => 'rw', isa => 'Str' );
has port => ( is => 'rw', isa => 'Int', default => 6667 );
has bot_class =>
( is => 'rw', isa => 'Str', default => 'Bot::BasicBot::Pluggable' );
has list_modules => ( is => 'rw', isa => 'Bool', default => 0 );
has list_stores => ( is => 'rw', isa => 'Bool', default => 0 );
has store => (
is => 'rw',
isa => 'App::Bot::BasicBot::Pluggable::Store',
coerce => 1,
builder => '_create_store'
);
has settings => (
metaclass => 'NoGetopt',
is => 'rw',
isa => 'HashRef',
default => sub { {} }
);
has loglevel => ( is => 'rw', isa => 'Str', default => 'warn' );
has logconfig => ( is => 'rw', isa => 'Str' );
has configfile => (
is => 'rw',
isa => 'Str|Undef',
default => Config::Find->find( name => 'bot-basicbot-pluggable.yaml' ),
);
has bot => (
metaclass => 'NoGetopt',
is => 'rw',
isa => 'Bot::BasicBot::Pluggable',
builder => '_create_bot',
lazy => 1,
);
has module => (
is => 'rw',
isa => 'ArrayRef',
default => sub { return [qw( Auth Loader )] }
);
sub BUILD {
my ($self) = @_;
if ( $self->password() ) {
$self->module( [ uniq @{ $self->module }, 'Auth' ] );
}
$self->_load_modules();
}
sub _load_modules {
my ($self) = @_;
my %settings = %{ $self->settings() };
my $logger = Log::Log4perl->get_logger( ref $self );
# Implicit loading of modules via $self->settings
my @modules = uniq @{ $self->module() }, keys %settings;
$self->module( [@modules] );
for my $module_name (@modules) {
my $module = try {
$self->bot->load($module_name);
}
catch {
$logger->error("$_");
};
next if !$module;
if ( exists( $settings{$module_name} ) ) {
for my $key ( keys %{ $settings{$module_name} } ) {
$module->set( $key, $settings{$module_name}->{$key} );
}
}
if ( $module_name eq 'Auth' and $self->password() ) {
$module->set( 'password_admin', $self->password() );
}
}
}
sub _create_store {
return Bot::BasicBot::Pluggable::Store->new_from_hashref(
{ type => 'Memory' } );
}
sub _create_bot {
my ($self) = @_;
my $class = $self->bot_class();
return $class->new(
channels => $self->channel(),
server => $self->server(),
nick => $self->nick(),
charset => $self->charset(),
port => $self->port(),
store => $self->store(),
loglevel => $self->loglevel(),
logconfig => $self->logconfig(),
);
}
sub run {
my ($self) = @_;
if ( $self->list_modules() ) {
print "$_\n" for $self->bot->available_modules;
exit 0;
}
if ( $self->list_stores() ) {
for ( $self->_available_stores ) {
s/Bot::BasicBot::Pluggable::Store:://;
print "$_\n";
}
exit 0;
}
$self->bot->run();
}
1;
__END__
=head1 NAME
App::Bot::BasicBot::Pluggable - Base class for bot applications
=head1 VERSION
version 0.97
=head1 SYNOPSIS
my bot = App::Bot::BasicBot::Pluggable( modules => [ 'Karma' ] )
$bot->run();
=head1 DESCRIPTION
This module is basically intended as base class for
L<Bot::BasicBot::Pluggable> frontends. It's attributes can be set
by command line options or a configuration file.
=head1 ATTRIBUTES
All subsequently listed attributes are documented in the manpage
of L<bot-basicbot-pluggable>. Just replace all dashes with underscores.
=over 4
=item server
=item nick
=item charset
=item password
=item port
=item list_modules
=item list_stores
=item loglevel
=item logconfig
=item configfile
=item module
=back
=head1 METHODS
=head2 run
If list_modules or list_stores are set to a true value, the according
list is printed to stdout. Otherwise the run method of the bot
specified by the bot_class method is called.
=head1 AUTHOR
Mario Domgoergen <mdom@cpan.org>
=head1 LICENSE
This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself