Significant refactor and clean-up of PBot class instantiation

This commit is contained in:
Pragmatic Software 2020-02-08 11:04:13 -08:00
parent 649f83f1b3
commit 02f93c8721
40 changed files with 146 additions and 558 deletions

View File

@ -12,34 +12,21 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::AntiFlood;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use feature 'switch';
no if $] >= 5.018, warnings => "experimental::smartmatch";
use PBot::DualIndexHashObject;
use Time::HiRes qw(gettimeofday tv_interval);
use Time::Duration;
use POSIX qw/strftime/;
use Text::CSV;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
# flags for 'validated' field
$self->{NICKSERV_VALIDATED} = (1<<0);

View File

@ -8,34 +8,19 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::AntiSpam;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use feature 'switch';
no if $] >= 5.018, warnings => "experimental::smartmatch";
use PBot::DualIndexHashObject;
use Carp ();
use Time::HiRes qw(gettimeofday);
use POSIX qw/strftime/;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
my $filename = $conf{spamkeywords_file} // $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/spam_keywords';
$self->{keywords} = PBot::DualIndexHashObject->new(name => 'SpamKeywords', filename => $filename, pbot => $self->{pbot});
$self->{keywords}->load;

View File

@ -11,32 +11,18 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::BanTracker;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Time::HiRes qw/gettimeofday/;
use Time::Duration;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
use Carp ();
sub new {
Carp::croak("Options to BanTracker should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to BanTracker");
$self->{banlist} = {};
$self->{pbot}->{registry}->add_default('text', 'bantracker', 'chanserv_ban_timeout', '604800');
$self->{pbot}->{registry}->add_default('text', 'bantracker', 'mute_timeout', '604800');
$self->{pbot}->{registry}->add_default('text', 'bantracker', 'debug', '0');
@ -46,6 +32,8 @@ sub initialize {
$self->{pbot}->{event_dispatcher}->register_handler('irc.endofnames', sub { $self->get_banlist(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.banlist', sub { $self->on_banlist_entry(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.quietlist', sub { $self->on_quietlist_entry(@_) });
$self->{banlist} = {};
}
sub dumpbans {

View File

@ -8,29 +8,18 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::BlackList;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use feature 'switch';
no if $] >= 5.018, warnings => "experimental::smartmatch";
use Carp ();
use Time::HiRes qw(gettimeofday);
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{filename} = $conf{filename};
$self->{blacklist} = {};
$self->{pbot}->{commands}->register(sub { $self->blacklist(@_) }, "blacklist", 1);

View File

@ -3,34 +3,21 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Capabilities;
use parent 'PBot::Class';
# purpose: provides interface to set/remove/modify/query user capabilities.
#
# Examples:
#
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use feature 'switch';
no if $] >= 5.018, warnings => "experimental::smartmatch";
use PBot::HashObject;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref $_[1] eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
my $filename = $conf{filename} // $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/capabilities';
$self->{caps} = PBot::HashObject->new(name => 'Capabilities', filename => $filename, pbot => $self->{pbot});
$self->{caps}->load;

View File

@ -8,28 +8,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::ChanOpCommands;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Carp ();
use Time::Duration;
use Time::HiRes qw/gettimeofday/;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
# register commands
$self->{pbot}->{commands}->register(sub { $self->ban_user(@_) }, "ban", 1);
$self->{pbot}->{commands}->register(sub { $self->unban_user(@_) }, "unban", 1);

View File

@ -8,27 +8,17 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::ChanOps;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use PBot::ChanOpCommands;
use Time::HiRes qw(gettimeofday);
use Time::Duration qw(concise duration);
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to ChanOps");
$self->{unban_timeout} = PBot::DualIndexHashObject->new(
pbot => $self->{pbot},

View File

@ -8,27 +8,13 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Channels;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Carp ();
use PBot::HashObject;
sub new {
Carp::croak ("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{channels} = PBot::HashObject->new(pbot => $self->{pbot}, name => 'Channels', filename => $conf{filename});
$self->load_channels;

37
PBot/Class.pm Normal file
View File

@ -0,0 +1,37 @@
# 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;
sub new {
my ($proto, %conf) = @_;
my $class = ref($proto) || $proto;
my $self = bless {}, $class;
if (not exists $conf{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);
return $self;
}
sub initialize {
my ($package, $filename, $line) = caller(0);
my (undef, undef, undef, $subroutine) = caller(1);
Carp::croak("Missing initialize subroutine, created by $subroutine at $filename:$line");
}
1;

View File

@ -10,30 +10,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Commands;
use parent 'PBot::Class', 'PBot::Registerable';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use base 'PBot::Registerable';
use Carp ();
use PBot::HashObject;
use Time::Duration qw/duration/;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->SUPER::initialize(%conf);
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->PBot::Registerable::initialize(%conf);
$self->{metadata} = PBot::HashObject->new(pbot => $self->{pbot}, name => 'Commands', filename => $conf{filename});
$self->load_metadata;
@ -49,12 +35,9 @@ sub initialize {
sub register {
my ($self, $subref, $name, $requires_cap) = @_;
Carp::croak("Missing parameters to Commands::register") if not defined $subref or not defined $name;
if (not defined $subref or not defined $name) {
Carp::croak("Missing parameters to Commands::register");
}
my $ref = $self->SUPER::register($subref);
my $ref = $self->PBot::Registerable::register($subref);
$ref->{name} = lc $name;
$ref->{requires_cap} = $requires_cap // 0;

View File

@ -12,29 +12,18 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::DualIndexHashObject;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Text::Levenshtein qw(fastdistance);
use JSON;
use Carp ();
sub new {
Carp::croak("Options to DualIndexHashObject should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{name} = $conf{name} // 'Dual Index hash object';
$self->{filename} = $conf{filename} // Carp::carp("Missing filename to DualIndexHashObject, will not be able to save to or load from file.");
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{hash} = {};
}

View File

@ -3,26 +3,15 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::EventDispatcher;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use IO::Select;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference in " . __FILE__);
$self->{handlers} = { any => [] };
}
@ -60,7 +49,8 @@ sub dispatch_event {
for (my $i = 0; $i < @{$self->{handlers}->{$event_type}}; $i++) {
my $ref = @{$self->{handlers}->{$event_type}}[$i];
my ($handler, $info) = ($ref->[0], $ref->[1]);
$self->{pbot}->{logger}->log("Dispatching $event_type to handler $info\n") if $self->{pbot}->{registry}->get_value('eventdispatcher', 'debug') > 1;
my $debug = $self->{pbot}->{registry}->get_value('eventdispatcher', 'debug') // 0;
$self->{pbot}->{logger}->log("Dispatching $event_type to handler $info\n") if $debug > 1;
eval {
$ret = $handler->($event_type, $event_data);

View File

@ -8,13 +8,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::FactoidCommands;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Carp ();
use Time::Duration;
use Time::HiRes qw(gettimeofday);
use Getopt::Long qw(GetOptionsFromString);
@ -46,18 +44,8 @@ our %factoid_metadata_capabilities = (
# all others are allowed to be factset by anybody
);
sub new {
Carp::croak("Options to FactoidCommands should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to FactoidCommands");
$self->{pbot}->{registry}->add_default('text', 'general', 'module_repo', $conf{module_repo} // 'https://github.com/pragma-/pbot/blob/master/modules/');
$self->{pbot}->{commands}->register(sub { $self->factadd(@_) }, "learn", 0);

View File

@ -8,14 +8,12 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::FactoidModuleLauncher;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use POSIX qw(WNOHANG);
use Carp ();
use Text::Balanced qw(extract_delimited);
use JSON;
use IPC::Run qw/run timeout/;
@ -24,17 +22,8 @@ use Encode;
# automatically reap children processes in background
$SIG{CHLD} = sub { while (waitpid(-1, WNOHANG) > 0) {} };
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
}
sub execute_module {

View File

@ -8,10 +8,9 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Factoids;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use feature 'switch';
@ -20,7 +19,6 @@ no if $] >= 5.018, warnings => "experimental::smartmatch";
use HTML::Entities;
use Time::HiRes qw(gettimeofday);
use Time::Duration qw(duration);
use Carp ();
use POSIX qw(strftime);
use Text::ParseWords;
use JSON;
@ -32,20 +30,9 @@ use PBot::DualIndexHashObject;
use PBot::Utils::Indefinite;
use PBot::Utils::ValidateString;
sub new {
Carp::croak("Options to Factoids should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
my $filename = $conf{filename};
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{factoids} = PBot::DualIndexHashObject->new(name => 'Factoids', filename => $filename, pbot => $self->{pbot});
$self->{pbot} = $self->{pbot};
@ -58,13 +45,11 @@ sub initialize {
$self->{pbot}->{registry}->add_default('text', 'factoids', 'max_channel_length', 20);
$self->{pbot}->{atexit}->register(sub { $self->save_factoids; return; });
$self->load_factoids;
}
sub load_factoids {
my $self = shift;
$self->{factoids}->load;
my ($text, $regex, $modules);

View File

@ -20,24 +20,13 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::FuncCommand;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{pbot}->{commands}->register(sub { $self->do_func(@_) }, 'func', 0);
$self->init_funcs;
}

View File

@ -11,29 +11,18 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::HashObject;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Text::Levenshtein qw(fastdistance);
use Carp ();
use JSON;
sub new {
Carp::croak("Options to HashObject should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
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->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{hash} = {};
}

View File

@ -8,29 +8,17 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::IRCHandlers;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Carp();
use Time::HiRes qw(gettimeofday);
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot parameter to " . __FILE__);
$self->{pbot}->{event_dispatcher}->register_handler('irc.welcome', sub { $self->on_connect(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.disconnect', sub { $self->on_disconnect(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.motd', sub { $self->on_motd(@_) });

View File

@ -8,27 +8,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::IgnoreList;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use PBot::IgnoreListCommands;
use Time::HiRes qw(gettimeofday);
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{filename} = $conf{filename};
$self->{ignore_list} = {};
@ -36,7 +25,6 @@ sub initialize {
$self->{last_timestamp} = {};
$self->{commands} = PBot::IgnoreListCommands->new(pbot => $self->{pbot});
$self->load_ignores();
$self->{pbot}->{timer}->register(sub { $self->check_ignore_timeouts }, 10);

View File

@ -8,27 +8,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::IgnoreListCommands;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Time::HiRes qw(gettimeofday);
use Time::Duration;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{pbot}->{commands}->register(sub { $self->ignore_user(@_) }, "ignore", 1);
$self->{pbot}->{commands}->register(sub { $self->unignore_user(@_) }, "unignore", 1);
$self->{pbot}->{capabilities}->add('admin', 'can-ignore', 1);

View File

@ -8,32 +8,19 @@
# 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 warnings; use strict;
use feature 'unicode_strings';
use base 'PBot::Registerable';
use Time::HiRes qw/gettimeofday/;
use Time::Duration;
use Carp ();
use PBot::Utils::ValidateString;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->SUPER::initialize(%conf);
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->PBot::Registerable::initialize(%conf);
$self->{pbot}->{registry}->add_default('text', 'general', 'compile_blocks', $conf{compile_blocks} // 1);
$self->{pbot}->{registry}->add_default('array', 'general', 'compile_blocks_channels', $conf{compile_blocks_channels} // '.*');

View File

@ -9,29 +9,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::LagChecker;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use feature 'switch';
use Time::HiRes qw(gettimeofday tv_interval);
use Time::Duration;
use Carp ();
sub new {
Carp::croak("Options to LagChecker should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to LagChecker");
$self->{lag_average} = undef; # average of entries in lag history, in seconds
$self->{lag_string} = undef; # string representation of lag history and lag average
$self->{lag_history} = []; # history of previous PING/PONG timings

View File

@ -3,22 +3,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Logger;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Scalar::Util qw/openhandle/;
use File::Basename;
use Carp ();
sub new {
Carp::croak("Options to Logger should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->{pbot} = $conf{pbot} // Carp::croak "Missing pbot reference to " . __FILE__;
sub initialize {
my ($self, %conf) = @_;
$self->{logfile} = $conf{filename} // Carp::croak "Missing logfile parameter in " . __FILE__;
$self->{start} = time;

View File

@ -12,30 +12,19 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::MessageHistory;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Getopt::Long qw(GetOptionsFromString);
use Time::HiRes qw(gettimeofday tv_interval);
use Time::Duration;
use Carp ();
use PBot::MessageHistory_SQLite;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{filename} = $conf{filename} // $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/message_history.sqlite3';
$self->{database} = PBot::MessageHistory_SQLite->new(pbot => $self->{pbot}, filename => $self->{filename});

View File

@ -8,10 +8,9 @@
# 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 warnings; use strict;
use feature 'unicode_strings';
use DBI;
@ -21,18 +20,8 @@ use Text::CSV;
use Text::Levenshtein qw/fastdistance/;
use Time::Duration;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference in " . __FILE__);
$self->{filename} = $conf{filename} // $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/message_history.sqlite3';
$self->{new_entries} = 0;

View File

@ -10,30 +10,18 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::NickList;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Text::Levenshtein qw/fastdistance/;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
use Carp ();
use Time::HiRes qw/gettimeofday/;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref $_[1] eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{nicklist} = {};
$self->{pbot}->{registry}->add_default('text', 'nicklist', 'debug', '0');

View File

@ -9,9 +9,7 @@
package PBot::PBot;
use strict;
use warnings;
use strict; use warnings;
use feature 'unicode_strings';
# unbuffer stdout
@ -20,6 +18,8 @@ STDOUT->autoflush(1);
use Carp ();
use PBot::Logger;
use PBot::VERSION;
use PBot::HashObject;
use PBot::DualIndexHashObject;
use PBot::Registry;
use PBot::Capabilities;
use PBot::SelectHandler;
@ -49,11 +49,9 @@ use PBot::Utils::ParseDate;
use PBot::FuncCommand;
sub new {
Carp::croak("Options to PBot should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my ($proto, %conf) = @_;
my $class = ref($proto) || $proto;
my $self = bless {}, $class;
$self->{atexit} = PBot::Registerable->new(%conf);
$self->register_signal_handlers;
$self->initialize(%conf);
return $self;
}
@ -62,6 +60,9 @@ sub initialize {
my ($self, %conf) = @_;
$self->{startup_timestamp} = time;
$self->{atexit} = PBot::Registerable->new(%conf, pbot => $self);
$self->register_signal_handlers;
my $data_dir = $conf{data_dir};
my $module_dir = $conf{module_dir};
my $plugin_dir = $conf{plugin_dir};
@ -114,7 +115,7 @@ sub initialize {
$self->{commands}->register(sub { $self->{capabilities}->capcmd(@_) }, "cap");
# prepare the version
$self->{version} = PBot::VERSION->new(pbot => $self, %conf);
$self->{version} = PBot::VERSION->new(pbot => $self, %conf);
$self->{logger}->log($self->{version}->version . "\n");
$self->{logger}->log("Args: @ARGV\n") if @ARGV;
@ -123,8 +124,8 @@ sub initialize {
$self->{logger}->log("module_dir: $module_dir\n");
$self->{logger}->log("plugin_dir: $plugin_dir\n");
$self->{timer} = PBot::Timer->new(timeout => 10, %conf);
$self->{func_cmd} = PBot::FuncCommand->new(pbot => $self, %conf);
$self->{timer} = PBot::Timer->new(pbot => $self, timeout => 10, %conf);
$self->{func_cmd} = PBot::FuncCommand->new(pbot => $self, %conf);
$self->{refresher} = PBot::Refresher->new(pbot => $self);
# create registry and set some defaults

View File

@ -8,26 +8,15 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Plugins;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use File::Basename;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{plugins} = {};
$self->{pbot}->{commands}->register(sub { $self->load_cmd(@_) }, "plug", 1);
$self->{pbot}->{commands}->register(sub { $self->unload_cmd(@_) }, "unplug", 1);

View File

@ -10,33 +10,21 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Refresher;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Module::Refresh;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{refresher} = Module::Refresh->new;
$self->{pbot}->{commands}->register(sub { $self->refresh(@_) }, "refresh", 1);
}
sub refresh {
my ($self, $from, $nick, $user, $host, $arguments) = @_;
my $result = eval {
if (not $arguments) {
$self->{pbot}->{logger}->log("Refreshing all modified modules\n");

View File

@ -8,22 +8,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Registerable;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Carp ();
sub new {
Carp::croak("Options to Registerable should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my $self = shift;
$self->{handlers} = [];
@ -31,7 +20,6 @@ sub initialize {
sub execute_all {
my $self = shift;
foreach my $func (@{ $self->{handlers} }) {
my $result = &{ $func->{subref} }(@_);
return $result if defined $result;
@ -42,11 +30,7 @@ sub execute_all {
sub execute {
my $self = shift;
my $ref = shift;
if (not defined $ref) {
Carp::croak("Missing reference parameter to Registerable::execute");
}
Carp::croak("Missing reference parameter to Registerable::execute") if not defined $ref;
foreach my $func (@{ $self->{handlers} }) {
if ($ref == $func || $ref == $func->{subref}) {
return &{ $func->{subref} }(@_);

View File

@ -9,29 +9,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Registry;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Time::HiRes qw(gettimeofday);
use Carp ();
use PBot::DualIndexHashObject;
use PBot::RegistryCommands;
sub new {
Carp::croak("Options to " . __FILE__ . " should be item/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
my $filename = $conf{filename} // Carp::croak("Missing filename reference in " . __FILE__);
$self->{registry} = PBot::DualIndexHashObject->new(name => 'Registry', filename => $filename, pbot => $self->{pbot});
$self->{triggers} = {};

View File

@ -8,25 +8,13 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::RegistryCommands;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{pbot}->{commands}->register(sub { $self->regset(@_) }, "regset", 1);
$self->{pbot}->{commands}->register(sub { $self->regunset(@_) }, "regunset", 1);
$self->{pbot}->{commands}->register(sub { $self->regshow(@_) }, "regshow", 0);

View File

@ -10,29 +10,22 @@
package PBot::SQLiteLogger;
use strict;
use warnings;
use strict; use warnings;
use feature 'unicode_strings';
use Carp;
use Time::HiRes qw(gettimeofday);
sub new
{
sub new {
my ($class, %conf) = @_;
my $self = {};
$self->{buf} = '';
$self->{timestamp} = gettimeofday;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference in " . __FILE__);
return bless $self, $class;
}
sub log
{
sub log {
my $self = shift;
$self->{buf} .= shift;
# DBI feeds us pieces at a time, so accumulate a complete line
# before outputing
if ($self->{buf} =~ tr/\n//) {

View File

@ -14,8 +14,7 @@ use warnings;
use feature 'unicode_strings';
sub PUSHED
{
sub PUSHED {
my ($class, $mode, $fh) = @_;
my $logger;
return bless \$logger, $class;
@ -23,13 +22,12 @@ sub PUSHED
sub OPEN {
my ($self, $path, $mode, $fh) = @_;
# $path is actually our logger object
# $path is our logger object
$$self = $path;
return 1;
}
sub WRITE
{
sub WRITE {
my ($self, $buf, $fh) = @_;
$$self->log($buf);
return length($buf);

View File

@ -3,26 +3,15 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::SelectHandler;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use IO::Select;
use Carp ();
sub new {
Carp::croak("Options to SelectHandler should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference in SelectHandler");
$self->{select} = IO::Select->new();
$self->{readers} = {};
$self->{buffers} = {};

View File

@ -3,27 +3,15 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::StdinReader;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use POSIX qw(tcgetpgrp getpgrp); # to check whether process is in background or foreground
use Carp ();
sub new {
Carp::croak("Options to StdinReader should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference in StdinReader");
# create implicit bot-admin account for bot
my $user = $self->{pbot}->{users}->find_user('.*', '*!stdin@pbot');
if (not defined $user or not $self->{pbot}->{capabilities}->userhas($user, 'botowner')) {

View File

@ -10,14 +10,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Timer;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Carp ();
our $min_timeout = 1;
our $max_seconds = 1000000;
our $seconds = 0;
@ -34,23 +31,13 @@ $SIG{ALRM} = sub {
$seconds -= $max_seconds if $seconds > $max_seconds;
};
sub new {
Carp::croak("Options to Timer should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
sub initialize {
my ($self, %conf) = @_;
my $timeout = $conf{timeout} // 10;
my $name = $conf{name} // "Unnamed $timeout Second Timer";
my $self = {
handlers => [],
name => $name,
timeout => $timeout,
enabled => 0,
};
bless $self, $class;
$min_timeout = $timeout if $timeout < $min_timeout;
$self->{name} = $conf{name} // "Unnamed $timeout Second Timer";
$self->{handlers} = [];
$self->{enabled} = 0;
# alarm signal handler (poor-man's timer)
$self->{timer_func} = sub { on_tick_handler($self) };
return $self;

View File

@ -8,27 +8,13 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::Users;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use PBot::DualIndexHashObject;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{users} = PBot::DualIndexHashObject->new(name => 'Users', filename => $conf{filename}, pbot => $conf{pbot});
$self->load;

View File

@ -9,34 +9,24 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::VERSION;
use parent 'PBot::Class';
use strict;
use warnings;
use strict; use warnings;
use feature 'unicode_strings';
BEGIN {
use Exporter;
our @ISA = 'Exporter';
our @EXPORT_OK = qw(version);
}
use LWP::UserAgent;
# These are set automatically by build/update_version.pl
# These are set automatically by the misc/update_version script
use constant {
BUILD_NAME => "PBot",
BUILD_REVISION => 3194,
BUILD_DATE => "2020-02-07",
};
sub new {
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
sub initialize {
my ($self, %conf) = @_;
$self->{pbot}->{commands}->register(sub { $self->version_cmd(@_) }, "version", 0);
$self->{last_check} = { timestamp => 0, version => BUILD_REVISION, date => BUILD_DATE };
return $self;
}
sub version {

View File

@ -8,29 +8,18 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
package PBot::WebPaste;
use parent 'PBot::Class';
use warnings;
use strict;
use warnings; use strict;
use feature 'unicode_strings';
use Time::HiRes qw/gettimeofday/;
use Time::Duration;
use LWP::UserAgent::Paranoid;
use Carp ();
use Encode;
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{paste_sites} = [
sub { $self->paste_ixio(@_) },
@ -41,9 +30,7 @@ sub initialize {
sub get_paste_site {
my ($self) = @_;
my $subref = $self->{paste_sites}->[$self->{current_site}];
if (++$self->{current_site} >= @{$self->{paste_sites}}) {
$self->{current_site} = 0;
}
@ -52,11 +39,9 @@ sub get_paste_site {
sub paste {
my ($self, $text, %opts) = @_;
my %default_opts = (
no_split => 0,
);
%opts = (%default_opts, %opts);
$text =~ s/(.{120})\s/$1\n/g unless $opts{no_split};
@ -66,10 +51,7 @@ sub paste {
for (my $tries = 3; $tries > 0; $tries--) {
my $paste_site = $self->get_paste_site;
$result = $paste_site->($text);
if ($result !~ m/error pasting/) {
last;
}
last if $result !~ m/error pasting/;
}
return $result;
}