Created
January 22, 2012 04:47
-
-
Save run4flat/1655640 to your computer and use it in GitHub Desktop.
piddlebot!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# This is a simple IRC bot that just rot13 encrypts public messages. | |
# It responds to "rot13 <text to encrypt>". | |
use warnings; | |
use strict; | |
use POE; | |
use POE::Component::IRC::State; | |
use constant CHANNEL => '#pdl'; | |
# Load the current piddlebot functions: | |
use piddlebot; | |
my $last_modified = (stat('piddlebot.pm'))[9]; | |
# Create the component that will represent an IRC network. | |
our ($irc) = POE::Component::IRC::State->spawn(); | |
our $my_nick = 'liddle_piddle_bot'; | |
# Make sure the bot gets operator status | |
use POE::Component::IRC::Plugin::CycleEmpty; | |
$irc->plugin_add('CycleEmpty', POE::Component::IRC::Plugin::CycleEmpty->new()); | |
# Create the bot session using methods in the main package, which are | |
# defined below. Note that irc_public, irc_message, and irc_join are just | |
# stubs that ensure the latest piddlebot.pm has been loaded, and then calls | |
# the latest do* response function. This way, I can make updates to the bot | |
# without having to restart it. | |
POE::Session->create( | |
package_states => [ | |
main => [ qw(_start irc_001 irc_join irc_public irc_msg) ] | |
] | |
); | |
# Run the bot! | |
$poe_kernel->run(); | |
#!!!!!!!!!!!!!! No lexicals below this point !!!!!!!!!!!!!!# | |
# The bot session has started. Register this bot with the "magnet" | |
# IRC component. Select a nickname. Connect to a server. | |
sub _start { | |
$irc->yield(register => "all"); | |
$irc->yield( | |
connect => { | |
Nick => $my_nick, | |
Server => 'irc.perl.org', | |
Port => '6667', | |
} | |
); | |
} | |
# A function that ensures that the latest piddlebot.pm is in use: | |
sub ensure_up_to_date { | |
my $latest_modified = (stat('piddlebot.pm'))[9]; | |
do 'piddlebot.pm' if $last_modified < $latest_modified; | |
} | |
# The bot has successfully connected to a server. Join a channel. | |
sub irc_001 { | |
$irc->yield(join => CHANNEL); | |
} | |
############# Modifiable Callbacks ############# | |
# The bot has received a public message. Reload the latest and | |
sub irc_public { | |
ensure_up_to_date; | |
goto &do_public_response; | |
} | |
# The bot has received a public message. Parse it for commands, and | |
# respond to interesting things. | |
sub irc_msg { | |
ensure_up_to_date; | |
goto &do_private_response; | |
} | |
sub irc_join { | |
ensure_up_to_date; | |
goto &do_join; | |
} | |
############# Response and Logging Functions ############# | |
# Save the message to the logfile: | |
sub log_it { | |
open my $logfile, '>>', 'pdl.log'; | |
my $ts = scalar localtime; | |
print $logfile " [$ts] ", @_; | |
print $logfile "\n" if (substr($_[-1], -1) ne "\n"); | |
} | |
sub say_it { | |
$irc->yield(privmsg => CHANNEL, join('', @_)); | |
log_it(@_); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
our ($irc, $my_name); | |
# Load the channel ops file: | |
open my $fh, '<', 'pdl-channel-ops.txt'; | |
my %ops; | |
while(my $line = <$fh>) { | |
chomp $line; | |
$ops{$line}++; | |
} | |
close $fh; | |
# Sub to write the verifications file out to disk: | |
sub write_out { | |
open $fh, '>', 'pdl-channel-ops.txt'; | |
foreach my $nick (keys %ops) { | |
print $fh "$nick\n"; | |
} | |
close $fh; | |
} | |
sub private_message { | |
my $nick = shift; | |
for my $line (@_) { | |
$irc->yield(privmsg => $nick, $line); | |
} | |
} | |
############# Doers ############# | |
sub do_public_response { | |
my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2]; | |
my $nick = (split /!/, $who)[0]; | |
log_it("<$nick> $msg\n"); | |
# Construct hyperlink if cpan is requested: | |
if ($msg =~ /^cpan (.+)/) { | |
say_it("http://p3rl.org/$1"); | |
} | |
# Construct a link to the docs on the web site: | |
elsif ($msg =~ /^help (.+)/) { | |
my $to_find = $1; | |
(my $location = $to_find) =~ s{::}{/}g; | |
say_it("$nick: http://pdl.perl.org/?docs=$location&title=PDL::$to_find"); | |
} | |
elsif ($msg =~ /^paste/) { | |
say_it("$nick: http://scsys.co.uk:8001/"); | |
} | |
elsif ($msg =~ /^liddle_piddle_bot.+?trust (\S+)/) { | |
my $to_op = $1; | |
chomp $to_op; | |
if ($ops{$nick}) { | |
# Op the person: | |
$irc->yield(mode => '#pdl +o', $to_op); | |
# Add the ident as a trusted nick | |
$ops{$to_op}++; | |
write_out(); | |
# Send the new user their temporary password: | |
private_message($to_op | |
, "Welcome, $to_op, to the inner sanctum. To learn more about what this means, please read" | |
, "https://github.com/PDLPorters/pdl/wiki/PDL-IRC" | |
); | |
} | |
else { | |
say_it("Silly $nick: only trusted users can tell me to trust someone"); | |
} | |
} | |
} | |
sub do_private_response { | |
my ($who, $message) = @_[ARG0, ARG2]; | |
my $nick = (split /!/, $who)[0]; | |
private_message($nick, "https://github.com/PDLPorters/pdl/wiki/PDL-IRC"); | |
} | |
sub do_join { | |
my ($who, $channel) = @_[ARG0, ARG1]; | |
my $nick = (split /!/, $who)[0]; | |
# send a cute message if we were the one joining: | |
if ($nick eq $irc->nick_name()) { | |
say_it("Hi everybody, I'm back!"); | |
} | |
# Make an op if they're recognized: | |
elsif ($ops{$nick}) { | |
$irc->yield(mode => '#pdl +o', $nick); | |
say_it("Welcome back, $nick"); | |
} | |
else { | |
say_it("Welcome, $nick"); | |
} | |
} | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment