mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-26 05:49:27 +01:00
Fix all potential case-sensitivity issues
Misc clean-ups and refactors
This commit is contained in:
parent
30fb36ba0a
commit
02552081d5
@ -99,19 +99,20 @@ sub whitelisted {
|
||||
|
||||
given ($mode) {
|
||||
when ('ban') {
|
||||
return 1 if exists $self->{whitelist}->hash->{$channel}
|
||||
and exists $self->{whitelist}->hash->{$channel}->{$hostmask}
|
||||
and $self->{whitelist}->hash->{$channel}->{$hostmask}->{ban};
|
||||
return 1 if exists $self->{whitelist}->{hash}->{$channel}
|
||||
and exists $self->{whitelist}->{hash}->{$channel}->{$hostmask}
|
||||
and $self->{whitelist}->{hash}->{$channel}->{$hostmask}->{ban};
|
||||
return 0;
|
||||
}
|
||||
|
||||
default {
|
||||
my $ret = eval {
|
||||
foreach my $chan (keys %{ $self->{whitelist}->hash }) {
|
||||
next unless $channel =~ m/^$chan$/i;
|
||||
foreach my $mask (keys %{ $self->{whitelist}->hash->{$chan} }) {
|
||||
next if $self->{whitelist}->hash->{$chan}->{$mask}->{ban};
|
||||
return 1 if $hostmask =~ m/^$mask$/i and $self->{whitelist}->hash->{$chan}->{$mask}->{$mode};
|
||||
foreach my $chan (keys %{ $self->{whitelist}->{hash} }) {
|
||||
next unless $channel eq $chan;
|
||||
foreach my $mask (keys %{ $self->{whitelist}->{hash}->{$chan} }) {
|
||||
next if $mask eq '_name';
|
||||
next if $self->{whitelist}->{hash}->{$chan}->{$mask}->{ban};
|
||||
return 1 if $hostmask eq $mask and $self->{whitelist}->{hash}->{$chan}->{$mask}->{$mode};
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -141,13 +142,14 @@ sub whitelist {
|
||||
when ($_ eq "list" or $_ eq "show") {
|
||||
my $text = "Whitelist:\n";
|
||||
my $entries = 0;
|
||||
foreach my $channel (keys %{ $self->{whitelist}->hash }) {
|
||||
$text .= " $channel:\n";
|
||||
foreach my $mask (keys %{ $self->{whitelist}->hash->{$channel} }) {
|
||||
foreach my $channel (keys %{ $self->{whitelist}->{hash} }) {
|
||||
$text .= " $self->{whitelist}->{hash}->{$channel}->{_name}:\n";
|
||||
foreach my $mask (keys %{ $self->{whitelist}->{hash}->{$channel} }) {
|
||||
next if $mask eq '_name';
|
||||
my $mode = '';
|
||||
$mode .= 'u' if $self->{whitelist}->hash->{$channel}->{$mask}->{user};
|
||||
$mode .= 'b' if $self->{whitelist}->hash->{$channel}->{$mask}->{ban};
|
||||
$mode .= 'a' if $self->{whitelist}->hash->{$channel}->{$mask}->{antiflood};
|
||||
$mode .= 'u' if $self->{whitelist}->{hash}->{$channel}->{$mask}->{user};
|
||||
$mode .= 'b' if $self->{whitelist}->{hash}->{$channel}->{$mask}->{ban};
|
||||
$mode .= 'a' if $self->{whitelist}->{hash}->{$channel}->{$mask}->{antiflood};
|
||||
$mode = '?' if not length $mode;
|
||||
$text .= " $mask [$mode],\n";
|
||||
$entries++;
|
||||
@ -160,23 +162,23 @@ sub whitelist {
|
||||
my ($channel, $mask, $flag, $value) = $self->{pbot}->{interpreter}->split_args($arglist, 4);
|
||||
return "Usage: whitelist set <channel> <mask> [flag] [value]" if not defined $channel or not defined $mask;
|
||||
|
||||
if (not exists $self->{whitelist}->hash->{$channel}) {
|
||||
if (not exists $self->{whitelist}->{hash}->{lc $channel}) {
|
||||
return "There is no such channel `$channel` in the whitelist.";
|
||||
}
|
||||
|
||||
if (not exists $self->{whitelist}->hash->{$channel}->{$mask}) {
|
||||
if (not exists $self->{whitelist}->{hash}->{lc $channel}->{lc $mask}) {
|
||||
return "There is no such mask `$mask` for channel `$channel` in the whitelist.";
|
||||
}
|
||||
|
||||
if (not defined $flag) {
|
||||
my $text = "Flags:\n";
|
||||
my $comma = '';
|
||||
foreach $flag (keys %{ $self->{whitelist}->hash->{$channel}->{$mask} }) {
|
||||
foreach $flag (keys %{ $self->{whitelist}->{hash}->{lc $channel}->{lc $mask} }) {
|
||||
if ($flag eq 'created_on') {
|
||||
my $timestamp = strftime "%a %b %e %H:%M:%S %Z %Y", localtime $self->{whitelist}->hash->{$channel}->{$mask}->{$flag};
|
||||
my $timestamp = strftime "%a %b %e %H:%M:%S %Z %Y", localtime $self->{whitelist}->{hash}->{lc $channel}->{lc $mask}->{$flag};
|
||||
$text .= $comma . "created_on: $timestamp";
|
||||
} else {
|
||||
$value = $self->{whitelist}->hash->{$channel}->{$mask}->{$flag};
|
||||
$value = $self->{whitelist}->{hash}->{lc $channel}->{lc $mask}->{$flag};
|
||||
$text .= $comma . "$flag: $value";
|
||||
}
|
||||
$comma = ",\n ";
|
||||
@ -185,7 +187,7 @@ sub whitelist {
|
||||
}
|
||||
|
||||
if (not defined $value) {
|
||||
$value = $self->{whitelist}->hash->{$channel}->{$mask}->{$flag};
|
||||
$value = $self->{whitelist}->{hash}->{lc $channel}->{lc $mask}->{$flag};
|
||||
if (not defined $value) {
|
||||
return "/say $flag is not set.";
|
||||
} else {
|
||||
@ -193,7 +195,7 @@ sub whitelist {
|
||||
}
|
||||
}
|
||||
|
||||
$self->{whitelist}->hash->{$channel}->{$mask}->{$flag} = $value;
|
||||
$self->{whitelist}->{hash}->{lc $channel}->{lc $mask}->{$flag} = $value;
|
||||
$self->{whitelist}->save;
|
||||
return "Flag set.";
|
||||
}
|
||||
@ -201,55 +203,45 @@ sub whitelist {
|
||||
my ($channel, $mask, $flag) = $self->{pbot}->{interpreter}->split_args($arglist, 3);
|
||||
return "Usage: whitelist unset <channel> <mask> <flag>" if not defined $channel or not defined $mask or not defined $flag;
|
||||
|
||||
if (not exists $self->{whitelist}->hash->{$channel}) {
|
||||
if (not exists $self->{whitelist}->{hash}->{lc $channel}) {
|
||||
return "There is no such channel `$channel` in the whitelist.";
|
||||
}
|
||||
|
||||
if (not exists $self->{whitelist}->hash->{$channel}->{$mask}) {
|
||||
if (not exists $self->{whitelist}->{hash}->{lc $channel}->{lc $mask}) {
|
||||
return "There is no such mask `$mask` for channel `$channel` in the whitelist.";
|
||||
}
|
||||
|
||||
if (not exists $self->{whitelist}->hash->{$channel}->{$mask}->{$flag}) {
|
||||
if (not exists $self->{whitelist}->{hash}->{lc $channel}->{lc $mask}->{$flag}) {
|
||||
return "There is no such flag `$flag` for mask `$mask` for channel `$channel` in the whitelist.";
|
||||
}
|
||||
|
||||
delete $self->{whitelist}->hash->{$channel}->{$mask}->{$flag};
|
||||
delete $self->{whitelist}->{hash}->{lc $channel}->{lc $mask}->{$flag};
|
||||
$self->{whitelist}->save;
|
||||
return "Flag unset.";
|
||||
}
|
||||
when ("add") {
|
||||
my ($channel, $mask, $mode) = $self->{pbot}->{interpreter}->split_args($arglist, 3);
|
||||
return "Usage: whitelist add <channel> <mask> [mode (user or ban, default: user)]" if not defined $channel or not defined $mask;
|
||||
|
||||
$mode = 'user' if not defined $mode;
|
||||
|
||||
if ($mode eq 'user') {
|
||||
$self->{whitelist}->hash->{$channel}->{$mask}->{user} = 1;
|
||||
} else {
|
||||
$self->{whitelist}->hash->{$channel}->{$mask}->{ban} = 1;
|
||||
}
|
||||
$self->{whitelist}->hash->{$channel}->{$mask}->{owner} = "$nick!$user\@$host";
|
||||
$self->{whitelist}->hash->{$channel}->{$mask}->{created_on} = gettimeofday;
|
||||
my $data = {
|
||||
owner => "$nick!$user\@$host",
|
||||
created_on => scalar gettimeofday
|
||||
};
|
||||
|
||||
$self->{whitelist}->save;
|
||||
if ($mode eq 'user') {
|
||||
$data->{user} = 1;
|
||||
} else {
|
||||
$data->{ban} = 1;
|
||||
}
|
||||
|
||||
$self->{whitelist}->add($channel, $mask, $data);
|
||||
return "/say $mask whitelisted in channel $channel";
|
||||
}
|
||||
when ("remove") {
|
||||
my ($channel, $mask) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
|
||||
return "Usage: whitelist remove <channel> <mask>" if not defined $channel or not defined $mask;
|
||||
|
||||
if (not defined $self->{whitelist}->hash->{$channel}) {
|
||||
return "No whitelists for channel $channel";
|
||||
}
|
||||
|
||||
if (not defined $self->{whitelist}->hash->{$channel}->{$mask}) {
|
||||
return "No such whitelist $mask for channel $channel";
|
||||
}
|
||||
|
||||
delete $self->{whitelist}->hash->{$channel}->{$mask};
|
||||
delete $self->{whitelist}->hash->{$channel} if keys %{ $self->{whitelist}->hash->{$channel} } == 0;
|
||||
$self->{whitelist}->save;
|
||||
return "/say $mask whitelist removed from channel $channel";
|
||||
return $self->{whitelist}->remove($channel, $mask);
|
||||
}
|
||||
default {
|
||||
return "Unknown command '$command'; commands are: list/show, add, remove";
|
||||
@ -667,7 +659,7 @@ sub unbanme {
|
||||
|
||||
foreach my $channel (@channels) {
|
||||
next if exists $unbanned->{$channel} and exists $unbanned->{$channel}->{$mask};
|
||||
next if not $self->{pbot}->{chanops}->{unban_timeout}->find_index($channel . '-floodbans', $mask);
|
||||
next if not $self->{pbot}->{chanops}->{unban_timeout}->exists($channel . '-floodbans', $mask);
|
||||
|
||||
my $message_account = $self->{pbot}->{messagehistory}->{database}->get_message_account($anick, $auser, $ahost);
|
||||
my @nickserv_accounts = $self->{pbot}->{messagehistory}->{database}->get_nickserv_accounts($message_account);
|
||||
|
@ -46,14 +46,16 @@ sub initialize {
|
||||
|
||||
sub is_spam {
|
||||
my ($self, $namespace, $text, $all_namespaces) = @_;
|
||||
my $lc_namespace = lc $namespace;
|
||||
|
||||
return 0 if not $self->{pbot}->{registry}->get_value('antispam', 'enforce');
|
||||
return 0 if $self->{pbot}->{registry}->get_value($namespace, 'dont_enforce_antispam');
|
||||
|
||||
my $ret = eval {
|
||||
foreach my $space (keys %{ $self->{keywords}->hash }) {
|
||||
if ($all_namespaces or $namespace =~ m/^$space$/i) {
|
||||
foreach my $keyword (keys %{ $self->{keywords}->hash->{$space} }) {
|
||||
foreach my $space (keys %{ $self->{keywords}->{hash} }) {
|
||||
if ($all_namespaces or $lc_namespace eq $space) {
|
||||
foreach my $keyword (keys %{ $self->{keywords}->{hash}->{$space} }) {
|
||||
next if $keyword eq '_name';
|
||||
return 1 if $text =~ m/$keyword/i;
|
||||
}
|
||||
}
|
||||
@ -82,10 +84,11 @@ sub antispam_cmd {
|
||||
when ($_ eq "list" or $_ eq "show") {
|
||||
my $text = "Spam keywords:\n";
|
||||
my $entries = 0;
|
||||
foreach my $namespace (keys %{ $self->{keywords}->hash }) {
|
||||
$text .= " $namespace:\n";
|
||||
foreach my $keyword (keys %{ $self->{keywords}->hash->{$namespace} }) {
|
||||
$text .= " $keyword,\n";
|
||||
foreach my $namespace (keys %{ $self->{keywords}->{hash} }) {
|
||||
$text .= " $self->{keywords}->{hash}->{$namespace}->{_name}:\n";
|
||||
foreach my $keyword (keys %{ $self->{keywords}->{hash}->{$namespace} }) {
|
||||
next if $keyword eq '_name';
|
||||
$text .= " $self->{keywords}->{hash}->{$namespace}->{$keyword}->{_name},\n";
|
||||
$entries++;
|
||||
}
|
||||
}
|
||||
@ -96,23 +99,23 @@ sub antispam_cmd {
|
||||
my ($namespace, $keyword, $flag, $value) = $self->{pbot}->{interpreter}->split_args($arglist, 4);
|
||||
return "Usage: antispam set <namespace> <regex> [flag] [value]" if not defined $namespace or not defined $keyword;
|
||||
|
||||
if (not exists $self->{keywords}->hash->{$namespace}) {
|
||||
if (not exists $self->{keywords}->{hash}->{lc $namespace}) {
|
||||
return "There is no such namespace `$namespace`.";
|
||||
}
|
||||
|
||||
if (not exists $self->{keywords}->hash->{$namespace}->{$keyword}) {
|
||||
return "There is no such regex `$keyword` for namespace `$namespace`.";
|
||||
if (not exists $self->{keywords}->{hash}->{lc $namespace}->{lc $keyword}) {
|
||||
return "There is no such regex `$keyword` for namespace `$self->{keywords}->{hash}->{$namespace}->{_name}`.";
|
||||
}
|
||||
|
||||
if (not defined $flag) {
|
||||
my $text = "Flags:\n";
|
||||
my $comma = '';
|
||||
foreach $flag (keys %{ $self->{keywords}->hash->{$namespace}->{$keyword} }) {
|
||||
foreach $flag (keys %{ $self->{keywords}->{hash}->{lc $namespace}->{lc $keyword} }) {
|
||||
if ($flag eq 'created_on') {
|
||||
my $timestamp = strftime "%a %b %e %H:%M:%S %Z %Y", localtime $self->{keywords}->hash->{$namespace}->{$keyword}->{$flag};
|
||||
my $timestamp = strftime "%a %b %e %H:%M:%S %Z %Y", localtime $self->{keywords}->{hash}->{lc $namespace}->{lc $keyword}->{$flag};
|
||||
$text .= $comma . "created_on: $timestamp";
|
||||
} else {
|
||||
$value = $self->{keywords}->hash->{$namespace}->{$keyword}->{$flag};
|
||||
$value = $self->{keywords}->{hash}->{lc $namespace}->{lc $keyword}->{$flag};
|
||||
$text .= $comma . "$flag: $value";
|
||||
}
|
||||
$comma = ",\n ";
|
||||
@ -121,7 +124,7 @@ sub antispam_cmd {
|
||||
}
|
||||
|
||||
if (not defined $value) {
|
||||
$value = $self->{keywords}->hash->{$namespace}->{$keyword}->{$flag};
|
||||
$value = $self->{keywords}->{hash}->{lc $namespace}->{lc $keyword}->{$flag};
|
||||
if (not defined $value) {
|
||||
return "/say $flag is not set.";
|
||||
} else {
|
||||
@ -129,7 +132,7 @@ sub antispam_cmd {
|
||||
}
|
||||
}
|
||||
|
||||
$self->{keywords}->hash->{$namespace}->{$keyword}->{$flag} = $value;
|
||||
$self->{keywords}->{hash}->{lc $namespace}->{lc $keyword}->{$flag} = $value;
|
||||
$self->{keywords}->save;
|
||||
return "Flag set.";
|
||||
}
|
||||
@ -137,46 +140,36 @@ sub antispam_cmd {
|
||||
my ($namespace, $keyword, $flag) = $self->{pbot}->{interpreter}->split_args($arglist, 3);
|
||||
return "Usage: antispam unset <namespace> <regex> <flag>" if not defined $namespace or not defined $keyword or not defined $flag;
|
||||
|
||||
if (not exists $self->{keywords}->hash->{$namespace}) {
|
||||
if (not exists $self->{keywords}->{hash}->{lc $namespace}) {
|
||||
return "There is no such namespace `$namespace`.";
|
||||
}
|
||||
|
||||
if (not exists $self->{keywords}->hash->{$namespace}->{$keyword}) {
|
||||
if (not exists $self->{keywords}->{hash}->{lc $namespace}->{lc $keyword}) {
|
||||
return "There is no such keyword `$keyword` for namespace `$namespace`.";
|
||||
}
|
||||
|
||||
if (not exists $self->{keywords}->hash->{$namespace}->{$keyword}->{$flag}) {
|
||||
if (not exists $self->{keywords}->{hash}->{lc $namespace}->{lc $keyword}->{$flag}) {
|
||||
return "There is no such flag `$flag` for regex `$keyword` for namespace `$namespace`.";
|
||||
}
|
||||
|
||||
delete $self->{keywords}->hash->{$namespace}->{$keyword}->{$flag};
|
||||
delete $self->{keywords}->{hash}->{lc $namespace}->{lc $keyword}->{$flag};
|
||||
$self->{keywords}->save;
|
||||
return "Flag unset.";
|
||||
}
|
||||
when ("add") {
|
||||
my ($namespace, $keyword) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
|
||||
return "Usage: antispam add <namespace> <regex>" if not defined $namespace or not defined $keyword;
|
||||
$self->{keywords}->hash->{$namespace}->{$keyword}->{owner} = "$nick!$user\@$host";
|
||||
$self->{keywords}->hash->{$namespace}->{$keyword}->{created_on} = gettimeofday;
|
||||
$self->{keywords}->save;
|
||||
my $data = {
|
||||
owner => "$nick!$user\@$host",
|
||||
created_on => scalar gettimeofday
|
||||
};
|
||||
$self->{keywords}->add($namespace, $keyword, $data);
|
||||
return "/say Added `$keyword`.";
|
||||
}
|
||||
when ("remove") {
|
||||
my ($namespace, $keyword) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
|
||||
return "Usage: antispam remove <namespace> <regex>" if not defined $namespace or not defined $keyword;
|
||||
|
||||
if (not defined $self->{keywords}->hash->{$namespace}) {
|
||||
return "No entries for namespace $namespace";
|
||||
}
|
||||
|
||||
if (not defined $self->{keywords}->hash->{$namespace}->{$keyword}) {
|
||||
return "No such entry for namespace $namespace";
|
||||
}
|
||||
|
||||
delete $self->{keywords}->hash->{$namespace}->{$keyword};
|
||||
delete $self->{keywords}->hash->{$namespace} if keys %{ $self->{keywords}->hash->{$namespace} } == 0;
|
||||
$self->{keywords}->save;
|
||||
return "/say Removed `$keyword`.";
|
||||
return $self->{keywords}->remove($namespace, $keyword);
|
||||
}
|
||||
default {
|
||||
return "Unknown command '$command'; commands are: list/show, add, remove";
|
||||
|
@ -92,11 +92,11 @@ sub on_banlist_entry {
|
||||
}
|
||||
|
||||
if ($timeout && $self->{pbot}->{chanops}->can_gain_ops($channel)) {
|
||||
if (not exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$target}) {
|
||||
if (not exists $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$target}) {
|
||||
$self->{pbot}->{logger}->log("Temp ban for $target in $channel.\n");
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$target}{timeout} = gettimeofday + $timeout;
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$target}{owner} = $source;
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$target}{reason} = 'Temp ban on *!*@... or *!...@gateway/web';
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$target}->{timeout} = gettimeofday + $timeout;
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$target}->{owner} = $source;
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$target}->{reason} = 'Temp ban on *!*@... or *!...@gateway/web';
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->save;
|
||||
}
|
||||
}
|
||||
@ -228,15 +228,15 @@ sub track_mode {
|
||||
delete $self->{banlist}->{$channel}->{$mode eq "-b" ? "+b" : "+q"}->{$target};
|
||||
|
||||
if ($mode eq "-b") {
|
||||
if ($self->{pbot}->{chanops}->{unban_timeout}->find_index($channel, $target)) {
|
||||
if ($self->{pbot}->{chanops}->{unban_timeout}->exists($channel, $target)) {
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->remove($channel, $target);
|
||||
} elsif ($self->{pbot}->{chanops}->{unban_timeout}->find_index($channel, "$target\$##stop_join_flood")) {
|
||||
} elsif ($self->{pbot}->{chanops}->{unban_timeout}->exists($channel, "$target\$##stop_join_flood")) {
|
||||
# freenode strips channel forwards from unban result if no ban exists with a channel forward
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->remove($channel, "$target\$##stop_join_flood");
|
||||
}
|
||||
}
|
||||
elsif ($mode eq "-q") {
|
||||
if ($self->{pbot}->{chanops}->{unmute_timeout}->find_index($channel, $target)) {
|
||||
if ($self->{pbot}->{chanops}->{unmute_timeout}->exists($channel, $target)) {
|
||||
$self->{pbot}->{chanops}->{unmute_timeout}->remove($channel, $target);
|
||||
}
|
||||
}
|
||||
|
@ -158,10 +158,11 @@ sub adminrem {
|
||||
|
||||
$channel = '.*' if $channel eq 'global';
|
||||
|
||||
if (exists $self->{pbot}->{admins}->{admins}->hash->{$channel}) {
|
||||
if (not exists $self->{pbot}->{admins}->{admins}->hash->{$channel}->{$hostmask}) {
|
||||
foreach my $mask (keys %{ $self->{pbot}->{admins}->{admins}->hash->{$channel} }) {
|
||||
if ($self->{pbot}->{admins}->{admins}->hash->{$channel}->{$mask}->{name} eq $hostmask) {
|
||||
if (exists $self->{pbot}->{admins}->{admins}->{hash}->{$channel}) {
|
||||
if (not exists $self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$hostmask}) {
|
||||
foreach my $mask (keys %{ $self->{pbot}->{admins}->{admins}->{hash}->{$channel} }) {
|
||||
next if $mask eq '_name';
|
||||
if ($self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$mask}->{name} eq $hostmask) {
|
||||
$hostmask = $mask;
|
||||
last;
|
||||
}
|
||||
@ -169,11 +170,7 @@ sub adminrem {
|
||||
}
|
||||
}
|
||||
|
||||
if ($self->{pbot}->{admins}->remove_admin($channel, $hostmask)) {
|
||||
return "Admin removed.";
|
||||
} else {
|
||||
return "No such admin found.";
|
||||
}
|
||||
return $self->{pbot}->{admins}->remove_admin($channel, $hostmask);
|
||||
}
|
||||
|
||||
sub adminset {
|
||||
@ -190,10 +187,11 @@ sub adminset {
|
||||
|
||||
$channel = '.*' if $channel eq 'global';
|
||||
|
||||
if (exists $self->{pbot}->{admins}->{admins}->hash->{$channel}) {
|
||||
if (not exists $self->{pbot}->{admins}->{admins}->hash->{$channel}->{$hostmask}) {
|
||||
foreach my $mask (keys %{ $self->{pbot}->{admins}->{admins}->hash->{$channel} }) {
|
||||
if ($self->{pbot}->{admins}->{admins}->hash->{$channel}->{$mask}->{name} eq $hostmask) {
|
||||
if (exists $self->{pbot}->{admins}->{admins}->{hash}->{$channel}) {
|
||||
if (not exists $self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$hostmask}) {
|
||||
foreach my $mask (keys %{ $self->{pbot}->{admins}->{admins}->{hash}->{$channel} }) {
|
||||
next if $mask eq '_name';
|
||||
if ($self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$mask}->{name} eq $hostmask) {
|
||||
$hostmask = $mask;
|
||||
last;
|
||||
}
|
||||
@ -239,10 +237,11 @@ sub adminunset {
|
||||
|
||||
$channel = '.*' if $channel eq 'global';
|
||||
|
||||
if (exists $self->{pbot}->{admins}->{admins}->hash->{$channel}) {
|
||||
if (not exists $self->{pbot}->{admins}->{admins}->hash->{$channel}->{$hostmask}) {
|
||||
foreach my $mask (keys %{ $self->{pbot}->{admins}->{admins}->hash->{$channel} }) {
|
||||
if ($self->{pbot}->{admins}->{admins}->hash->{$channel}->{$mask}->{name} eq $hostmask) {
|
||||
if (exists $self->{pbot}->{admins}->{admins}->{hash}->{$channel}) {
|
||||
if (not exists $self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$hostmask}) {
|
||||
foreach my $mask (keys %{ $self->{pbot}->{admins}->{admins}->{hash}->{$channel} }) {
|
||||
next if $mask eq '_name';
|
||||
if ($self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$mask}->{name} eq $hostmask) {
|
||||
$hostmask = $mask;
|
||||
last;
|
||||
}
|
||||
|
@ -38,45 +38,29 @@ sub initialize {
|
||||
sub add_admin {
|
||||
my $self = shift;
|
||||
my ($name, $channel, $hostmask, $level, $password, $dont_save) = @_;
|
||||
$channel = lc $channel;
|
||||
$channel = '.*' if $channel !~ m/^#/;
|
||||
$hostmask = lc $hostmask;
|
||||
$self->{admins}->hash->{$channel}->{$hostmask}->{name} = $name;
|
||||
$self->{admins}->hash->{$channel}->{$hostmask}->{level} = $level;
|
||||
$self->{admins}->hash->{$channel}->{$hostmask}->{password} = $password;
|
||||
|
||||
my $data = {
|
||||
name => $name,
|
||||
level => $level,
|
||||
password => $password
|
||||
};
|
||||
|
||||
$self->{pbot}->{logger}->log("Adding new level $level admin: [$name] [$hostmask] for channel [$channel]\n");
|
||||
$self->save_admins unless $dont_save;
|
||||
$self->{admins}->add($channel, $hostmask, $data, $dont_save);
|
||||
}
|
||||
|
||||
sub remove_admin {
|
||||
my $self = shift;
|
||||
my ($channel, $hostmask) = @_;
|
||||
|
||||
$channel = lc $channel;
|
||||
$hostmask = lc $hostmask;
|
||||
$channel = '.*' if $channel !~ m/^#/;
|
||||
|
||||
my $admin = delete $self->{admins}->hash->{$channel}->{$hostmask};
|
||||
|
||||
if (not keys %{$self->{admins}->hash->{$channel}}) {
|
||||
delete $self->{admins}->hash->{$channel};
|
||||
}
|
||||
|
||||
if (defined $admin) {
|
||||
$self->{pbot}->{logger}->log("Removed level $admin->{level} admin [$admin->{name}] [$hostmask] from channel [$channel]\n");
|
||||
$self->save_admins;
|
||||
return 1;
|
||||
} else {
|
||||
$self->{pbot}->{logger}->log("Attempt to remove non-existent admin [$hostmask] from channel [$channel]\n");
|
||||
return 0;
|
||||
}
|
||||
return $self->{admins}->remove($channel, $hostmask);
|
||||
}
|
||||
|
||||
sub load_admins {
|
||||
my $self = shift;
|
||||
my $filename;
|
||||
|
||||
if (@_) { $filename = shift; } else { $filename = $self->{admins}->filename; }
|
||||
if (@_) { $filename = shift; } else { $filename = $self->{admins}->{filename}; }
|
||||
|
||||
if (not defined $filename) {
|
||||
Carp::carp "No admins path specified -- skipping loading of admins";
|
||||
@ -86,18 +70,20 @@ sub load_admins {
|
||||
$self->{admins}->load;
|
||||
|
||||
my $i = 0;
|
||||
foreach my $channel (keys %{ $self->{admins}->hash } ) {
|
||||
foreach my $hostmask (keys %{ $self->{admins}->hash->{$channel} }) {
|
||||
foreach my $channel (sort keys %{ $self->{admins}->{hash} } ) {
|
||||
foreach my $hostmask (sort keys %{ $self->{admins}->{hash}->{$channel} }) {
|
||||
next if $hostmask eq '_name';
|
||||
$i++;
|
||||
my $name = $self->{admins}->hash->{$channel}->{$hostmask}->{name};
|
||||
my $level = $self->{admins}->hash->{$channel}->{$hostmask}->{level};
|
||||
my $password = $self->{admins}->hash->{$channel}->{$hostmask}->{password};
|
||||
my $name = $self->{admins}->{hash}->{$channel}->{$hostmask}->{name};
|
||||
my $level = $self->{admins}->{hash}->{$channel}->{$hostmask}->{level};
|
||||
my $password = $self->{admins}->{hash}->{$channel}->{$hostmask}->{password};
|
||||
|
||||
if (not defined $name or not defined $level or not defined $password) {
|
||||
Carp::croak "Admin #$i of $filename is missing critical data\n";
|
||||
Carp::croak "An admin in $filename is missing critical data\n";
|
||||
}
|
||||
|
||||
$self->{pbot}->{logger}->log("Adding new level $level admin: [$name] [$hostmask] for channel [$channel]\n");
|
||||
my $chan = $channel eq '.*' ? 'global' : $channel;
|
||||
$self->{pbot}->{logger}->log("Adding new level $level $chan admin: $name $hostmask\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,18 +103,19 @@ sub find_admin {
|
||||
$hostmask = lc $hostmask;
|
||||
|
||||
my $result = eval {
|
||||
foreach my $channel_regex (keys %{ $self->{admins}->hash }) {
|
||||
foreach my $channel_regex (keys %{ $self->{admins}->{hash} }) {
|
||||
if ($from !~ m/^#/ or $from =~ m/^$channel_regex$/i) {
|
||||
foreach my $hostmask_regex (keys %{ $self->{admins}->hash->{$channel_regex} }) {
|
||||
foreach my $hostmask_regex (keys %{ $self->{admins}->{hash}->{$channel_regex} }) {
|
||||
next if $hostmask_regex eq '_name';
|
||||
if ($hostmask_regex =~ m/[*?]/) {
|
||||
# contains * or ? so it's converted to a regex
|
||||
my $hostmask_quoted = quotemeta $hostmask_regex;
|
||||
$hostmask_quoted =~ s/\\\*/.*?/g;
|
||||
$hostmask_quoted =~ s/\\\?/./g;
|
||||
return $self->{admins}->hash->{$channel_regex}->{$hostmask_regex} if $hostmask =~ m/^$hostmask_quoted$/i;
|
||||
return $self->{admins}->{hash}->{$channel_regex}->{$hostmask_regex} if $hostmask =~ m/^$hostmask_quoted$/i;
|
||||
} else {
|
||||
# direct comparison
|
||||
return $self->{admins}->hash->{$channel_regex}->{$hostmask_regex} if $hostmask eq lc $hostmask_regex;
|
||||
return $self->{admins}->{hash}->{$channel_regex}->{$hostmask_regex} if $hostmask eq lc $hostmask_regex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,13 +278,13 @@ sub checkban {
|
||||
$channel = lc $channel;
|
||||
$target = lc $target;
|
||||
|
||||
my $mask = $self->{pbot}->{chanops}->nick_to_banmask($target);
|
||||
my $mask = lc $self->{pbot}->{chanops}->nick_to_banmask($target);
|
||||
|
||||
if (exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}
|
||||
&& exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}) {
|
||||
my $timeout = $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}{timeout};
|
||||
my $owner = $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}{owner};
|
||||
my $reason = $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}{reason};
|
||||
if (exists $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}
|
||||
&& exists $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$mask}) {
|
||||
my $timeout = $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$mask}->{timeout};
|
||||
my $owner = $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$mask}->{owner};
|
||||
my $reason = $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$mask}->{reason};
|
||||
my $duration = concise duration($timeout - gettimeofday);
|
||||
|
||||
my $result = "$mask banned in $channel ";
|
||||
@ -316,13 +316,13 @@ sub checkmute {
|
||||
$channel = lc $channel;
|
||||
$target = lc $target;
|
||||
|
||||
my $mask = $self->{pbot}->{chanops}->nick_to_banmask($target);
|
||||
my $mask = lc $self->{pbot}->{chanops}->nick_to_banmask($target);
|
||||
|
||||
if (exists $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}
|
||||
&& exists $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}) {
|
||||
my $timeout = $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}{timeout};
|
||||
my $owner = $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}{owner};
|
||||
my $reason = $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}{reason};
|
||||
if (exists $self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{$channel}
|
||||
&& exists $self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{$channel}->{$mask}) {
|
||||
my $timeout = $self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{$channel}->{$mask}->{timeout};
|
||||
my $owner = $self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{$channel}->{$mask}->{owner};
|
||||
my $reason = $self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{$channel}->{$mask}->{reason};
|
||||
my $duration = concise duration($timeout - gettimeofday);
|
||||
|
||||
my $result = "$mask muted in $channel ";
|
||||
@ -386,11 +386,11 @@ sub ban_user {
|
||||
my @targets = split /,/, $target;
|
||||
my $immediately = @targets > 1 ? 0 : 1;
|
||||
foreach my $t (@targets) {
|
||||
my $mask = $self->{pbot}->{chanops}->nick_to_banmask($t);
|
||||
my $mask = lc $self->{pbot}->{chanops}->nick_to_banmask($t);
|
||||
|
||||
if ($no_length && exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}
|
||||
&& exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}) {
|
||||
my $timeout = $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}{timeout};
|
||||
if ($no_length && exists $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}
|
||||
&& exists $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$mask}) {
|
||||
my $timeout = $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{$channel}->{$mask}->{timeout};
|
||||
my $duration = duration($timeout - gettimeofday);
|
||||
|
||||
$result .= "$sep$mask has $duration remaining on their $channel ban";
|
||||
@ -517,11 +517,11 @@ sub mute_user {
|
||||
my @targets = split /,/, $target;
|
||||
my $immediately = @targets > 1 ? 0 : 1;
|
||||
foreach my $t (@targets) {
|
||||
my $mask = $self->{pbot}->{chanops}->nick_to_banmask($t);
|
||||
my $mask = lc $self->{pbot}->{chanops}->nick_to_banmask($t);
|
||||
|
||||
if ($no_length && exists $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}
|
||||
&& exists $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}) {
|
||||
my $timeout = $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}{timeout};
|
||||
if ($no_length && exists $self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{$channel}
|
||||
&& exists $self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{$channel}->{$mask}) {
|
||||
my $timeout = $self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{$channel}->{$mask}->{timeout};
|
||||
my $duration = duration($timeout - gettimeofday);
|
||||
|
||||
$result .= "$sep$mask has $duration remaining on their $channel mute";
|
||||
|
@ -69,9 +69,9 @@ sub initialize {
|
||||
sub can_gain_ops {
|
||||
my ($self, $channel) = @_;
|
||||
$channel = lc $channel;
|
||||
return exists $self->{pbot}->{channels}->{channels}->hash->{$channel}
|
||||
&& $self->{pbot}->{channels}->{channels}->hash->{$channel}{chanop}
|
||||
&& $self->{pbot}->{channels}->{channels}->hash->{$channel}{enabled};
|
||||
return exists $self->{pbot}->{channels}->{channels}->{hash}->{$channel}
|
||||
&& $self->{pbot}->{channels}->{channels}->{hash}->{$channel}->{chanop}
|
||||
&& $self->{pbot}->{channels}->{channels}->{hash}->{$channel}->{enabled};
|
||||
}
|
||||
|
||||
sub gain_ops {
|
||||
@ -240,14 +240,14 @@ sub ban_user_timed {
|
||||
$self->ban_user($mask, $channel, $immediately);
|
||||
|
||||
if ($length > 0) {
|
||||
$self->{unban_timeout}->hash->{$channel}->{$mask}{timeout} = gettimeofday + $length;
|
||||
$self->{unban_timeout}->hash->{$channel}->{$mask}{owner} = $owner if defined $owner;
|
||||
$self->{unban_timeout}->hash->{$channel}->{$mask}{reason} = $reason if defined $reason;
|
||||
$self->{unban_timeout}->save;
|
||||
my $data = {
|
||||
timeout => gettimeofday + $length
|
||||
};
|
||||
$data->{owner} = $owner if defined $owner;
|
||||
$data->{reason} = $reason if defined $reason;
|
||||
$self->{unban_timeout}->add($channel, $mask, $data);
|
||||
} else {
|
||||
if ($self->{pbot}->{chanops}->{unban_timeout}->find_index($channel, $mask)) {
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->remove($channel, $mask);
|
||||
}
|
||||
$self->{unban_timeout}->remove($channel, $mask);
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,14 +281,14 @@ sub mute_user_timed {
|
||||
$self->mute_user($mask, $channel, $immediately);
|
||||
|
||||
if ($length > 0) {
|
||||
$self->{unmute_timeout}->hash->{$channel}->{$mask}{timeout} = gettimeofday + $length;
|
||||
$self->{unmute_timeout}->hash->{$channel}->{$mask}{owner} = $owner if defined $owner;
|
||||
$self->{unmute_timeout}->hash->{$channel}->{$mask}{reason} = $reason if defined $reason;
|
||||
$self->{unmute_timeout}->save;
|
||||
my $data = {
|
||||
timeout => gettimeofday + $length
|
||||
};
|
||||
$data->{owner} = $owner if defined $owner;
|
||||
$data->{reason} = $reason if defined $reason;
|
||||
$self->{unmute_timeout}->add($channel, $mask, $data);
|
||||
} else {
|
||||
if ($self->{pbot}->{chanops}->{unmute_timeout}->find_index($channel, $mask)) {
|
||||
$self->{pbot}->{chanops}->{unmute_timeout}->remove($channel, $mask);
|
||||
}
|
||||
$self->{unmute_timeout}->remove($channel, $mask);
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,9 +304,8 @@ sub join_channel {
|
||||
delete $self->{is_opped}->{$channel};
|
||||
delete $self->{op_requested}->{$channel};
|
||||
|
||||
if (exists $self->{pbot}->{channels}->{channels}->hash->{$channel}
|
||||
and exists $self->{pbot}->{channels}->{channels}->hash->{$channel}{permop}
|
||||
and $self->{pbot}->{channels}->{channels}->hash->{$channel}{permop}) {
|
||||
if (exists $self->{pbot}->{channels}->{channels}->{hash}->{lc $channel}
|
||||
and $self->{pbot}->{channels}->{channels}->{hash}->{lc $channel}->{permop}) {
|
||||
$self->gain_ops($channel);
|
||||
}
|
||||
|
||||
@ -328,12 +327,12 @@ sub part_channel {
|
||||
|
||||
sub has_ban_timeout {
|
||||
my ($self, $channel, $mask) = @_;
|
||||
return exists $self->{unban_timeout}->hash->{lc $channel}->{lc $mask};
|
||||
return exists $self->{unban_timeout}->{hash}->{lc $channel}->{lc $mask};
|
||||
}
|
||||
|
||||
sub has_mute_timeout {
|
||||
my ($self, $channel, $mask) = @_;
|
||||
return exists $self->{unmute_timeout}->hash->{lc $channel}->{lc $mask};
|
||||
return exists $self->{unmute_timeout}->{hash}->{lc $channel}->{lc $mask};
|
||||
}
|
||||
|
||||
sub add_to_ban_queue {
|
||||
@ -443,10 +442,11 @@ sub check_unban_timeouts {
|
||||
|
||||
my $now = gettimeofday();
|
||||
|
||||
foreach my $channel (keys %{ $self->{unban_timeout}->hash }) {
|
||||
foreach my $mask (keys %{ $self->{unban_timeout}->hash->{$channel} }) {
|
||||
if ($self->{unban_timeout}->hash->{$channel}->{$mask}{timeout} < $now) {
|
||||
$self->{unban_timeout}->hash->{$channel}->{$mask}{timeout} = $now + 7200;
|
||||
foreach my $channel (keys %{ $self->{unban_timeout}->{hash} }) {
|
||||
foreach my $mask (keys %{ $self->{unban_timeout}->{hash}->{$channel} }) {
|
||||
next if $mask eq '_name';
|
||||
if ($self->{unban_timeout}->{hash}->{$channel}->{$mask}->{timeout} < $now) {
|
||||
$self->{unban_timeout}->{hash}->{$channel}->{$mask}->{timeout} = $now + 7200;
|
||||
$self->unban_user($mask, $channel);
|
||||
}
|
||||
}
|
||||
@ -460,10 +460,11 @@ sub check_unmute_timeouts {
|
||||
|
||||
my $now = gettimeofday();
|
||||
|
||||
foreach my $channel (keys %{ $self->{unmute_timeout}->hash }) {
|
||||
foreach my $mask (keys %{ $self->{unmute_timeout}->hash->{$channel} }) {
|
||||
if ($self->{unmute_timeout}->hash->{$channel}->{$mask}{timeout} < $now) {
|
||||
$self->{unmute_timeout}->hash->{$channel}->{$mask}{timeout} = $now + 7200;
|
||||
foreach my $channel (keys %{ $self->{unmute_timeout}->{hash} }) {
|
||||
foreach my $mask (keys %{ $self->{unmute_timeout}->{hash}->{$channel} }) {
|
||||
next if $mask eq '_name';
|
||||
if ($self->{unmute_timeout}->{hash}->{$channel}->{$mask}->{timeout} < $now) {
|
||||
$self->{unmute_timeout}->{hash}->{$channel}->{$mask}->{timeout} = $now + 7200;
|
||||
$self->unmute_user($mask, $channel);
|
||||
}
|
||||
}
|
||||
@ -476,21 +477,17 @@ sub check_opped_timeouts {
|
||||
|
||||
foreach my $channel (keys %{ $self->{is_opped} }) {
|
||||
if ($self->{is_opped}->{$channel}{timeout} < $now) {
|
||||
unless (exists $self->{pbot}->{channels}->{channels}->hash->{$channel}
|
||||
and exists $self->{pbot}->{channels}->{channels}->hash->{$channel}{permop}
|
||||
and $self->{pbot}->{channels}->{channels}->hash->{$channel}{permop}) {
|
||||
unless (exists $self->{pbot}->{channels}->{channels}->{hash}->{lc $channel}
|
||||
and $self->{pbot}->{channels}->{channels}->{hash}->{lc $channel}->{permop}) {
|
||||
$self->lose_ops($channel);
|
||||
}
|
||||
} else {
|
||||
# my $timediff = $self->{is_opped}->{$channel}{timeout} - $now;
|
||||
# $self->{pbot}->{logger}->log("deop $channel in $timediff seconds\n");
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $channel (keys %{ $self->{op_requested} }) {
|
||||
if ($now - $self->{op_requested}->{$channel} > 60 * 5) {
|
||||
if (exists $self->{pbot}->{channels}->{channels}->hash->{$channel}
|
||||
and $self->{pbot}->{channels}->{channels}->hash->{$channel}{enabled}) {
|
||||
if (exists $self->{pbot}->{channels}->{channels}->{hash}->{lc $channel}
|
||||
and $self->{pbot}->{channels}->{channels}->{hash}->{lc $channel}->{enabled}) {
|
||||
$self->{pbot}->{logger}->log("5 minutes since OP request for $channel and no OP yet; trying again ...\n");
|
||||
delete $self->{op_requested}->{$channel};
|
||||
$self->gain_ops($channel);
|
||||
|
@ -18,12 +18,8 @@ use Carp ();
|
||||
use PBot::HashObject;
|
||||
|
||||
sub new {
|
||||
if (ref($_[1]) eq 'HASH') {
|
||||
Carp::croak ("Options to " . __FILE__ . " should be key/value pairs, not hash reference");
|
||||
}
|
||||
|
||||
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;
|
||||
@ -32,37 +28,29 @@ sub new {
|
||||
sub initialize {
|
||||
my ($self, %conf) = @_;
|
||||
|
||||
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
||||
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
||||
|
||||
$self->{channels} = PBot::HashObject->new(pbot => $self->{pbot}, name => 'Channels', filename => delete $conf{filename});
|
||||
$self->{channels} = PBot::HashObject->new(pbot => $self->{pbot}, name => 'Channels', filename => $conf{filename});
|
||||
$self->load_channels;
|
||||
|
||||
$self->{pbot}->{commands}->register(sub { $self->set(@_) }, "chanset", 40);
|
||||
$self->{pbot}->{commands}->register(sub { $self->unset(@_) }, "chanunset", 40);
|
||||
$self->{pbot}->{commands}->register(sub { $self->add(@_) }, "chanadd", 40);
|
||||
$self->{pbot}->{commands}->register(sub { $self->remove(@_) }, "chanrem", 40);
|
||||
$self->{pbot}->{commands}->register(sub { $self->list(@_) }, "chanlist", 10);
|
||||
$self->{pbot}->{commands}->register(sub { $self->set(@_) }, "chanset", 40);
|
||||
$self->{pbot}->{commands}->register(sub { $self->unset(@_) }, "chanunset", 40);
|
||||
$self->{pbot}->{commands}->register(sub { $self->add(@_) }, "chanadd", 40);
|
||||
$self->{pbot}->{commands}->register(sub { $self->remove(@_) }, "chanrem", 40);
|
||||
$self->{pbot}->{commands}->register(sub { $self->list(@_) }, "chanlist", 10);
|
||||
}
|
||||
|
||||
sub set {
|
||||
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
my ($channel, $key, $value) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
|
||||
|
||||
if (not defined $channel) {
|
||||
return "Usage: chanset <channel> [key [value]]";
|
||||
}
|
||||
|
||||
return "Usage: chanset <channel> [key [value]]" if not defined $channel;
|
||||
return $self->{channels}->set($channel, $key, $value);
|
||||
}
|
||||
|
||||
sub unset {
|
||||
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
my ($channel, $key) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
|
||||
|
||||
if (not defined $channel or not defined $key) {
|
||||
return "Usage: chanunset <channel> <key>";
|
||||
}
|
||||
|
||||
return "Usage: chanunset <channel> <key>" if not defined $channel or not defined $key;
|
||||
return $self->{channels}->unset($channel, $key);
|
||||
}
|
||||
|
||||
@ -73,12 +61,13 @@ sub add {
|
||||
return "Usage: chanadd <channel>";
|
||||
}
|
||||
|
||||
my $hash = {};
|
||||
$hash->{enabled} = 1;
|
||||
$hash->{chanop} = 0;
|
||||
$hash->{permop} = 0;
|
||||
my $data = {
|
||||
enabled => 1,
|
||||
chanop => 0,
|
||||
permop => 0
|
||||
};
|
||||
|
||||
return $self->{channels}->add($arguments, $hash);
|
||||
return $self->{channels}->add($arguments, $data);
|
||||
}
|
||||
|
||||
sub remove {
|
||||
@ -95,11 +84,11 @@ sub list {
|
||||
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
||||
my $result;
|
||||
|
||||
foreach my $index (sort keys %{ $self->{channels}->hash }) {
|
||||
$result .= "$index: {";
|
||||
foreach my $index (sort keys %{ $self->{channels}->{hash} }) {
|
||||
$result .= "$self->{channels}->{hash}->{$index}->{_name}: {";
|
||||
my $comma = ' ';
|
||||
foreach my $key (sort keys %{ ${ $self->{channels}->hash }{$index} }) {
|
||||
$result .= "$comma$key => ${ $self->{channels}->hash }{$index}{$key}";
|
||||
foreach my $key (sort keys %{ $self->{channels}->{hash}->{$index} }) {
|
||||
$result .= "$comma$key => $self->{channels}->{hash}->{$index}->{$key}";
|
||||
$comma = ', ';
|
||||
}
|
||||
$result .= " }\n";
|
||||
@ -111,9 +100,9 @@ sub autojoin {
|
||||
my ($self) = @_;
|
||||
return if $self->{pbot}->{joined_channels};
|
||||
my $chans;
|
||||
foreach my $chan (keys %{ $self->{pbot}->{channels}->{channels}->hash }) {
|
||||
if ($self->{pbot}->{channels}->{channels}->hash->{$chan}{enabled}) {
|
||||
$chans .= "$chan,";
|
||||
foreach my $chan (keys %{ $self->{channels}->{hash} }) {
|
||||
if ($self->{channels}->{hash}->{$chan}->{enabled}) {
|
||||
$chans .= "$self->{channels}->{hash}->{$chan}->{_name},";
|
||||
}
|
||||
}
|
||||
$self->{pbot}->{logger}->log("Joining channels: $chans\n");
|
||||
@ -123,34 +112,30 @@ sub autojoin {
|
||||
|
||||
sub is_active {
|
||||
my ($self, $channel) = @_;
|
||||
return exists $self->{channels}->hash->{$channel} && $self->{channels}->hash->{$channel}->{enabled};
|
||||
my $lc_channel = lc $channel;
|
||||
return exists $self->{channels}->{hash}->{$lc_channel} && $self->{channels}->{hash}->{$lc_channel}->{enabled};
|
||||
}
|
||||
|
||||
sub is_active_op {
|
||||
my ($self, $channel) = @_;
|
||||
return $self->is_active($channel) && $self->{channels}->hash->{$channel}->{chanop};
|
||||
return $self->is_active($channel) && $self->{channels}->{hash}->{lc $channel}->{chanop};
|
||||
}
|
||||
|
||||
sub get_meta {
|
||||
my ($self, $channel, $key) = @_;
|
||||
my $index = $self->{channels}->find_hash($channel);
|
||||
return undef if not defined $index;
|
||||
return $self->{channels}->{hash}->{$index}->{$key};
|
||||
my $lc_channel = lc $channel;
|
||||
return undef if not exists $self->{channels}->{hash}->{$lc_channel};
|
||||
return $self->{channels}->{hash}->{$lc_channel}->{$key};
|
||||
}
|
||||
|
||||
sub load_channels {
|
||||
my $self = shift;
|
||||
$self->{channels}->load();
|
||||
my ($self) = @_;
|
||||
$self->{channels}->load;
|
||||
}
|
||||
|
||||
sub save_channels {
|
||||
my $self = shift;
|
||||
$self->{channels}->save();
|
||||
}
|
||||
|
||||
sub channels {
|
||||
my $self = shift;
|
||||
return $self->{channels};
|
||||
my ($self) = @_;
|
||||
$self->{channels}->save;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -2,7 +2,10 @@
|
||||
# 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.
|
||||
# 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.
|
||||
|
||||
# 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
|
||||
@ -20,12 +23,8 @@ use JSON;
|
||||
use Carp ();
|
||||
|
||||
sub new {
|
||||
if (ref($_[1]) eq 'HASH') {
|
||||
Carp::croak("Options to DualIndexHashObject should be key/value pairs, not hash reference");
|
||||
}
|
||||
|
||||
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;
|
||||
@ -33,34 +32,16 @@ sub new {
|
||||
|
||||
sub initialize {
|
||||
my ($self, %conf) = @_;
|
||||
|
||||
$self->{name} = delete $conf{name} // 'Dual Index hash object';
|
||||
$self->{filename} = delete $conf{filename} // Carp::carp("Missing filename to DualIndexHashObject, will not be able to save to or load from file.");
|
||||
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
||||
$self->{hash} = {};
|
||||
}
|
||||
|
||||
|
||||
sub hash_add {
|
||||
my ($self, $primary_index_key, $secondary_index_key, $hash) = @_;
|
||||
|
||||
if (defined $hash) {
|
||||
if (exists $self->hash->{$primary_index_key}->{$secondary_index_key}) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
foreach my $key (keys %$hash) {
|
||||
$self->hash->{$primary_index_key}->{$secondary_index_key}->{$key} = $hash->{$key};
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub load {
|
||||
my ($self, $filename) = @_;
|
||||
|
||||
$filename = $self->filename if not defined $filename;
|
||||
$filename = $self->{filename} if not defined $filename;
|
||||
|
||||
if (not defined $filename) {
|
||||
Carp::carp "No $self->{name} filename specified -- skipping loading from file";
|
||||
@ -81,13 +62,50 @@ sub load {
|
||||
|
||||
$self->{hash} = decode_json $contents if length $contents;
|
||||
close FILE;
|
||||
|
||||
# update existing entries to use _name to preserve case
|
||||
# and lowercase any non-lowercased entries
|
||||
foreach my $primary_index (keys %{ $self->{hash} }) {
|
||||
if (not exists $self->{hash}->{$primary_index}->{_name}) {
|
||||
if (lc $primary_index eq $primary_index) {
|
||||
$self->{hash}->{$primary_index}->{_name} = $primary_index;
|
||||
} else {
|
||||
if (exists $self->{hash}->{lc $primary_index}) {
|
||||
Carp::croak "Cannot update $self->{name} primary index $primary_index; duplicate object found";
|
||||
}
|
||||
|
||||
my $data = delete $self->{hash}->{$primary_index};
|
||||
$data->{_name} = $primary_index;
|
||||
$primary_index = lc $primary_index;
|
||||
$self->{hash}->{$primary_index} = $data;
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $secondary_index (keys %{ $self->{hash}->{$primary_index} }) {
|
||||
next if $secondary_index eq '_name';
|
||||
if (not exists $self->{hash}->{$primary_index}->{$secondary_index}->{_name}) {
|
||||
if (lc $secondary_index eq $secondary_index) {
|
||||
$self->{hash}->{$primary_index}->{$secondary_index}->{_name} = $secondary_index;
|
||||
} else {
|
||||
if (exists $self->{hash}->{$primary_index}->{lc $secondary_index}) {
|
||||
Carp::croak "Cannot update $self->{name} $primary_index sub-object $secondary_index; duplicate object found";
|
||||
}
|
||||
|
||||
my $data = delete $self->{hash}->{$primary_index}->{$secondary_index};
|
||||
$data->{_name} = $secondary_index;
|
||||
$secondary_index = lc $secondary_index;
|
||||
$self->{hash}->{$primary_index}->{$secondary_index} = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub save {
|
||||
my $self = shift;
|
||||
my $filename;
|
||||
|
||||
if (@_) { $filename = shift; } else { $filename = $self->filename; }
|
||||
if (@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
||||
|
||||
if (not defined $filename) {
|
||||
Carp::carp "No $self->{name} filename specified -- skipping saving to file.\n";
|
||||
@ -109,77 +127,61 @@ sub clear {
|
||||
$self->{hash} = {};
|
||||
}
|
||||
|
||||
sub find_index {
|
||||
my $self = shift;
|
||||
my ($primary_index_key, $secondary_index_key) = map {lc} @_;
|
||||
|
||||
return undef if not defined $primary_index_key;
|
||||
|
||||
return undef if not exists $self->hash->{$primary_index_key};
|
||||
|
||||
return $primary_index_key if not defined $secondary_index_key;
|
||||
|
||||
foreach my $index (keys %{ $self->hash->{$primary_index_key} }) {
|
||||
return $index if $secondary_index_key eq lc $index;
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub levenshtein_matches {
|
||||
my ($self, $primary_index_key, $secondary_index_key, $distance, $strictnamespace) = @_;
|
||||
my ($self, $primary_index, $secondary_index, $distance, $strictnamespace) = @_;
|
||||
my $comma = '';
|
||||
my $result = "";
|
||||
|
||||
$distance = 0.60 if not defined $distance;
|
||||
|
||||
$primary_index_key = '.*' if not defined $primary_index_key;
|
||||
$primary_index = '.*' if not defined $primary_index;
|
||||
|
||||
if (not $secondary_index_key) {
|
||||
foreach my $index (sort keys %{ $self->hash }) {
|
||||
my $distance_result = fastdistance($primary_index_key, $index);
|
||||
my $length = (length($primary_index_key) > length($index)) ? length $primary_index_key : length $index;
|
||||
if (not $secondary_index) {
|
||||
foreach my $index (sort keys %{ $self->{hash} }) {
|
||||
my $distance_result = fastdistance($primary_index, $index);
|
||||
my $length = (length $primary_index > length $index) ? length $primary_index : length $index;
|
||||
|
||||
if ($distance_result / $length < $distance) {
|
||||
if ($index =~ / /) {
|
||||
$result .= $comma . "\"$index\"";
|
||||
my $name = $self->{hash}->{$index}->{_name};
|
||||
if ($name =~ / /) {
|
||||
$result .= $comma . "\"$name\"";
|
||||
} else {
|
||||
$result .= $comma . $index;
|
||||
$result .= $comma . $name;
|
||||
}
|
||||
$comma = ", ";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my $primary = $self->find_index($primary_index_key);
|
||||
|
||||
if (not $primary) {
|
||||
my $lc_primary_index = lc $primary_index;
|
||||
if (not exists $self->{hash}->{$lc_primary_index}) {
|
||||
return 'none';
|
||||
}
|
||||
|
||||
my $last_header = "";
|
||||
my $header = "";
|
||||
|
||||
foreach my $index1 (sort keys %{ $self->hash }) {
|
||||
$header = "[$index1] ";
|
||||
$header = "[global channel] " if $header eq "[.*] ";
|
||||
foreach my $index1 (sort keys %{ $self->{hash} }) {
|
||||
$header = "[$self->{hash}->{$index1}->{_name}] ";
|
||||
$header = '[global] ' if $header eq '[.*] ';
|
||||
|
||||
if ($strictnamespace) {
|
||||
next unless $index1 eq '.*' or $index1 eq $primary;
|
||||
$header = "" unless $header eq '[global channel] ';
|
||||
next unless $index1 eq '.*' or $index1 eq $lc_primary_index;
|
||||
$header = "" unless $header eq '[global] ';
|
||||
}
|
||||
|
||||
foreach my $index2 (sort keys %{ $self->hash->{$index1} }) {
|
||||
my $distance_result = fastdistance($secondary_index_key, $index2);
|
||||
my $length = (length($secondary_index_key) > length($index2)) ? length $secondary_index_key : length $index2;
|
||||
foreach my $index2 (sort keys %{ $self->{hash}->{$index1} }) {
|
||||
my $distance_result = fastdistance($secondary_index, $index2);
|
||||
my $length = (length $secondary_index > length $index2) ? length $secondary_index : length $index2;
|
||||
|
||||
if ($distance_result / $length < $distance) {
|
||||
my $name = $self->{hash}->{$index1}->{$index2}->{_name};
|
||||
$header = "" if $last_header eq $header;
|
||||
$last_header = $header;
|
||||
$comma = '; ' if $comma ne '' and $header ne '';
|
||||
if ($index2 =~ / /) {
|
||||
$result .= $comma . $header . "\"$index2\"";
|
||||
if ($name =~ / /) {
|
||||
$result .= $comma . $header . "\"$name\"";
|
||||
} else {
|
||||
$result .= $comma . $header . $index2;
|
||||
$result .= $comma . $header . $name;
|
||||
}
|
||||
$comma = ", ";
|
||||
}
|
||||
@ -193,31 +195,34 @@ sub levenshtein_matches {
|
||||
}
|
||||
|
||||
sub set {
|
||||
my ($self, $primary_index_key, $secondary_index_key, $key, $value, $dont_save) = @_;
|
||||
my ($self, $primary_index, $secondary_index, $key, $value, $dont_save) = @_;
|
||||
my $lc_primary_index = lc $primary_index;
|
||||
my $lc_secondary_index = lc $secondary_index;
|
||||
|
||||
my $primary = $self->find_index($primary_index_key);
|
||||
|
||||
if (not $primary) {
|
||||
my $result = "No such $self->{name} object [$primary_index_key]; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index_key);
|
||||
if (not exists $self->{hash}->{$lc_primary_index}) {
|
||||
my $result = "$self->{name}: $primary_index not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
my $secondary = $self->find_index($primary, $secondary_index_key);
|
||||
|
||||
if (not $secondary) {
|
||||
my $secondary_text = $secondary_index_key =~ / / ? "\"$secondary_index_key\"" : $secondary_index_key;
|
||||
my $result = "No such $self->{name} object [$primary_index_key] $secondary_text; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary, $secondary_index_key);
|
||||
if (not exists $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}) {
|
||||
my $secondary_text = $secondary_index =~ / / ? "\"$secondary_index\"" : $secondary_index;
|
||||
my $result = "$self->{name}: [$self->{hash}->{$lc_primary_index}->{_name}] $secondary_text not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index, $secondary_index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
my $name1 = $self->{hash}->{$lc_primary_index}->{_name};
|
||||
my $name2 = $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}->{_name};
|
||||
|
||||
$name1 = 'global' if $name1 eq '.*';
|
||||
$name2 = "\"$name2\"" if $name2 =~ / /;
|
||||
|
||||
if (not defined $key) {
|
||||
my $secondary_text = $secondary =~ / / ? "\"$secondary\"" : $secondary;
|
||||
my $result = "[" . ($primary eq '.*' ? 'global' : $primary) . "] $secondary_text keys:\n";
|
||||
my $result = "[$name1] $name2 keys:\n";
|
||||
my $comma = '';
|
||||
foreach my $key (sort keys %{ $self->hash->{$primary}->{$secondary} }) {
|
||||
$result .= $comma . "$key => " . $self->hash->{$primary}->{$secondary}->{$key};
|
||||
foreach my $key (sort keys %{ $self->{hash}->{$lc_primary_index}->{$lc_secondary_index} }) {
|
||||
$result .= $comma . "$key => " . $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}->{$key};
|
||||
$comma = ";\n";
|
||||
}
|
||||
$result .= "none" if ($comma eq '');
|
||||
@ -225,104 +230,114 @@ sub set {
|
||||
}
|
||||
|
||||
if (not defined $value) {
|
||||
$value = $self->hash->{$primary}->{$secondary}->{$key};
|
||||
$value = $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}->{$key};
|
||||
} else {
|
||||
$self->hash->{$primary}->{$secondary}->{$key} = $value;
|
||||
$self->{hash}->{$lc_primary_index}->{$lc_secondary_index}->{$key} = $value;
|
||||
$self->save unless $dont_save;
|
||||
}
|
||||
|
||||
$primary = 'global' if $primary eq '.*';
|
||||
$secondary = "\"$secondary\"" if $secondary =~ / /;
|
||||
return "[$primary] $secondary: '$key' " . (defined $value ? "set to '$value'" : "is not set.");
|
||||
return "[$name1] $name2: '$key' " . (defined $value ? "set to '$value'" : "is not set.");
|
||||
}
|
||||
|
||||
sub unset {
|
||||
my ($self, $primary_index_key, $secondary_index_key, $key) = @_;
|
||||
my ($self, $primary_index, $secondary_index, $key) = @_;
|
||||
my $lc_primary_index = lc $primary_index;
|
||||
my $lc_secondary_index = lc $secondary_index;
|
||||
|
||||
my $primary = $self->find_index($primary_index_key);
|
||||
|
||||
if (not $primary) {
|
||||
my $result = "No such $self->{name} object group '$primary_index_key'; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index_key);
|
||||
if (not exists $self->{hash}->{$lc_primary_index}) {
|
||||
my $result = "$self->{name}: $primary_index not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
my $secondary = $self->find_index($primary, $secondary_index_key);
|
||||
my $name1 = $self->{hash}->{$lc_primary_index}->{_name};
|
||||
$name1 = 'global' if $name1 eq '.*';
|
||||
|
||||
if (not $secondary) {
|
||||
my $result = "No such $self->{name} object '$secondary_index_key'; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary, $secondary_index_key);
|
||||
if (not exists $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}) {
|
||||
my $result = "$self->{name}: [$name1] $secondary_index not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index, $secondary_index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
delete $self->hash->{$primary}->{$secondary}->{$key};
|
||||
delete $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}->{$key};
|
||||
$self->save();
|
||||
|
||||
$primary = 'global' if $primary eq '.*';
|
||||
$secondary = "\"$secondary\"" if $secondary =~ / /;
|
||||
return "[$self->{name}] ($primary) $secondary: '$key' unset.";
|
||||
my $name2 = $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}->{_name};
|
||||
$name2 = "\"$name2\"" if $name2 =~ / /;
|
||||
|
||||
return "$self->{name}: [$name1] $name2: '$key' unset.";
|
||||
}
|
||||
|
||||
sub add {
|
||||
my ($self, $primary_index_key, $secondary_index_key, $hash) = @_;
|
||||
my ($self, $primary_index, $secondary_index, $data, $dont_save) = @_;
|
||||
my $lc_primary_index = lc $primary_index;
|
||||
my $lc_secondary_index = lc $secondary_index;
|
||||
|
||||
if ($self->hash_add($primary_index_key, $secondary_index_key, $hash)) {
|
||||
$self->save();
|
||||
} else {
|
||||
return "Error occurred adding new $self->{name} object.";
|
||||
if (exists $self->{hash}->{$lc_primary_index} and exists $self->{$lc_primary_index}->{$lc_secondary_index}) {
|
||||
return "Error: entry already exists";
|
||||
}
|
||||
|
||||
return "'$secondary_index_key' added to $primary_index_key [$self->{name}].";
|
||||
if (not exists $self->{hash}->{$lc_primary_index}) {
|
||||
$self->{hash}->{$lc_primary_index}->{_name} = $primary_index; # preserve case
|
||||
}
|
||||
|
||||
$data->{_name} = $secondary_index; # preserve case
|
||||
$self->{hash}->{$lc_primary_index}->{$lc_secondary_index} = {%$data};
|
||||
$self->save() unless $dont_save;
|
||||
|
||||
my $name1 = $self->{hash}->{$lc_primary_index}->{_name};
|
||||
my $name2 = $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}->{_name};
|
||||
$name1 = 'global' if $name1 eq '.*';
|
||||
$name2 = "\"$name2\"" if $name2 =~ / /;
|
||||
return "$self->{name}: [$name1]: $name2 added.";
|
||||
}
|
||||
|
||||
sub remove {
|
||||
my ($self, $primary_index_key, $secondary_index_key) = @_;
|
||||
my ($self, $primary_index, $secondary_index) = @_;
|
||||
my $lc_primary_index = lc $primary_index;
|
||||
my $lc_secondary_index = lc $secondary_index;
|
||||
|
||||
my $primary = $self->find_index($primary_index_key);
|
||||
|
||||
if (not $primary) {
|
||||
my $result = "No such $self->{name} object group '$primary_index_key'; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index_key);
|
||||
if (not exists $self->{hash}->{$lc_primary_index}) {
|
||||
my $result = "$self->{name}: $primary_index not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (not $secondary_index_key) {
|
||||
delete $self->hash->{$primary};
|
||||
if (not $secondary_index) {
|
||||
my $data = delete $self->{hash}->{$lc_primary_index};
|
||||
my $name = $data->{_name};
|
||||
$name = 'global' if $name eq '.*';
|
||||
$self->save;
|
||||
return "'$primary' group removed from $self->{name}.";
|
||||
return "$self->{name}: $name removed.";
|
||||
}
|
||||
|
||||
my $secondary = $self->find_index($primary, $secondary_index_key);
|
||||
my $name1 = $self->{hash}->{$lc_primary_index}->{_name};
|
||||
$name1 = 'global' if $name1 eq '.*';
|
||||
|
||||
if (not $secondary) {
|
||||
my $result = "No such $self->{name} object '$secondary_index_key'; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary, $secondary_index_key);
|
||||
if (not exists $self->{hash}->{$lc_primary_index}->{$lc_secondary_index}) {
|
||||
my $result = "$self->{name}: [$name1] $secondary_index not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($primary_index, $secondary_index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
delete $self->hash->{$primary}->{$secondary};
|
||||
my $data = delete $self->{hash}->{$lc_primary_index}->{$lc_secondary_index};
|
||||
my $name2 = $data->{_name};
|
||||
$name2 = "\"$name2\"" if $name2 =~ / /;
|
||||
|
||||
# remove primary group if no more secondaries
|
||||
if (scalar keys %{ $self->hash->{$primary} } == 0) {
|
||||
delete $self->hash->{$primary};
|
||||
if (keys %{ $self->{hash}->{$lc_primary_index} } == 0) {
|
||||
delete $self->{hash}->{$lc_primary_index};
|
||||
}
|
||||
|
||||
$self->save();
|
||||
return "'$secondary' removed from $primary group [$self->{name}].";
|
||||
return "$self->{name}: [$name1] $name2 removed.";
|
||||
}
|
||||
|
||||
# Getters and setters
|
||||
|
||||
sub hash {
|
||||
my $self = shift;
|
||||
return $self->{hash};
|
||||
}
|
||||
|
||||
sub filename {
|
||||
my $self = shift;
|
||||
|
||||
if (@_) { $self->{filename} = shift; }
|
||||
return $self->{filename};
|
||||
sub exists {
|
||||
my ($self, $primary_index, $secondary_index) = @_;
|
||||
$primary_index = lc $primary_index;
|
||||
$secondary_index = lc $secondary_index;
|
||||
return (exists $self->{hash}->{$primary_index} and exists $self->{hash}->{$primary_index}->{$secondary_index});
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -25,18 +25,6 @@ use JSON;
|
||||
|
||||
use PBot::Utils::SafeFilename;
|
||||
|
||||
sub new {
|
||||
if (ref($_[1]) eq 'HASH') {
|
||||
Carp::croak("Options to FactoidCommands should be key/value pairs, not hash reference");
|
||||
}
|
||||
|
||||
my ($class, %conf) = @_;
|
||||
|
||||
my $self = bless {}, $class;
|
||||
$self->initialize(%conf);
|
||||
return $self;
|
||||
}
|
||||
|
||||
our %factoid_metadata_levels = (
|
||||
created_on => 90,
|
||||
enabled => 10,
|
||||
@ -59,44 +47,47 @@ our %factoid_metadata_levels = (
|
||||
# all others are allowed to be factset by anybody/default to level 0
|
||||
);
|
||||
|
||||
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) = @_;
|
||||
|
||||
my $pbot = delete $conf{pbot};
|
||||
if (not defined $pbot) {
|
||||
Carp::croak("Missing pbot reference to FactoidCommands");
|
||||
}
|
||||
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to FactoidCommands");
|
||||
|
||||
$self->{pbot} = $pbot;
|
||||
$self->{pbot}->{registry}->add_default('text', 'general', 'module_repo', $conf{module_repo} // 'https://github.com/pragma-/pbot/blob/master/modules/');
|
||||
|
||||
$pbot->{registry}->add_default('text', 'general', 'module_repo', $conf{module_repo} // 'https://github.com/pragma-/pbot/blob/master/modules/');
|
||||
|
||||
$pbot->{commands}->register(sub { return $self->factadd(@_) }, "learn", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factadd(@_) }, "factadd", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factrem(@_) }, "forget", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factrem(@_) }, "factrem", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factshow(@_) }, "factshow", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factinfo(@_) }, "factinfo", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factlog(@_) }, "factlog", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factundo(@_) }, "factundo", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factredo(@_) }, "factredo", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factset(@_) }, "factset", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factunset(@_) }, "factunset", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factchange(@_) }, "factchange", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factalias(@_) }, "factalias", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factmove(@_) }, "factmove", 0);
|
||||
$pbot->{commands}->register(sub { return $self->call_factoid(@_) }, "fact", 0);
|
||||
$pbot->{commands}->register(sub { return $self->factfind(@_) }, "factfind", 0);
|
||||
$pbot->{commands}->register(sub { return $self->list(@_) }, "list", 0);
|
||||
$pbot->{commands}->register(sub { return $self->top20(@_) }, "top20", 0);
|
||||
$pbot->{commands}->register(sub { return $self->load_module(@_) }, "load", 90);
|
||||
$pbot->{commands}->register(sub { return $self->unload_module(@_) }, "unload", 90);
|
||||
$pbot->{commands}->register(sub { return $self->histogram(@_) }, "histogram", 0);
|
||||
$pbot->{commands}->register(sub { return $self->count(@_) }, "count", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factadd(@_) }, "learn", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factadd(@_) }, "factadd", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factrem(@_) }, "forget", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factrem(@_) }, "factrem", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factshow(@_) }, "factshow", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factinfo(@_) }, "factinfo", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factlog(@_) }, "factlog", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factundo(@_) }, "factundo", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factredo(@_) }, "factredo", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factset(@_) }, "factset", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factunset(@_) }, "factunset", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factchange(@_) }, "factchange", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factalias(@_) }, "factalias", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factmove(@_) }, "factmove", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->call_factoid(@_) }, "fact", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->factfind(@_) }, "factfind", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->list(@_) }, "list", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->top20(@_) }, "top20", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->load_module(@_) }, "load", 90);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->unload_module(@_) }, "unload", 90);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->histogram(@_) }, "histogram", 0);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->count(@_) }, "count", 0);
|
||||
|
||||
# the following commands have not yet been updated to use the new factoid structure
|
||||
# DO NOT USE!! Factoid corruption may occur.
|
||||
$pbot->{commands}->register(sub { return $self->add_regex(@_) }, "regex", 999);
|
||||
$self->{pbot}->{commands}->register(sub { return $self->add_regex(@_) }, "regex", 999);
|
||||
}
|
||||
|
||||
sub call_factoid {
|
||||
@ -127,6 +118,9 @@ sub log_factoid {
|
||||
my $self = shift;
|
||||
my ($channel, $trigger, $hostmask, $msg, $dont_save_undo) = @_;
|
||||
|
||||
$channel = lc $channel;
|
||||
$trigger = lc $trigger;
|
||||
|
||||
my $channel_path = $channel;
|
||||
$channel_path = 'global' if $channel_path eq '.*';
|
||||
|
||||
@ -166,7 +160,7 @@ sub log_factoid {
|
||||
splice @{$undos->{list}}, $undos->{idx} + 1;
|
||||
}
|
||||
|
||||
push @{$undos->{list}}, $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger};
|
||||
push @{$undos->{list}}, $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger};
|
||||
$undos->{idx}++;
|
||||
|
||||
eval { store $undos, "$path/$trigger_safe.$channel_path_safe.undo"; };
|
||||
@ -264,7 +258,11 @@ sub find_factoid_with_optional_channel {
|
||||
$from_chan = '.*' if $channel eq 'global';
|
||||
|
||||
if ($opts{explicit} and $channel =~ /^#/ and $from_chan =~ /^#/ and $channel ne $from_chan) {
|
||||
return "/say $trigger belongs to $channel, not $from_chan. Please switch to or explicitly specify $channel.";
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
return "/say $trigger_name belongs to $channel_name, not $from_chan. Please switch to or explicitly specify $channel_name.";
|
||||
}
|
||||
|
||||
return ($channel, $trigger, $remaining_args);
|
||||
@ -395,8 +393,13 @@ sub factundo {
|
||||
my $path = $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/factlog';
|
||||
my $undos = eval { retrieve("$path/$trigger_safe.$channel_path_safe.undo"); };
|
||||
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
if (not $undos) {
|
||||
return "There are no undos available for [$channel] $trigger.";
|
||||
return "There are no undos available for [$channel_name] $trigger_name.";
|
||||
}
|
||||
|
||||
if (defined $list_undos) {
|
||||
@ -404,14 +407,14 @@ sub factundo {
|
||||
return $self->list_undo_history($undos, $list_undos);
|
||||
}
|
||||
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
my $admininfo = $self->{pbot}->{admins}->loggedin($channel, "$nick!$user\@$host");
|
||||
if ($factoids->{$channel}->{$trigger}->{'locked'}) {
|
||||
return "/say $trigger is locked and cannot be reverted." if not defined $admininfo;
|
||||
return "/say $trigger_name is locked and cannot be reverted." if not defined $admininfo;
|
||||
|
||||
if (exists $factoids->{$channel}->{$trigger}->{'effective-level'}
|
||||
and $admininfo->{level} < $factoids->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
return "/say $trigger is locked with an effective-level higher than your level and cannot be reverted.";
|
||||
return "/say $trigger_name is locked with an effective-level higher than your level and cannot be reverted.";
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,14 +422,14 @@ sub factundo {
|
||||
return "Don't be absurd." if $goto_revision < 1;
|
||||
if ($goto_revision > @{$undos->{list}}) {
|
||||
if (@{$undos->{list}} == 1) {
|
||||
return "There is only one revision available for [$channel] $trigger.";
|
||||
return "There is only one revision available for [$channel_name] $trigger_name.";
|
||||
} else {
|
||||
return "There are " . @{$undos->{list}} . " revisions available for [$channel] $trigger.";
|
||||
return "There are " . @{$undos->{list}} . " revisions available for [$channel_name] $trigger_name.";
|
||||
}
|
||||
}
|
||||
|
||||
if ($goto_revision == $undos->{idx} + 1) {
|
||||
return "[$channel] $trigger is already at revision $goto_revision.";
|
||||
return "[$channel_name] $trigger_name is already at revision $goto_revision.";
|
||||
}
|
||||
|
||||
$undos->{idx} = $goto_revision - 1;
|
||||
@ -434,18 +437,18 @@ sub factundo {
|
||||
$self->{pbot}->{logger}->log("Error storing undo: $@\n") if $@;
|
||||
} else {
|
||||
unless ($deleted) {
|
||||
return "There are no more undos remaining for [$channel] $trigger." if not $undos->{idx};
|
||||
return "There are no more undos remaining for [$channel_name] $trigger_name." if not $undos->{idx};
|
||||
$undos->{idx}--;
|
||||
eval { store $undos, "$path/$trigger_safe.$channel_path_safe.undo"; };
|
||||
$self->{pbot}->{logger}->log("Error storing undo: $@\n") if $@;
|
||||
}
|
||||
}
|
||||
|
||||
$self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger} = $undos->{list}->[$undos->{idx}];
|
||||
$self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger} = $undos->{list}->[$undos->{idx}];
|
||||
|
||||
my $changes = $self->hash_differences_as_string($undos->{list}->[$undos->{idx} + 1], $undos->{list}->[$undos->{idx}]);
|
||||
$self->log_factoid($channel, $trigger, "$nick!$user\@$host", "reverted (undo): $changes", 1);
|
||||
return "[$channel] $trigger reverted (revision " . ($undos->{idx} + 1) . "): $changes\n";
|
||||
return "[$channel_name] $trigger_name reverted (revision " . ($undos->{idx} + 1) . "): $changes\n";
|
||||
}
|
||||
|
||||
sub factredo {
|
||||
@ -480,11 +483,16 @@ sub factredo {
|
||||
my $channel_path_safe = safe_filename $channel_path;
|
||||
my $trigger_safe = safe_filename $trigger;
|
||||
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
my $path = $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/factlog';
|
||||
my $undos = eval { retrieve("$path/$trigger_safe.$channel_path_safe.undo"); };
|
||||
|
||||
if (not $undos) {
|
||||
return "There are no redos available for [$channel] $trigger.";
|
||||
return "There are no redos available for [$channel_name] $trigger_name.";
|
||||
}
|
||||
|
||||
if (defined $list_undos) {
|
||||
@ -492,33 +500,33 @@ sub factredo {
|
||||
return $self->list_undo_history($undos, $list_undos);
|
||||
}
|
||||
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
my $admininfo = $self->{pbot}->{admins}->loggedin($channel, "$nick!$user\@$host");
|
||||
if ($factoids->{$channel}->{$trigger}->{'locked'}) {
|
||||
return "/say $trigger is locked and cannot be reverted." if not defined $admininfo;
|
||||
return "/say $trigger_name is locked and cannot be reverted." if not defined $admininfo;
|
||||
|
||||
if (exists $factoids->{$channel}->{$trigger}->{'effective-level'}
|
||||
and $admininfo->{level} < $factoids->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
return "/say $trigger is locked with an effective-level higher than your level and cannot be reverted.";
|
||||
return "/say $trigger_name is locked with an effective-level higher than your level and cannot be reverted.";
|
||||
}
|
||||
}
|
||||
|
||||
if (not defined $goto_revision and $undos->{idx} + 1 == @{$undos->{list}}) {
|
||||
return "There are no more redos remaining for [$channel] $trigger.";
|
||||
return "There are no more redos remaining for [$channel_name] $trigger_name.";
|
||||
}
|
||||
|
||||
if (defined $goto_revision) {
|
||||
return "Don't be absurd." if $goto_revision < 1;
|
||||
if ($goto_revision > @{$undos->{list}}) {
|
||||
if (@{$undos->{list}} == 1) {
|
||||
return "There is only one revision available for [$channel] $trigger.";
|
||||
return "There is only one revision available for [$channel_name] $trigger_name.";
|
||||
} else {
|
||||
return "There are " . @{$undos->{list}} . " revisions available for [$channel] $trigger.";
|
||||
return "There are " . @{$undos->{list}} . " revisions available for [$channel_name] $trigger_name.";
|
||||
}
|
||||
}
|
||||
|
||||
if ($goto_revision == $undos->{idx} + 1) {
|
||||
return "[$channel] $trigger is already at revision $goto_revision.";
|
||||
return "[$channel_name] $trigger_name is already at revision $goto_revision.";
|
||||
}
|
||||
|
||||
$undos->{idx} = $goto_revision - 1;
|
||||
@ -530,11 +538,11 @@ sub factredo {
|
||||
$self->{pbot}->{logger}->log("Error storing undo: $@\n") if $@;
|
||||
}
|
||||
|
||||
$self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger} = $undos->{list}->[$undos->{idx}];
|
||||
$self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger} = $undos->{list}->[$undos->{idx}];
|
||||
|
||||
my $changes = $self->hash_differences_as_string($undos->{list}->[$undos->{idx} - 1], $undos->{list}->[$undos->{idx}]);
|
||||
$self->log_factoid($channel, $trigger, "$nick!$user\@$host", "reverted (redo): $changes", 1);
|
||||
return "[$channel] $trigger restored (revision " . ($undos->{idx} + 1) . "): $changes\n";
|
||||
return "[$channel_name] $trigger_name restored (revision " . ($undos->{idx} + 1) . "): $changes\n";
|
||||
}
|
||||
|
||||
sub factset {
|
||||
@ -544,6 +552,9 @@ sub factset {
|
||||
my ($channel, $trigger, $arguments) = $self->find_factoid_with_optional_channel($from, $args, 'factset', usage => 'Usage: factset [channel] <factoid> [key [value]]', explicit => 1);
|
||||
return $channel if not defined $trigger; # if $trigger is not defined, $channel is an error message
|
||||
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
my $arglist = $self->{pbot}->{interpreter}->make_args($arguments);
|
||||
my ($key, $value) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
|
||||
|
||||
@ -577,8 +588,8 @@ sub factset {
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $value and !$level and $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{'locked'}) {
|
||||
return "/say $trigger is locked; unlock before setting.";
|
||||
if (defined $value and !$level and $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{'locked'}) {
|
||||
return "/say $trigger_name is locked; unlock before setting.";
|
||||
}
|
||||
|
||||
if (lc $key eq 'effective-level' and defined $value and $level > 0) {
|
||||
@ -591,15 +602,15 @@ sub factset {
|
||||
$self->{pbot}->{factoids}->{factoids}->set($channel, $trigger, 'locked', '1');
|
||||
}
|
||||
|
||||
if (lc $key eq 'locked' and exists $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
if ($level < $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
if (lc $key eq 'locked' and exists $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
if ($level < $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
return "You cannot unlock this factoid because its effective-level is greater than your level.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $owner_channel) {
|
||||
my $factoid = $self->{pbot}->{factoids}->{factoids}->hash->{$owner_channel}->{$owner_trigger};
|
||||
my $factoid = $self->{pbot}->{factoids}->{factoids}->{hash}->{$owner_channel}->{$owner_trigger};
|
||||
|
||||
my $owner;
|
||||
my $mask;
|
||||
@ -614,7 +625,7 @@ sub factset {
|
||||
}
|
||||
|
||||
if ((defined $value and $key ne 'action') and lc $mask ne lc $owner and $level == 0) {
|
||||
return "You are not the owner of $trigger.";
|
||||
return "You are not the owner of $trigger_name.";
|
||||
}
|
||||
}
|
||||
|
||||
@ -669,15 +680,15 @@ sub factunset {
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
if (exists $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
if (lc $key eq 'locked') {
|
||||
if ($level >= $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
if ($level >= $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
$self->{pbot}->{factoids}->{factoids}->unset($channel, $trigger, 'effective-level');
|
||||
} else {
|
||||
return "You cannot unlock this factoid because its effective-level is higher than your level.";
|
||||
}
|
||||
} elsif (lc $key eq 'effective-level') {
|
||||
if ($level < $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
if ($level < $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
return "You cannot unset the effective-level because it is higher than your level.";
|
||||
}
|
||||
}
|
||||
@ -685,18 +696,23 @@ sub factunset {
|
||||
|
||||
my $oldvalue;
|
||||
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
if (defined $owner_channel) {
|
||||
my $factoid = $self->{pbot}->{factoids}->{factoids}->hash->{$owner_channel}->{$owner_trigger};
|
||||
my $factoid = $self->{pbot}->{factoids}->{factoids}->{hash}->{$owner_channel}->{$owner_trigger};
|
||||
|
||||
my ($owner) = $factoid->{'owner'} =~ m/([^!]+)/;
|
||||
|
||||
if (lc $nick ne lc $owner and $level == 0) {
|
||||
return "You are not the owner of $trigger.";
|
||||
return "You are not the owner of $trigger_name.";
|
||||
}
|
||||
$oldvalue = $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{$key};
|
||||
$oldvalue = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{$key};
|
||||
}
|
||||
|
||||
return "[$channel] $trigger: key '$key' does not exist." if not defined $oldvalue;
|
||||
return "[$channel_name] $trigger_name: key '$key' does not exist." if not defined $oldvalue;
|
||||
|
||||
my $result = $self->{pbot}->{factoids}->{factoids}->unset($channel, $trigger, $key);
|
||||
|
||||
@ -720,10 +736,11 @@ sub list {
|
||||
|
||||
if ($arguments =~ /^modules$/i) {
|
||||
$text = "Loaded modules: ";
|
||||
foreach my $channel (sort keys %{ $self->{pbot}->{factoids}->{factoids}->hash }) {
|
||||
foreach my $command (sort keys %{ $self->{pbot}->{factoids}->{factoids}->hash->{$channel} }) {
|
||||
if ($self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$command}->{type} eq 'module') {
|
||||
$text .= "$command ";
|
||||
foreach my $channel (sort keys %{ $self->{pbot}->{factoids}->{factoids}->{hash} }) {
|
||||
foreach my $command (sort keys %{ $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel} }) {
|
||||
next if $command eq '_name';
|
||||
if ($self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$command}->{type} eq 'module') {
|
||||
$text .= "$self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$command}->{_name} ";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -743,17 +760,18 @@ sub list {
|
||||
$text = "Admins: ";
|
||||
my $last_channel = "";
|
||||
my $sep = "";
|
||||
foreach my $channel (sort keys %{ $self->{pbot}->{admins}->{admins}->hash }) {
|
||||
foreach my $channel (sort keys %{ $self->{pbot}->{admins}->{admins}->{hash} }) {
|
||||
next if $from =~ m/^#/ and $channel ne $from and $channel ne '.*';
|
||||
if ($last_channel ne $channel) {
|
||||
$text .= $sep . ($channel eq ".*" ? "global" : $channel) . ": ";
|
||||
$last_channel = $channel;
|
||||
$sep = "";
|
||||
}
|
||||
foreach my $hostmask (sort { $self->{pbot}->{admins}->{admins}->hash->{$channel}->{$a}->{name} cmp $self->{pbot}->{admins}->{admins}->hash->{$channel}->{$b}->{name} } keys %{ $self->{pbot}->{admins}->{admins}->hash->{$channel} }) {
|
||||
foreach my $hostmask (sort { return 0 if $a eq '_name' or $b eq '_name'; $self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$a}->{name} cmp $self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$b}->{name} } keys %{ $self->{pbot}->{admins}->{admins}->{hash}->{$channel} }) {
|
||||
next if $hostmask eq '_name';
|
||||
$text .= $sep;
|
||||
$text .= "*" if $self->{pbot}->{admins}->{admins}->hash->{$channel}->{$hostmask}->{loggedin};
|
||||
$text .= $self->{pbot}->{admins}->{admins}->hash->{$channel}->{$hostmask}->{name} . " (" . $self->{pbot}->{admins}->{admins}->hash->{$channel}->{$hostmask}->{level} . ")";
|
||||
$text .= "*" if $self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$hostmask}->{loggedin};
|
||||
$text .= $self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$hostmask}->{name} . " (" . $self->{pbot}->{admins}->{admins}->{hash}->{$channel}->{$hostmask}->{level} . ")";
|
||||
$sep = "; ";
|
||||
}
|
||||
}
|
||||
@ -800,55 +818,67 @@ sub factmove {
|
||||
return "Source factoid $source not found in channel $src_channel";
|
||||
}
|
||||
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $source_channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$found_src_channel}->{_name};
|
||||
my $source_trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$found_src_channel}->{$found_source}->{_name};
|
||||
$source_channel_name = 'global' if $source_channel_name eq '.*';
|
||||
$source_trigger_name = "\"$source_trigger_name\"" if $source_trigger_name =~ / /;
|
||||
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
|
||||
my ($owner) = $factoids->{$found_src_channel}->{$found_source}->{'owner'} =~ m/([^!]+)/;
|
||||
|
||||
if ((lc $nick ne lc $owner) and (not $self->{pbot}->{admins}->loggedin($found_src_channel, "$nick!$user\@$host"))) {
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host attempted to move [$found_src_channel] $found_source (not owner)\n");
|
||||
my $chan = ($found_src_channel eq '.*' ? 'the global channel' : $found_src_channel);
|
||||
return "You are not the owner of $found_source for $chan";
|
||||
return "You are not the owner of $source_trigger_name for $source_channel_name.";
|
||||
}
|
||||
|
||||
if ($factoids->{$found_src_channel}->{$found_source}->{'locked'}) {
|
||||
return "/say $found_source is locked; unlock before moving.";
|
||||
return "/say $source_trigger_name is locked; unlock before moving.";
|
||||
}
|
||||
|
||||
my ($found_target_channel, $found_target) = $self->{pbot}->{factoids}->find_factoid($target_channel, $target, exact_channel => 1, exact_trigger => 1);
|
||||
|
||||
if (defined $found_target_channel) {
|
||||
return "Target factoid $target already exists in channel $target_channel";
|
||||
my $target_channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$found_target_channel}->{_name};
|
||||
my $target_trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$found_target_channel}->{$found_target}->{_name};
|
||||
$target_channel_name = 'global' if $target_channel_name eq '.*';
|
||||
$target_trigger_name = "\"$target_trigger_name\"" if $target_trigger_name =~ / /;
|
||||
return "Target factoid $target_trigger_name already exists in channel $target_channel_name.";
|
||||
}
|
||||
|
||||
my ($overchannel, $overtrigger) = $self->{pbot}->{factoids}->find_factoid('.*', $target, exact_channel => 1, exact_trigger => 1);
|
||||
if (defined $overtrigger and $self->{pbot}->{factoids}->{factoids}->hash->{'.*'}->{$overtrigger}->{'nooverride'}) {
|
||||
if (defined $overtrigger and $self->{pbot}->{factoids}->{factoids}->{hash}->{'.*'}->{$overtrigger}->{'nooverride'}) {
|
||||
my $override_channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$overchannel}->{_name};
|
||||
my $override_trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$overchannel}->{$overtrigger}->{_name};
|
||||
$override_channel_name = 'global' if $override_channel_name eq '.*';
|
||||
$override_trigger_name = "\"$override_trigger_name\"" if $override_trigger_name =~ / /;
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host attempt to override $target\n");
|
||||
return "/say $target already exists for the global channel and cannot be overridden for " . ($target_channel eq '.*' ? 'the global channel' : $target_channel) . ".";
|
||||
return "/say $override_trigger_name already exists for the global channel and cannot be overridden for " . ($target_channel eq '.*' ? 'the global channel' : $target_channel) . ".";
|
||||
}
|
||||
|
||||
if ($self->{pbot}->{commands}->exists($target)) {
|
||||
return "/say $target already exists as a built-in command.";
|
||||
}
|
||||
|
||||
$target_channel = lc $target_channel;
|
||||
$target_channel = '.*' if $target_channel !~ /^#/;
|
||||
|
||||
$factoids->{$target_channel}->{$target} = $factoids->{$found_src_channel}->{$found_source};
|
||||
delete $factoids->{$found_src_channel}->{$found_source};
|
||||
|
||||
$factoids->{lc $target_channel}->{lc $target} = delete $factoids->{$found_src_channel}->{$found_source};
|
||||
$factoids->{lc $target_channel}->{lc $target}->{_name} = $target;
|
||||
$factoids->{lc $target_channel}->{_name} = $target_channel if not exists $factoids->{lc $target_channel}->{_name};
|
||||
$self->{pbot}->{factoids}->save_factoids;
|
||||
|
||||
$found_src_channel = 'global' if $found_src_channel eq '.*';
|
||||
$target_channel = 'global' if $target_channel eq '.*';
|
||||
|
||||
if ($src_channel eq $target_channel) {
|
||||
$self->log_factoid($found_src_channel, $found_source, "$nick!$user\@$host", "renamed from $found_source to $target");
|
||||
$self->log_factoid($target_channel, $target, "$nick!$user\@$host", "renamed from $found_source to $target");
|
||||
return "[$found_src_channel] $found_source renamed to $target";
|
||||
if ($src_channel eq lc $target_channel) {
|
||||
$self->log_factoid($found_src_channel, $found_source, "$nick!$user\@$host", "renamed from $source_trigger_name to $target");
|
||||
$self->log_factoid($target_channel, $target, "$nick!$user\@$host", "renamed from $source_trigger_name to $target");
|
||||
return "[$source_channel_name] $source_trigger_name renamed to $target";
|
||||
} else {
|
||||
$self->log_factoid($found_src_channel, $found_source, "$nick!$user\@$host", "moved from $found_src_channel/$found_source to $target_channel/$target");
|
||||
$self->log_factoid($target_channel, $target, "$nick!$user\@$host", "moved from $found_src_channel/$found_source to $target_channel/$target");
|
||||
return "[$found_src_channel] $found_source moved to [$target_channel] $target";
|
||||
$self->log_factoid($found_src_channel, $found_source, "$nick!$user\@$host", "moved from $source_channel_name/$source_trigger_name to $target_channel/$target");
|
||||
$self->log_factoid($target_channel, $target, "$nick!$user\@$host", "moved from $source_channel_name/$source_trigger_name to $target_channel/$target");
|
||||
return "[$source_channel_name] $source_trigger_name moved to [$target_channel] $target";
|
||||
}
|
||||
}
|
||||
|
||||
@ -859,7 +889,7 @@ sub factalias {
|
||||
my ($chan, $alias, $command) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
|
||||
|
||||
if (defined $chan and not ($chan eq '.*' or $chan =~ m/^#/)) {
|
||||
# $chan doesn't look like a channel, so shift everything right
|
||||
# $chan doesn't look like a channel, so shift everything to the right
|
||||
# and replace $chan with $from
|
||||
if (defined $command and length $command) {
|
||||
$command = "$alias $command";
|
||||
@ -887,14 +917,18 @@ sub factalias {
|
||||
my ($channel, $alias_trigger) = $self->{pbot}->{factoids}->find_factoid($chan, $alias, exact_channel => 1, exact_trigger => 1);
|
||||
|
||||
if (defined $alias_trigger) {
|
||||
$self->{pbot}->{logger}->log("attempt to overwrite existing command\n");
|
||||
return "'$alias_trigger' already exists for channel $channel";
|
||||
my $alias_channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $alias_trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$alias_trigger}->{_name};
|
||||
$alias_channel_name = 'global' if $alias_channel_name eq '.*';
|
||||
$alias_trigger_name = "\"$alias_trigger_name\"" if $alias_trigger_name =~ / /;
|
||||
return "$alias_trigger_name already exists for $alias_channel_name.";
|
||||
}
|
||||
|
||||
my ($overchannel, $overtrigger) = $self->{pbot}->{factoids}->find_factoid('.*', $alias, exact_channel => 1, exact_trigger => 1);
|
||||
if (defined $overtrigger and $self->{pbot}->{factoids}->{factoids}->hash->{'.*'}->{$overtrigger}->{'nooverride'}) {
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host attempt to override $alias\n");
|
||||
return "/say $alias already exists for the global channel and cannot be overridden for " . ($chan eq '.*' ? 'the global channel' : $chan) . ".";
|
||||
if (defined $overtrigger and $self->{pbot}->{factoids}->{factoids}->{hash}->{'.*'}->{$overtrigger}->{'nooverride'}) {
|
||||
my $override_trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$overchannel}->{$overtrigger}->{_name};
|
||||
$override_trigger_name = "\"$override_trigger_name\"" if $override_trigger_name =~ / /;
|
||||
return "/say $override_trigger_name already exists for the global channel and cannot be overridden for " . ($chan eq '.*' ? 'the global channel' : $chan) . ".";
|
||||
}
|
||||
|
||||
if ($self->{pbot}->{commands}->exists($alias)) {
|
||||
@ -905,20 +939,21 @@ sub factalias {
|
||||
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host [$chan] aliased $alias => $command\n");
|
||||
$self->{pbot}->{factoids}->save_factoids();
|
||||
return "'$alias' aliases '$command' for " . ($chan eq '.*' ? 'the global channel' : $chan);
|
||||
return "$alias aliases `$command` for " . ($chan eq '.*' ? 'the global channel' : $chan);
|
||||
}
|
||||
|
||||
sub add_regex {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
my ($keyword, $text) = $arguments =~ /^(.*?)\s+(.*)$/ if defined $arguments;
|
||||
|
||||
$from = '.*' if not defined $from or $from !~ /^#/;
|
||||
|
||||
if (not defined $keyword) {
|
||||
$text = "";
|
||||
foreach my $trigger (sort keys %{ $factoids->{$from} }) {
|
||||
foreach my $trigger (sort keys %{ $factoids->{lc $from} }) {
|
||||
next if $trigger eq '_name';
|
||||
if ($factoids->{$from}->{$trigger}->{type} eq 'regex') {
|
||||
$text .= $trigger . " ";
|
||||
}
|
||||
@ -980,6 +1015,7 @@ sub factadd {
|
||||
# the URL is the remaining arguments
|
||||
my ($url) = $self->{pbot}->{interpreter}->split_args(\@arglist, 1);
|
||||
|
||||
# FIXME: move this to registry
|
||||
if ($url !~ m/^https?:\/\/(?:sprunge.us|ix.io)\/\w+$/) {
|
||||
return "Invalid URL: acceptable URLs are: http://sprunge.us, http://ix.io";
|
||||
}
|
||||
@ -1028,30 +1064,33 @@ sub factadd {
|
||||
|
||||
my ($channel, $trigger) = $self->{pbot}->{factoids}->find_factoid($from_chan, $keyword, exact_channel => 1, exact_trigger => 1);
|
||||
if (defined $trigger) {
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
if (not $force) {
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host attempt to overwrite $keyword\n");
|
||||
return "/say $keyword_text already exists for " . ($from_chan eq '.*' ? 'the global channel' : $from_chan) . ".";
|
||||
return "/say $trigger_name already exists for $channel_name.";
|
||||
} else {
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
|
||||
if ($factoids->{$channel}->{$trigger}->{'locked'}) {
|
||||
return "/say $keyword_text is locked; unlock before overwriting.";
|
||||
return "/say $trigger_name is locked; unlock before overwriting.";
|
||||
}
|
||||
|
||||
my ($owner) = $factoids->{$channel}->{$trigger}->{'owner'} =~ m/([^!]+)/;
|
||||
|
||||
if ((lc $nick ne lc $owner) and (not $self->{pbot}->{admins}->loggedin($channel, "$nick!$user\@$host"))) {
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host attempted to overwrite $trigger [not owner]\n");
|
||||
my $chan = ($channel eq '.*' ? 'the global channel' : $channel);
|
||||
return "You are not the owner of $keyword_text for $chan; cannot overwrite";
|
||||
return "You are not the owner of $trigger_name for $channel_name; cannot force overwrite.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
($channel, $trigger) = $self->{pbot}->{factoids}->find_factoid('.*', $keyword, exact_channel => 1, exact_trigger => 1);
|
||||
if (defined $trigger and $self->{pbot}->{factoids}->{factoids}->hash->{'.*'}->{$trigger}->{'nooverride'}) {
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host attempt to override $keyword_text\n");
|
||||
return "/say $keyword_text already exists for the global channel and cannot be overridden for " . ($from_chan eq '.*' ? 'the global channel' : $from_chan) . ".";
|
||||
if (defined $trigger and $self->{pbot}->{factoids}->{factoids}->{hash}->{'.*'}->{$trigger}->{'nooverride'}) {
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
return "/say $trigger_name already exists for the global channel and cannot be overridden for " . ($from_chan eq '.*' ? 'the global channel' : $from_chan) . ".";
|
||||
}
|
||||
|
||||
if ($self->{pbot}->{commands}->exists($keyword)) {
|
||||
@ -1067,7 +1106,7 @@ sub factadd {
|
||||
sub factrem {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
|
||||
my ($from_chan, $from_trig) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
|
||||
|
||||
@ -1082,44 +1121,45 @@ sub factrem {
|
||||
$channel = '.*' if $channel eq 'global';
|
||||
$from_chan = '.*' if $channel eq 'global';
|
||||
|
||||
my $trigger_text = $trigger =~ / / ? "\"$trigger\"" : $trigger;
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
if ($factoids->{$channel}->{$trigger}->{type} eq 'module') {
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host attempted to remove $trigger_text [not factoid]\n");
|
||||
return "/say $trigger_text is not a factoid.";
|
||||
return "/say $trigger_name is not a factoid.";
|
||||
}
|
||||
|
||||
if ($channel =~ /^#/ and $from_chan =~ /^#/ and $channel ne $from_chan) {
|
||||
return "/say $trigger_text belongs to $channel, but this is $from_chan. Please switch to $channel or /msg to remove this factoid.";
|
||||
return "/say $trigger_name belongs to $channel_name, but this is $from_chan. Please switch to $channel_name or use /msg to remove this factoid.";
|
||||
}
|
||||
|
||||
my ($owner) = $factoids->{$channel}->{$trigger}->{'owner'} =~ m/([^!]+)/;
|
||||
|
||||
if ((lc $nick ne lc $owner) and (not $self->{pbot}->{admins}->loggedin($channel, "$nick!$user\@$host"))) {
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host attempted to remove $trigger_text [not owner]\n");
|
||||
my $chan = ($channel eq '.*' ? 'the global channel' : $channel);
|
||||
return "You are not the owner of $trigger_text for $chan";
|
||||
return "You are not the owner of $trigger_name for $channel_name.";
|
||||
}
|
||||
|
||||
if ($factoids->{$channel}->{$trigger}->{'locked'}) {
|
||||
return "/say $trigger_text is locked; unlock before deleting.";
|
||||
return "/say $trigger_name is locked; unlock before deleting.";
|
||||
}
|
||||
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host removed [$channel][$trigger][" . $factoids->{$channel}->{$trigger}->{action} . "]\n");
|
||||
$self->{pbot}->{factoids}->remove_factoid($channel, $trigger);
|
||||
$self->log_factoid($channel, $trigger, "$nick!$user\@$host", "deleted", 1);
|
||||
return "/say $trigger_text removed from " . ($channel eq '.*' ? 'the global channel' : $channel) . ".";
|
||||
return "/say $trigger_name removed from $channel_name.";
|
||||
}
|
||||
|
||||
sub histogram {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
my %hash;
|
||||
my $factoid_count = 0;
|
||||
|
||||
foreach my $channel (keys %$factoids) {
|
||||
foreach my $command (keys %{ $factoids->{$channel} }) {
|
||||
next if $command eq '_name';
|
||||
if ($factoids->{$channel}->{$command}->{type} eq 'text') {
|
||||
$hash{$factoids->{$channel}->{$command}->{owner}}++;
|
||||
$factoid_count++;
|
||||
@ -1142,7 +1182,7 @@ sub histogram {
|
||||
sub factshow {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
|
||||
$stuff->{preserve_whitespace} = 1;
|
||||
|
||||
@ -1174,15 +1214,16 @@ sub factshow {
|
||||
my ($channel, $trigger) = $self->find_factoid_with_optional_channel($from, $args, 'factshow', usage => $usage);
|
||||
return $channel if not defined $trigger; # if $trigger is not defined, $channel is an error message
|
||||
|
||||
my $trigger_text = $trigger =~ / / ? "\"$trigger\"" : $trigger;
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
my $result = "$trigger_text: ";
|
||||
my $result = "$trigger_name: ";
|
||||
|
||||
if ($paste) {
|
||||
$result .= $self->{pbot}->{webpaste}->paste($factoids->{$channel}->{$trigger}->{action}, no_split => 1);
|
||||
$channel = 'global' if $channel eq '.*';
|
||||
$chan = 'global' if $chan eq '.*';
|
||||
$result = "[$channel] $result" if $channel ne $chan;
|
||||
$result = "[$channel_name] $result" if $channel ne lc $chan;
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -1192,9 +1233,7 @@ sub factshow {
|
||||
$result .= ' [module]';
|
||||
}
|
||||
|
||||
$channel = 'global' if $channel eq '.*';
|
||||
$chan = 'global' if $chan eq '.*';
|
||||
$result = "[$channel] $result" if $channel ne $chan;
|
||||
$result = "[$channel_name] $result" if $channel ne lc $chan;
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -1283,7 +1322,7 @@ sub factlog {
|
||||
sub factinfo {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
|
||||
my ($chan, $trig) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
|
||||
|
||||
@ -1295,35 +1334,38 @@ sub factinfo {
|
||||
my ($channel, $trigger) = $self->find_factoid_with_optional_channel($from, $arguments, 'factinfo');
|
||||
return $channel if not defined $trigger; # if $trigger is not defined, $channel is an error message
|
||||
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
my $created_ago = ago(gettimeofday - $factoids->{$channel}->{$trigger}->{created_on});
|
||||
my $ref_ago = ago(gettimeofday - $factoids->{$channel}->{$trigger}->{last_referenced_on}) if defined $factoids->{$channel}->{$trigger}->{last_referenced_on};
|
||||
|
||||
$chan = ($channel eq '.*' ? 'global channel' : $channel);
|
||||
|
||||
# factoid
|
||||
if ($factoids->{$channel}->{$trigger}->{type} eq 'text') {
|
||||
return "/say $trigger: Factoid submitted by " . $factoids->{$channel}->{$trigger}->{owner} . " for $chan on " . localtime($factoids->{$channel}->{$trigger}->{created_on}) . " [$created_ago], " . (defined $factoids->{$channel}->{$trigger}->{edited_by} ? "last edited by $factoids->{$channel}->{$trigger}->{edited_by} on " . localtime($factoids->{$channel}->{$trigger}->{edited_on}) . " [" . ago(gettimeofday - $factoids->{$channel}->{$trigger}->{edited_on}) . "], " : "") . "referenced " . $factoids->{$channel}->{$trigger}->{ref_count} . " times (last by " . $factoids->{$channel}->{$trigger}->{ref_user} . (exists $factoids->{$channel}->{$trigger}->{last_referenced_on} ? " on " . localtime($factoids->{$channel}->{$trigger}->{last_referenced_on}) . " [$ref_ago]" : "") . ")";
|
||||
return "/say $trigger_name: Factoid submitted by " . $factoids->{$channel}->{$trigger}->{owner} . " for $channel_name on " . localtime($factoids->{$channel}->{$trigger}->{created_on}) . " [$created_ago], " . (defined $factoids->{$channel}->{$trigger}->{edited_by} ? "last edited by $factoids->{$channel}->{$trigger}->{edited_by} on " . localtime($factoids->{$channel}->{$trigger}->{edited_on}) . " [" . ago(gettimeofday - $factoids->{$channel}->{$trigger}->{edited_on}) . "], " : "") . "referenced " . $factoids->{$channel}->{$trigger}->{ref_count} . " times (last by " . $factoids->{$channel}->{$trigger}->{ref_user} . (exists $factoids->{$channel}->{$trigger}->{last_referenced_on} ? " on " . localtime($factoids->{$channel}->{$trigger}->{last_referenced_on}) . " [$ref_ago]" : "") . ")";
|
||||
}
|
||||
|
||||
# module
|
||||
if ($factoids->{$channel}->{$trigger}->{type} eq 'module') {
|
||||
my $module_repo = $self->{pbot}->{registry}->get_value('general', 'module_repo');
|
||||
$module_repo .= "$factoids->{$channel}->{$trigger}->{workdir}/" if exists $factoids->{$channel}->{$trigger}->{workdir};
|
||||
return "/say $trigger: Module loaded by " . $factoids->{$channel}->{$trigger}->{owner} . " for $chan on " . localtime($factoids->{$channel}->{$trigger}->{created_on}) . " [$created_ago] -> $module_repo" . $factoids->{$channel}->{$trigger}->{action} . ", used " . $factoids->{$channel}->{$trigger}->{ref_count} . " times (last by " . $factoids->{$channel}->{$trigger}->{ref_user} . (exists $factoids->{$channel}->{$trigger}->{last_referenced_on} ? " on " . localtime($factoids->{$channel}->{$trigger}->{last_referenced_on}) . " [$ref_ago]" : "") . ")";
|
||||
return "/say $trigger_name: Module loaded by " . $factoids->{$channel}->{$trigger}->{owner} . " for $channel_name on " . localtime($factoids->{$channel}->{$trigger}->{created_on}) . " [$created_ago] -> $module_repo" . $factoids->{$channel}->{$trigger}->{action} . ", used " . $factoids->{$channel}->{$trigger}->{ref_count} . " times (last by " . $factoids->{$channel}->{$trigger}->{ref_user} . (exists $factoids->{$channel}->{$trigger}->{last_referenced_on} ? " on " . localtime($factoids->{$channel}->{$trigger}->{last_referenced_on}) . " [$ref_ago]" : "") . ")";
|
||||
}
|
||||
|
||||
# regex
|
||||
if ($factoids->{$channel}->{$trigger}->{type} eq 'regex') {
|
||||
return "/say $trigger: Regex created by " . $factoids->{$channel}->{$trigger}->{owner} . " for $chan on " . localtime($factoids->{$channel}->{$trigger}->{created_on}) . " [$created_ago], " . (defined $factoids->{$channel}->{$trigger}->{edited_by} ? "last edited by $factoids->{$channel}->{$trigger}->{edited_by} on " . localtime($factoids->{$channel}->{$trigger}->{edited_on}) . " [" . ago(gettimeofday - $factoids->{$channel}->{$trigger}->{edited_on}) . "], " : "") . " used " . $factoids->{$channel}->{$trigger}->{ref_count} . " times (last by " . $factoids->{$channel}->{$trigger}->{ref_user} . (exists $factoids->{$channel}->{$trigger}->{last_referenced_on} ? " on " . localtime($factoids->{$channel}->{$trigger}->{last_referenced_on}) . " [$ref_ago]" : "") . ")";
|
||||
return "/say $trigger_name: Regex created by " . $factoids->{$channel}->{$trigger}->{owner} . " for $channel_name on " . localtime($factoids->{$channel}->{$trigger}->{created_on}) . " [$created_ago], " . (defined $factoids->{$channel}->{$trigger}->{edited_by} ? "last edited by $factoids->{$channel}->{$trigger}->{edited_by} on " . localtime($factoids->{$channel}->{$trigger}->{edited_on}) . " [" . ago(gettimeofday - $factoids->{$channel}->{$trigger}->{edited_on}) . "], " : "") . " used " . $factoids->{$channel}->{$trigger}->{ref_count} . " times (last by " . $factoids->{$channel}->{$trigger}->{ref_user} . (exists $factoids->{$channel}->{$trigger}->{last_referenced_on} ? " on " . localtime($factoids->{$channel}->{$trigger}->{last_referenced_on}) . " [$ref_ago]" : "") . ")";
|
||||
}
|
||||
|
||||
return "/say $arguments is not a factoid or a module";
|
||||
return "/say $arguments is not a factoid or a module.";
|
||||
}
|
||||
|
||||
sub top20 {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
my %hash = ();
|
||||
my $text = "";
|
||||
my $i = 0;
|
||||
@ -1337,9 +1379,10 @@ sub top20 {
|
||||
if (not defined $args) {
|
||||
foreach my $chan (sort keys %{ $factoids }) {
|
||||
next if lc $chan ne lc $channel;
|
||||
foreach my $command (sort {$factoids->{$chan}->{$b}{ref_count} <=> $factoids->{$chan}->{$a}{ref_count}} keys %{ $factoids->{$chan} }) {
|
||||
if ($factoids->{$chan}->{$command}{ref_count} > 0 and $factoids->{$chan}->{$command}{type} eq 'text') {
|
||||
$text .= "$command ($factoids->{$chan}->{$command}{ref_count}) ";
|
||||
foreach my $command (sort {$factoids->{$chan}->{$b}->{ref_count} <=> $factoids->{$chan}->{$a}->{ref_count}} keys %{ $factoids->{$chan} }) {
|
||||
next if $command eq '_name';
|
||||
if ($factoids->{$chan}->{$command}->{ref_count} > 0 and $factoids->{$chan}->{$command}->{type} eq 'text') {
|
||||
$text .= "$factoids->{$chan}->{$command}->{_name} ($factoids->{$chan}->{$command}->{ref_count}) ";
|
||||
$i++;
|
||||
last if $i >= 20;
|
||||
}
|
||||
@ -1353,10 +1396,11 @@ sub top20 {
|
||||
foreach my $chan (sort keys %{ $factoids }) {
|
||||
next if lc $chan ne lc $channel;
|
||||
foreach my $command (sort { $factoids->{$chan}->{$b}{created_on} <=> $factoids->{$chan}->{$a}{created_on} } keys %{ $factoids->{$chan} }) {
|
||||
next if $command eq '_name';
|
||||
my $ago = concise ago gettimeofday - $factoids->{$chan}->{$command}->{created_on};
|
||||
my $owner = $factoids->{$chan}->{$command}->{owner};
|
||||
$owner =~ s/!.*$//;
|
||||
$text .= " $command [$ago by $owner]\n";
|
||||
$text .= " $factoids->{$chan}->{$command}->{_name} [$ago by $owner]\n";
|
||||
$i++;
|
||||
last if $i >= 50;
|
||||
}
|
||||
@ -1369,13 +1413,14 @@ sub top20 {
|
||||
my $user = lc $args;
|
||||
foreach my $chan (sort keys %{ $factoids }) {
|
||||
next if lc $chan ne lc $channel;
|
||||
foreach my $command (sort { ($factoids->{$chan}->{$b}{last_referenced_on} || 0) <=> ($factoids->{$chan}->{$a}{last_referenced_on} || 0) } keys %{ $factoids->{$chan} }) {
|
||||
if ($factoids->{$chan}->{$command}{ref_user} =~ /\Q$args\E/i) {
|
||||
if ($user ne lc $factoids->{$chan}->{$command}{ref_user} && not $user =~ /$factoids->{$chan}->{$command}{ref_user}/i) {
|
||||
$user .= " ($factoids->{$chan}->{$command}{ref_user})";
|
||||
foreach my $command (sort { ($factoids->{$chan}->{$b}->{last_referenced_on} || 0) <=> ($factoids->{$chan}->{$a}->{last_referenced_on} || 0) } keys %{ $factoids->{$chan} }) {
|
||||
next if $command eq '_name';
|
||||
if ($factoids->{$chan}->{$command}->{ref_user} =~ /\Q$args\E/i) {
|
||||
if ($user ne lc $factoids->{$chan}->{$command}->{ref_user} && not $user =~ /$factoids->{$chan}->{$command}->{ref_user}/i) {
|
||||
$user .= " ($factoids->{$chan}->{$command}->{ref_user})";
|
||||
}
|
||||
my $ago = $factoids->{$chan}->{$command}{last_referenced_on} ? concise ago(gettimeofday - $factoids->{$chan}->{$command}{last_referenced_on}) : "unknown";
|
||||
$text .= " $command [$ago]\n";
|
||||
$text .= " $factoids->{$chan}->{$command}->{_name} [$ago]\n";
|
||||
$i++;
|
||||
last if $i >= 20;
|
||||
}
|
||||
@ -1389,7 +1434,7 @@ sub top20 {
|
||||
sub count {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
my $i = 0;
|
||||
my $total = 0;
|
||||
|
||||
@ -1402,6 +1447,7 @@ sub count {
|
||||
eval {
|
||||
foreach my $channel (keys %{ $factoids }) {
|
||||
foreach my $command (keys %{ $factoids->{$channel} }) {
|
||||
next if $command eq '_name';
|
||||
next if $factoids->{$channel}->{$command}->{type} ne 'text';
|
||||
$total++;
|
||||
if ($factoids->{$channel}->{$command}->{owner} =~ /^\Q$arguments\E$/i) {
|
||||
@ -1426,7 +1472,7 @@ sub count {
|
||||
sub factfind {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
|
||||
my $usage = "Usage: factfind [-channel channel] [-owner regex] [-editby regex] [-refby regex] [-regex] [text]";
|
||||
|
||||
@ -1506,24 +1552,21 @@ sub factfind {
|
||||
foreach my $chan (sort keys %{ $factoids }) {
|
||||
next if defined $channel and $chan !~ /^$channel$/i;
|
||||
foreach my $trigger (sort keys %{ $factoids->{$chan} }) {
|
||||
next if $trigger eq '_name';
|
||||
if ($factoids->{$chan}->{$trigger}->{type} eq 'text' or $factoids->{$chan}->{$trigger}->{type} eq 'regex') {
|
||||
if ($factoids->{$chan}->{$trigger}->{owner} =~ /^$owner$/i
|
||||
&& $factoids->{$chan}->{$trigger}->{ref_user} =~ /^$refby$/i
|
||||
&& (exists $factoids->{$chan}->{$trigger}->{edited_by} ? $factoids->{$chan}->{$trigger}->{edited_by} =~ /^$editby$/i : 1)) {
|
||||
next if ($arguments ne "" && $factoids->{$chan}->{$trigger}->{action} !~ /$regex/i && $trigger !~ /$regex/i);
|
||||
|
||||
$i++;
|
||||
|
||||
if ($chan ne $last_chan) {
|
||||
$text .= $chan eq '.*' ? "[global channel] " : "[$chan] ";
|
||||
$text .= $chan eq '.*' ? "[global channel] " : "[$factoids->{$chan}->{_name}] ";
|
||||
$last_chan = $chan;
|
||||
}
|
||||
if ($trigger =~ / /) {
|
||||
$text .= "\"$trigger\" ";
|
||||
} else {
|
||||
$text .= "$trigger ";
|
||||
}
|
||||
$last_trigger = $trigger;
|
||||
my $trigger_name = $factoids->{$chan}->{$trigger}->{_name};
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
$text .= "$trigger_name ";
|
||||
$last_trigger = $trigger_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1534,19 +1577,18 @@ sub factfind {
|
||||
|
||||
if ($i == 1) {
|
||||
chop $text;
|
||||
return "Found one factoid submitted for " . ($last_chan eq '.*' ? 'global channel' : $last_chan) . " " . $argtype . ": $last_trigger is $factoids->{$last_chan}->{$last_trigger}->{action}";
|
||||
return "Found one factoid submitted for " . ($last_chan eq '.*' ? 'global channel' : $factoids->{$last_chan}->{_name}) . " " . $argtype . ": $last_trigger is $factoids->{$last_chan}->{$last_trigger}->{action}";
|
||||
} else {
|
||||
return "Found $i factoids " . $argtype . ": $text" unless $i == 0;
|
||||
|
||||
my $chans = (defined $channel ? ($channel eq '.*' ? 'global channel' : $channel) : 'any channels');
|
||||
return "No factoids " . $argtype . " submitted for $chans";
|
||||
return "No factoids " . $argtype . " submitted for $chans.";
|
||||
}
|
||||
}
|
||||
|
||||
sub factchange {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids_hash = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
my ($channel, $trigger, $keyword, $delim, $tochange, $changeto, $modifier, $url);
|
||||
|
||||
$stuff->{preserve_whitespace} = 1;
|
||||
@ -1629,25 +1671,31 @@ sub factchange {
|
||||
return "/say $keyword not found in channel $from_chan.";
|
||||
}
|
||||
|
||||
my $channel_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{_name};
|
||||
my $trigger_name = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
$channel_name = 'global' if $channel_name eq '.*';
|
||||
$trigger_name = "\"$trigger_name\"" if $trigger_name =~ / /;
|
||||
|
||||
$from_chan = '.*' if $from_chan eq 'global';
|
||||
|
||||
if ($channel =~ /^#/ and $from_chan =~ /^#/ and $channel ne $from_chan) {
|
||||
return "/say $trigger belongs to $channel, but this is $from_chan. Please switch to $channel or use /msg to change this factoid.";
|
||||
return "/say $trigger_name belongs to $channel_name, but this is $from_chan. Please switch to $channel_name or use /msg to change this factoid.";
|
||||
}
|
||||
|
||||
my $admininfo = $self->{pbot}->{admins}->loggedin($channel, "$nick!$user\@$host");
|
||||
if ($factoids->{$channel}->{$trigger}->{'locked'}) {
|
||||
return "/say $trigger is locked and cannot be changed." if not defined $admininfo;
|
||||
if ($factoids_hash->{$channel}->{$trigger}->{'locked'}) {
|
||||
return "/say $trigger_name is locked and cannot be changed." if not defined $admininfo;
|
||||
|
||||
if (exists $factoids->{$channel}->{$trigger}->{'effective-level'}
|
||||
and $admininfo->{level} < $factoids->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
return "/say $trigger is locked with an effective-level higher than your level and cannot be changed.";
|
||||
if (exists $factoids_hash->{$channel}->{$trigger}->{'effective-level'}
|
||||
and $admininfo->{level} < $factoids_hash->{$channel}->{$trigger}->{'effective-level'}) {
|
||||
return "/say $trigger_name is locked with an effective-level higher than your level and cannot be changed.";
|
||||
}
|
||||
}
|
||||
|
||||
my $action = $factoids->{$channel}->{$trigger}->{action};
|
||||
my $action = $factoids_hash->{$channel}->{$trigger}->{action};
|
||||
|
||||
if (defined $url) {
|
||||
# FIXME: move this to registry
|
||||
if ($url !~ m/^https?:\/\/(?:sprunge.us|ix.io)\/\w+$/) {
|
||||
return "Invalid URL: acceptable URLs are: http://sprunge.us, http://ix.io";
|
||||
}
|
||||
@ -1714,66 +1762,72 @@ sub factchange {
|
||||
return "";
|
||||
};
|
||||
|
||||
return "/msg $nick Change $trigger: $@" if $@;
|
||||
if ($@) {
|
||||
my $err = $@;
|
||||
$err =~ s/ at PBot\/FactoidCommand.*$//;
|
||||
return "/msg $nick Change $trigger_name failed: $err";
|
||||
}
|
||||
return $ret if length $ret;
|
||||
}
|
||||
|
||||
if (length $action > 8000 and not defined $admininfo) {
|
||||
return "Change $trigger failed; result is too long.";
|
||||
return "Change $trigger_name failed; result is too long.";
|
||||
}
|
||||
|
||||
if (not length $action) {
|
||||
return "Change $trigger failed; factoids cannot be empty.";
|
||||
return "Change $trigger_name failed; factoids cannot be empty.";
|
||||
}
|
||||
|
||||
$self->{pbot}->{logger}->log("($from) $nick!$user\@$host: changed '$trigger' 's/$tochange/$changeto/\n");
|
||||
|
||||
$factoids->{$channel}->{$trigger}->{action} = $action;
|
||||
$factoids->{$channel}->{$trigger}->{edited_by} = "$nick!$user\@$host";
|
||||
$factoids->{$channel}->{$trigger}->{edited_on} = gettimeofday;
|
||||
$factoids_hash->{$channel}->{$trigger}->{action} = $action;
|
||||
$factoids_hash->{$channel}->{$trigger}->{edited_by} = "$nick!$user\@$host";
|
||||
$factoids_hash->{$channel}->{$trigger}->{edited_on} = gettimeofday;
|
||||
$self->{pbot}->{factoids}->save_factoids();
|
||||
$self->log_factoid($channel, $trigger, "$nick!$user\@$host", "changed to $factoids->{$channel}->{$trigger}->{action}");
|
||||
return "Changed: $trigger is " . $factoids->{$channel}->{$trigger}->{action};
|
||||
$self->log_factoid($channel, $trigger, "$nick!$user\@$host", "changed to $factoids_hash->{$channel}->{$trigger}->{action}");
|
||||
return "Changed: $trigger_name is " . $factoids_hash->{$channel}->{$trigger}->{action};
|
||||
}
|
||||
|
||||
# FIXME: these two functions need to use $stuff->{arglist}
|
||||
|
||||
sub load_module {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
my ($keyword, $module) = $arguments =~ /^(.*?)\s+(.*)$/ if defined $arguments;
|
||||
|
||||
if (not defined $module) {
|
||||
return "Usage: load <keyword> <module>";
|
||||
}
|
||||
|
||||
if (not exists($factoids->{'.*'}->{$keyword})) {
|
||||
if (not exists($factoids->{'.*'}->{lc $keyword})) {
|
||||
$self->{pbot}->{factoids}->add_factoid('module', '.*', "$nick!$user\@$host", $keyword, $module);
|
||||
$factoids->{'.*'}->{$keyword}->{add_nick} = 1;
|
||||
$factoids->{'.*'}->{$keyword}->{nooverride} = 1;
|
||||
$factoids->{'.*'}->{lc $keyword}->{add_nick} = 1;
|
||||
$factoids->{'.*'}->{lc $keyword}->{nooverride} = 1;
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host loaded module $keyword => $module\n");
|
||||
$self->{pbot}->{factoids}->save_factoids();
|
||||
return "Loaded module $keyword => $module";
|
||||
} else {
|
||||
return "There is already a keyword named $keyword.";
|
||||
return "There is already a keyword named $factoids->{'.*'}->{$keyword}->{_name}.";
|
||||
}
|
||||
}
|
||||
|
||||
sub unload_module {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments) = @_;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
|
||||
my $factoids = $self->{pbot}->{factoids}->{factoids}->{hash};
|
||||
|
||||
if (not defined $arguments) {
|
||||
return "Usage: unload <keyword>";
|
||||
} elsif (not exists $factoids->{'.*'}->{$arguments}) {
|
||||
} elsif (not exists $factoids->{'.*'}->{lc $arguments}) {
|
||||
return "/say $arguments not found.";
|
||||
} elsif ($factoids->{'.*'}->{$arguments}{type} ne 'module') {
|
||||
return "/say $arguments is not a module.";
|
||||
} elsif ($factoids->{'.*'}->{lc $arguments}->{type} ne 'module') {
|
||||
return "/say " . $factoids->{'.*'}->{lc $arguments}->{_name} . " is not a module.";
|
||||
} else {
|
||||
delete $factoids->{'.*'}->{$arguments};
|
||||
my $data = delete $factoids->{'.*'}->{lc $arguments};
|
||||
$self->{pbot}->{factoids}->save_factoids();
|
||||
$self->{pbot}->{logger}->log("$nick!$user\@$host unloaded module $arguments\n");
|
||||
return "/say $arguments unloaded.";
|
||||
return "/say $data->{_name} unloaded.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ sub execute_module {
|
||||
$stuff->{keyword} = $trigger;
|
||||
$stuff->{trigger} = $trigger;
|
||||
|
||||
my $module = $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{action};
|
||||
my $module = $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{action};
|
||||
my $module_dir = $self->{pbot}->{registry}->get_value('general', 'module_dir');
|
||||
|
||||
$self->{pbot}->{logger}->log("(" . (defined $stuff->{from} ? $stuff->{from} : "(undef)") . "): $stuff->{nick}!$stuff->{user}\@$stuff->{host}: Executing module [$stuff->{command}] $module $stuff->{arguments}\n");
|
||||
@ -108,8 +108,8 @@ sub execute_module {
|
||||
Carp::croak("Could not chdir to '$module_dir': $!");
|
||||
}
|
||||
|
||||
if (exists $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{workdir}) {
|
||||
chdir $self->{pbot}->{factoids}->{factoids}->hash->{$channel}->{$trigger}->{workdir};
|
||||
if (exists $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{workdir}) {
|
||||
chdir $self->{pbot}->{factoids}->{factoids}->{hash}->{$channel}->{$trigger}->{workdir};
|
||||
}
|
||||
|
||||
my ($exitval, $stdout, $stderr) = eval {
|
||||
@ -191,7 +191,7 @@ sub module_pipe_reader {
|
||||
$self->{pbot}->{interpreter}->handle_result($stuff, $stuff->{result});
|
||||
} else {
|
||||
# don't override nick if already set
|
||||
if (exists $stuff->{special} and $stuff->{special} ne 'code-factoid' and exists $self->{pbot}->{factoids}->{factoids}->hash->{$stuff->{channel}}->{$stuff->{trigger}}->{add_nick} and $self->{pbot}->{factoids}->{factoids}->hash->{$stuff->{channel}}->{$stuff->{trigger}}->{add_nick} != 0) {
|
||||
if (exists $stuff->{special} and $stuff->{special} ne 'code-factoid' and exists $self->{pbot}->{factoids}->{factoids}->{hash}->{$stuff->{channel}}->{$stuff->{trigger}}->{add_nick} and $self->{pbot}->{factoids}->{factoids}->{hash}->{$stuff->{channel}}->{$stuff->{trigger}}->{add_nick} != 0) {
|
||||
$stuff->{nickoverride} = $stuff->{nick};
|
||||
$stuff->{no_nickoverride} = 0;
|
||||
$stuff->{force_nickoverride} = 1;
|
||||
|
254
PBot/Factoids.pm
254
PBot/Factoids.pm
@ -34,12 +34,8 @@ use PBot::Utils::Indefinite;
|
||||
use PBot::Utils::ValidateString;
|
||||
|
||||
sub new {
|
||||
if (ref($_[1]) eq 'HASH') {
|
||||
Carp::croak("Options to Factoids should be key/value pairs, not hash reference");
|
||||
}
|
||||
|
||||
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;
|
||||
@ -49,13 +45,13 @@ sub initialize {
|
||||
my ($self, %conf) = @_;
|
||||
|
||||
my $filename = $conf{filename};
|
||||
my $pbot = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
||||
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
||||
|
||||
$self->{factoids} = PBot::DualIndexHashObject->new(name => 'Factoids', filename => $filename, pbot => $pbot);
|
||||
$self->{factoids} = PBot::DualIndexHashObject->new(name => 'Factoids', filename => $filename, pbot => $self->{pbot});
|
||||
|
||||
$self->{pbot} = $pbot;
|
||||
$self->{commands} = PBot::FactoidCommands->new(pbot => $pbot);
|
||||
$self->{factoidmodulelauncher} = PBot::FactoidModuleLauncher->new(pbot => $pbot);
|
||||
$self->{pbot} = $self->{pbot};
|
||||
$self->{commands} = PBot::FactoidCommands->new(pbot => $self->{pbot});
|
||||
$self->{factoidmodulelauncher} = PBot::FactoidModuleLauncher->new(pbot => $self->{pbot});
|
||||
|
||||
$self->{pbot}->{registry}->add_default('text', 'factoids', 'default_rate_limit', 15);
|
||||
$self->{pbot}->{registry}->add_default('text', 'factoids', 'max_name_length', 100);
|
||||
@ -64,7 +60,6 @@ sub initialize {
|
||||
|
||||
$self->{pbot}->{atexit}->register(sub { $self->save_factoids; return; });
|
||||
|
||||
$self->{compartments} = {};
|
||||
$self->load_factoids;
|
||||
}
|
||||
|
||||
@ -74,12 +69,13 @@ sub load_factoids {
|
||||
$self->{factoids}->load;
|
||||
|
||||
my ($text, $regex, $modules);
|
||||
foreach my $channel (keys %{ $self->{factoids}->hash }) {
|
||||
foreach my $trigger (keys %{ $self->{factoids}->hash->{$channel} }) {
|
||||
$self->{pbot}->{logger}->log("Missing type for $channel->$trigger\n") if not $self->{factoids}->hash->{$channel}->{$trigger}->{type};
|
||||
$text++ if $self->{factoids}->hash->{$channel}->{$trigger}->{type} eq 'text';
|
||||
$regex++ if $self->{factoids}->hash->{$channel}->{$trigger}->{type} eq 'regex';
|
||||
$modules++ if $self->{factoids}->hash->{$channel}->{$trigger}->{type} eq 'module';
|
||||
foreach my $channel (keys %{ $self->{factoids}->{hash} }) {
|
||||
foreach my $trigger (keys %{ $self->{factoids}->{hash}->{$channel} }) {
|
||||
next if $trigger eq '_name';
|
||||
$self->{pbot}->{logger}->log("Missing type for $channel->$trigger\n") if not $self->{factoids}->{hash}->{$channel}->{$trigger}->{type};
|
||||
$text++ if $self->{factoids}->{hash}->{$channel}->{$trigger}->{type} eq 'text';
|
||||
$regex++ if $self->{factoids}->{hash}->{$channel}->{$trigger}->{type} eq 'regex';
|
||||
$modules++ if $self->{factoids}->{hash}->{$channel}->{$trigger}->{type} eq 'module';
|
||||
}
|
||||
}
|
||||
$self->{pbot}->{logger}->log(" " . ($text + $regex + $modules) . " factoids loaded ($text text, $regex regexs, $modules modules).\n");
|
||||
@ -94,7 +90,6 @@ sub add_default_factoids {
|
||||
|
||||
sub save_factoids {
|
||||
my $self = shift;
|
||||
|
||||
$self->{factoids}->save;
|
||||
$self->export_factoids;
|
||||
}
|
||||
@ -105,18 +100,28 @@ sub add_factoid {
|
||||
|
||||
$type = lc $type;
|
||||
$channel = '.*' if $channel !~ /^#/;
|
||||
$channel = lc $channel;
|
||||
|
||||
$self->{factoids}->hash->{$channel}->{$trigger}->{enabled} = 1;
|
||||
$self->{factoids}->hash->{$channel}->{$trigger}->{type} = $type;
|
||||
$self->{factoids}->hash->{$channel}->{$trigger}->{action} = $action;
|
||||
$self->{factoids}->hash->{$channel}->{$trigger}->{owner} = $owner;
|
||||
$self->{factoids}->hash->{$channel}->{$trigger}->{created_on} = gettimeofday;
|
||||
$self->{factoids}->hash->{$channel}->{$trigger}->{ref_count} = 0;
|
||||
$self->{factoids}->hash->{$channel}->{$trigger}->{ref_user} = "nobody";
|
||||
$self->{factoids}->hash->{$channel}->{$trigger}->{rate_limit} = $self->{pbot}->{registry}->get_value('factoids', 'default_rate_limit');
|
||||
my $data;
|
||||
|
||||
$self->save_factoids unless $dont_save;
|
||||
if (exists $self->{factoids}->{hash}->{lc $channel}->{lc $trigger}) {
|
||||
# only update action field if force-adding it through factadd -f
|
||||
$data = $self->{factoids}->{hash}->{lc $channel}->{lc $trigger};
|
||||
$data->{action} = $action;
|
||||
$data->{type} = $type;
|
||||
} else {
|
||||
$data = {
|
||||
enabled => 1,
|
||||
type => $type,
|
||||
action => $action,
|
||||
owner => $owner,
|
||||
created_on => scalar gettimeofday,
|
||||
ref_count => 0,
|
||||
ref_user => "nobody",
|
||||
rate_limit => $self->{pbot}->{registry}->get_value('factoids', 'default_rate_limit')
|
||||
};
|
||||
}
|
||||
|
||||
$self->{factoids}->add($channel, $trigger, $data, $dont_save);
|
||||
|
||||
unless ($dont_save) {
|
||||
$self->{commands}->log_factoid($channel, $trigger, $owner, "created: $action");
|
||||
@ -129,11 +134,12 @@ sub remove_factoid {
|
||||
|
||||
$channel = '.*' if $channel !~ /^#/;
|
||||
$channel = lc $channel;
|
||||
$trigger = lc $trigger;
|
||||
|
||||
delete $self->{factoids}->hash->{$channel}->{$trigger};
|
||||
delete $self->{factoids}->{hash}->{$channel}->{$trigger};
|
||||
|
||||
if (not scalar keys %{ $self->{factoids}->hash->{$channel} }) {
|
||||
delete $self->{factoids}->hash->{$channel};
|
||||
if (not scalar keys %{ $self->{factoids}->{hash}->{$channel} }) {
|
||||
delete $self->{factoids}->{hash}->{$channel};
|
||||
}
|
||||
|
||||
$self->save_factoids;
|
||||
@ -160,16 +166,18 @@ sub export_factoids {
|
||||
my $i = 0;
|
||||
my $table_id = 1;
|
||||
|
||||
foreach my $channel (sort keys %{ $self->{factoids}->hash }) {
|
||||
next if not scalar keys %{ $self->{factoids}->hash->{$channel} };
|
||||
my $chan = $channel eq '.*' ? 'global' : $channel;
|
||||
foreach my $channel (sort keys %{ $self->{factoids}->{hash} }) {
|
||||
next if not scalar keys %{ $self->{factoids}->{hash}->{$channel} };
|
||||
my $chan = $self->{factoids}->{hash}->{$channel}->{_name};
|
||||
$chan = 'global' if $chan eq '.*';
|
||||
|
||||
print FILE "<a href='#" . encode_entities($chan) . "'>" . encode_entities($chan) . "</a><br>\n";
|
||||
}
|
||||
|
||||
foreach my $channel (sort keys %{ $self->{factoids}->hash }) {
|
||||
next if not scalar keys %{ $self->{factoids}->hash->{$channel} };
|
||||
my $chan = $channel eq '.*' ? 'global' : $channel;
|
||||
foreach my $channel (sort keys %{ $self->{factoids}->{hash} }) {
|
||||
next if not scalar keys %{ $self->{factoids}->{hash}->{$channel} };
|
||||
my $chan = $self->{factoids}->{hash}->{$channel}->{_name};
|
||||
$chan = 'global' if $chan eq '.*';
|
||||
print FILE "<a name='" . encode_entities($chan) . "'></a>\n";
|
||||
print FILE "<hr>\n<h3>" . encode_entities($chan) . "</h3>\n<hr>\n";
|
||||
print FILE "<table border=\"0\" id=\"table$table_id\" class=\"tablesorter\">\n";
|
||||
@ -185,8 +193,10 @@ sub export_factoids {
|
||||
print FILE "</tr>\n</thead>\n<tbody>\n";
|
||||
$table_id++;
|
||||
|
||||
foreach my $trigger (sort keys %{ $self->{factoids}->hash->{$channel} }) {
|
||||
if ($self->{factoids}->hash->{$channel}->{$trigger}->{type} eq 'text') {
|
||||
foreach my $trigger (sort keys %{ $self->{factoids}->{hash}->{$channel} }) {
|
||||
next if $trigger eq '_name';
|
||||
my $trigger_name = $self->{factoids}->{hash}->{$channel}->{$trigger}->{_name};
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$trigger}->{type} eq 'text') {
|
||||
$i++;
|
||||
if ($i % 2) {
|
||||
print FILE "<tr bgcolor=\"#dddddd\">\n";
|
||||
@ -194,12 +204,12 @@ sub export_factoids {
|
||||
print FILE "<tr>\n";
|
||||
}
|
||||
|
||||
print FILE "<td>" . encode_entities($self->{factoids}->hash->{$channel}->{$trigger}->{owner}) . "</td>\n";
|
||||
print FILE "<td>" . encode_entities(strftime "%Y/%m/%d %H:%M:%S", localtime $self->{factoids}->hash->{$channel}->{$trigger}->{created_on}) . "</td>\n";
|
||||
print FILE "<td>" . encode_entities($self->{factoids}->{hash}->{$channel}->{$trigger}->{owner}) . "</td>\n";
|
||||
print FILE "<td>" . encode_entities(strftime "%Y/%m/%d %H:%M:%S", localtime $self->{factoids}->{hash}->{$channel}->{$trigger}->{created_on}) . "</td>\n";
|
||||
|
||||
print FILE "<td>" . $self->{factoids}->hash->{$channel}->{$trigger}->{ref_count} . "</td>\n";
|
||||
print FILE "<td>" . $self->{factoids}->{hash}->{$channel}->{$trigger}->{ref_count} . "</td>\n";
|
||||
|
||||
my $action = $self->{factoids}->hash->{$channel}->{$trigger}->{action};
|
||||
my $action = $self->{factoids}->{hash}->{$channel}->{$trigger}->{action};
|
||||
|
||||
if ($action =~ m/https?:\/\/[^ ]+/) {
|
||||
$action =~ s/(.*?)http(s?:\/\/[^ ]+)/encode_entities($1) . "<a href='http" . encode_entities($2) . "'>http" . encode_entities($2) . "<\/a>"/ge;
|
||||
@ -208,27 +218,27 @@ sub export_factoids {
|
||||
$action = encode_entities($action);
|
||||
}
|
||||
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$trigger}->{action_with_args}) {
|
||||
my $with_args = $self->{factoids}->hash->{$channel}->{$trigger}->{action_with_args};
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$trigger}->{action_with_args}) {
|
||||
my $with_args = $self->{factoids}->{hash}->{$channel}->{$trigger}->{action_with_args};
|
||||
$with_args =~ s/(.*?)http(s?:\/\/[^ ]+)/encode_entities($1) . "<a href='http" . encode_entities($2) . "'>http" . encode_entities($2) . "<\/a>"/ge;
|
||||
$with_args =~ s/(.*)<\/a>(.*$)/"$1<\/a>" . encode_entities($2)/e;
|
||||
print FILE "<td width=100%><b>" . encode_entities($trigger) . "</b> is $action<br><br><b>with_args:</b> " . encode_entities($with_args) . "</td>\n";
|
||||
print FILE "<td width=100%><b>" . encode_entities($trigger_name) . "</b> is $action<br><br><b>with_args:</b> " . encode_entities($with_args) . "</td>\n";
|
||||
} else {
|
||||
print FILE "<td width=100%><b>" . encode_entities($trigger) . "</b> is $action</td>\n";
|
||||
print FILE "<td width=100%><b>" . encode_entities($trigger_name) . "</b> is $action</td>\n";
|
||||
}
|
||||
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$trigger}->{edited_by}) {
|
||||
print FILE "<td>" . $self->{factoids}->hash->{$channel}->{$trigger}->{edited_by} . "</td>\n";
|
||||
print FILE "<td>" . encode_entities(strftime "%Y/%m/%d %H:%M:%S", localtime $self->{factoids}->hash->{$channel}->{$trigger}->{edited_on}) . "</td>\n";
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$trigger}->{edited_by}) {
|
||||
print FILE "<td>" . $self->{factoids}->{hash}->{$channel}->{$trigger}->{edited_by} . "</td>\n";
|
||||
print FILE "<td>" . encode_entities(strftime "%Y/%m/%d %H:%M:%S", localtime $self->{factoids}->{hash}->{$channel}->{$trigger}->{edited_on}) . "</td>\n";
|
||||
} else {
|
||||
print FILE "<td></td>\n";
|
||||
print FILE "<td></td>\n";
|
||||
}
|
||||
|
||||
print FILE "<td>" . encode_entities($self->{factoids}->hash->{$channel}->{$trigger}->{ref_user}) . "</td>\n";
|
||||
print FILE "<td>" . encode_entities($self->{factoids}->{hash}->{$channel}->{$trigger}->{ref_user}) . "</td>\n";
|
||||
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$trigger}->{last_referenced_on}) {
|
||||
print FILE "<td>" . encode_entities(strftime "%Y/%m/%d %H:%M:%S", localtime $self->{factoids}->hash->{$channel}->{$trigger}->{last_referenced_on}) . "</td>\n";
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$trigger}->{last_referenced_on}) {
|
||||
print FILE "<td>" . encode_entities(strftime "%Y/%m/%d %H:%M:%S", localtime $self->{factoids}->{hash}->{$channel}->{$trigger}->{last_referenced_on}) . "</td>\n";
|
||||
} else {
|
||||
print FILE "<td></td>\n";
|
||||
}
|
||||
@ -281,6 +291,7 @@ sub find_factoid {
|
||||
|
||||
$from = '.*' if not defined $from or $from !~ /^#/;
|
||||
$from = lc $from;
|
||||
$keyword = lc $keyword;
|
||||
|
||||
$self->{pbot}->{logger}->log("from: $from\n") if $debug;
|
||||
|
||||
@ -293,7 +304,7 @@ sub find_factoid {
|
||||
$self->{pbot}->{logger}->log("string: $string\n") if $debug;
|
||||
return undef if $self->{pbot}->{commands}->exists($keyword);
|
||||
# check factoids
|
||||
foreach my $channel (sort keys %{ $self->{factoids}->hash }) {
|
||||
foreach my $channel (sort keys %{ $self->{factoids}->{hash} }) {
|
||||
if ($opts{exact_channel}) {
|
||||
if ($opts{exact_trigger} == 1) {
|
||||
next unless $from eq lc $channel;
|
||||
@ -302,11 +313,12 @@ sub find_factoid {
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $trigger (keys %{ $self->{factoids}->hash->{$channel} }) {
|
||||
if ($keyword =~ m/^\Q$trigger\E$/i) {
|
||||
foreach my $trigger (keys %{ $self->{factoids}->{hash}->{$channel} }) {
|
||||
next if $trigger eq '_name';
|
||||
if ($keyword eq $trigger) {
|
||||
$self->{pbot}->{logger}->log("return $channel: $trigger\n") if $debug;
|
||||
|
||||
if ($opts{find_alias} && $self->{factoids}->hash->{$channel}->{$trigger}->{action} =~ /^\/call\s+(.*)$/ms) {
|
||||
if ($opts{find_alias} && $self->{factoids}->{hash}->{$channel}->{$trigger}->{action} =~ /^\/call\s+(.*)$/ms) {
|
||||
my $command;
|
||||
if (length $arguments) {
|
||||
$command = "$1 $arguments";
|
||||
@ -329,19 +341,20 @@ sub find_factoid {
|
||||
|
||||
# then check regex factoids
|
||||
if (not $opts{exact_trigger}) {
|
||||
foreach my $channel (sort keys %{ $self->{factoids}->hash }) {
|
||||
foreach my $channel (sort keys %{ $self->{factoids}->{hash} }) {
|
||||
if ($opts{exact_channel}) {
|
||||
next unless $from eq lc $channel or $channel eq '.*';
|
||||
}
|
||||
|
||||
foreach my $trigger (sort keys %{ $self->{factoids}->hash->{$channel} }) {
|
||||
if ($self->{factoids}->hash->{$channel}->{$trigger}->{type} eq 'regex') {
|
||||
foreach my $trigger (sort keys %{ $self->{factoids}->{hash}->{$channel} }) {
|
||||
next if $trigger eq '_name';
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$trigger}->{type} eq 'regex') {
|
||||
$self->{pbot}->{logger}->log("checking regex $string =~ m/$trigger/i\n") if $debug >= 2;
|
||||
if ($string =~ m/$trigger/i) {
|
||||
$self->{pbot}->{logger}->log("return regex $channel: $trigger\n") if $debug;
|
||||
|
||||
if ($opts{find_alias}) {
|
||||
my $command = $self->{factoids}->hash->{$channel}->{$trigger}->{action};
|
||||
my $command = $self->{factoids}->{hash}->{$channel}->{$trigger}->{action};
|
||||
my $arglist = $self->{pbot}->{interpreter}->make_args($command);
|
||||
($keyword, $arguments) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
|
||||
$string = $keyword . (length $arguments ? " $arguments" : "");
|
||||
@ -475,14 +488,14 @@ sub expand_factoid_vars {
|
||||
|
||||
my ($var_chan, $var) = ($factoids[0]->[0], $factoids[0]->[1]);
|
||||
|
||||
if ($self->{factoids}->hash->{$var_chan}->{$var}->{action} =~ m{^/call (.*)}ms) {
|
||||
if ($self->{factoids}->{hash}->{$var_chan}->{$var}->{action} =~ m{^/call (.*)}ms) {
|
||||
$test_v = $1;
|
||||
next if ++$recurse > 100;
|
||||
goto ALIAS;
|
||||
}
|
||||
|
||||
if ($self->{factoids}->hash->{$var_chan}->{$var}->{type} eq 'text') {
|
||||
my $change = $self->{factoids}->hash->{$var_chan}->{$var}->{action};
|
||||
if ($self->{factoids}->{hash}->{$var_chan}->{$var}->{type} eq 'text') {
|
||||
my $change = $self->{factoids}->{hash}->{$var_chan}->{$var}->{action};
|
||||
my @list = $self->{pbot}->{interpreter}->split_line($change);
|
||||
my @mylist;
|
||||
for (my $i = 0; $i <= $#list; $i++) {
|
||||
@ -695,7 +708,7 @@ sub expand_action_arguments {
|
||||
sub execute_code_factoid_using_vm {
|
||||
my ($self, $stuff) = @_;
|
||||
|
||||
unless (exists $self->{factoids}->hash->{$stuff->{channel}}->{$stuff->{keyword}}->{interpolate} and $self->{factoids}->hash->{$stuff->{channel}}->{$stuff->{keyword}}->{interpolate} eq '0') {
|
||||
unless (exists $self->{factoids}->{hash}->{lc $stuff->{channel}}->{lc $stuff->{keyword}}->{interpolate} and $self->{factoids}->{hash}->{lc $stuff->{channel}}->{lc $stuff->{keyword}}->{interpolate} eq '0') {
|
||||
if ($stuff->{code} =~ m/(?:\$\{?nick\b|\$\{?args\b|\$\{?arg\[)/ and length $stuff->{arguments}) {
|
||||
$stuff->{no_nickoverride} = 1;
|
||||
} else {
|
||||
@ -705,7 +718,7 @@ sub execute_code_factoid_using_vm {
|
||||
$stuff->{action} = $stuff->{code};
|
||||
$stuff->{code} = $self->expand_factoid_vars($stuff);
|
||||
|
||||
if ($self->{factoids}->hash->{$stuff->{channel}}->{$stuff->{keyword}}->{'allow_empty_args'}) {
|
||||
if ($self->{factoids}->{hash}->{lc $stuff->{channel}}->{lc $stuff->{keyword}}->{'allow_empty_args'}) {
|
||||
$stuff->{code} = $self->expand_action_arguments($stuff->{code}, $stuff->{arguments}, '');
|
||||
} else {
|
||||
$stuff->{code} = $self->expand_action_arguments($stuff->{code}, $stuff->{arguments}, $stuff->{nick});
|
||||
@ -716,8 +729,8 @@ sub execute_code_factoid_using_vm {
|
||||
|
||||
my %h = (nick => $stuff->{nick}, channel => $stuff->{from}, lang => $stuff->{lang}, code => $stuff->{code}, arguments => $stuff->{arguments}, factoid => "$stuff->{channel}:$stuff->{keyword}");
|
||||
|
||||
if (exists $self->{factoids}->hash->{$stuff->{channel}}->{$stuff->{keyword}}->{'persist-key'}) {
|
||||
$h{'persist-key'} = $self->{factoids}->hash->{$stuff->{channel}}->{$stuff->{keyword}}->{'persist-key'};
|
||||
if (exists $self->{factoids}->{hash}->{lc $stuff->{channel}}->{lc $stuff->{keyword}}->{'persist-key'}) {
|
||||
$h{'persist-key'} = $self->{factoids}->{hash}->{lc $stuff->{channel}}->{lc $stuff->{keyword}}->{'persist-key'};
|
||||
}
|
||||
|
||||
my $json = encode_json \%h;
|
||||
@ -766,7 +779,7 @@ sub interpreter {
|
||||
$stuff->{ref_from} = "";
|
||||
}
|
||||
|
||||
if (defined $channel and not $channel eq '.*' and not lc $channel eq $stuff->{from}) {
|
||||
if (defined $channel and not $channel eq '.*' and not $channel eq lc $stuff->{from}) {
|
||||
$stuff->{ref_from} = $channel;
|
||||
}
|
||||
|
||||
@ -782,11 +795,12 @@ sub interpreter {
|
||||
my ($fwd_chan, $fwd_trig);
|
||||
|
||||
# build string of which channels contain the keyword, keeping track of the last one and count
|
||||
foreach my $chan (keys %{ $self->{factoids}->hash }) {
|
||||
foreach my $trig (keys %{ $self->{factoids}->hash->{$chan} }) {
|
||||
my $type = $self->{factoids}->hash->{$chan}->{$trig}->{type};
|
||||
if (($type eq 'text' or $type eq 'module') and lc $trig eq $lc_keyword) {
|
||||
$chans .= $comma . $chan;
|
||||
foreach my $chan (keys %{ $self->{factoids}->{hash} }) {
|
||||
foreach my $trig (keys %{ $self->{factoids}->{hash}->{$chan} }) {
|
||||
next if $trig eq '_name';
|
||||
my $type = $self->{factoids}->{hash}->{$chan}->{$trig}->{type};
|
||||
if (($type eq 'text' or $type eq 'module') and $trig eq $lc_keyword) {
|
||||
$chans .= $comma . $self->{factoids}->{hash}->{$chan}->{_name};
|
||||
$comma = ", ";
|
||||
$found++;
|
||||
$fwd_chan = $chan;
|
||||
@ -801,7 +815,7 @@ sub interpreter {
|
||||
# if multiple channels have this keyword, then ask user to disambiguate
|
||||
if ($found > 1) {
|
||||
return undef if $stuff->{referenced};
|
||||
return $ref_from . "Ambiguous keyword '$original_keyword' exists in multiple channels (use 'fact <channel> <keyword>' to choose one): $chans";
|
||||
return $ref_from . "Ambiguous keyword '$original_keyword' exists in multiple channels (use 'fact <channel> $original_keyword' to choose one): $chans";
|
||||
}
|
||||
# if there's just one other channel that has this keyword, trigger that instance
|
||||
elsif ($found == 1) {
|
||||
@ -849,53 +863,53 @@ sub interpreter {
|
||||
$stuff->{channel} = $channel;
|
||||
$stuff->{original_keyword} = $original_keyword;
|
||||
|
||||
return undef if $stuff->{referenced} and $self->{factoids}->hash->{$channel}->{$keyword}->{noembed};
|
||||
return undef if $stuff->{referenced} and $self->{factoids}->{hash}->{$channel}->{$keyword}->{noembed};
|
||||
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$keyword}->{locked_to_channel}) {
|
||||
if ($stuff->{ref_from} ne "") { # called from annother channel
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{locked_to_channel}) {
|
||||
if ($stuff->{ref_from} ne "") { # called from another channel
|
||||
return "$keyword may be invoked only in $stuff->{ref_from}.";
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$keyword}->{last_referenced_on}) {
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$keyword}->{last_referenced_in}) {
|
||||
if ($self->{factoids}->hash->{$channel}->{$keyword}->{last_referenced_in} eq $stuff->{from}) {
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{last_referenced_on}) {
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{last_referenced_in}) {
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$keyword}->{last_referenced_in} eq $stuff->{from}) {
|
||||
my $ratelimit = $self->{pbot}->{registry}->get_value($stuff->{from}, 'ratelimit_override');
|
||||
$ratelimit = $self->{factoids}->hash->{$channel}->{$keyword}->{rate_limit} if not defined $ratelimit;
|
||||
if (gettimeofday - $self->{factoids}->hash->{$channel}->{$keyword}->{last_referenced_on} < $ratelimit) {
|
||||
$ratelimit = $self->{factoids}->{hash}->{$channel}->{$keyword}->{rate_limit} if not defined $ratelimit;
|
||||
if (gettimeofday - $self->{factoids}->{hash}->{$channel}->{$keyword}->{last_referenced_on} < $ratelimit) {
|
||||
my $ref_from = $stuff->{ref_from} ? "[$stuff->{ref_from}] " : "";
|
||||
return "/msg $stuff->{nick} $ref_from'$keyword' is rate-limited; try again in " . duration ($ratelimit - int(gettimeofday - $self->{factoids}->hash->{$channel}->{$keyword}->{last_referenced_on})) . "." unless $self->{pbot}->{admins}->loggedin($channel, "$stuff->{nick}!$stuff->{user}\@$stuff->{host}");
|
||||
return "/msg $stuff->{nick} $ref_from'$keyword' is rate-limited; try again in " . duration ($ratelimit - int(gettimeofday - $self->{factoids}->{hash}->{$channel}->{$keyword}->{last_referenced_on})) . "." unless $self->{pbot}->{admins}->loggedin($channel, "$stuff->{nick}!$stuff->{user}\@$stuff->{host}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$self->{factoids}->hash->{$channel}->{$keyword}->{ref_count}++;
|
||||
$self->{factoids}->hash->{$channel}->{$keyword}->{ref_user} = "$stuff->{nick}!$stuff->{user}\@$stuff->{host}";
|
||||
$self->{factoids}->hash->{$channel}->{$keyword}->{last_referenced_on} = gettimeofday;
|
||||
$self->{factoids}->hash->{$channel}->{$keyword}->{last_referenced_in} = $stuff->{from} || "stdin";
|
||||
$self->{factoids}->{hash}->{$channel}->{$keyword}->{ref_count}++;
|
||||
$self->{factoids}->{hash}->{$channel}->{$keyword}->{ref_user} = "$stuff->{nick}!$stuff->{user}\@$stuff->{host}";
|
||||
$self->{factoids}->{hash}->{$channel}->{$keyword}->{last_referenced_on} = gettimeofday;
|
||||
$self->{factoids}->{hash}->{$channel}->{$keyword}->{last_referenced_in} = $stuff->{from} || "stdin";
|
||||
|
||||
my $action;
|
||||
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$keyword}->{usage} and not length $stuff->{arguments} and $self->{factoids}->hash->{$channel}->{$keyword}->{requires_arguments}) {
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{usage} and not length $stuff->{arguments} and $self->{factoids}->{hash}->{$channel}->{$keyword}->{requires_arguments}) {
|
||||
$stuff->{alldone} = 1;
|
||||
my $usage = $self->{factoids}->hash->{$channel}->{$keyword}->{usage};
|
||||
my $usage = $self->{factoids}->{hash}->{$channel}->{$keyword}->{usage};
|
||||
$usage =~ s/\$0|\$\{0\}/$keyword/g;
|
||||
return $usage;
|
||||
}
|
||||
|
||||
if (length $stuff->{arguments} and exists $self->{factoids}->hash->{$channel}->{$keyword}->{action_with_args}) {
|
||||
$action = $self->{factoids}->hash->{$channel}->{$keyword}->{action_with_args};
|
||||
if (length $stuff->{arguments} and exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{action_with_args}) {
|
||||
$action = $self->{factoids}->{hash}->{$channel}->{$keyword}->{action_with_args};
|
||||
} else {
|
||||
$action = $self->{factoids}->hash->{$channel}->{$keyword}->{action};
|
||||
$action = $self->{factoids}->{hash}->{$channel}->{$keyword}->{action};
|
||||
}
|
||||
|
||||
if ($action =~ m{^/code\s+([^\s]+)\s+(.+)$}msi) {
|
||||
my ($lang, $code) = ($1, $2);
|
||||
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$keyword}->{usage} and not length $stuff->{arguments}) {
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{usage} and not length $stuff->{arguments}) {
|
||||
$stuff->{alldone} = 1;
|
||||
my $usage = $self->{factoids}->hash->{$channel}->{$keyword}->{usage};
|
||||
my $usage = $self->{factoids}->{hash}->{$channel}->{$keyword}->{usage};
|
||||
$usage =~ s/\$0|\$\{0\}/$keyword/g;
|
||||
return $usage;
|
||||
}
|
||||
@ -926,14 +940,14 @@ sub handle_action {
|
||||
|
||||
my $ref_from = $stuff->{ref_from} ? "[$stuff->{ref_from}] " : "";
|
||||
|
||||
unless (exists $self->{factoids}->hash->{$channel}->{$keyword}->{interpolate} and $self->{factoids}->hash->{$channel}->{$keyword}->{interpolate} eq '0') {
|
||||
unless (exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{interpolate} and $self->{factoids}->{hash}->{$channel}->{$keyword}->{interpolate} eq '0') {
|
||||
my ($root_channel, $root_keyword) = $self->find_factoid($stuff->{ref_from} ? $stuff->{ref_from} : $stuff->{from}, $stuff->{root_keyword}, arguments => $stuff->{arguments}, exact_channel => 1);
|
||||
if (not defined $root_channel or not defined $root_keyword) {
|
||||
$root_channel = $channel;
|
||||
$root_keyword = $keyword;
|
||||
}
|
||||
if (not length $stuff->{keyword_override} and length $self->{factoids}->hash->{$root_channel}->{$root_keyword}->{keyword_override}) {
|
||||
$stuff->{keyword_override} = $self->{factoids}->hash->{$root_channel}->{$root_keyword}->{keyword_override};
|
||||
if (not length $stuff->{keyword_override} and length $self->{factoids}->{hash}->{$root_channel}->{$root_keyword}->{keyword_override}) {
|
||||
$stuff->{keyword_override} = $self->{factoids}->{hash}->{$root_channel}->{$root_keyword}->{keyword_override};
|
||||
}
|
||||
$stuff->{action} = $action;
|
||||
$action = $self->expand_factoid_vars($stuff);
|
||||
@ -941,7 +955,7 @@ sub handle_action {
|
||||
|
||||
if (length $stuff->{arguments}) {
|
||||
if ($action =~ m/\$\{?args/ or $action =~ m/\$\{?arg\[/) {
|
||||
unless (defined $self->{factoids}->hash->{$channel}->{$keyword}->{interpolate} and $self->{factoids}->hash->{$channel}->{$keyword}->{interpolate} eq '0') {
|
||||
unless (defined $self->{factoids}->{hash}->{$channel}->{$keyword}->{interpolate} and $self->{factoids}->{hash}->{$channel}->{$keyword}->{interpolate} eq '0') {
|
||||
$action = $self->expand_action_arguments($action, $stuff->{arguments}, $stuff->{nick});
|
||||
$stuff->{no_nickoverride} = 1;
|
||||
} else {
|
||||
@ -950,7 +964,7 @@ sub handle_action {
|
||||
$stuff->{arguments} = "";
|
||||
$stuff->{original_arguments} = "";
|
||||
} else {
|
||||
if ($self->{factoids}->hash->{$channel}->{$keyword}->{type} eq 'text') {
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$keyword}->{type} eq 'text') {
|
||||
my $target = $self->{pbot}->{nicklist}->is_present_similar($stuff->{from}, $stuff->{arguments});
|
||||
|
||||
if ($target and $action !~ /\$\{?(?:nick|args)\b/) {
|
||||
@ -963,12 +977,12 @@ sub handle_action {
|
||||
}
|
||||
} else {
|
||||
# no arguments supplied, replace $args with $nick/$tonick, etc
|
||||
if (exists $self->{factoids}->hash->{$channel}->{$keyword}->{usage}) {
|
||||
$action = "/say " . $self->{factoids}->hash->{$channel}->{$keyword}->{usage};
|
||||
if (exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{usage}) {
|
||||
$action = "/say " . $self->{factoids}->{hash}->{$channel}->{$keyword}->{usage};
|
||||
$action =~ s/\$0|\$\{0\}/$keyword/g;
|
||||
$stuff->{alldone} = 1;
|
||||
} else {
|
||||
if ($self->{factoids}->hash->{$channel}->{$keyword}->{'allow_empty_args'}) {
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$keyword}->{'allow_empty_args'}) {
|
||||
$action = $self->expand_action_arguments($action, undef, '');
|
||||
} else {
|
||||
$action = $self->expand_action_arguments($action, undef, $stuff->{nick});
|
||||
@ -981,13 +995,13 @@ sub handle_action {
|
||||
if ($action =~ /^\/call\s+(.*)$/ms) {
|
||||
my $command = $1;
|
||||
$command =~ s/\n$//;
|
||||
unless ($self->{factoids}->hash->{$channel}->{$keyword}->{'require_explicit_args'}) {
|
||||
unless ($self->{factoids}->{hash}->{$channel}->{$keyword}->{'require_explicit_args'}) {
|
||||
my $args = $stuff->{arguments};
|
||||
$command .= " $args" if length $args and not $stuff->{special} eq 'code-factoid';
|
||||
$stuff->{arguments} = '';
|
||||
}
|
||||
|
||||
unless ($self->{factoids}->hash->{$channel}->{$keyword}->{'no_keyword_override'}) {
|
||||
unless ($self->{factoids}->{hash}->{$channel}->{$keyword}->{'no_keyword_override'}) {
|
||||
if ($command =~ s/\s*--keyword-override=([^ ]+)\s*//) {
|
||||
$stuff->{keyword_override} = $1;
|
||||
}
|
||||
@ -998,12 +1012,12 @@ sub handle_action {
|
||||
|
||||
$self->{pbot}->{logger}->log("[" . (defined $stuff->{from} ? $stuff->{from} : "stdin") . "] ($stuff->{nick}!$stuff->{user}\@$stuff->{host}) [$keyword_text] aliased to: [$command]\n");
|
||||
|
||||
if (defined $self->{factoids}->hash->{$channel}->{$keyword}->{'effective-level'}) {
|
||||
if ($self->{factoids}->hash->{$channel}->{$keyword}->{'locked'}) {
|
||||
if (defined $self->{factoids}->{hash}->{$channel}->{$keyword}->{'effective-level'}) {
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$keyword}->{'locked'}) {
|
||||
$self->{pbot}->{logger}->log("Effective-level set to $self->{factoids}->{hash}->{$channel}->{$keyword}->{'effective-level'}\n");
|
||||
$stuff->{'effective-level'} = $self->{factoids}->hash->{$channel}->{$keyword}->{'effective-level'};
|
||||
$stuff->{'effective-level'} = $self->{factoids}->{hash}->{$channel}->{$keyword}->{'effective-level'};
|
||||
} else {
|
||||
$self->{pbot}->{logger}->log("Ignoring effective-level of $self->{factoids}->hash->{$channel}->{$keyword}->{'effective-level'} on unlocked factoid\n");
|
||||
$self->{pbot}->{logger}->log("Ignoring effective-level of $self->{factoids}->{hash}->{$channel}->{$keyword}->{'effective-level'} on unlocked factoid\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1012,24 +1026,24 @@ sub handle_action {
|
||||
|
||||
$self->{pbot}->{logger}->log("(" . (defined $stuff->{from} ? $stuff->{from} : "(undef)") . "): $stuff->{nick}!$stuff->{user}\@$stuff->{host}: $keyword_text: action: \"$action\"\n");
|
||||
|
||||
if ($self->{factoids}->hash->{$channel}->{$keyword}->{enabled} == 0) {
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$keyword}->{enabled} == 0) {
|
||||
$self->{pbot}->{logger}->log("$keyword_text disabled.\n");
|
||||
return "/msg $stuff->{nick} ${ref_from}$keyword_text is currently disabled.";
|
||||
}
|
||||
|
||||
unless (exists $self->{factoids}->hash->{$channel}->{$keyword}->{interpolate} and $self->{factoids}->hash->{$channel}->{$keyword}->{interpolate} eq '0') {
|
||||
unless (exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{interpolate} and $self->{factoids}->{hash}->{$channel}->{$keyword}->{interpolate} eq '0') {
|
||||
my ($root_channel, $root_keyword) = $self->find_factoid($stuff->{ref_from} ? $stuff->{ref_from} : $stuff->{from}, $stuff->{root_keyword}, arguments => $stuff->{arguments}, exact_channel => 1);
|
||||
if (not defined $root_channel or not defined $root_keyword) {
|
||||
$root_channel = $channel;
|
||||
$root_keyword = $keyword;
|
||||
}
|
||||
if (not length $stuff->{keyword_override} and length $self->{factoids}->hash->{$root_channel}->{$root_keyword}->{keyword_override}) {
|
||||
$stuff->{keyword_override} = $self->{factoids}->hash->{$root_channel}->{$root_keyword}->{keyword_override};
|
||||
if (not length $stuff->{keyword_override} and length $self->{factoids}->{hash}->{$root_channel}->{$root_keyword}->{keyword_override}) {
|
||||
$stuff->{keyword_override} = $self->{factoids}->{hash}->{$root_channel}->{$root_keyword}->{keyword_override};
|
||||
}
|
||||
$stuff->{action} = $action;
|
||||
$action = $self->expand_factoid_vars($stuff);
|
||||
|
||||
if ($self->{factoids}->hash->{$channel}->{$keyword}->{'allow_empty_args'}) {
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$keyword}->{'allow_empty_args'}) {
|
||||
$action = $self->expand_action_arguments($action, $stuff->{arguments}, '');
|
||||
} else {
|
||||
$action = $self->expand_action_arguments($action, $stuff->{arguments}, $stuff->{nick});
|
||||
@ -1038,8 +1052,8 @@ sub handle_action {
|
||||
|
||||
return $action if $stuff->{special} eq 'code-factoid';
|
||||
|
||||
if ($self->{factoids}->hash->{$channel}->{$keyword}->{type} eq 'module') {
|
||||
my $preserve_whitespace = $self->{factoids}->hash->{$channel}->{$keyword}->{preserve_whitespace};
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$keyword}->{type} eq 'module') {
|
||||
my $preserve_whitespace = $self->{factoids}->{hash}->{$channel}->{$keyword}->{preserve_whitespace};
|
||||
$preserve_whitespace = 0 if not defined $preserve_whitespace;
|
||||
|
||||
$stuff->{preserve_whitespace} = $preserve_whitespace;
|
||||
@ -1053,7 +1067,7 @@ sub handle_action {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
elsif ($self->{factoids}->hash->{$channel}->{$keyword}->{type} eq 'text') {
|
||||
elsif ($self->{factoids}->{hash}->{$channel}->{$keyword}->{type} eq 'text') {
|
||||
# Don't allow user-custom /msg factoids, unless factoid triggered by admin
|
||||
if ($action =~ m/^\/msg/i) {
|
||||
my $admin = $self->{pbot}->{admins}->loggedin($stuff->{from}, "$stuff->{nick}!$stuff->{user}\@$stuff->{host}");
|
||||
@ -1074,12 +1088,12 @@ sub handle_action {
|
||||
if ($action =~ m/^\/(?:say|me|msg)/i) {
|
||||
return $action;
|
||||
} elsif ($action =~ s/^\/kick\s+//) {
|
||||
if (not exists $self->{factoids}->hash->{$channel}->{$keyword}->{'effective-level'}) {
|
||||
if (not exists $self->{factoids}->{hash}->{$channel}->{$keyword}->{'effective-level'}) {
|
||||
$stuff->{authorized} = 0;
|
||||
return "/say $stuff->{nick}: $keyword_text doesn't have the effective-level to do that.";
|
||||
}
|
||||
my $level = 10;
|
||||
if ($self->{factoids}->hash->{$channel}->{$keyword}->{'effective-level'} >= $level) {
|
||||
if ($self->{factoids}->{hash}->{$channel}->{$keyword}->{'effective-level'} >= $level) {
|
||||
$stuff->{authorized} = 1;
|
||||
return "/kick " . $action;
|
||||
} else {
|
||||
@ -1090,7 +1104,7 @@ sub handle_action {
|
||||
return "/say $keyword_text is $action";
|
||||
}
|
||||
}
|
||||
} elsif ($self->{factoids}->hash->{$channel}->{$keyword}->{type} eq 'regex') {
|
||||
} elsif ($self->{factoids}->{hash}->{$channel}->{$keyword}->{type} eq 'regex') {
|
||||
my $result = eval {
|
||||
my $string = "$stuff->{original_keyword}" . (defined $stuff->{arguments} ? " $stuff->{arguments}" : "");
|
||||
my $cmd;
|
||||
|
@ -2,7 +2,9 @@
|
||||
# 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.
|
||||
# setting and deleting values, saving to and loading from files, etc. Provides
|
||||
# case-insensitive access to the index key while preserving original case when
|
||||
# displaying index key.
|
||||
|
||||
# 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
|
||||
@ -20,12 +22,8 @@ use Carp ();
|
||||
use JSON;
|
||||
|
||||
sub new {
|
||||
if (ref($_[1]) eq 'HASH') {
|
||||
Carp::croak("Options to HashObject should be key/value pairs, not hash reference");
|
||||
}
|
||||
|
||||
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;
|
||||
@ -33,34 +31,17 @@ sub new {
|
||||
|
||||
sub initialize {
|
||||
my ($self, %conf) = @_;
|
||||
|
||||
$self->{name} = delete $conf{name} // 'hash object';
|
||||
$self->{filename} = delete $conf{filename} // Carp::carp("Missing filename to HashObject, will not be able to save to or load from file.");
|
||||
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
||||
$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} = {};
|
||||
}
|
||||
|
||||
sub hash_add {
|
||||
my ($self, $index_key, $hash) = @_;
|
||||
|
||||
if (defined $hash) {
|
||||
if (exists $self->hash->{$index_key}) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
foreach my $key (keys %$hash) {
|
||||
$self->hash->{$index_key}{$key} = $hash->{$key};
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub load {
|
||||
my $self = shift;
|
||||
my $filename;
|
||||
|
||||
if (@_) { $filename = shift; } else { $filename = $self->filename; }
|
||||
if (@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
||||
|
||||
if (not defined $filename) {
|
||||
Carp::carp "No $self->{name} filename specified -- skipping loading from file";
|
||||
@ -81,13 +62,31 @@ sub load {
|
||||
|
||||
$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 (lc $index eq $index) {
|
||||
$self->{hash}->{$index}->{_name} = $index;
|
||||
} else {
|
||||
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;
|
||||
$self->{hash}->{lc $index} = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub save {
|
||||
my $self = shift;
|
||||
my $filename;
|
||||
|
||||
if (@_) { $filename = shift; } else { $filename = $self->filename; }
|
||||
if (@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
||||
|
||||
if (not defined $filename) {
|
||||
Carp::carp "No $self->{name} filename specified -- skipping saving to file.\n";
|
||||
@ -109,40 +108,14 @@ sub clear {
|
||||
$self->{hash} = {};
|
||||
}
|
||||
|
||||
sub find_hash {
|
||||
my ($self, $keyword) = @_;
|
||||
|
||||
my $result = eval {
|
||||
foreach my $index (keys %{ $self->hash }) {
|
||||
if ($keyword =~ m/^\Q$index\E$/i) {
|
||||
return $index;
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
$self->{pbot}->{logger}->log("find_hash: bad regex: $@\n");
|
||||
return undef;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub levenshtein_matches {
|
||||
my ($self, $keyword) = @_;
|
||||
my $comma = '';
|
||||
my $result = "";
|
||||
|
||||
foreach my $index (sort keys %{ $self->hash }) {
|
||||
foreach my $index (sort keys %{ $self->{hash} }) {
|
||||
my $distance = fastdistance($keyword, $index);
|
||||
|
||||
# print "Distance $distance for $keyword (" , (length $keyword) , ") vs $index (" , length $index , ")\n";
|
||||
|
||||
my $length = (length($keyword) > length($index)) ? length $keyword : length $index;
|
||||
|
||||
# print "Percentage: ", $distance / $length, "\n";
|
||||
my $length = (length $keyword > length $index) ? length $keyword : length $index;
|
||||
|
||||
if ($length != 0 && $distance / $length < 0.50) {
|
||||
$result .= $comma . $index;
|
||||
@ -157,20 +130,20 @@ sub levenshtein_matches {
|
||||
|
||||
sub set {
|
||||
my ($self, $index, $key, $value, $dont_save) = @_;
|
||||
my $lc_index = lc $index;
|
||||
|
||||
my $hash_index = $self->find_hash($index);
|
||||
|
||||
if (not $hash_index) {
|
||||
my $result = "No such $self->{name} object '$index'; similiar matches: ";
|
||||
if (not exists $self->{hash}->{$lc_index}) {
|
||||
my $result = "$self->{name}: $index not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (not defined $key) {
|
||||
my $result = "[$self->{name}] $hash_index keys: ";
|
||||
my $result = "[$self->{name}] $self->{hash}->{$lc_index}->{_name} keys: ";
|
||||
my $comma = '';
|
||||
foreach my $k (sort keys %{ $self->hash->{$hash_index} }) {
|
||||
$result .= $comma . "$k => " . $self->hash->{$hash_index}{$k};
|
||||
foreach my $k (sort keys %{ $self->{hash}->{$lc_index} }) {
|
||||
next if $k eq '_name';
|
||||
$result .= $comma . "$k => " . $self->{hash}->{$lc_index}->{$k};
|
||||
$comma = "; ";
|
||||
}
|
||||
$result .= "none" if ($comma eq '');
|
||||
@ -178,73 +151,59 @@ sub set {
|
||||
}
|
||||
|
||||
if (not defined $value) {
|
||||
$value = $self->hash->{$hash_index}{$key};
|
||||
$value = $self->{hash}->{$lc_index}->{$key};
|
||||
} else {
|
||||
$self->hash->{$hash_index}{$key} = $value;
|
||||
$self->save() unless $dont_save;
|
||||
$self->{hash}->{$lc_index}->{$key} = $value;
|
||||
$self->save unless $dont_save;
|
||||
}
|
||||
|
||||
return "[$self->{name}] $hash_index: '$key' " . (defined $value ? "set to '$value'" : "is not set.");
|
||||
return "[$self->{name}] $self->{hash}->{$lc_index}->{_name}: '$key' " . (defined $value ? "set to '$value'" : "is not set.");
|
||||
}
|
||||
|
||||
sub unset {
|
||||
my ($self, $index, $key) = @_;
|
||||
my $lc_index = lc $index;
|
||||
|
||||
my $hash_index = $self->find_hash($index);
|
||||
|
||||
if (not $hash_index) {
|
||||
my $result = "No such $self->{name} object '$index'; similiar matches: ";
|
||||
if (not exists $self->{hash}->{$lc_index}) {
|
||||
my $result = "$self->{name}: $index not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
delete $self->hash->{$hash_index}{$key};
|
||||
$self->save();
|
||||
delete $self->{hash}->{$lc_index}->{$key};
|
||||
$self->save;
|
||||
|
||||
return "[$self->{name}] $hash_index: '$key' unset.";
|
||||
return "[$self->{name}] $self->{hash}->{$lc_index}->{_name}: '$key' unset.";
|
||||
}
|
||||
|
||||
sub add {
|
||||
my ($self, $index_key, $hash) = @_;
|
||||
my ($self, $index, $data) = @_;
|
||||
my $lc_index = lc $index;
|
||||
|
||||
if ($self->hash_add($index_key, $hash)) {
|
||||
$self->save();
|
||||
} else {
|
||||
return "Error occurred adding new $self->{name} object.";
|
||||
if (exists $self->{hash}->{$lc_index}) {
|
||||
return "Error: $self->{hash}->{$lc_index}->{_name} already exists in $self->{name}.";
|
||||
}
|
||||
|
||||
return "'$index_key' added to $self->{name}.";
|
||||
$data->{_name} = $index; # preserve case of index
|
||||
$self->{hash}->{$lc_index} = {%$data};
|
||||
$self->save;
|
||||
return "$index added to $self->{name}.";
|
||||
}
|
||||
|
||||
sub remove {
|
||||
my ($self, $index) = @_;
|
||||
my $lc_index = lc $index;
|
||||
|
||||
my $hash_index = $self->find_hash($index);
|
||||
|
||||
if (not $hash_index) {
|
||||
my $result = "No such $self->{name} object '$index'; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($index);
|
||||
if (not exists $self->{hash}->{$lc_index}) {
|
||||
my $result = "$self->{name}: $index not found; similiar matches: ";
|
||||
$result .= $self->levenshtein_matches($lc_index);
|
||||
return $result;
|
||||
}
|
||||
|
||||
delete $self->hash->{$hash_index};
|
||||
$self->save();
|
||||
my $data = delete $self->{hash}->{$lc_index};
|
||||
$self->save;
|
||||
|
||||
return "'$hash_index' removed from $self->{name}.";
|
||||
}
|
||||
|
||||
# Getters and setters
|
||||
|
||||
sub hash {
|
||||
my $self = shift;
|
||||
return $self->{hash};
|
||||
}
|
||||
|
||||
sub filename {
|
||||
my $self = shift;
|
||||
|
||||
if (@_) { $self->{filename} = shift; }
|
||||
return $self->{filename};
|
||||
return "$data->{_name} removed from $self->{name}.";
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -297,7 +297,7 @@ sub on_mode {
|
||||
if ($mode eq "+b") {
|
||||
if ($nick eq "ChanServ" or $target =~ m/##fix_your_connection$/i) {
|
||||
if ($self->{pbot}->{chanops}->can_gain_ops($channel)) {
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$target}{timeout} = gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout');
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->{hash}->{lc $channel}->{lc $target}->{timeout} = gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout');
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->save;
|
||||
}
|
||||
} elsif ($target =~ m/^\*!\*@/ or $target =~ m/^\*!.*\@gateway\/web/i) {
|
||||
@ -308,9 +308,9 @@ sub on_mode {
|
||||
}
|
||||
|
||||
if ($timeout && $self->{pbot}->{chanops}->can_gain_ops($channel)) {
|
||||
if (not exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{lc $channel}->{lc $target}) {
|
||||
if (not exists $self->{pbot}->{chanops}->{unban_timeout}->{hash}->{lc $channel}->{lc $target}) {
|
||||
$self->{pbot}->{logger}->log("Temp ban for $target in $channel.\n");
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$target}{timeout} = gettimeofday + $timeout;
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->{hash}->{lc $channel}->{lc $target}->{timeout} = gettimeofday + $timeout;
|
||||
$self->{pbot}->{chanops}->{unban_timeout}->save;
|
||||
}
|
||||
}
|
||||
@ -319,7 +319,7 @@ sub on_mode {
|
||||
elsif ($mode eq "+q") {
|
||||
if ($nick ne $event->{conn}->nick) { # bot muted
|
||||
if ($self->{pbot}->{chanops}->can_gain_ops($channel)) {
|
||||
$self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$target}{timeout} = gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'mute_timeout');
|
||||
$self->{pbot}->{chanops}->{unmute_timeout}->{hash}->{lc $channel}->{lc $target}->{timeout} = gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'mute_timeout');
|
||||
$self->{pbot}->{chanops}->{unmute_timeout}->save;
|
||||
}
|
||||
}
|
||||
|
@ -850,11 +850,11 @@ sub handle_result {
|
||||
my ($chan, $trigger) = $self->{pbot}->{factoids}->find_factoid($stuff->{from}, $cmd, arguments => $args, exact_channel => 1, exact_trigger => 0, find_alias => 1);
|
||||
if (defined $trigger) {
|
||||
if ($stuff->{preserve_whitespace} == 0) {
|
||||
$stuff->{preserve_whitespace} = $self->{pbot}->{factoids}->{factoids}->hash->{$chan}->{$trigger}->{preserve_whitespace};
|
||||
$stuff->{preserve_whitespace} = $self->{pbot}->{factoids}->{factoids}->{hash}->{$chan}->{$trigger}->{preserve_whitespace};
|
||||
$stuff->{preserve_whitespace} = 0 if not defined $stuff->{preserve_whitespace};
|
||||
}
|
||||
|
||||
$use_output_queue = $self->{pbot}->{factoids}->{factoids}->hash->{$chan}->{$trigger}->{use_output_queue};
|
||||
$use_output_queue = $self->{pbot}->{factoids}->{factoids}->{hash}->{$chan}->{$trigger}->{use_output_queue};
|
||||
$use_output_queue = 0 if not defined $use_output_queue;
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ sub update_timestamp {
|
||||
$self->{nicklist}->{$channel}->{$nick}->{timestamp} = gettimeofday;
|
||||
} else {
|
||||
$self->{pbot}->{logger}->log("Adding nick '$orig_nick' to channel '$channel'\n") if $self->{pbot}->{registry}->get_value('nicklist', 'debug');
|
||||
$self->{nicklist}->{$channel}->{$nick} = { nick => $orig_nick, timestamp => gettimeofday };
|
||||
$self->{nicklist}->{$channel}->{$nick} = { nick => $orig_nick, timestamp => scalar gettimeofday };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,8 @@ sub refresh {
|
||||
|
||||
# update version factoid
|
||||
my $version = $self->{pbot}->{version}->version();
|
||||
if ($self->{pbot}->{factoids}->{factoids}->hash->{'.*'}->{'version'}->{'action'} ne "/say $version") {
|
||||
$self->{pbot}->{factoids}->{factoids}->hash->{'.*'}->{'version'}->{'action'} = "/say $version";
|
||||
if ($self->{pbot}->{factoids}->{factoids}->{hash}->{'.*'}->{'version'}->{'action'} ne "/say $version") {
|
||||
$self->{pbot}->{factoids}->{factoids}->{hash}->{'.*'}->{'version'}->{'action'} = "/say $version";
|
||||
$self->{pbot}->{logger}->log("New version: $version\n");
|
||||
}
|
||||
|
||||
|
@ -49,9 +49,10 @@ sub initialize {
|
||||
sub load {
|
||||
my $self = shift;
|
||||
$self->{registry}->load;
|
||||
foreach my $section (keys %{ $self->{registry}->hash }) {
|
||||
foreach my $item (keys %{ $self->{registry}->hash->{$section} }) {
|
||||
$self->process_trigger($section, $item, $self->{registry}->hash->{$section}->{$item}->{value});
|
||||
foreach my $section (keys %{ $self->{registry}->{hash} }) {
|
||||
foreach my $item (keys %{ $self->{registry}->{hash}->{$section} }) {
|
||||
next if $item eq '_name';
|
||||
$self->process_trigger($section, $item, $self->{registry}->{hash}->{$section}->{$item}->{value});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,16 +71,25 @@ sub add {
|
||||
my $self = shift;
|
||||
my ($type, $section, $item, $value, $is_default) = @_;
|
||||
|
||||
my $lc_section = lc $section;
|
||||
my $lc_item = lc $item;
|
||||
|
||||
$type = lc $type;
|
||||
$section = lc $section;
|
||||
$item = lc $item;
|
||||
|
||||
if ($is_default) {
|
||||
return if exists $self->{registry}->hash->{$section} and exists $self->{registry}->hash->{$section}->{$item};
|
||||
return if exists $self->{registry}->{hash}->{$lc_section} and exists $self->{registry}->{hash}->{$lc_section}->{$lc_item};
|
||||
}
|
||||
|
||||
$self->{registry}->hash->{$section}->{$item}->{value} = $value;
|
||||
$self->{registry}->hash->{$section}->{$item}->{type} = $type unless exists $self->{registry}->hash->{$section}->{$item}->{type};
|
||||
if (not exists $self->{registry}->{hash}->{$lc_section}) {
|
||||
$self->{registry}->{hash}->{$lc_section}->{_name} = $section;
|
||||
}
|
||||
|
||||
if (not exists $self->{registry}->{hash}->{$lc_section}->{$lc_item}) {
|
||||
$self->{registry}->{hash}->{$lc_section}->{$lc_item}->{_name} = $item;
|
||||
}
|
||||
|
||||
$self->{registry}->{hash}->{$lc_section}->{$lc_item}->{value} = $value;
|
||||
$self->{registry}->{hash}->{$lc_section}->{$lc_item}->{type} = $type unless exists $self->{registry}->{hash}->{$lc_section}->{$lc_item}->{type};
|
||||
|
||||
$self->process_trigger($section, $item, $value) unless $is_default;
|
||||
$self->save unless $is_default;
|
||||
@ -90,11 +100,12 @@ sub remove {
|
||||
my ($section, $item) = @_;
|
||||
|
||||
$section = lc $section;
|
||||
$item = lc $item;
|
||||
|
||||
delete $self->{registry}->hash->{$section}->{$item};
|
||||
delete $self->{registry}->{hash}->{$section}->{$item};
|
||||
|
||||
if (not scalar keys %{ $self->{registry}->hash->{$section} }) {
|
||||
delete $self->{registry}->hash->{$section};
|
||||
if (not scalar keys %{ $self->{registry}->{hash}->{$section} }) {
|
||||
delete $self->{registry}->{hash}->{$section};
|
||||
}
|
||||
|
||||
$self->save;
|
||||
@ -113,9 +124,9 @@ sub set {
|
||||
$key = lc $key if defined $key;
|
||||
|
||||
if ($is_default) {
|
||||
return if exists $self->{registry}->hash->{$section}
|
||||
and exists $self->{registry}->hash->{$section}->{$item}
|
||||
and exists $self->{registry}->hash->{$section}->{$item}->{$key};
|
||||
return if exists $self->{registry}->{hash}->{$section}
|
||||
and exists $self->{registry}->{hash}->{$section}->{$item}
|
||||
and exists $self->{registry}->{hash}->{$section}->{$item}->{$key};
|
||||
}
|
||||
|
||||
my $oldvalue = $self->get_value($section, $item, 1) if defined $value;
|
||||
@ -146,19 +157,22 @@ sub unset {
|
||||
|
||||
sub get_value {
|
||||
my ($self, $section, $item, $as_text, $stuff) = @_;
|
||||
$section = lc $section;
|
||||
$item = lc $item;
|
||||
my $key = $item;
|
||||
|
||||
if (defined $stuff and exists $stuff->{nick}) {
|
||||
if (exists $self->{registry}->hash->{$section} and exists $self->{registry}->hash->{$section}->{"$item.nick.$stuff->{nick}"}) {
|
||||
$key = "$item.nick.$stuff->{nick}";
|
||||
my $stuff_nick = lc $stuff->{nick};
|
||||
if (exists $self->{registry}->{hash}->{$section} and exists $self->{registry}->{hash}->{$section}->{"$item.nick.$stuff_nick"}) {
|
||||
$key = "$item.nick.$stuff_nick";
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $self->{registry}->hash->{$section} and exists $self->{registry}->hash->{$section}->{$key}) {
|
||||
if (not $as_text and $self->{registry}->hash->{$section}->{$key}->{type} eq 'array') {
|
||||
return split /\s*,\s*/, $self->{registry}->hash->{$section}->{$key}->{value};
|
||||
if (exists $self->{registry}->{hash}->{$section} and exists $self->{registry}->{hash}->{$section}->{$key}) {
|
||||
if (not $as_text and $self->{registry}->{hash}->{$section}->{$key}->{type} eq 'array') {
|
||||
return split /\s*,\s*/, $self->{registry}->{hash}->{$section}->{$key}->{value};
|
||||
} else {
|
||||
return $self->{registry}->hash->{$section}->{$key}->{value};
|
||||
return $self->{registry}->{hash}->{$section}->{$key}->{value};
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
@ -166,20 +180,23 @@ sub get_value {
|
||||
|
||||
sub get_array_value {
|
||||
my ($self, $section, $item, $index, $stuff) = @_;
|
||||
$section = lc $section;
|
||||
$item = lc $item;
|
||||
my $key = $item;
|
||||
|
||||
if (defined $stuff and exists $stuff->{nick}) {
|
||||
if (exists $self->{registry}->hash->{$section} and exists $self->{registry}->hash->{$section}->{"$item.nick.$stuff->{nick}"}) {
|
||||
$key = "$item.nick.$stuff->{nick}";
|
||||
my $stuff_nick = lc $stuff->{nick};
|
||||
if (exists $self->{registry}->{hash}->{$section} and exists $self->{registry}->{hash}->{$section}->{"$item.nick.$stuff_nick"}) {
|
||||
$key = "$item.nick.$stuff_nick";
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $self->{registry}->hash->{$section} and exists $self->{registry}->hash->{$section}->{$key}) {
|
||||
if ($self->{registry}->hash->{$section}->{$key}->{type} eq 'array') {
|
||||
my @array = split /\s*,\s*/, $self->{registry}->hash->{$section}->{$key}->{value};
|
||||
if (exists $self->{registry}->{hash}->{$section} and exists $self->{registry}->{hash}->{$section}->{$key}) {
|
||||
if ($self->{registry}->{hash}->{$section}->{$key}->{type} eq 'array') {
|
||||
my @array = split /\s*,\s*/, $self->{registry}->{hash}->{$section}->{$key}->{value};
|
||||
return $array[$index >= $#array ? $#array : $index];
|
||||
} else {
|
||||
return $self->{registry}->hash->{$section}->{$key}->{value};
|
||||
return $self->{registry}->{hash}->{$section}->{$key}->{value};
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
@ -187,13 +204,14 @@ sub get_array_value {
|
||||
|
||||
sub add_trigger {
|
||||
my ($self, $section, $item, $subref) = @_;
|
||||
|
||||
$self->{triggers}->{$section}->{$item} = $subref;
|
||||
$self->{triggers}->{lc $section}->{lc $item} = $subref;
|
||||
}
|
||||
|
||||
sub process_trigger {
|
||||
my $self = shift;
|
||||
my ($section, $item) = @_;
|
||||
$section = lc $section;
|
||||
$item = lc $item;
|
||||
|
||||
if (exists $self->{triggers}->{$section} and exists $self->{triggers}->{$section}->{$item}) {
|
||||
return &{ $self->{triggers}->{$section}->{$item} }(@_);
|
||||
|
@ -87,11 +87,14 @@ sub regunset {
|
||||
return $usage;
|
||||
}
|
||||
|
||||
if (not exists $self->{pbot}->{registry}->{registry}->hash->{$section}) {
|
||||
$section = lc $section;
|
||||
$item = lc $item;
|
||||
|
||||
if (not exists $self->{pbot}->{registry}->{registry}->{hash}->{$section}) {
|
||||
return "No such registry section $section.";
|
||||
}
|
||||
|
||||
if (not exists $self->{pbot}->{registry}->{registry}->hash->{$section}->{$item}) {
|
||||
if (not exists $self->{pbot}->{registry}->{registry}->{hash}->{$section}->{$item}) {
|
||||
return "No such item $item in section $section.";
|
||||
}
|
||||
|
||||
@ -152,7 +155,7 @@ sub regunsetmeta {
|
||||
sub regshow {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
|
||||
my $registry = $self->{pbot}->{registry}->{registry}->hash;
|
||||
my $registry = $self->{pbot}->{registry}->{registry}->{hash};
|
||||
|
||||
my $usage = "Usage: regshow <section>.<item>";
|
||||
|
||||
@ -169,6 +172,9 @@ sub regshow {
|
||||
return $usage;
|
||||
}
|
||||
|
||||
$section = lc $section;
|
||||
$item = lc $item;
|
||||
|
||||
if (not exists $registry->{$section}) {
|
||||
return "No such registry section $section.";
|
||||
}
|
||||
@ -193,7 +199,7 @@ sub regshow {
|
||||
sub regfind {
|
||||
my $self = shift;
|
||||
my ($from, $nick, $user, $host, $arguments) = @_;
|
||||
my $registry = $self->{pbot}->{registry}->{registry}->hash;
|
||||
my $registry = $self->{pbot}->{registry}->{registry}->{hash};
|
||||
|
||||
my $usage = "Usage: regfind [-showvalues] [-section section] <regex>";
|
||||
|
||||
@ -214,14 +220,17 @@ sub regfind {
|
||||
return $usage;
|
||||
}
|
||||
|
||||
$section = lc $section;
|
||||
|
||||
my ($text, $last_item, $last_section, $i);
|
||||
$last_section = "";
|
||||
$i = 0;
|
||||
eval {
|
||||
use re::engine::RE2 -strict => 1;
|
||||
foreach my $section_key (sort keys %{ $registry }) {
|
||||
next if defined $section and $section_key !~ /^$section$/i;
|
||||
next if defined $section and $section_key ne $section;
|
||||
foreach my $item_key (sort keys %{ $registry->{$section_key} }) {
|
||||
next if $item_key eq '_name';
|
||||
if ($registry->{$section_key}->{$item_key}->{private}) {
|
||||
# do not match on value if private
|
||||
next if $item_key !~ /$arguments/i;
|
||||
@ -289,7 +298,10 @@ sub regchange {
|
||||
return "Usage: regchange <section>.<item> s/<pattern>/<replacement>/";
|
||||
}
|
||||
|
||||
my $registry = $self->{pbot}->{registry}->{registry}->hash;
|
||||
$section = lc $section;
|
||||
$item = lc $item;
|
||||
|
||||
my $registry = $self->{pbot}->{registry}->{registry}->{hash};
|
||||
|
||||
if (not exists $registry->{$section}) {
|
||||
return "No such registry section $section.";
|
||||
|
@ -20,7 +20,7 @@ sub safe_filename {
|
||||
}
|
||||
}
|
||||
|
||||
return $safe;
|
||||
return lc $safe;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -46,7 +46,7 @@ sub on_nickchange {
|
||||
my $kick_msg = $self->{pbot}->{registry}->get_value('antiaway', 'kick_msg');
|
||||
my $channels = $self->{pbot}->{nicklist}->get_channels($newnick);
|
||||
foreach my $chan (@$channels) {
|
||||
next if not exists $self->{pbot}->{channels}->{channels}->hash->{$chan} or not $self->{pbot}->{channels}->{channels}->hash->{$chan}{chanop};
|
||||
next if not exists $self->{pbot}->{channels}->{channels}->{hash}->{$chan} or not $self->{pbot}->{channels}->{channels}->{hash}->{$chan}->{chanop};
|
||||
$self->{pbot}->{logger}->log("$newnick matches bad away nick regex, kicking from $chan\n");
|
||||
$self->{pbot}->{chanops}->add_op_command($chan, "kick $chan $newnick $kick_msg");
|
||||
$self->{pbot}->{chanops}->gain_ops($chan);
|
||||
|
@ -61,7 +61,7 @@ sub on_kick {
|
||||
my ($nick, $user, $host, $target, $channel, $reason) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host, $event->{event}->to, $event->{event}->{args}[0], $event->{event}->{args}[1]);
|
||||
|
||||
return 0 if not $self->{pbot}->{channels}->is_active($channel);
|
||||
return 0 if $self->{pbot}->{channels}->{channels}->hash->{$channel}->{noautorejoin};
|
||||
return 0 if $self->{pbot}->{channels}->{channels}->{hash}->{lc $channel}->{noautorejoin};
|
||||
|
||||
if ($target eq $self->{pbot}->{registry}->get_value('irc', 'botnick')) {
|
||||
$self->rejoin_channel($channel);
|
||||
@ -75,7 +75,7 @@ sub on_part {
|
||||
my ($nick, $user, $host, $channel) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host, $event->{event}->to);
|
||||
|
||||
return 0 if not $self->{pbot}->{channels}->is_active($channel);
|
||||
return 0 if $self->{pbot}->{channels}->{channels}->hash->{$channel}->{noautorejoin};
|
||||
return 0 if $self->{pbot}->{channels}->{channels}->{hash}->{lc $channel}->{noautorejoin};
|
||||
|
||||
if ($nick eq $self->{pbot}->{registry}->get_value('irc', 'botnick')) {
|
||||
$self->rejoin_channel($channel);
|
||||
|
@ -206,12 +206,12 @@ sub load_metadata {
|
||||
debug_state => 0,
|
||||
};
|
||||
|
||||
if (not exists $self->{metadata}->hash->{settings}) {
|
||||
$self->{metadata}->hash->{settings} = $defaults;
|
||||
if (not exists $self->{metadata}->{hash}->{settings}) {
|
||||
$self->{metadata}->{hash}->{settings} = $defaults;
|
||||
} else {
|
||||
foreach my $key (keys %$defaults) {
|
||||
if (not exists $self->{metadata}->hash->{settings}->{$key}) {
|
||||
$self->{metadata}->hash->{settings}->{$key} = $defaults->{$key};
|
||||
if (not exists $self->{metadata}->{hash}->{settings}->{$key}) {
|
||||
$self->{metadata}->{hash}->{settings}->{$key} = $defaults->{$key};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -748,10 +748,11 @@ sub spinach_cmd {
|
||||
my @truth_count = split /\s/, $self->{state_data}->{current_question}->{answer};
|
||||
my @lie_count = split /\s/, $arguments;
|
||||
|
||||
=cut
|
||||
if (@truth_count > 1 and @lie_count == 1) {
|
||||
return "/msg $nick Your lie cannot be one word for this question. Please try again.";
|
||||
}
|
||||
|
||||
=cut
|
||||
my $found_truth = 0;
|
||||
|
||||
if (not $self->validate_lie($self->{state_data}->{current_question}->{answer}, $arguments)) {
|
||||
@ -887,33 +888,33 @@ sub spinach_cmd {
|
||||
return "Bad filter: No categories match. Try again.";
|
||||
}
|
||||
|
||||
$self->{metadata}->hash->{filter}->{"category_" . $_ . "_filter"} = $args;
|
||||
$self->{metadata}->{hash}->{filter}->{"category_" . $_ . "_filter"} = $args;
|
||||
$self->save_metadata;
|
||||
return "Spinach $_ filter set.";
|
||||
}
|
||||
|
||||
when ('clear') {
|
||||
delete $self->{metadata}->hash->{filter};
|
||||
delete $self->{metadata}->{hash}->{filter};
|
||||
$self->save_metadata;
|
||||
return "Spinach filter cleared.";
|
||||
}
|
||||
|
||||
when ('show') {
|
||||
if (not exists $self->{metadata}->hash->{filter}->{category_include_filter}
|
||||
and not exists $self->{metadata}->hash->{filter}->{category_exclude_filter}) {
|
||||
if (not exists $self->{metadata}->{hash}->{filter}->{category_include_filter}
|
||||
and not exists $self->{metadata}->{hash}->{filter}->{category_exclude_filter}) {
|
||||
return "There is no Spinach filter set.";
|
||||
}
|
||||
|
||||
my $text = "Spinach ";
|
||||
my $comma = "";
|
||||
|
||||
if (exists $self->{metadata}->hash->{filter}->{category_include_filter}) {
|
||||
$text .= "include filter set to: " . $self->{metadata}->hash->{filter}->{category_include_filter};
|
||||
if (exists $self->{metadata}->{hash}->{filter}->{category_include_filter}) {
|
||||
$text .= "include filter set to: " . $self->{metadata}->{hash}->{filter}->{category_include_filter};
|
||||
$comma = "; ";
|
||||
}
|
||||
|
||||
if (exists $self->{metadata}->hash->{filter}->{category_exclude_filter}) {
|
||||
$text .= $comma . "exclude filter set to: " . $self->{metadata}->hash->{filter}->{category_exclude_filter};
|
||||
if (exists $self->{metadata}->{hash}->{filter}->{category_exclude_filter}) {
|
||||
$text .= $comma . "exclude filter set to: " . $self->{metadata}->{hash}->{filter}->{category_exclude_filter};
|
||||
}
|
||||
|
||||
return $text;
|
||||
@ -2427,7 +2428,7 @@ sub getplayers {
|
||||
if ($state->{first_tock}) {
|
||||
$tock = 15;
|
||||
} else {
|
||||
$tock = 90;
|
||||
$tock = 300;
|
||||
}
|
||||
|
||||
if ($state->{ticks} % $tock == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user