1 ################################
3 ################################
5 package BotModules::MiniLogger;
14 '' => '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.',
16 foreach (keys %{$self->{'patterns'}}) {
17 $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.";
19 if ($self->isAdmin($event)) {
20 $help{''} .= ' To add a new pattern, use the following syntax: vars MiniLogger patterns \'+|name|pattern\'';
21 $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\'.';
26 # RegisterConfig - Called when initialised, should call registerVariables
29 $self->SUPER::RegisterConfig(@_);
30 $self->registerVariables(
31 # [ name, save?, settable? ]
32 ['log', 0, 0, {}], # log -> channel -> patternName -> [<who> text]
33 ['bufferSize', 1, 1, 20], # number of comments to remember, per channel/pattern combination
34 ['patterns', 1, 1, {'links'=>'<?(:?[Uu][Rr][LlIi]:)?\s*(?:https?|ftp)://[^\s>"]+>?'}], # list of patternNames and patterns (regexp)
35 ['blockedPatterns', 1, 1, []], # list of patterns (regexp) to ignore
41 my ($event, $message) = @_;
42 if (($message =~ /^\s*([a-zA-Z0-9]+)(?:\s+(.+?))?(?:\s+in\s+(.+?))?\s*$/osi) and ($self->{'patterns'}->{$1})) {
43 $self->Report($event, $3, $1, $2); # event, channel, log, pattern
44 } elsif ($self->isAdmin($event)) {
45 if ($message =~ /^\s*flush\s+minilogs\s*$/osi) {
46 $self->FlushMinilogs($event);
48 return $self->SUPER::Told(@_);
51 return $self->SUPER::Told(@_);
53 return 0; # we've dealt with it, no need to do anything else.
59 if (($event->{'firsttype'} eq 'Told') or ($event->{'firsttype'} eq 'Heard')) {
60 $self->DoLog($event, "<$event->{'from'}> $event->{'data'}");
61 } elsif (($event->{'firsttype'} eq 'Felt') or ($event->{'firsttype'} eq 'Saw')) {
62 $self->DoLog($event, "* $event->{'from'} $event->{'data'}");
68 my ($event, $message) = @_;
69 if ($event->{'channel'} ne '') {
70 # don't log private messages
71 foreach my $pattern (keys %{$self->{'patterns'}}) {
72 my $regexp = $self->sanitizeRegexp($self->{'patterns'}->{$pattern});
73 if ($message =~ /$regexp/s) {
74 # wohay, we have a candidate!
75 # now check for possible blockers...
76 unless ($self->isBlocked($message)) {
77 $self->debug("LOGGING: $message");
78 push(@{$self->{'log'}->{$event->{'channel'}}->{$pattern}}, $message);
79 if (@{$self->{'log'}->{$event->{'channel'}}->{$pattern}} > $self->{'bufferSize'}) {
80 shift(@{$self->{'log'}->{$event->{'channel'}}->{$pattern}});
91 foreach my $blockedPattern (@{$self->{'blockedPatterns'}}) {
92 my $regexp = $self->sanitizeRegexp($blockedPattern);
93 if ($message =~ /$regexp/s) {
102 my ($event, $channel, $log, $pattern) = @_;
103 my @channels = $channel ? lc($channel) : @{$self->{'channels'}};
105 $pattern = $self->sanitizeRegexp($pattern);
106 foreach $channel (@channels) {
107 foreach my $match (@{$self->{'log'}->{$channel}->{$log}}) {
108 if ((!$pattern) or ($match =~ /$pattern/s)) {
109 $self->directSay($event, $match);
115 $self->directSay($event, 'No matches, sorry.');
117 $self->channelSay($event, "$event->{'from'}: minilog matches /msg'ed");
123 # remove dead channels
124 my %channels = map { lc($_) => 1 } @{$self->{'channels'}};
125 foreach my $channel (keys %{$self->{'log'}}) {
126 if ($channels{$channel}) {
128 foreach my $pattern (keys %{$self->{'log'}->{$channel}}) {
129 if ($self->{'patterns'}) {
130 # remove any newly blocked patterns
132 foreach my $match (@{$self->{'log'}->{$channel}->{$pattern}}) {
133 unless ($self->isBlocked($match)) {
134 push (@newpatterns, $match);
139 @{$self->{'log'}->{$channel}->{$pattern}} = (@newpatterns[
140 @newpatterns - $self->{'bufferSize'} < 0 ? 0 : @newpatterns - $self->{'bufferSize'},
144 @{$self->{'log'}->{$channel}->{$pattern}} = ();
147 delete($self->{'log'}->{$channel}->{$pattern});
151 delete($self->{'log'}->{$channel});
154 $self->say($event, 'Minilogs flushed.');