зеркало из https://github.com/mozilla/pjs.git
156 строки
5.9 KiB
Plaintext
156 строки
5.9 KiB
Plaintext
################################
|
|
# MiniLogger Module #
|
|
################################
|
|
|
|
package BotModules::MiniLogger;
|
|
use vars qw(@ISA);
|
|
@ISA = qw(BotModules);
|
|
1;
|
|
|
|
sub Help {
|
|
my $self = shift;
|
|
my ($event) = @_;
|
|
my %help = (
|
|
'' => 'This module keeps a log of the last few comments that match some patterns. For example, it can be used to remember URIs that have recently been mentioned.',
|
|
);
|
|
foreach (keys %{$self->{'patterns'}}) {
|
|
$help{$_} = 'Returns any recent comment that matched the pattern /'.$self->sanitizeRegexp($self->{'patterns'}->{$_})."/. To narrow the search down even more, you can include a search string after the $_, as in '$_ goats'. To restrict the search to a particular channel, append \'in <channel>\' at the end.";
|
|
}
|
|
if ($self->isAdmin($event)) {
|
|
$help{''} .= ' To add a new pattern, use the following syntax: vars MiniLogger patterns \'+|name|pattern\'';
|
|
$help{'flush'} = 'Deletes any logs for patterns or channels that are no longer relevant, makes sure all the logs are no longer than the \'bufferSize\' length. Syntax: \'flush minilogs\'.';
|
|
}
|
|
return \%help;
|
|
}
|
|
|
|
# RegisterConfig - Called when initialised, should call registerVariables
|
|
sub RegisterConfig {
|
|
my $self = shift;
|
|
$self->SUPER::RegisterConfig(@_);
|
|
$self->registerVariables(
|
|
# [ name, save?, settable? ]
|
|
['log', 0, 0, {}], # log -> channel -> patternName -> [<who> text]
|
|
['bufferSize', 1, 1, 20], # number of comments to remember, per channel/pattern combination
|
|
['patterns', 1, 1, {'links'=>'<?(:?[Uu][Rr][LlIi]:)?\s*(?:https?|ftp)://[^\s>"]+>?'}], # list of patternNames and patterns (regexp)
|
|
['blockedPatterns', 1, 1, []], # list of patterns (regexp) to ignore
|
|
);
|
|
}
|
|
|
|
sub Told {
|
|
my $self = shift;
|
|
my ($event, $message) = @_;
|
|
if (($message =~ /^\s*([a-zA-Z0-9]+)(?:\s+(.+?))?(?:\s+in\s+(.+?))?\s*$/osi) and ($self->{'patterns'}->{$1})) {
|
|
$self->Report($event, $3, $1, $2); # event, channel, log, pattern
|
|
} elsif ($self->isAdmin($event)) {
|
|
if ($message =~ /^\s*flush\s+minilogs\s*$/osi) {
|
|
$self->FlushMinilogs($event);
|
|
} else {
|
|
return $self->SUPER::Told(@_);
|
|
}
|
|
} else {
|
|
return $self->SUPER::Told(@_);
|
|
}
|
|
return 0; # we've dealt with it, no need to do anything else.
|
|
}
|
|
|
|
sub Log {
|
|
my $self = shift;
|
|
my ($event) = @_;
|
|
if (($event->{'firsttype'} eq 'Told') or ($event->{'firsttype'} eq 'Heard')) {
|
|
$self->DoLog($event, "<$event->{'from'}> $event->{'data'}");
|
|
} elsif (($event->{'firsttype'} eq 'Felt') or ($event->{'firsttype'} eq 'Saw')) {
|
|
$self->DoLog($event, "* $event->{'from'} $event->{'data'}");
|
|
}
|
|
}
|
|
|
|
sub DoLog {
|
|
my $self = shift;
|
|
my ($event, $message) = @_;
|
|
if ($event->{'channel'} ne '') {
|
|
# don't log private messages
|
|
foreach my $pattern (keys %{$self->{'patterns'}}) {
|
|
my $regexp = $self->sanitizeRegexp($self->{'patterns'}->{$pattern});
|
|
if ($message =~ /$regexp/s) {
|
|
# wohay, we have a candidate!
|
|
# now check for possible blockers...
|
|
unless ($self->isBlocked($message)) {
|
|
$self->debug("LOGGING: $message");
|
|
push(@{$self->{'log'}->{$event->{'channel'}}->{$pattern}}, $message);
|
|
if (@{$self->{'log'}->{$event->{'channel'}}->{$pattern}} > $self->{'bufferSize'}) {
|
|
shift(@{$self->{'log'}->{$event->{'channel'}}->{$pattern}});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sub isBlocked {
|
|
my $self = shift;
|
|
my ($message) = @_;
|
|
foreach my $blockedPattern (@{$self->{'blockedPatterns'}}) {
|
|
my $regexp = $self->sanitizeRegexp($blockedPattern);
|
|
if ($message =~ /$regexp/s) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sub Report {
|
|
my $self = shift;
|
|
my ($event, $channel, $log, $pattern) = @_;
|
|
my @channels = $channel ? lc($channel) : @{$self->{'channels'}};
|
|
my $count;
|
|
$pattern = $self->sanitizeRegexp($pattern);
|
|
foreach $channel (@channels) {
|
|
foreach my $match (@{$self->{'log'}->{$channel}->{$log}}) {
|
|
if ((!$pattern) or ($match =~ /$pattern/s)) {
|
|
$self->directSay($event, $match);
|
|
$count++;
|
|
}
|
|
}
|
|
}
|
|
unless ($count) {
|
|
$self->directSay($event, 'No matches, sorry.');
|
|
}
|
|
$self->channelSay($event, "$event->{'from'}: minilog matches /msg'ed");
|
|
}
|
|
|
|
sub FlushMinilogs {
|
|
my $self = shift;
|
|
my ($event) = @_;
|
|
# remove dead channels
|
|
my %channels = map { lc($_) => 1 } @{$self->{'channels'}};
|
|
foreach my $channel (keys %{$self->{'log'}}) {
|
|
if ($channels{$channel}) {
|
|
# remove dead logs
|
|
foreach my $pattern (keys %{$self->{'log'}->{$channel}}) {
|
|
if ($self->{'patterns'}) {
|
|
# remove any newly blocked patterns
|
|
my @newpatterns;
|
|
foreach my $match (@{$self->{'log'}->{$channel}->{$pattern}}) {
|
|
unless ($self->isBlocked($match)) {
|
|
push (@newpatterns, $match);
|
|
}
|
|
}
|
|
# remove excess logs
|
|
if (@newpatterns) {
|
|
@{$self->{'log'}->{$channel}->{$pattern}} = (@newpatterns[
|
|
@newpatterns - $self->{'bufferSize'} < 0 ? 0 : @newpatterns - $self->{'bufferSize'},
|
|
$#newpatterns]
|
|
);
|
|
} else {
|
|
@{$self->{'log'}->{$channel}->{$pattern}} = ();
|
|
}
|
|
} else {
|
|
delete($self->{'log'}->{$channel}->{$pattern});
|
|
}
|
|
}
|
|
} else {
|
|
delete($self->{'log'}->{$channel});
|
|
}
|
|
}
|
|
$self->say($event, 'Minilogs flushed.');
|
|
}
|