Adam
view release on metacpan or search on metacpan
lib/Adam.pm view on Meta::CPAN
sub default_password { '' }
has flood => (
isa => 'Bool',
reader => 'can_flood',
traits => ['Getopt'],
cmd_flag => 'flood',
builder => 'default_flood',
);
sub default_flood { 0 }
has plugins => (
isa => 'HashRef',
traits => [ 'Hash', 'NoGetopt' ],
lazy => 1,
auto_deref => 1,
builder => 'default_plugins',
handles => {
plugin_names => 'keys',
get_plugin => 'get',
has_plugins => 'count'
}
);
sub core_plugins {
return {
'Core_Connector' => 'POE::Component::IRC::Plugin::Connector',
'Core_BotAddressed' => 'POE::Component::IRC::Plugin::BotAddressed',
'Core_AutoJoin' => POE::Component::IRC::Plugin::AutoJoin->new(
Channels => { map { $_ => '' } @{ $_[0]->get_channels } },
),
'Core_NickReclaim' =>
POE::Component::IRC::Plugin::NickReclaim->new( poll => 30 ),
};
}
sub custom_plugins { {} }
sub default_plugins {
return { %{ $_[0]->core_plugins }, %{ $_[0]->custom_plugins } };
}
has plugin_manager => (
isa => 'POE::Component::IRC::Plugin::PlugMan',
is => 'ro',
lazy_build => 1,
);
sub _build_plugin_manager {
POE::Component::IRC::Plugin::PlugMan->new(
botowner => $_[0]->get_owner,
debug => 1
);
}
before 'START' => sub {
my ($self) = @_;
$self->plugin_add( 'PlugMan' => $self->plugin_manager );
};
has poco_irc_args => (
isa => 'HashRef',
accessor => 'get_poco_irc_args',
traits => [ 'Hash', 'Getopt' ],
cmd_flag => 'extra_args',
builder => 'default_poco_irc_args',
);
sub default_poco_irc_args {
{};
}
has poco_irc_options => (
isa => 'HashRef',
accessor => 'get_poco_irc_options',
traits => [ 'Hash', 'Getopt' ],
cmd_flag => 'extra_args',
builder => 'default_poco_irc_options',
);
sub default_poco_irc_options { { trace => 0 } }
has _irc => (
isa => 'POE::Component::IRC',
accessor => 'irc',
lazy_build => 1,
handles => {
irc_session_id => 'session_id',
server_name => 'server_name',
plugin_add => 'plugin_add',
}
);
sub _build__irc {
my $self = shift;
POE::Component::IRC::State->spawn(
Nick => $self->get_nickname,
Server => $self->get_server,
Port => $self->get_port,
Ircname => $self->get_nickname,
Options => $self->get_poco_irc_options,
Flood => $self->can_flood,
Username => $self->get_username,
Password => $self->get_password,
%{ $self->get_poco_irc_args },
);
}
sub privmsg {
my $self = shift;
POE::Kernel->post( $self->irc_session_id => privmsg => @_ );
}
sub START {
my ( $self, $heap ) = @_[ OBJECT, HEAP ];
$poe_kernel->post( $self->irc_session_id => register => 'all' );
$poe_kernel->post( $self->irc_session_id => connect => {} );
$self->info( 'connecting to ' . $self->get_server . ':' . $self->get_port );
return;
}
sub load_plugin {
my ( $self, $name, $plugin ) = @_;
$self->plugin_manager->load( $name => $plugin, bot => $self );
}
event irc_plugin_add => sub {
my ( $self, $desc, $plugin ) = @_[ OBJECT, ARG0, ARG1 ];
$self->info("loaded plugin: $desc");
if ( $desc eq 'PlugMan' ) {
$self->debug("loading other plugins");
for my $name ( sort $self->plugin_names ) {
$self->debug("loading $name");
$plugin = $self->get_plugin($name);
$self->load_plugin( $name => $plugin );
}
}
};
event irc_connected => sub {
my ( $self, $sender ) = @_[ OBJECT, SENDER ];
$self->info( "connected to " . $self->get_server . ':' . $self->get_port );
return;
};
# We registered for all events, this will produce some debug info.
sub DEFAULT {
my ( $self, $event, $args ) = @_[ OBJECT, ARG0 .. $#_ ];
my @output = ("$event: ");
foreach my $arg (@$args) {
if ( ref($arg) eq ' ARRAY ' ) {
push( @output, "[" . join( " ,", @$arg ) . "]" );
}
else {
push( @output, "'$arg' " );
}
}
$self->debug( join ' ', @output );
return 0;
}
sub run {
$_[0]->new_with_options unless blessed $_[0];
POE::Kernel->run;
}
has _loop => (
is => 'rw',
traits => ['NoGetopt'],
predicate => 'has_loop',
);
sub async {
my $self = shift;
require IO::Async::Loop::POE;
$self = $self->new_with_options unless blessed $self;
my $loop = IO::Async::Loop::POE->new();
$self->_loop($loop);
$loop->run;
}
sub stop {
my $self = shift;
if ($self->has_loop) {
$self->_loop->stop;
} else {
POE::Kernel->stop;
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Adam - The patriarch of IRC Bots
=head1 VERSION
version 1.003
=head1 SYNOPSIS
See the Synopsis in L<Moses>. Adam is not meant to be used directly.
=head1 DESCRIPTION
The Adam class implements an IRC bot based on L<POE::Component::IRC::State>,
L<Moose>, and L<MooseX::POE>. It supports two event loop modes: the default
L<POE> loop via C<run()>, and an L<IO::Async> mode via C<async()> that allows
( run in 0.492 second using v1.01-cache-2.11-cpan-39bf76dae61 )