our
$VERSION
=
'0.03'
;
Component::IRC
Component::IRC::Plugin::PAUSE::RecentUploads
Component::IRC::Plugin::CPAN::Info
Component::IRC::Plugin::Connector
Component::IRC::Plugin::NickReclaim
Component::IRC::Plugin::BotAddressed
)
;
my
$configdir
=
$ENV
{CPAN_BOT_DIR} ||
''
;
if
( !
$configdir
&&
$ENV
{HOME} ) {
$configdir
=
"$ENV{HOME}/.cpan_bot"
;
}
my
$config
=
do
"$configdir/config"
;
unless
(
defined
$config
) {
die
"Failed to load config `$configdir/config` ($!) ($@)"
;
}
my
@Channels
= @{
$config
->{channels} };
my
$Do_NickServ
=
$config
->{do_nickserv};
my
$NickServ_Pass
=
$config
->{nickserv_pass};
my
@PAUSE_Options
= @{
$config
->{PAUSE_options} || [] };
my
@CPANInfo_Options
= @{
$config
->{CPANInfo_options} || [] };
my
$irc
= POE::Component::IRC->spawn(
nick
=>
$config
->{nick},
server
=>
$config
->{server},
port
=>
$config
->{port},
ircname
=>
$config
->{ircname},
) or
die
"Oh noes :( $!"
;
POE::Session->create(
package_states
=> [
main
=> [
qw(
_start
irc_001
_default
lag_o_meter
irc_notice
irc_public
irc_bot_addressed
pause_uploads_list
)
],
],
);
$poe_kernel
->run();
sub
_start {
$irc
->yield(
register
=>
'all'
);
$irc
->plugin_add(
'BotAddressed'
=> POE::Component::IRC::Plugin::BotAddressed->new
);
$irc
->plugin_add(
'NickReclaim'
=> POE::Component::IRC::Plugin::NickReclaim->new
);
$_
[HEAP]->{connector} = POE::Component::IRC::Plugin::Connector->new;
$irc
->plugin_add(
'Connector'
=>
$_
[HEAP]->{connector}
);
$irc
->plugin_add(
'CPANInfo'
=>
POE::Component::IRC::Plugin::CPAN::Info->new(
@CPANInfo_Options
)
);
$irc
->yield(
connect
=> { } );
$_
[KERNEL]->delay(
'lag_o_meter'
=> 60 );
undef
;
}
sub
irc_001 {
my
(
$kernel
,
$sender
) =
@_
[ KERNEL, SENDER ];
unless
(
$Do_NickServ
) {
$kernel
->post(
$sender
=>
join
=>
$_
)
for
@Channels
;
$irc
->plugin_add(
'PAUSE'
=>
POE::Component::IRC::Plugin::PAUSE::RecentUploads->new(
@PAUSE_Options
)
);
}
undef
;
}
sub
irc_public {
undef
;
}
sub
pause_uploads_list {
print
"\n[ "
.
localtime
(
$_
[ARG0]) .
"] Fetched new list from PAUSE\n"
;
}
sub
irc_bot_addressed {
my
(
$kernel
,
$heap
,
$sender
) =
@_
[ KERNEL, HEAP, SENDER ];
my
(
$nick
) = (
split
/!/,
$_
[ARG0] )[0];
my
(
$channel
) =
$_
[ARG1]->[0];
my
(
$what
) =
$_
[ARG2];
if
(
$what
=~ /^source(?: \s* code )?\s*$/i ) {
$kernel
->post(
$sender
=>
privmsg
=>
$channel
=>
"$nick, my source can be found in "
);
}
}
sub
irc_notice {
my
(
$kernel
,
$sender
,
$who
,
$what
) =
@_
[KERNEL, SENDER, ARG0, ARG2];
if
(
$Do_NickServ
and
$who
eq
'NickServ!NickServ@services.'
) {
if
(
$what
eq
'This nickname is owned by someone else'
) {
$kernel
->post(
$sender
=>
privmsg
=>
'NickServ'
=>
'identify '
.
$NickServ_Pass
);
}
elsif
(
$what
eq
'Password accepted - you are now recognized'
) {
print
"\nIdentified with NickServ\n\n"
;
$kernel
->post(
$sender
=>
join
=>
$_
)
for
@Channels
;
$irc
->plugin_add(
'PAUSE'
=>
POE::Component::IRC::Plugin::PAUSE::RecentUploads->new(
@PAUSE_Options
)
);
}
}
undef
;
}
sub
lag_o_meter {
my
(
$kernel
,
$heap
) =
@_
[KERNEL,HEAP];
print
STDOUT
"Time: "
.
time
()
.
" Lag: "
.
$heap
->{connector}->lag() .
"\n"
;
$kernel
->delay(
'lag_o_meter'
=> 60 );
undef
;
}
sub
_default {
my
(
$event
,
$args
) =
@_
[ARG0 ..
$#_
];
my
@output
= (
"$event: "
);
foreach
my
$arg
(
@$args
) {
if
(
ref
(
$arg
) eq
'ARRAY'
) {
push
(
@output
,
"["
.
join
(
" ,"
,
@$arg
) .
"]"
);
}
else
{
push
(
@output
,
"'$arg'"
);
}
}
print
STDOUT
join
' '
,
@output
,
"\n"
;
return
0;
}
=head1 NAME
cpan_bot - an IRC CPAN Info bot
=head1 DESCRIPTION
An IRC bot to report recent uploads to PAUSE and provide
information about CPAN authors/distributions/modules.
=head1 USAGE
perl cpan_bot.pl
=head1 CONFIG
The config file is a file containing a simple hashref which the
script will C<
do
''
>
default
location the script will
look
for
is ~/.cpan_bot/config however the path can be changed
via enviromental variable C<CPAN_BOT_DIR>, thus config file
will be located at C<
"$CPAN_BOT_DIR/config"
>
The sample config file is as follows:
{
nick
=>
'CPAN2'
,
server
=>
'irc.freenode.net'
,
port
=> 6667,
ircname
=>
'CPAN bot'
,
do_nickserv
=> 1,
nickserv_pass
=>
'passo-word'
,
channels
=> [
'#zofbot'
],
PAUSE_options
=> [
store
=>
'/home/zoffix/.cpan_bot/pause.data'
,
login
=>
'ZOFFIX'
,
pass
=>
'passo-word'
,
interval
=> 600,
channels
=> [
'#zofbot'
],
],
CPANInfo_options
=> [
path
=>
'/home/zoffix/.cpan_bot/'
,
],
}
=over 10
=item nick
Bot's nickname. Note: PoCo::IRC::NickReclaim is used, thus
if
C<nick>
is taken, bot will
use
C<nick>
with
an underscore appended.
=item server
The IRC server to
connect
to.
=item port
The port of IRC server to
connect
to.
=item ircname
Whatever it is, will be passed to POE::Component::IRC constructor as
a value
for
'ircname'
=item do_nickserv
This is was developed
for
FreeNode IRC network. If set to a true value
will identify
with
services
before
joining any channels. Not tested
on any other networks, make sure to set to C<0>
if
you can't identify
or bot will not
join
anything.
=item nickserv_pass
Password to
use
for
identification
with
NickServ. Ignored
if
C<do_nickserv> is set to a false value.
=item channels
Takes an arrayref of channels to
join
.
=item PAUSE_options
Takes an I<arrayref>, this is what to pass to
L<POE::Component::IRC::Plugin::PAUSE::RecentUploads> constructor.
=item CPANInfo_options
Takes an I<arrayref>, this is what to pass to
L<POE::Component::IRC::Plugin::CPAN::Info> constructor.
=back
=head1 AUTHOR
Zoffix Znet <zoffix
@cpan
.org>
=head1 LICENSE
Same as Perl