2010-03-22 08:33:44 +01:00
|
|
|
# File: IgnoreList.pm
|
2010-03-24 07:47:40 +01:00
|
|
|
# Author: pragma_
|
2010-03-17 07:36:54 +01:00
|
|
|
#
|
2010-03-22 08:33:44 +01:00
|
|
|
# Purpose: Manages ignore list.
|
2010-03-17 07:36:54 +01:00
|
|
|
|
2017-03-05 22:33:31 +01:00
|
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
2010-03-17 07:36:54 +01:00
|
|
|
package PBot::IgnoreList;
|
2020-02-08 20:04:13 +01:00
|
|
|
use parent 'PBot::Class';
|
2010-03-17 07:36:54 +01:00
|
|
|
|
2020-02-08 20:04:13 +01:00
|
|
|
use warnings; use strict;
|
2019-07-11 03:40:53 +02:00
|
|
|
use feature 'unicode_strings';
|
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
use Time::Duration qw/concise duration/;
|
2010-03-17 07:36:54 +01:00
|
|
|
|
2010-03-22 08:33:44 +01:00
|
|
|
sub initialize {
|
2020-02-15 23:38:32 +01:00
|
|
|
my ($self, %conf) = @_;
|
2020-03-04 22:24:40 +01:00
|
|
|
|
2020-02-15 23:38:32 +01:00
|
|
|
$self->{filename} = $conf{filename};
|
2010-04-06 20:38:27 +02:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
$self->{ignorelist} = PBot::DualIndexHashObject->new(pbot => $self->{pbot}, name => 'IgnoreList', filename => $self->{filename});
|
|
|
|
$self->{ignorelist}->load;
|
2020-03-06 22:23:40 +01:00
|
|
|
$self->enqueue_ignores;
|
2020-03-04 22:24:40 +01:00
|
|
|
|
2020-05-04 22:21:35 +02:00
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_ignore(@_) }, "ignore", 1);
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_unignore(@_) }, "unignore", 1);
|
2014-05-18 02:27:57 +02:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
$self->{pbot}->{capabilities}->add('admin', 'can-ignore', 1);
|
|
|
|
$self->{pbot}->{capabilities}->add('admin', 'can-unignore', 1);
|
|
|
|
|
|
|
|
$self->{pbot}->{capabilities}->add('chanop', 'can-ignore', 1);
|
|
|
|
$self->{pbot}->{capabilities}->add('chanop', 'can-unignore', 1);
|
2020-03-06 22:23:40 +01:00
|
|
|
}
|
|
|
|
|
2020-05-04 22:21:35 +02:00
|
|
|
sub cmd_ignore {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
|
|
|
|
my ($target, $channel, $length) = $self->{pbot}->{interpreter}->split_args($context->{arglist}, 3);
|
|
|
|
|
|
|
|
return "Usage: ignore <hostmask> [channel [timeout]] | ignore list" if not defined $target;
|
|
|
|
|
|
|
|
if ($target =~ /^list$/i) {
|
|
|
|
my $text = "Ignored:\n\n";
|
|
|
|
my $now = time;
|
|
|
|
my $ignored = 0;
|
|
|
|
|
|
|
|
foreach my $channel (sort $self->{ignorelist}->get_keys) {
|
|
|
|
$text .= $channel eq '.*' ? "global:\n" : "$channel:\n";
|
|
|
|
my @list;
|
|
|
|
foreach my $hostmask (sort $self->{ignorelist}->get_keys($channel)) {
|
|
|
|
my $timeout = $self->{ignorelist}->get_data($channel, $hostmask, 'timeout');
|
|
|
|
if ($timeout == -1) {
|
|
|
|
push @list, " $hostmask";
|
|
|
|
} else {
|
|
|
|
push @list, " $hostmask (" . (concise duration $timeout - $now) . ')';
|
|
|
|
}
|
|
|
|
$ignored++;
|
|
|
|
}
|
|
|
|
$text .= join ";\n", @list;
|
|
|
|
$text .= "\n";
|
|
|
|
}
|
|
|
|
return "Ignore list is empty." if not $ignored;
|
|
|
|
return "/msg $context->{nick} $text";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not defined $channel) {
|
|
|
|
$channel = ".*"; # all channels
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not defined $length) {
|
|
|
|
$length = -1; # permanently
|
|
|
|
} else {
|
|
|
|
my $error;
|
|
|
|
($length, $error) = $self->{pbot}->{parsedate}->parsedate($length);
|
|
|
|
return $error if defined $error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $self->add($channel, $target, $length, $context->{hostmask});
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_unignore {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
my ($target, $channel) = $self->{pbot}->{interpreter}->split_args($context->{arglist}, 2);
|
|
|
|
if (not defined $target) { return "Usage: unignore <hostmask> [channel]"; }
|
|
|
|
if (not defined $channel) { $channel = '.*'; }
|
|
|
|
return $self->remove($channel, $target);
|
|
|
|
}
|
|
|
|
|
2020-03-06 22:23:40 +01:00
|
|
|
sub enqueue_ignores {
|
|
|
|
my ($self) = @_;
|
|
|
|
my $now = time;
|
|
|
|
|
|
|
|
foreach my $channel ($self->{ignorelist}->get_keys) {
|
|
|
|
foreach my $hostmask ($self->{ignorelist}->get_keys($channel)) {
|
|
|
|
my $timeout = $self->{ignorelist}->get_data($channel, $hostmask, 'timeout');
|
|
|
|
next if $timeout == -1; # permanent ignore
|
2014-05-17 22:08:19 +02:00
|
|
|
|
2020-03-06 22:23:40 +01:00
|
|
|
my $interval = $timeout - $now;
|
|
|
|
$interval = 0 if $interval < 0;
|
|
|
|
|
|
|
|
$self->{pbot}->{timer}->enqueue_event(sub {
|
|
|
|
$self->remove($channel, $hostmask);
|
|
|
|
}, $interval, "ignore_timeout $channel $hostmask"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2010-03-22 08:33:44 +01:00
|
|
|
}
|
2010-03-17 07:36:54 +01:00
|
|
|
|
2010-03-22 08:33:44 +01:00
|
|
|
sub add {
|
2020-03-04 22:24:40 +01:00
|
|
|
my ($self, $channel, $hostmask, $length, $owner) = @_;
|
2010-03-17 07:36:54 +01:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
if ($hostmask !~ /!/) {
|
|
|
|
$hostmask .= '!*@*';
|
|
|
|
} elsif ($hostmask !~ /@/) {
|
|
|
|
$hostmask .= '@*';
|
|
|
|
}
|
2010-04-06 20:38:27 +02:00
|
|
|
|
2020-04-30 01:55:09 +02:00
|
|
|
$channel = '.*' if $channel !~ /^#/;
|
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
my $regex = quotemeta $hostmask;
|
2020-03-06 22:23:40 +01:00
|
|
|
$regex =~ s/\\\*/.*?/g;
|
2020-03-04 22:24:40 +01:00
|
|
|
$regex =~ s/\\\?/./g;
|
2010-03-17 07:36:54 +01:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
my $data = {
|
|
|
|
owner => $owner,
|
|
|
|
created_on => time,
|
|
|
|
regex => $regex,
|
|
|
|
};
|
2010-03-17 07:36:54 +01:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
if ($length < 0) {
|
|
|
|
$data->{timeout} = -1;
|
|
|
|
} else {
|
|
|
|
$data->{timeout} = time + $length;
|
|
|
|
}
|
2015-03-17 05:08:25 +01:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
$self->{ignorelist}->add($channel, $hostmask, $data);
|
2015-03-17 05:08:25 +01:00
|
|
|
|
2020-03-06 22:23:40 +01:00
|
|
|
if ($length > 0) {
|
|
|
|
$self->{pbot}->{timer}->dequeue_event("ignore_timeout $channel $hostmask");
|
|
|
|
|
|
|
|
$self->{pbot}->{timer}->enqueue_event(sub {
|
|
|
|
$self->remove($channel, $hostmask);
|
|
|
|
}, $length, "ignore_timeout $channel $hostmask"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
my $duration = $data->{timeout} == -1 ? 'all eternity' : duration $length;
|
|
|
|
return "$hostmask ignored for $duration";
|
2010-04-06 20:38:27 +02:00
|
|
|
}
|
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
sub remove {
|
|
|
|
my ($self, $channel, $hostmask) = @_;
|
2020-03-06 22:23:40 +01:00
|
|
|
|
|
|
|
if ($hostmask !~ /!/) {
|
|
|
|
$hostmask .= '!*@*';
|
|
|
|
} elsif ($hostmask !~ /@/) {
|
|
|
|
$hostmask .= '@*';
|
|
|
|
}
|
|
|
|
|
2020-04-30 01:55:09 +02:00
|
|
|
$channel = '.*' if $channel !~ /^#/;
|
|
|
|
|
2020-03-06 22:23:40 +01:00
|
|
|
$self->{pbot}->{timer}->dequeue_event("ignore_timeout $channel $hostmask");
|
2020-03-04 22:24:40 +01:00
|
|
|
return $self->{ignorelist}->remove($channel, $hostmask);
|
2017-08-06 06:38:46 +02:00
|
|
|
}
|
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
sub is_ignored {
|
|
|
|
my ($self, $channel, $hostmask) = @_;
|
2010-04-06 20:38:27 +02:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
return 0 if $self->{pbot}->{users}->loggedin_admin($channel, $hostmask);
|
2019-06-26 18:34:19 +02:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
foreach my $chan ('.*', $channel) {
|
|
|
|
foreach my $ignored ($self->{ignorelist}->get_keys($chan)) {
|
|
|
|
my $regex = $self->{ignorelist}->get_data($chan, $ignored, 'regex');
|
|
|
|
return 1 if $hostmask =~ /^$regex$/i;
|
|
|
|
}
|
2020-02-15 23:38:32 +01:00
|
|
|
}
|
2010-04-06 20:38:27 +02:00
|
|
|
|
2020-03-04 22:24:40 +01:00
|
|
|
return 0;
|
2010-04-06 20:38:27 +02:00
|
|
|
}
|
|
|
|
|
2010-03-17 07:36:54 +01:00
|
|
|
1;
|