App-Devbot
view release on metacpan or search on metacpan
lib/App/Devbot.pm view on Meta::CPAN
package App::Devbot;
use v5.14;
use strict;
use warnings;
our $VERSION = 0.001004;
use POE;
use POE::Component::IRC::State;
use POE::Component::IRC::Plugin::AutoJoin;
use POE::Component::IRC::Plugin::NickServID;
use File::Slurp qw/append_file/;
use IRC::Utils qw/parse_user/;
use Getopt::Long;
use POSIX qw/strftime/;
use Regexp::Common qw /net/;
##################################################
my $nick='devbot';
my $password;
my $server='irc.oftc.net';
my $port=6697;
my $ssl=1;
my @channels;
my $trace=0;
my $log=1;
my $store_files=0;
GetOptions (
"nick=s" => \$nick,
"password=s" => \$password,
"server=s" => \$server,
"port=i" => \$port,
"ssl!" => \$ssl,
"channel=s" => \@channels,
"log!" => \$log,
"store-files!" => \$store_files,
"trace!" => \$trace,
);
my $irc;
sub mode_char {
my ($channel, $nick)=@_;
return '~' if $irc->is_channel_owner($channel, $nick);
return '&' if $irc->is_channel_admin($channel, $nick);
return '@' if $irc->is_channel_operator($channel, $nick);
return '%' if $irc->is_channel_halfop($channel, $nick);
return '+' if $irc->has_channel_voice($channel, $nick);
return ' '
}
sub log_event{
return unless $log;
my ($channel, @strings) = @_;
my $file=strftime '%F', localtime;
mkdir 'logs';
mkdir "logs/$channel";
append_file "logs/$channel/$file.txt", strftime ('%T ', localtime), @strings, "\n";
}
sub bot_start{
$irc->plugin_add (NickServID => POE::Component::IRC::Plugin::NickServID->new(Password => $password)) if defined $password;
$irc->plugin_add (AutoJoin => POE::Component::IRC::Plugin::AutoJoin->new(
Channels => \@channels,
RejoinOnKick => 1,
Rejoin_delay => 10,
Retry_when_banned => 60,
));
$server = $1 if $server =~ /^($RE{net}{domain})$/;
$port = $1 if $port =~ /^([0-9]+)$/;
$irc->yield(register => "all");
$irc->yield(
connect => {
Nick => $nick,
Username => 'devbot',
Ircname => "devbot $VERSION",
Server => $server,
Port => $port,
UseSSL => $ssl,
}
);
}
sub on_public{
my ($fulluser, $channels, $message)=@_[ARG0, ARG1, ARG2];
my $nick=parse_user $fulluser;
for (@$channels) {
my $mode_char=mode_char $_, $nick;
log_event $_, "<$mode_char$nick> $message";
}
}
sub on_ctcp_action{
my ($fulluser, $channels, $message)=@_[ARG0, ARG1, ARG2];
my $nick=parse_user $fulluser;
log_event $_, "* $nick $message" for @$channels;
}
sub on_join{
my ($fulluser, $channel)=@_[ARG0, ARG1];
my ($nick, $user, $host)=parse_user $fulluser;
log_event $channel, "-!- $nick [$user\@$host] has joined $channel";
}
sub on_part{
my ($fulluser, $channel, $message)=@_[ARG0, ARG1, ARG2];
my ($nick, $user, $host)=parse_user $fulluser;
log_event $channel, "-!- $nick [$user\@$host] has left $channel [$message]";
}
sub on_kick{
my ($fulluser, $channel, $target, $message)=@_[ARG0, ARG1, ARG2, ARG3];
my $nick=parse_user $fulluser;
log_event $channel, "-!- $target was kicked from $channel by $nick [$message]";
}
lib/App/Devbot.pm view on Meta::CPAN
return unless $type eq 'SEND';
return unless $irc->nick_channels($nick);
return if $name =~ m,/,;
mkdir 'files';
$irc->yield(dcc_accept => $cookie, "files/$name");
}
sub run{
$irc=POE::Component::IRC::State->spawn();
POE::Session->create(
inline_states => {
_start => \&bot_start,
irc_public => \&on_public,
irc_ctcp_action => \&on_ctcp_action,
irc_join => \&on_join,
irc_part => \&on_part,
irc_kick => \&on_kick,
irc_mode => \&on_mode,
irc_topic => \&on_topic,
irc_nick => \&on_nick,
irc_quit => \&on_quit,
irc_dcc_request => \&on_dcc_request
},
options => {
trace => $trace
}
);
$poe_kernel->run();
}
1;
__END__
=head1 NAME
App::Devbot - IRC bot which helps development
=head1 SYNOPSIS
use App::Devbot;
App::Devbot->run;
=head1 DESCRIPTION
App::Devbot is an IRC bot which helps developers collaborate.
Right now, it only does channel logging and file storage. It might do more in the future.
=head1 OPTIONS
=over
=item B<--nick> I<nickname>
The nickname of devbot. Defaults to devbot.
=item B<--password> I<password>
If supplied, identify to NickServ with this password
=item B<--server> I<hostname>
The server to connect to. Defaults to irc.oftc.net.
=item B<--port> I<port>
The port to connect to. Defaults to 6697.
=item B<--ssl>, B<--no-ssl>
B<--ssl> enables connecting to the server with SSL, B<--no-ssl> disables this. Defaults to B<--ssl>.
=item B<--channel> I<channel>
Makes devbot connect to I<channel>. Can be supplied multiple times for multiple channels. Has no default value.
=item B<--log>, B<--no-log>
B<--log> enables logging events to 'logs/I<CHANNEL>/I<DATE>.txt'. B<--no-log> disables logging. Defaults to B<--log>.
=item B<--store-files>, B<--no-store-files>
B<--store-files> enables storing files received via DCC to 'files/I<FILENAME>'. Files are only accepted if the sender and devbot share a channel. B<Only use when all channel users are trusted>. B<--no-store-files> disables storing files. Defaults to ...
=item B<--trace>, B<--no-trace>
B<--trace> enables POE::Component::IRC::State tracing. Useful for debugging. B<--no-trace> disables tracing. Defaults to B<--no-trace>.
=back
=head1 CAVEATS
As stated above, the B<--store-files> option should only be used on private channels where every user is trusted.
=head1 AUTHOR
Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by Marius Gavrilescu
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
( run in 0.732 second using v1.01-cache-2.11-cpan-e1769b4cff6 )