mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-27 06:19:25 +01:00
164 lines
3.6 KiB
Perl
164 lines
3.6 KiB
Perl
# File: Pluggable.pm
|
|
# Author: pragma-
|
|
#
|
|
# Purpose: Loads and manages pluggable modules.
|
|
|
|
package PBot::Pluggable;
|
|
|
|
use warnings;
|
|
use strict;
|
|
|
|
use File::Basename;
|
|
use Carp ();
|
|
|
|
sub new {
|
|
if(ref($_[1]) eq 'HASH') {
|
|
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference");
|
|
}
|
|
|
|
my ($class, %conf) = @_;
|
|
|
|
my $self = bless {}, $class;
|
|
$self->initialize(%conf);
|
|
return $self;
|
|
}
|
|
|
|
sub initialize {
|
|
my ($self, %conf) = @_;
|
|
|
|
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
|
|
|
$self->{modules} = {};
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->load_cmd(@_) }, "plug", 90);
|
|
$self->{pbot}->{commands}->register(sub { $self->unload_cmd(@_) }, "unplug", 90);
|
|
$self->{pbot}->{commands}->register(sub { $self->list_cmd(@_) }, "pluglist", 0);
|
|
|
|
$self->autoload(%conf);
|
|
}
|
|
|
|
sub autoload {
|
|
my ($self, %conf) = @_;
|
|
|
|
$self->{pbot}->{logger}->log("Loading pluggable modules ...\n");
|
|
my $module_count = 0;
|
|
|
|
my @modules = glob 'PBot/Pluggable/*.pm';
|
|
|
|
foreach my $module (sort @modules) {
|
|
$module = basename $module;
|
|
$module =~ s/.pm$//;
|
|
|
|
# do not load modules that begin with an underscore
|
|
next if $module =~ m/^_/;
|
|
|
|
$module_count++ if $self->load($module, %conf)
|
|
}
|
|
|
|
$self->{pbot}->{logger}->log("$module_count module" . ($module_count == 1 ? '' : 's') . " loaded.\n");
|
|
}
|
|
|
|
sub load {
|
|
my ($self, $module, %conf) = @_;
|
|
|
|
$self->unload($module);
|
|
|
|
my $class = "PBot::Pluggable::$module";
|
|
|
|
$self->{pbot}->{refresher}->{refresher}->refresh_module("PBot/Pluggable/$module.pm");
|
|
|
|
my $ret = eval {
|
|
eval "require $class";
|
|
|
|
if ($@) {
|
|
chomp $@;
|
|
$self->{pbot}->{logger}->log("Error loading $module: $@\n");
|
|
return 0;
|
|
}
|
|
|
|
$self->{pbot}->{logger}->log("Loading $module\n");
|
|
my $mod = $class->new(pbot => $self->{pbot}, %conf);
|
|
$self->{modules}->{$module} = $mod;
|
|
$self->{pbot}->{refresher}->{refresher}->update_cache("PBot/Pluggable/$module.pm");
|
|
return 1;
|
|
};
|
|
|
|
if ($@) {
|
|
chomp $@;
|
|
$self->{pbot}->{logger}->log("Error loading $module: $@\n");
|
|
return 0;
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
sub unload {
|
|
my ($self, $module) = @_;
|
|
|
|
$self->{pbot}->{refresher}->{refresher}->unload_module("PBot::Pluggable::$module");
|
|
$self->{pbot}->{refresher}->{refresher}->unload_subs("PBot/Pluggable/$module.pm");
|
|
|
|
if (exists $self->{modules}->{$module}) {
|
|
eval {
|
|
$self->{modules}->{$module}->unload;
|
|
delete $self->{modules}->{$module};
|
|
};
|
|
if ($@) {
|
|
chomp $@;
|
|
$self->{pbot}->{logger}->log("Warning: got error unloading module $module: $@\n");
|
|
}
|
|
$self->{pbot}->{logger}->log("Pluggable module $module unloaded.\n");
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
sub load_cmd {
|
|
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
|
|
|
if (not length $arguments) {
|
|
return "Usage: plug <plugin>";
|
|
}
|
|
|
|
if ($self->load($arguments)) {
|
|
return "Loaded $arguments plugin.";
|
|
} else {
|
|
return "Plugin $arguments failed to load.";
|
|
}
|
|
}
|
|
|
|
sub unload_cmd {
|
|
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
|
|
|
if (not length $arguments) {
|
|
return "Usage: unplug <plugin>";
|
|
}
|
|
|
|
if ($self->unload($arguments)) {
|
|
return "Unloaded $arguments plugin.";
|
|
} else {
|
|
return "Plugin $arguments failed to load.";
|
|
}
|
|
}
|
|
|
|
sub list_cmd {
|
|
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
|
|
|
my $result = "Loaded plugins: ";
|
|
my $count = 0;
|
|
my $comma = '';
|
|
|
|
foreach my $plugin (sort keys $self->{modules}) {
|
|
$result .= $comma . $plugin;
|
|
$count++;
|
|
$comma = ', ';
|
|
}
|
|
|
|
$result .= 'none' if $count == 0;
|
|
|
|
return $result;
|
|
}
|
|
|
|
1;
|