diff --git a/PBot/AntiFlood.pm b/PBot/AntiFlood.pm index 507dc55c..e3e6b2c1 100644 --- a/PBot/AntiFlood.pm +++ b/PBot/AntiFlood.pm @@ -1,5 +1,4 @@ # File: AntiFlood.pm -# Author: pragma_ # # Purpose: Tracks message and nickserv statistics to enforce anti-flooding and # ban-evasion detection. @@ -14,12 +13,7 @@ package PBot::AntiFlood; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use Time::HiRes qw(gettimeofday tv_interval); use Time::Duration; diff --git a/PBot/AntiSpam.pm b/PBot/AntiSpam.pm index 4027c802..3497ea66 100644 --- a/PBot/AntiSpam.pm +++ b/PBot/AntiSpam.pm @@ -1,5 +1,4 @@ # File: AntiSpam.pm -# Author: pragma_ # # Purpose: Checks if a message is spam @@ -10,12 +9,7 @@ package PBot::AntiSpam; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use Time::HiRes qw(gettimeofday); use POSIX qw/strftime/; diff --git a/PBot/BanList.pm b/PBot/BanList.pm index 5e0abad2..b0325ab2 100644 --- a/PBot/BanList.pm +++ b/PBot/BanList.pm @@ -1,5 +1,4 @@ # File: BanList.pm -# Author: pragma_ # # Purpose: Populates and maintains channel banlists by checking mode +b/+q on # joining channels and by tracking modes +b/+q and -b/-q in channels. Keeps @@ -13,17 +12,12 @@ package PBot::BanList; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::HiRes qw/gettimeofday/; use Time::Duration; -use Data::Dumper; use POSIX qw/strftime/; -$Data::Dumper::Sortkeys = 1; - sub initialize { my ($self, %conf) = @_; diff --git a/PBot/BlackList.pm b/PBot/BlackList.pm index 52ec67f2..697d7f92 100644 --- a/PBot/BlackList.pm +++ b/PBot/BlackList.pm @@ -1,5 +1,4 @@ # File: BlackList.pm -# Author: pragma_ # # Purpose: Manages list of hostmasks that are not allowed to join a channel. @@ -10,12 +9,7 @@ package PBot::BlackList; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use Time::HiRes qw(gettimeofday); diff --git a/PBot/Capabilities.pm b/PBot/Capabilities.pm index dbfdd785..c645504a 100644 --- a/PBot/Capabilities.pm +++ b/PBot/Capabilities.pm @@ -1,3 +1,7 @@ +# File: Capabilites.pm +# +# Purpose: Fine-grained user permissions. + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -5,16 +9,7 @@ package PBot::Capabilities; use parent 'PBot::Class'; -# purpose: provides interface to set/remove/modify/query user capabilities. -# -# Examples: See doc/Admin.md for examples. - -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/PBot/ChanOpCommands.pm b/PBot/ChanOpCommands.pm index 7d19bbb2..7ca04626 100644 --- a/PBot/ChanOpCommands.pm +++ b/PBot/ChanOpCommands.pm @@ -1,5 +1,4 @@ # File: ChanOpCommands.pm -# Author: pragma_ # # Purpose: Channel operator command subroutines. @@ -8,12 +7,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::ChanOpCommands; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::Duration; use Time::HiRes qw/gettimeofday/; diff --git a/PBot/ChanOps.pm b/PBot/ChanOps.pm index 5e221aa3..3d94fb3f 100644 --- a/PBot/ChanOps.pm +++ b/PBot/ChanOps.pm @@ -1,5 +1,4 @@ # File: ChanOps.pm -# Author: pragma_ # # Purpose: Provides channel operator status tracking and commands. @@ -8,14 +7,12 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::ChanOps; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use PBot::ChanOpCommands; + use Time::HiRes qw(gettimeofday); use Time::Duration qw(concise duration); diff --git a/PBot/Channels.pm b/PBot/Channels.pm index 98c5b6f9..71fd1d05 100644 --- a/PBot/Channels.pm +++ b/PBot/Channels.pm @@ -1,5 +1,4 @@ # File: Channels.pm -# Author: pragma_ # # Purpose: Manages list of channels and auto-joins. @@ -10,9 +9,7 @@ package PBot::Channels; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/PBot/Class.pm b/PBot/Class.pm index edf9c901..3fa97609 100644 --- a/PBot/Class.pm +++ b/PBot/Class.pm @@ -1,34 +1,33 @@ +# File: Class.pm +# +# Purpose: Base class for PBot classes. This prevents each PBot class from +# needing to define the new() constructor and other boilerplate. +# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::Class; -# purpose: base class for all PBot classes -# -# This prevents each PBot class from needing to define the new() subroutine -# and such boilerplate. - -use warnings; -use strict; - -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; sub new { - my ($proto, %conf) = @_; - my $class = ref($proto) || $proto; + my ($class, %args) = @_; + my $self = bless {}, $class; - if (not exists $conf{pbot}) { + # ensure class was passed a PBot instance + if (not exists $args{pbot}) { my ($package, $filename, $line) = caller(0); my (undef, undef, undef, $subroutine) = caller(1); Carp::croak("Missing pbot reference to " . $class . ", created by $subroutine at $filename:$line"); } - $self->{pbot} = $conf{pbot}; + $self->{pbot} = $args{pbot}; + $self->{pbot}->{logger}->log("Initializing $class\n"); - $self->initialize(%conf); + $self->initialize(%args); + return $self; } diff --git a/PBot/Commands.pm b/PBot/Commands.pm index 300f6abe..2d0c5e0b 100644 --- a/PBot/Commands.pm +++ b/PBot/Commands.pm @@ -1,7 +1,5 @@ # File: Commands.pm # -# Author: pragma_ -# # Purpose: Registers commands. Invokes commands with user capability # validation. @@ -12,9 +10,7 @@ package PBot::Commands; use parent 'PBot::Class', 'PBot::Registerable'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::Duration qw/duration/; diff --git a/PBot/DualIndexHashObject.pm b/PBot/DualIndexHashObject.pm index 763c018d..29d381dc 100644 --- a/PBot/DualIndexHashObject.pm +++ b/PBot/DualIndexHashObject.pm @@ -1,11 +1,11 @@ # File: DualIndexHashObject.pm -# Author: pragma_ # # Purpose: Provides a hash-table object with an abstracted API that includes -# setting and deleting values, saving to and loading from files, etc. This -# extends the HashObject with an additional index key. Provides case-insensitive -# access to both index keys, while preserving original case when displaying the -# keys. +# setting and deleting values, saving to and loading from files, etc. +# +# DualIndexHashObject extends the HashObject with an additional index key. +# Provides case-insensitive access to both index keys, while preserving +# original case when displaying the keys. # # Data is stored in working memory for lightning fast performance. If you have # a huge amount of data, consider DualIndexSQLiteObject instead. @@ -16,29 +16,26 @@ package PBot::DualIndexHashObject; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Text::Levenshtein qw(fastdistance); use JSON; sub new { - my ($proto, %conf) = @_; - my $class = ref($proto) || $proto; - my $self = bless {}, $class; - Carp::croak("Missing pbot reference to " . __FILE__) unless exists $conf{pbot}; - $self->{pbot} = $conf{pbot}; - $self->initialize(%conf); + my ($class, %args) = @_; + my $self = bless {}, $class; + Carp::croak("Missing pbot reference to " . __FILE__) unless exists $args{pbot}; + $self->{pbot} = delete $args{pbot}; + $self->initialize(%args); return $self; } sub initialize { my ($self, %conf) = @_; - $self->{name} = $conf{name} // 'Dual Index hash object'; + $self->{name} = $conf{name} // 'unnamed'; $self->{filename} = $conf{filename} // Carp::carp("Missing filename to DualIndexHashObject, will not be able to save to or load from file."); $self->{save_queue_timeout} = $conf{save_queue_timeout} // 0; - $self->{hash} = {}; + $self->{hash} = {}; } sub load { diff --git a/PBot/DualIndexSQLiteObject.pm b/PBot/DualIndexSQLiteObject.pm index dc566191..0118dde2 100644 --- a/PBot/DualIndexSQLiteObject.pm +++ b/PBot/DualIndexSQLiteObject.pm @@ -1,5 +1,4 @@ # File: DualIndexSQLiteObject.pm -# Author: pragma_ # # Purpose: Provides a dual-indexed SQLite object with an abstracted API that includes # setting and deleting values, caching, displaying nearest matches, etc. Designed to @@ -11,20 +10,17 @@ package PBot::DualIndexSQLiteObject; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use DBI; use Text::Levenshtein qw(fastdistance); sub new { - my ($proto, %conf) = @_; - my $class = ref($proto) || $proto; - my $self = bless {}, $class; - Carp::croak("Missing pbot reference to " . __FILE__) unless exists $conf{pbot}; - $self->{pbot} = $conf{pbot}; - $self->initialize(%conf); + my ($class, %args) = @_; + my $self = bless {}, $class; + Carp::croak("Missing pbot reference to " . __FILE__) unless exists $args{pbot}; + $self->{pbot} = delete $args{pbot}; + $self->initialize(%args); return $self; } diff --git a/PBot/EventDispatcher.pm b/PBot/EventDispatcher.pm index 57f3920e..ae908f73 100644 --- a/PBot/EventDispatcher.pm +++ b/PBot/EventDispatcher.pm @@ -1,3 +1,7 @@ +# File: EventDispatcher.pm +# +# Purpose: Registers event handlers and dispatches events to them. + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -5,11 +9,7 @@ package PBot::EventDispatcher; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; - -use IO::Select; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/PBot/FactoidCommands.pm b/PBot/FactoidCommands.pm index 1945c3c6..5ca479d8 100644 --- a/PBot/FactoidCommands.pm +++ b/PBot/FactoidCommands.pm @@ -1,5 +1,4 @@ # File: FactoidCommands.pm -# Author: pragma_ # # Purpose: Factoid command subroutines. @@ -8,12 +7,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::FactoidCommands; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::Duration; use Time::HiRes qw(gettimeofday); diff --git a/PBot/Factoids.pm b/PBot/Factoids.pm index d8818829..8d3fa95b 100644 --- a/PBot/Factoids.pm +++ b/PBot/Factoids.pm @@ -1,7 +1,6 @@ # File: Factoids.pm -# Author: pragma_ # -# Purpose: Provides functionality for factoids and a type of external module execution. +# Purpose: Provides functionality for factoids. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,12 +9,7 @@ package PBot::Factoids; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use HTML::Entities; use Time::HiRes qw(gettimeofday); diff --git a/PBot/Functions.pm b/PBot/Functions.pm index 87a51368..963d9469 100644 --- a/PBot/Functions.pm +++ b/PBot/Functions.pm @@ -1,6 +1,4 @@ - # File: Functions.pm -# Author: pragma_ # # Purpose: Special `func` command that executes built-in functions with # optional arguments. Usage: func [arguments]. @@ -22,9 +20,7 @@ package PBot::Functions; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/PBot/HashObject.pm b/PBot/HashObject.pm index 624cf019..d2ee3ed1 100644 --- a/PBot/HashObject.pm +++ b/PBot/HashObject.pm @@ -1,5 +1,4 @@ # File: HashObject.pm -# Author: pragma_ # # Purpose: Provides a hash-table object with an abstracted API that includes # setting and deleting values, saving to and loading from files, etc. Provides @@ -12,38 +11,39 @@ package PBot::HashObject; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Text::Levenshtein qw(fastdistance); use JSON; sub new { - my ($proto, %conf) = @_; - my $class = ref($proto) || $proto; + my ($class, %args) = @_; my $self = bless {}, $class; - Carp::croak("Missing pbot reference to " . __FILE__) unless exists $conf{pbot}; - $self->{pbot} = $conf{pbot}; - $self->initialize(%conf); + Carp::croak("Missing pbot reference to " . __FILE__) unless exists $args{pbot}; + $self->{pbot} = delete $args{pbot}; + $self->initialize(%args); return $self; } sub initialize { my ($self, %conf) = @_; - $self->{name} = $conf{name} // 'hash object'; - $self->{filename} = $conf{filename} // Carp::carp("Missing filename to HashObject, will not be able to save to or load from file."); + + $self->{name} = $conf{name} // 'unnammed'; $self->{hash} = {}; + $self->{filename} = $conf{filename}; + + if (not defined $self->{filename}) { + Carp::carp("Missing filename for $self->{name} HashObject, will not be able to save to or load from file."); + } } sub load { - my $self = shift; - my $filename; - if (@_) { $filename = shift; } - else { $filename = $self->{filename}; } + my ($self, $filename) = @_; - $self->clear; + # allow overriding $self->{filename} with $filename parameter + $filename //= $self->{filename}; + # no filename? nothing to load if (not defined $filename) { Carp::carp "No $self->{name} filename specified -- skipping loading from file"; return; @@ -56,37 +56,55 @@ sub load { return; } + # slurp file into $contents my $contents = do { local $/; ; }; - $self->{hash} = decode_json $contents; close FILE; - # update existing entries to use _name to preserve case - # and lowercase any non-lowercased entries - foreach my $index (keys %{$self->{hash}}) { - if (not exists $self->{hash}->{$index}->{_name}) { - if ($index ne lc $index) { - if (exists $self->{hash}->{lc $index}) { - Carp::croak "Cannot update $self->{name} object $index; duplicate object found"; - } + eval { + # first try to deocde json, throws exception on misparse/errors + my $newhash = decode_json $contents; - my $data = delete $self->{hash}->{$index}; - $data->{_name} = $index; - $self->{hash}->{lc $index} = $data; + # clear current hash only if decode succeeded + $self->clear; + + # update internal hash + $self->{hash} = $newhash; + + # update existing entries to use _name to preserve typographical casing + # e.g., when someone edits a config file by hand, they might add an + # entry with uppercase characters in its name. + foreach my $index (keys %{$self->{hash}}) { + if (not exists $self->{hash}->{$index}->{_name}) { + if ($index ne lc $index) { + if (exists $self->{hash}->{lc $index}) { + Carp::croak "Cannot update $self->{name} object $index; duplicate object found"; + } + + my $data = delete $self->{hash}->{$index}; + $data->{_name} = $index; # _name is original typographical case + $self->{hash}->{lc $index} = $data; # index key is lowercased + } } } + }; + + if ($@) { + # json parse error or such + $self->{pbot}->{logger}->log("Warning: failed to load $filename: $@\n"); } } sub save { - my $self = shift; - my $filename; - if (@_) { $filename = shift; } - else { $filename = $self->{filename}; } + my ($self, $filename) = @_; + # allow parameter overriding internal field + $filename //= $self->{filename}; + + # no filename? nothing to save if (not defined $filename) { Carp::carp "No $self->{name} filename specified -- skipping saving to file.\n"; return; @@ -94,42 +112,53 @@ sub save { $self->{pbot}->{logger}->log("Saving $self->{name} to $filename\n"); + # add update_version to metadata if (not $self->get_data('$metadata$', 'update_version')) { $self->add('$metadata$', { update_version => PBot::VERSION::BUILD_REVISION }); } + # ensure `name` metadata is current $self->set('$metadata$', 'name', $self->{name}, 1); + # encode hash as JSON my $json = JSON->new; my $json_text = $json->pretty->canonical->utf8->encode($self->{hash}); + # print JSON to file open(FILE, "> $filename") or die "Couldn't open $filename: $!\n"; print FILE "$json_text\n"; close(FILE); } sub clear { - my $self = shift; + my ($self) = @_; $self->{hash} = {}; } sub levenshtein_matches { my ($self, $keyword) = @_; - my $comma = ''; - my $result = ""; + + my @matches; foreach my $index (sort keys %{$self->{hash}}) { my $distance = fastdistance($keyword, $index); - my $length = (length $keyword > length $index) ? length $keyword : length $index; + + my $length_a = length $keyword; + my $length_b = length $index; + my $length = $length_a > $length_b ? $length_a : $length_b; if ($length != 0 && $distance / $length < 0.50) { - $result .= $comma . $index; - $comma = ", "; + push @matches, $index; } } + return 'none' if not @matches; + + my $result = join ', ', @matches; + + # "a, b, c, d" -> "a, b, c or d" $result =~ s/(.*), /$1 or /; - $result = "none" if $comma eq ''; + return $result; } @@ -137,29 +166,41 @@ sub set { my ($self, $index, $key, $value, $dont_save) = @_; my $lc_index = lc $index; + # find similarly named keys if (not exists $self->{hash}->{$lc_index}) { - my $result = "$self->{name}: $index not found; similiar matches: "; + my $result = "$self->{name}: $index not found; similar matches: "; $result .= $self->levenshtein_matches($index); return $result; } if (not defined $key) { + # if no key provided, then list all keys and values my $result = "[$self->{name}] " . $self->get_key_name($lc_index) . " keys: "; - my $comma = ''; - foreach my $k (sort grep { $_ ne '_name' } keys %{$self->{hash}->{$lc_index}}) { - $result .= $comma . "$k: " . $self->{hash}->{$lc_index}->{$k}; - $comma = ";\n"; + + my @entries; + + foreach my $key (sort grep { $_ ne '_name' } keys %{$self->{hash}->{$lc_index}}) { + push @entries, "$key: $self->{hash}->{$lc_index}->{$key}"; } - $result .= "none" if ($comma eq ''); + + if (@entries) { + $result .= join ";\n", @entries; + } else { + $result .= 'none'; + } + return $result; } if (not defined $value) { + # if no value provided, then show this key's value $value = $self->{hash}->{$lc_index}->{$key}; } else { + # otherwise update the value belonging to key $self->{hash}->{$lc_index}->{$key} = $value; $self->save unless $dont_save; } + return "[$self->{name}] " . $self->get_key_name($lc_index) . ": $key " . (defined $value ? "set to $value" : "is not set."); } @@ -168,7 +209,7 @@ sub unset { my $lc_index = lc $index; if (not exists $self->{hash}->{$lc_index}) { - my $result = "$self->{name}: $index not found; similiar matches: "; + my $result = "$self->{name}: $index not found; similar matches: "; $result .= $self->levenshtein_matches($index); return $result; } @@ -227,7 +268,7 @@ sub remove { my $lc_index = lc $index; if (not exists $self->{hash}->{$lc_index}) { - my $result = "$self->{name}: $index not found; similiar matches: "; + my $result = "$self->{name}: $index not found; similar matches: "; $result .= $self->levenshtein_matches($lc_index); return $result; } diff --git a/PBot/IRC.pm b/PBot/IRC.pm index 0894850d..6651e232 100644 --- a/PBot/IRC.pm +++ b/PBot/IRC.pm @@ -22,8 +22,7 @@ use PBot::IRC::EventQueue; # pragma_ 2011/01/21 use IO::Select; use Carp; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; # grab the drop-in replacement for time() from Time::HiRes, if it's available BEGIN { Time::HiRes->import('time') if eval "require Time::HiRes"; } diff --git a/PBot/IRCHandlers.pm b/PBot/IRCHandlers.pm index 3437baf1..a82c7c91 100644 --- a/PBot/IRCHandlers.pm +++ b/PBot/IRCHandlers.pm @@ -1,5 +1,4 @@ # File: IRCHandlers.pm -# Author: pragma_ # # Purpose: Subroutines to handle IRC events @@ -8,12 +7,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::IRCHandlers; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::HiRes qw(gettimeofday); use Data::Dumper; diff --git a/PBot/IgnoreList.pm b/PBot/IgnoreList.pm index 218e4d7c..4e0befe7 100644 --- a/PBot/IgnoreList.pm +++ b/PBot/IgnoreList.pm @@ -1,5 +1,4 @@ # File: IgnoreList.pm -# Author: pragma_ # # Purpose: Manages ignore list. @@ -10,9 +9,7 @@ package PBot::IgnoreList; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::Duration qw/concise duration/; diff --git a/PBot/Imports.pm b/PBot/Imports.pm new file mode 100644 index 00000000..473913b7 --- /dev/null +++ b/PBot/Imports.pm @@ -0,0 +1,35 @@ +# File: Imports.pm +# +# Purpose: Boilerplate imports for PBot packages. + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package PBot::Imports; + +use Import::Into; + +sub import { + my $target = caller; + + # use strict + strict->import::into($target); + + # use warnings + warnings->import::into($target); + + # use feature ':5.16' + feature->import::into($target, ':5.16'); + + # use utf8 + utf8->import::into($target); + + # no if $] >= 5.018, warnings => 'experimental'; + warnings->unimport::out_of($target, 'experimental') if $] >= 5.018 +} + +sub unimport { +} + +1; diff --git a/PBot/Interpreter.pm b/PBot/Interpreter.pm index 717d8dcc..f844bb66 100644 --- a/PBot/Interpreter.pm +++ b/PBot/Interpreter.pm @@ -1,5 +1,4 @@ # File: Interpreter.pm -# Author: pragma_ # # Purpose: Main entry point to parse and interpret a string into bot # commands and dispatch the commands to registered interpreters. @@ -12,12 +11,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::Interpreter; - use parent 'PBot::Class', 'PBot::Registerable'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::HiRes qw/gettimeofday/; use Time::Duration; diff --git a/PBot/LagChecker.pm b/PBot/LagChecker.pm index 1ed70b76..3ec4a992 100644 --- a/PBot/LagChecker.pm +++ b/PBot/LagChecker.pm @@ -1,5 +1,4 @@ # File: LagChecker.pm -# Author: pragma_ # # Purpose: sends PING command to IRC server and times duration for PONG reply in # order to maintain lag history and average. @@ -9,12 +8,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::LagChecker; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::HiRes qw(gettimeofday tv_interval); use Time::Duration; diff --git a/PBot/Logger.pm b/PBot/Logger.pm index b1c72cd7..9a296c3b 100644 --- a/PBot/Logger.pm +++ b/PBot/Logger.pm @@ -1,25 +1,26 @@ +# File: Logger.pm +# +# Purpose: Logs text to file and STDOUT. + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::Logger; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Scalar::Util qw/openhandle/; use File::Basename; use File::Copy; sub new { - my ($proto, %conf) = @_; - my $class = ref($proto) || $proto; - my $self = bless {}, $class; - Carp::croak("Missing pbot reference to " . __FILE__) unless exists $conf{pbot}; - $self->{pbot} = $conf{pbot}; + my ($class, %args) = @_; + my $self = bless {}, $class; + Carp::croak("Missing pbot reference to " . __FILE__) unless exists $args{pbot}; + $self->{pbot} = delete $args{pbot}; print "Initializing " . __PACKAGE__ . "\n" unless $self->{pbot}->{overrides}->{'general.daemon'}; - $self->initialize(%conf); + $self->initialize(%args); return $self; } diff --git a/PBot/MessageHistory.pm b/PBot/MessageHistory.pm index 7fabee96..4927423b 100644 --- a/PBot/MessageHistory.pm +++ b/PBot/MessageHistory.pm @@ -1,5 +1,4 @@ # File: MessageHistory.pm -# Author: pragma_ # # Purpose: Keeps track of who has said what and when, as well as their # nickserv accounts and alter-hostmasks. @@ -12,12 +11,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::MessageHistory; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Getopt::Long qw(GetOptionsFromArray); use Time::HiRes qw(gettimeofday tv_interval); diff --git a/PBot/MessageHistory_SQLite.pm b/PBot/MessageHistory_SQLite.pm index 9f105cda..6b919a5a 100644 --- a/PBot/MessageHistory_SQLite.pm +++ b/PBot/MessageHistory_SQLite.pm @@ -1,19 +1,19 @@ # File: MessageHistory_SQLite.pm -# Author: pragma_ # -# Purpose: SQLite backend for storing/retreiving a user's message history +# Purpose: SQLite backend for storing/retreiving a user's message history. +# Peforms intelligent hostmask and nickserv heuristics to link nicknames +# in order to ensure message history is stored in the right user account +# ids. This is also extremely useful for detecting ban-evasions and listing +# also-known-as data for a nickname (see the !aka bot command). # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::MessageHistory_SQLite; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use DBI; use Carp qw(shortmess); diff --git a/PBot/MiscCommands.pm b/PBot/MiscCommands.pm index 978157a0..0e376792 100644 --- a/PBot/MiscCommands.pm +++ b/PBot/MiscCommands.pm @@ -1,8 +1,7 @@ # File: MiscCommands.pm # -# Author: pragma_ -# -# Purpose: Registers misc PBot commands. +# Purpose: Registers misc PBot commands that don't really belong in any +# other file. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -11,9 +10,7 @@ package PBot::MiscCommands; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::Duration qw/duration/; diff --git a/PBot/Modules.pm b/PBot/Modules.pm index 5e6bcfae..e37a49f2 100644 --- a/PBot/Modules.pm +++ b/PBot/Modules.pm @@ -1,6 +1,5 @@ # File: Modules.pm -# Author: pragma_ - +# # Purpose: Modules are command-line programs and scripts that can be loaded # via PBot factoids. Command arguments are passed as command-line arguments. # The standard output from the script is returned as the bot command result. @@ -12,12 +11,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::Modules; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use IPC::Run qw/run timeout/; use Encode; diff --git a/PBot/NickList.pm b/PBot/NickList.pm index c22130ed..e6e6db8a 100644 --- a/PBot/NickList.pm +++ b/PBot/NickList.pm @@ -1,5 +1,4 @@ # File: NickList.pm -# Author: pragma_ # # Purpose: Maintains lists of nicks currently present in channels. # Used to retrieve list of channels a nick is present in or to @@ -10,12 +9,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::NickList; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Text::Levenshtein qw/fastdistance/; use Data::Dumper; diff --git a/PBot/PBot.pm b/PBot/PBot.pm index 91d5a55e..c5dd0a70 100644 --- a/PBot/PBot.pm +++ b/PBot/PBot.pm @@ -1,5 +1,4 @@ # File: PBot.pm -# Author: pragma_ # # Purpose: IRC Bot # @@ -22,9 +21,7 @@ package PBot::PBot; -use strict; use warnings; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Carp (); use PBot::Logger; @@ -76,10 +73,9 @@ use Encode; @ARGV = map { decode('UTF-8', $_, 1) } @ARGV; sub new { - my ($proto, %conf) = @_; - my $class = ref($proto) || $proto; - my $self = bless {}, $class; - $self->initialize(%conf); + my ($class, %args) = @_; + my $self = bless {}, $class; + $self->initialize(%args); return $self; } diff --git a/PBot/Plugins.pm b/PBot/Plugins.pm index c10342e3..0b2c0fb0 100644 --- a/PBot/Plugins.pm +++ b/PBot/Plugins.pm @@ -1,7 +1,6 @@ # File: Plugins.pm -# Author: pragma- # -# Purpose: Loads and manages plugins. +# Purpose: Loads and manages external plugins. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,9 +9,7 @@ package PBot::Plugins; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use File::Basename; diff --git a/PBot/ProcessManager.pm b/PBot/ProcessManager.pm index 3656aac3..8d2acc62 100644 --- a/PBot/ProcessManager.pm +++ b/PBot/ProcessManager.pm @@ -1,19 +1,16 @@ # File: ProcessManager.pm -# Author: pragma_ # -# Purpose: Handles forking and execution of module/subroutine processes +# Purpose: Handles forking and execution of module/subroutine processes. +# Provides commands to list running processes and to kill them. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::ProcessManager; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::Duration qw/concise duration/; use Time::HiRes qw/gettimeofday/; diff --git a/PBot/Refresher.pm b/PBot/Refresher.pm index 2dfdd379..6b2cf3f6 100644 --- a/PBot/Refresher.pm +++ b/PBot/Refresher.pm @@ -1,5 +1,4 @@ # File: Refresher.pm -# Author: pragma_ # # Purpose: Refreshes/reloads module subroutines. Does not refresh/reload # module member data, only subroutines. TODO: reinitialize modules in order @@ -12,17 +11,17 @@ package PBot::Refresher; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Module::Refresh; use File::Basename; sub initialize { my ($self, %conf) = @_; - $self->{refresher} = Module::Refresh->new; + $self->{pbot}->{commands}->register(sub { $self->cmd_refresh(@_) }, "refresh", 1); + + $self->{refresher} = Module::Refresh->new; } sub cmd_refresh { diff --git a/PBot/Registerable.pm b/PBot/Registerable.pm index 258ed6d6..4b7f5fe5 100644 --- a/PBot/Registerable.pm +++ b/PBot/Registerable.pm @@ -1,5 +1,4 @@ # File: Registerable.pm -# Author: pragma_ # # Purpose: Provides functionality to register and execute one or more subroutines. @@ -9,17 +8,14 @@ package PBot::Registerable; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; sub new { - my ($proto, %conf) = @_; - my $class = ref($proto) || $proto; + my ($class, %args) = @_; my $self = bless {}, $class; - Carp::croak("Missing pbot reference to " . __FILE__) unless exists $conf{pbot}; - $self->{pbot} = $conf{pbot}; - $self->initialize(%conf); + Carp::croak("Missing pbot reference to " . __FILE__) unless exists $args{pbot}; + $self->{pbot} = delete $args{pbot}; + $self->initialize(%args); return $self; } diff --git a/PBot/Registry.pm b/PBot/Registry.pm index b72f3259..b1eea706 100644 --- a/PBot/Registry.pm +++ b/PBot/Registry.pm @@ -1,5 +1,4 @@ # File: Registry.pm -# Author: pragma_ # # Purpose: Provides a centralized registry of configuration settings that can # easily be examined and updated via getters and setters. @@ -9,12 +8,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::Registry; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::HiRes qw(gettimeofday); use PBot::RegistryCommands; diff --git a/PBot/RegistryCommands.pm b/PBot/RegistryCommands.pm index 71594f19..66acacc0 100644 --- a/PBot/RegistryCommands.pm +++ b/PBot/RegistryCommands.pm @@ -1,5 +1,4 @@ # File: RegistryCommands.pm -# Author: pragma_ # # Purpose: Bot commands to manipulate Registry entries. @@ -10,9 +9,7 @@ package PBot::RegistryCommands; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/PBot/SQLiteLogger.pm b/PBot/SQLiteLogger.pm index 67aa0140..23385128 100644 --- a/PBot/SQLiteLogger.pm +++ b/PBot/SQLiteLogger.pm @@ -1,5 +1,4 @@ # File: SQLiteLogger -# Author: pragma_ # # Purpose: Logs SQLite trace messages to Logger.pm with profiling of elapsed # time between messages. @@ -10,23 +9,25 @@ package PBot::SQLiteLogger; -use strict; use warnings; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::HiRes qw(gettimeofday); sub new { - my ($class, %conf) = @_; - my $self = {}; - $self->{buf} = ''; - $self->{timestamp} = gettimeofday; - $self->{pbot} = $conf{pbot}; + my ($class, %args) = @_; + + my $self = { + pbot => $args{pbot}, + buf => '', + timestamp => scalar gettimeofday, + }; + return bless $self, $class; } sub log { my $self = shift; + $self->{buf} .= shift; # DBI feeds us pieces at a time, so accumulate a complete line @@ -38,17 +39,26 @@ sub log { } sub log_message { - my $self = shift; + my ($self) = @_; + my $now = gettimeofday; my $elapsed = $now - $self->{timestamp}; + + # log SQL statements that take more than 100ms since the last log if ($elapsed >= 0.100) { $self->{pbot}->{logger}->log("^^^ SLOW SQL ^^^\n"); } + + # log SQL statement and elapsed duration since last statement $elapsed = sprintf '%10.3f', $elapsed; $self->{pbot}->{logger}->log("$elapsed : $self->{buf}"); + + # update timestamp $self->{timestamp} = $now; } sub close { - my $self = shift; + my ($self) = @_; + + # log anything left in buf when closing if ($self->{buf}) { $self->log_message; $self->{buf} = ''; diff --git a/PBot/SQLiteLoggerLayer.pm b/PBot/SQLiteLoggerLayer.pm index 1cad17bc..fbfba180 100644 --- a/PBot/SQLiteLoggerLayer.pm +++ b/PBot/SQLiteLoggerLayer.pm @@ -1,7 +1,6 @@ # File: SQLiteLoggerLayer -# Author: pragma_ # -# Purpose: PerlIO::via layer to log DBI trace messages +# Purpose: PerlIO::via layer to log DBI trace messages. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,11 +8,7 @@ package PBot::SQLiteLoggerLayer; -use strict; -use warnings; - -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; sub PUSHED { my ($class, $mode, $fh) = @_; @@ -23,20 +18,18 @@ sub PUSHED { sub OPEN { my ($self, $path, $mode, $fh) = @_; - - # $path is our logger object - $$self = $path; + $$self = $path; # path is our PBot::Logger object return 1; } sub WRITE { my ($self, $buf, $fh) = @_; - $$self->log($buf); + $$self->log($buf); # log message return length($buf); } sub CLOSE { - my $self = shift; + my ($self) = @_; $$self->close(); return 0; } diff --git a/PBot/SelectHandler.pm b/PBot/SelectHandler.pm index 63dedd74..59bd5867 100644 --- a/PBot/SelectHandler.pm +++ b/PBot/SelectHandler.pm @@ -1,3 +1,7 @@ +# File: SelectHandler.pm +# +# Purpose: Invokes select() system call and handles its events. + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -5,9 +9,7 @@ package PBot::SelectHandler; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use IO::Select; diff --git a/PBot/StdinReader.pm b/PBot/StdinReader.pm index cc2a7f10..20c2eb2f 100644 --- a/PBot/StdinReader.pm +++ b/PBot/StdinReader.pm @@ -1,3 +1,7 @@ +# File: StdinReader.pm +# +# Purpose: Reads input from STDIN. + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -5,9 +9,7 @@ package PBot::StdinReader; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use POSIX qw(tcgetpgrp getpgrp); # to check whether process is in background or foreground diff --git a/PBot/Timer.pm b/PBot/Timer.pm index a7c3779b..d9d7cbdb 100644 --- a/PBot/Timer.pm +++ b/PBot/Timer.pm @@ -1,5 +1,4 @@ # File: Timer.pm -# Author: pragma_ # # Purpose: Provides functionality to register subroutines/events to be invoked # at a future time, optionally recurring. @@ -19,9 +18,7 @@ package PBot::Timer; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::Duration qw/concise duration/; diff --git a/PBot/Updater.pm b/PBot/Updater.pm index 2e4d16a9..5f0a38e1 100644 --- a/PBot/Updater.pm +++ b/PBot/Updater.pm @@ -1,7 +1,8 @@ # File: Updater.pm -# Author: pragma_ # -# Purpose: Updates data/configration files to new locations/formats based +# Purpose: Migrates data files from older versions to newer versions. +# +# Updates data/configration files to new locations/formats based # on versioning information. Ensures data/configuration files are in the # proper location and using the latest data structure. @@ -12,9 +13,7 @@ package PBot::Updater; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use File::Basename; diff --git a/PBot/Users.pm b/PBot/Users.pm index 11080505..4e874ade 100644 --- a/PBot/Users.pm +++ b/PBot/Users.pm @@ -1,5 +1,4 @@ # File: Users.pm -# Author: pragma_ # # Purpose: Manages list of bot users/admins and their metadata. @@ -10,9 +9,7 @@ package PBot::Users; use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; @@ -28,11 +25,12 @@ sub initialize { $self->{pbot}->{commands}->register(sub { $self->cmd_my(@_) }, "my", 0); $self->{pbot}->{commands}->register(sub { $self->cmd_id(@_) }, "id", 0); - $self->{pbot}->{capabilities}->add('admin', 'can-useradd', 1); - $self->{pbot}->{capabilities}->add('admin', 'can-userdel', 1); - $self->{pbot}->{capabilities}->add('admin', 'can-userset', 1); - $self->{pbot}->{capabilities}->add('admin', 'can-userunset', 1); - $self->{pbot}->{capabilities}->add('can-modify-admins', undef, 1); + $self->{pbot}->{capabilities}->add('admin', 'can-useradd', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-userdel', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-userset', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-userunset', 1); + + $self->{pbot}->{capabilities}->add('can-modify-admins', undef, 1); $self->{pbot}->{event_dispatcher}->register_handler('irc.join', sub { $self->on_join(@_) }); $self->{pbot}->{event_dispatcher}->register_handler('irc.part', sub { $self->on_departure(@_) }); diff --git a/PBot/VERSION.pm b/PBot/VERSION.pm index a0b04690..90d894f5 100644 --- a/PBot/VERSION.pm +++ b/PBot/VERSION.pm @@ -1,8 +1,7 @@ # File: VERSION.pm -# Author: pragma_ # # Purpose: Keeps track of bot version. Can compare current version against -# latest version on github or version.check_url site. +# latest version on github or URL in `version.check_url` registry entry. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -11,9 +10,7 @@ package PBot::VERSION; use parent 'PBot::Class'; -use strict; use warnings; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use LWP::UserAgent; diff --git a/PBot/WebPaste.pm b/PBot/WebPaste.pm index 4e48edf3..d41470fb 100644 --- a/PBot/WebPaste.pm +++ b/PBot/WebPaste.pm @@ -1,5 +1,4 @@ # File: WebPaste.pm -# Author: pragma_ # # Purpose: Pastes text to a cycling list of web paste sites. @@ -8,12 +7,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package PBot::WebPaste; - use parent 'PBot::Class'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; +use PBot::Imports; use Time::HiRes qw/gettimeofday/; use Time::Duration; diff --git a/Plugins/ActionTrigger.pm b/Plugins/ActionTrigger.pm index 211e13cf..5bda0cec 100644 --- a/Plugins/ActionTrigger.pm +++ b/Plugins/ActionTrigger.pm @@ -31,11 +31,7 @@ use parent 'Plugins::Plugin'; # # TODO: share actually useful examples from personal bot -use warnings; use strict; -use feature 'unicode_strings'; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use DBI; use Time::Duration qw/duration/; diff --git a/Plugins/AntiAway.pm b/Plugins/AntiAway.pm index 82ebdd22..0b17b21d 100644 --- a/Plugins/AntiAway.pm +++ b/Plugins/AntiAway.pm @@ -1,5 +1,4 @@ # File: AntiAway.pm -# Author: pragma_ # # Purpose: Kicks people that visibly auto-away with ACTIONs or nick-changes @@ -10,8 +9,7 @@ package Plugins::AntiAway; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/Plugins/AntiKickAutoRejoin.pm b/Plugins/AntiKickAutoRejoin.pm index 3ad167bb..eb4e8021 100644 --- a/Plugins/AntiKickAutoRejoin.pm +++ b/Plugins/AntiKickAutoRejoin.pm @@ -1,5 +1,4 @@ # File: AntiKickAutoRejoin.pm -# Author: pragma_ # # Purpose: Temporarily bans people who immediately auto-rejoin after a kick. @@ -8,11 +7,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::AntiKickAutoRejoin; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use Time::HiRes qw/gettimeofday/; use Time::Duration; diff --git a/Plugins/AntiNickSpam.pm b/Plugins/AntiNickSpam.pm index b7284dcc..a22c4b42 100644 --- a/Plugins/AntiNickSpam.pm +++ b/Plugins/AntiNickSpam.pm @@ -1,5 +1,4 @@ # File: AntiNickSpam.pm -# Author: pragma_ # # Purpose: Temporarily mutes $~a in channel if too many nicks were # mentioned within a time period; used to combat botnet spam @@ -9,11 +8,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::AntiNickSpam; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use Time::Duration qw/duration/; use Time::HiRes qw/gettimeofday/; diff --git a/Plugins/AntiRepeat.pm b/Plugins/AntiRepeat.pm index 9dc3137b..6d07dbf4 100644 --- a/Plugins/AntiRepeat.pm +++ b/Plugins/AntiRepeat.pm @@ -5,11 +5,7 @@ package Plugins::AntiRepeat; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use String::LCSS qw/lcss/; use Time::HiRes qw/gettimeofday/; diff --git a/Plugins/AntiTwitter.pm b/Plugins/AntiTwitter.pm index 50a88c25..bb68d488 100644 --- a/Plugins/AntiTwitter.pm +++ b/Plugins/AntiTwitter.pm @@ -1,29 +1,20 @@ # File: AntiTwitter.pm -# Author: pragma_ # -# Purpose: Warns people off from using @nick style addressing. Temp-bans if they -# persist. +# Purpose: Warns people off from using @nick style addressing. Temp-bans +# if they persist. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::AntiTwitter; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use Time::HiRes qw/gettimeofday/; use Time::Duration qw/duration/; -use feature 'switch'; - -use utf8; - -no if $] >= 5.018, warnings => "experimental::smartmatch"; - sub initialize { my ($self, %conf) = @_; $self->{pbot}->{event_dispatcher}->register_handler('irc.public', sub { $self->on_public(@_) }); diff --git a/Plugins/AutoRejoin.pm b/Plugins/AutoRejoin.pm index 26f30cd0..83e72370 100644 --- a/Plugins/AutoRejoin.pm +++ b/Plugins/AutoRejoin.pm @@ -1,5 +1,4 @@ # File: AutoRejoin.pm -# Author: pragma_ # # Purpose: Auto-rejoin channels after kick or whatever. @@ -8,12 +7,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::AutoRejoin; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; - use Time::HiRes qw/gettimeofday/; use Time::Duration; diff --git a/Plugins/Battleship.pm b/Plugins/Battleship.pm index 450a9dcd..92774c5b 100644 --- a/Plugins/Battleship.pm +++ b/Plugins/Battleship.pm @@ -3,16 +3,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::Battleship; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; - -use feature 'switch'; - -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use Time::Duration qw/concise duration/; use Data::Dumper; diff --git a/Plugins/Connect4.pm b/Plugins/Connect4.pm index 703aebd3..d584bae8 100644 --- a/Plugins/Connect4.pm +++ b/Plugins/Connect4.pm @@ -5,11 +5,7 @@ package Plugins::Connect4; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use Time::Duration qw/concise duration/; use Data::Dumper; diff --git a/Plugins/Counter.pm b/Plugins/Counter.pm index db33577b..60f3af3f 100644 --- a/Plugins/Counter.pm +++ b/Plugins/Counter.pm @@ -5,11 +5,7 @@ package Plugins::Counter; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use DBI; use Time::Duration qw/duration/; diff --git a/Plugins/Date.pm b/Plugins/Date.pm index 84c6a1b4..210216f9 100644 --- a/Plugins/Date.pm +++ b/Plugins/Date.pm @@ -1,5 +1,4 @@ # File: Date.pm -# Author: pragma- # # Purpose: Adds command to display time and date for timezones. @@ -10,8 +9,7 @@ package Plugins::Date; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use Getopt::Long qw(GetOptionsFromArray); diff --git a/Plugins/Example.pm b/Plugins/Example.pm index 7f5eb7f1..25e985fe 100644 --- a/Plugins/Example.pm +++ b/Plugins/Example.pm @@ -1,3 +1,7 @@ +# File: Example.pm +# +# Purpose: Example plugin boilerplate. + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -5,8 +9,7 @@ package Plugins::Example; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/Plugins/FuncBuiltins.pm b/Plugins/FuncBuiltins.pm index cd7a0c9c..5d45f5e3 100644 --- a/Plugins/FuncBuiltins.pm +++ b/Plugins/FuncBuiltins.pm @@ -1,5 +1,4 @@ # File: FuncBuiltins.pm -# Author: pragma- # # Purpose: Registers the basic built-in Functions @@ -10,8 +9,7 @@ package Plugins::FuncBuiltins; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/Plugins/FuncGrep.pm b/Plugins/FuncGrep.pm index ec8e9a18..61f5a144 100644 --- a/Plugins/FuncGrep.pm +++ b/Plugins/FuncGrep.pm @@ -1,5 +1,4 @@ # File: FuncGrep.pm -# Author: pragma- # # Purpose: Registers the grep Function @@ -10,8 +9,7 @@ package Plugins::FuncGrep; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/Plugins/FuncPlural.pm b/Plugins/FuncPlural.pm index f22f09c2..7bdacc9f 100644 --- a/Plugins/FuncPlural.pm +++ b/Plugins/FuncPlural.pm @@ -1,7 +1,6 @@ # File: FuncPlural.pm -# Author: pragma- # -# Purpose: Registers the plural Function +# Purpose: Registers the plural Function. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,8 +9,7 @@ package Plugins::FuncPlural; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; @@ -51,8 +49,13 @@ sub pluralize_word { 'us' => 'uses', 'x' => 'xes', 'ium' => 'ia', - 'um' => 'a', 'stomach' => 'stomachs' , 'cactus' => 'cacti' , 'cactus' => 'cacti' , 'knoif' => 'knoives' , 'sheaf' => -'sheaves' , 'dwarf' => 'dwarves' , + 'um' => 'a', + 'stomach' => 'stomachs', + 'cactus' => 'cacti', + 'cactus' => 'cacti', + 'knoif' => 'knoives', + 'sheaf' => 'sheaves', + 'dwarf' => 'dwarves', 'loaf' => 'loaves', 'louse' => 'lice', 'die' => 'dice', diff --git a/Plugins/FuncSed.pm b/Plugins/FuncSed.pm index b157423c..92a95e25 100644 --- a/Plugins/FuncSed.pm +++ b/Plugins/FuncSed.pm @@ -1,5 +1,4 @@ # File: FuncSed.pm -# Author: pragma- # # Purpose: Registers the sed Function @@ -10,8 +9,7 @@ package Plugins::FuncSed; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; @@ -32,7 +30,6 @@ sub unload { # near-verbatim insertion of krok's `sed` factoid no warnings; - sub func_sed { my $self = shift; my $text = "@_"; diff --git a/Plugins/GoogleSearch.pm b/Plugins/GoogleSearch.pm index c6d2f336..845d320c 100644 --- a/Plugins/GoogleSearch.pm +++ b/Plugins/GoogleSearch.pm @@ -1,15 +1,11 @@ -#!/usr/bin/perl - # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::GoogleSearch; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use WWW::Google::CustomSearch; use HTML::Entities; diff --git a/Plugins/MagicCommand.pm b/Plugins/MagicCommand.pm deleted file mode 100644 index ffe2dc62..00000000 --- a/Plugins/MagicCommand.pm +++ /dev/null @@ -1,33 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This module is intended to provide a "magic" command that allows -# the bot owner to trigger special arbitrary code (by editing this -# module and refreshing loaded modules before running the magical -# command). - -package Plugins::MagicCommand; -use parent 'Plugins::Plugin'; - -use warnings; use strict; -use feature 'unicode_strings'; - -sub initialize { - my ($self, %conf) = @_; - $self->{pbot}->{commands}->register(sub { return $self->cmd_magic(@_) }, "mc", 90); -} - -sub unload { - my $self = shift; - $self->{pbot}->{commands}->unregister("mc"); -} - -sub cmd_magic { - my ($self, $context) = @_; - - # do something magical! - return "Did something magical."; -} - -1; diff --git a/Plugins/ParseDate.pm b/Plugins/ParseDate.pm index 7be377de..44a7bced 100644 --- a/Plugins/ParseDate.pm +++ b/Plugins/ParseDate.pm @@ -7,8 +7,7 @@ package Plugins::ParseDate; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use Time::Duration qw/duration/; diff --git a/Plugins/Plang.pm b/Plugins/Plang.pm index 158079b0..7d1b4489 100644 --- a/Plugins/Plang.pm +++ b/Plugins/Plang.pm @@ -1,5 +1,4 @@ # File: Plang.pm -# Author: pragma- # # Purpose: Scripting language for creating advanced PBot factoids # and interacting with various internal PBot APIs. @@ -11,8 +10,7 @@ package Plugins::Plang; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use Getopt::Long qw(GetOptionsFromArray); diff --git a/Plugins/Plugin.pm b/Plugins/Plugin.pm index dc63d7b4..827822bd 100644 --- a/Plugins/Plugin.pm +++ b/Plugins/Plugin.pm @@ -1,26 +1,28 @@ +# File: Plugin.pm +# +# Purpose: Base class for PBot plugins. + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::Plugin; -# purpose: base class for PBot plugins - -use warnings; use strict; +use PBot::Imports; sub new { - my ($proto, %conf) = @_; - my $class = ref($proto) || $proto; + my ($class, %args) = @_; + my $self = bless {}, $class; - if (not exists $conf{pbot}) { + if (not exists $args{pbot}) { my ($package, $filename, $line) = caller(0); my (undef, undef, undef, $subroutine) = caller(1); Carp::croak("Missing pbot reference to " . $class . ", created by $subroutine at $filename:$line"); } - $self->{pbot} = $conf{pbot}; - $self->initialize(%conf); + $self->{pbot} = $args{pbot}; + $self->initialize(%args); return $self; } diff --git a/Plugins/Quotegrabs.pm b/Plugins/Quotegrabs.pm index 1f761ac6..581f48a8 100644 --- a/Plugins/Quotegrabs.pm +++ b/Plugins/Quotegrabs.pm @@ -1,18 +1,18 @@ # File: Quotegrabs.pm -# Author: pragma_ # -# Purpose: Allows users to "grab" quotes from message history and store them for later retrieval. +# Purpose: Allows users to "grab" quotes from message history and store them +# for later retrieval. Can grab a quote from any point in the message history, +# not just the most recent message. Can grab multiple distinct messages with +# one `grab` command. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::Quotegrabs; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use HTML::Entities; use Time::Duration; diff --git a/Plugins/RelayUnreg.pm b/Plugins/RelayUnreg.pm index af8e7a7b..05715b15 100644 --- a/Plugins/RelayUnreg.pm +++ b/Plugins/RelayUnreg.pm @@ -1,9 +1,11 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::RelayUnreg; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use Time::HiRes qw/gettimeofday/; diff --git a/Plugins/RemindMe.pm b/Plugins/RemindMe.pm index f958a41e..57a27a7f 100644 --- a/Plugins/RemindMe.pm +++ b/Plugins/RemindMe.pm @@ -5,11 +5,7 @@ package Plugins::RemindMe; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; - -use feature 'switch'; -no if $] >= 5.018, warnings => "experimental::smartmatch"; +use PBot::Imports; use DBI; use Time::Duration qw/concise duration/; @@ -281,6 +277,9 @@ sub cmd_remindme { Getopt::Long::Configure("bundling"); my @opt_args = $self->{pbot}->{interpreter}->split_line($context->{arguments}, strip_quotes => 1); + use Data::Dumper; + print "args: [$context->{arguments}]\n"; + print Dumper \@opt_args; GetOptionsFromArray( \@opt_args, 'r:i' => \$repeat, diff --git a/Plugins/RestrictedMod.pm b/Plugins/RestrictedMod.pm index 1db13ff2..30ef8bf6 100644 --- a/Plugins/RestrictedMod.pm +++ b/Plugins/RestrictedMod.pm @@ -1,3 +1,11 @@ +# File: RestrictedMod.pm +# +# Purpose: Provides restricted moderation abilities to voiced users. +# They are allowed to ban/mute/kick only users that are not admins, +# whitelisted, or autoop/autovoice. This is useful for, e.g., IRCnet +# configurations where +v users are recognized as "semi-trusted" in +# order to provide assistance in combating heavy spam and drone traffic. + # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -5,14 +13,7 @@ package Plugins::RestrictedMod; use parent 'Plugins::Plugin'; -# purpose: provides restricted moderation abilities to voiced users. -# They are allowed to ban/mute/kick only users that are not admins, -# whitelisted, or autoop/autovoice. This is useful for, e.g., IRCnet -# configurations where +v users are recognized as "semi-trusted" in -# order to provide assistance in combating heavy spam and drone traffic. - -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use Storable qw/dclone/; diff --git a/Plugins/Spinach.pm b/Plugins/Spinach.pm index 5faf69f9..f5f23aee 100644 --- a/Plugins/Spinach.pm +++ b/Plugins/Spinach.pm @@ -3,18 +3,13 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::Spinach; - use parent 'Plugins::Plugin'; -use warnings; use strict; +use PBot::Imports; +use PBot::HashObject; -use FindBin; -use lib "$FindBin::RealBin/../.."; -use feature 'switch'; - -no if $] >= 5.018, warnings => "experimental::smartmatch"; - -use feature 'unicode_strings'; +use Plugins::Spinach::Stats; +use Plugins::Spinach::Rank; use JSON; @@ -34,13 +29,9 @@ use Data::Dumper; $Data::Dumper::Sortkeys = sub { my ($h) = @_; my @a = sort grep { not /^(?:seen_questions|alternativeSpellings)$/ } keys %$h; \@a; }; + $Data::Dumper::Useqq = 1; -use PBot::HashObject; - -use Plugins::Spinach::Stats; -use Plugins::Spinach::Rank; - sub initialize { my ($self, %conf) = @_; $self->{pbot}->{commands}->register(sub { $self->cmd_spinach(@_) }, 'spinach', 0); diff --git a/Plugins/TypoSub.pm b/Plugins/TypoSub.pm index 8a29004a..52e7379f 100644 --- a/Plugins/TypoSub.pm +++ b/Plugins/TypoSub.pm @@ -1,11 +1,6 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -package Plugins::TypoSub; -use parent 'Plugins::Plugin'; - -# purpose: Replaces "typos" with "corrections". +# File: TypoSub.pm +# +# Purpose: Replaces "typos" with "corrections". # # Examples: # @@ -17,8 +12,15 @@ use parent 'Plugins::Plugin'; # s/like/love/ # alice meant to say: i love candy -use warnings; use strict; -use feature 'unicode_strings'; +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package Plugins::TypoSub; +use parent 'Plugins::Plugin'; + +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/Plugins/UrlTitles.pm b/Plugins/UrlTitles.pm index c02cd666..2c887e2b 100644 --- a/Plugins/UrlTitles.pm +++ b/Plugins/UrlTitles.pm @@ -1,5 +1,4 @@ # File: UrlTitles.pm -# Author: pragma- # # Purpose: Display titles of URLs in channel messages. @@ -10,8 +9,7 @@ package Plugins::UrlTitles; use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; sub initialize { my ($self, %conf) = @_; diff --git a/Plugins/Weather.pm b/Plugins/Weather.pm index 63212497..5f13febd 100644 --- a/Plugins/Weather.pm +++ b/Plugins/Weather.pm @@ -1,5 +1,4 @@ # File: Weather.pm -# Author: pragma- # # Purpose: Weather command. @@ -8,11 +7,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::Weather; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; +use PBot::Imports; use PBot::Utils::LWPUserAgentCached; use XML::LibXML; diff --git a/Plugins/Wttr.pm b/Plugins/Wttr.pm index 2148fd80..2f30f953 100644 --- a/Plugins/Wttr.pm +++ b/Plugins/Wttr.pm @@ -1,5 +1,4 @@ # File: Wttr.pm -# Author: pragma- # # Purpose: Weather command using Wttr.in. @@ -8,18 +7,11 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. package Plugins::Wttr; - use parent 'Plugins::Plugin'; -use warnings; use strict; -use feature 'unicode_strings'; -use utf8; - -use feature 'switch'; - -no if $] >= 5.018, warnings => "experimental::smartmatch"; - +use PBot::Imports; use PBot::Utils::LWPUserAgentCached; + use JSON; use URI::Escape qw/uri_escape_utf8/; use Getopt::Long qw(GetOptionsFromArray);