mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 16:46:26 +00:00
265 lines
9.9 KiB
Plaintext
265 lines
9.9 KiB
Plaintext
################################
|
|
# RDF Module #
|
|
################################
|
|
# this is really an RSS module, not an RDF module.
|
|
# but oh well.
|
|
|
|
package BotModules::RDF;
|
|
use XML::RSS;
|
|
use vars qw(@ISA);
|
|
@ISA = qw(BotModules);
|
|
1;
|
|
|
|
# RegisterConfig - Called when initialised, should call registerVariables
|
|
sub RegisterConfig {
|
|
my $self = shift;
|
|
$self->SUPER::RegisterConfig(@_);
|
|
$self->registerVariables(
|
|
# [ name, save?, settable? ]
|
|
['sites', 1, 1, {}],
|
|
['updateDelay', 1, 1, 600],
|
|
['preferredLineLength', 1, 1, 80],
|
|
['maxInChannel', 1, 1, 5],
|
|
['trimTitles', 1, 1, '0'],
|
|
['data', 0, 0, {}], # data -> uri -> (title, link, last, items -> uri)
|
|
['mutes', 1, 1, {}], # uri -> "channel channel channel"
|
|
);
|
|
}
|
|
|
|
# Schedule - called when bot connects to a server, to install any schedulers
|
|
# use $self->schedule($event, $delay, $times, $data)
|
|
# where $times is 1 for a single event, -1 for recurring events,
|
|
# and a +ve number for an event that occurs that many times.
|
|
sub Schedule {
|
|
my $self = shift;
|
|
my ($event) = @_;
|
|
$self->schedule($event, \$self->{'updateDelay'}, -1, 'rdf');
|
|
$self->SUPER::Schedule($event);
|
|
}
|
|
|
|
sub Help {
|
|
my $self = shift;
|
|
my ($event) = @_;
|
|
my %commands;
|
|
if ($self->isAdmin($event)) {
|
|
$commands{''} = "The RDF module monitors various websites. Add new RDF channels to the 'sites' hash. Duplicates with different nicknames are fine. For example, \"vars $self->{'_name'} sites '+|slashdot|http://...'\" and \"vars $self->{'_name'} sites '+|/.|http://...'\" is fine. To remove a site from the RDF 'sites' hash, use this syntax \"vars $self->{_name} sites '-slashdot'";
|
|
$commands{'mute'} = 'Disable reporting of a site in a channel. (Only does something if the given site exists.) Syntax: mute <site> in <channel>';
|
|
$commands{'unmute'} = 'Enable reporting of a site in a channel. By default, sites are reported in all channels that the module is active in. Syntax: unmute <site> in <channel>';
|
|
} else {
|
|
$commands{''} = 'The RDF module monitors various websites.';
|
|
}
|
|
foreach my $site (keys(%{$self->{'sites'}})) {
|
|
if ($self->{'data'}->{$self->{'sites'}->{$site}}) {
|
|
$commands{$site} = "Reports the headlines listed in $self->{'data'}->{$self->{'sites'}->{$site}}->{'title'}";
|
|
|
|
# -- #mozilla was here --
|
|
# <Hixie> anyway, $self->{'data'}->{$self->{'sites'}->{$site}}->{'title'} is
|
|
# another nice piece of perl (embedded in a quoted string in this case)
|
|
# <moogle> yeah, that's a bit more familiar
|
|
# <jag> Oooh, nice one
|
|
# <jag> Reminds me of Java, a bit :-)
|
|
# <jag> Without all the casting about from Object to Hashtable
|
|
# <Hixie> all this, BTW, is from the RDF module (the one that mozbot uses to
|
|
# report changes in mozillazine and so on)
|
|
# <moogle> I still tend to comment these things a bit just for maintainability
|
|
# by others who might not wish to do mental gymnastics :)
|
|
# <Hixie> :-)
|
|
|
|
} else {
|
|
$commands{$site} = "Reports the headlines listed in $self->{'sites'}->{$site}";
|
|
}
|
|
|
|
}
|
|
return \%commands;
|
|
}
|
|
|
|
sub Told {
|
|
my $self = shift;
|
|
my ($event, $message) = @_;
|
|
foreach my $site (keys(%{$self->{'sites'}})) {
|
|
if ($message =~ /^\s*(\Q$site\E)\s*$/si) {
|
|
$self->GetSite($event, $1, 'request');
|
|
return 0; # dealt with it...
|
|
}
|
|
}
|
|
if ($self->isAdmin($event)) {
|
|
if ($message =~ /^\s*mute\s+(\S+?)\s+in\s+(\S+?)\s*$/osi) {
|
|
my $site = $1 eq 'RDF' ? '' : $self->{'sites'}->{$1};
|
|
my $siteName = $site eq '' ? 'all sites' : $site;
|
|
if (defined($site)) {
|
|
$self->{'mutes'}->{$site} .= " $2";
|
|
$self->saveConfig();
|
|
$self->say($event, "$event->{'from'}: RDF notifications for $siteName muted in channel $2.");
|
|
} else {
|
|
# can't say this, other modules might recognise it: $self->say($event, "$event->{'from'}: I don't know about any '$1' site...");
|
|
}
|
|
} elsif ($message =~ /^\s*unmute\s+(\S+?)\s+in\s+(\S+?)\s*$/osi) {
|
|
my $site = $1 eq 'RDF' ? '' : $self->{'sites'}->{$1};
|
|
my $siteName = $site eq '' ? 'all sites' : $site;
|
|
if (defined($site)) {
|
|
my %mutedChannels = map { lc($_) => 1 } split(/ /o, $self->{'mutes'}->{$site});
|
|
delete($mutedChannels{lc($2)}); # get rid of any mentions of that channel
|
|
$self->{'mutes'}->{$site} = join(' ', keys(%mutedChannels));
|
|
$self->saveConfig();
|
|
$self->say($event, "$event->{'from'}: RDF notifications for $siteName resumed in channel $2.");
|
|
} else {
|
|
# can't say this, other modules might recognise it: $self->say($event, "$event->{'from'}: I don't know about any '$1' site...");
|
|
}
|
|
} else {
|
|
return $self->SUPER::Told(@_);
|
|
}
|
|
} else {
|
|
return $self->SUPER::Told(@_);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sub GetSite {
|
|
my $self = shift;
|
|
my ($event, $site, $intent) = @_;
|
|
if (defined($self->{'sites'}->{$site})) {
|
|
my $uri = $self->{'sites'}->{$site};
|
|
$self->getURI($event, $uri, $intent);
|
|
} else {
|
|
# XXX
|
|
}
|
|
}
|
|
|
|
sub GotURI {
|
|
my $self = shift;
|
|
my ($event, $uri, $output, $intent) = @_;
|
|
|
|
$self->{'data'}->{$uri}->{'ready'} = defined($self->{'data'}->{$uri});
|
|
|
|
if ($output) {
|
|
|
|
# last update stamp
|
|
my $last = $event->{'time'};
|
|
$self->{'data'}->{$uri}->{'last'} = $last;
|
|
|
|
# Parse It
|
|
my $rss = XML::RSS->new();
|
|
eval { $rss->parse($output) };
|
|
if ($@) {
|
|
$self->debug("$uri is not a valid RSS file");
|
|
if ($intent eq 'request') {
|
|
$self->say($event, "$event->{'from'}: Dude, the file is not valid RSS! ($uri)");
|
|
}
|
|
return;
|
|
}
|
|
|
|
# Set Link and Title
|
|
$self->{data}->{$uri}->{'link'} = $rss->{'channel'}->{'link'};
|
|
$self->{data}->{$uri}->{'title'} = $rss->{'channel'}->{'title'};
|
|
|
|
foreach my $item (@{$rss->{'items'}}) {
|
|
unless (($item->{title} =~ /^last update/osi) ||
|
|
(defined($self->{'data'}->{$uri}->{'items'}->{$item->{'title'}}))) {
|
|
$self->{'data'}->{$uri}->{'items'}->{$item->{'title'}} = $last;
|
|
}
|
|
}
|
|
|
|
$self->ReportDiffs($event, $uri, $intent);
|
|
if ($intent eq 'request') {
|
|
$self->ReportAll($event, $uri);
|
|
}
|
|
|
|
} else {
|
|
|
|
if ($intent eq 'request') {
|
|
$self->say($event, "$event->{'from'}: Dude, the file was empty! ($uri)");
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sub Scheduled {
|
|
my $self = shift;
|
|
my ($event, @data) = @_;
|
|
if ($data[0] eq 'rdf') {
|
|
my %sites = map { $_ => 1 } values(%{$self->{'sites'}});
|
|
foreach (keys(%sites)) {
|
|
$self->getURI($event, $_, 'update');
|
|
}
|
|
} else {
|
|
$self->SUPER::Scheduled($event, @data);
|
|
}
|
|
}
|
|
|
|
sub ReportDiffs {
|
|
my $self = shift;
|
|
my ($event, $uri, $request) = @_;
|
|
return unless $self->{'data'}->{$uri}->{'ready'};
|
|
my $last = $self->{'data'}->{$uri}->{'last'};
|
|
my @output;
|
|
foreach (keys(%{$self->{'data'}->{$uri}->{'items'}})) {
|
|
push(@output, $_) if ($self->{'data'}->{$uri}->{'items'}->{$_} == $last);
|
|
}
|
|
|
|
# -- #mrt was here --
|
|
# <mozbot> Friday's security advisories -- The first stable
|
|
# Xen release -- Linux Gazette #95
|
|
# <mozbot> KDE Under The Microscope -- Additional OpenSSL info
|
|
# <Hixie> wtf
|
|
# <mozbot> Just appeared in jbisbee.com -
|
|
# http://www.jbisbee.com/ : PoCo::RSS::Aggregator
|
|
# <Hixie> why is it repeating the same thing over and over
|
|
# <mozbot> PoCo::RSSAggregator & XML::RSS::Feed Uploaded to
|
|
# CPAN -- More PoCo::RSSAggregator
|
|
# <Hixie> mozbot: shutup please
|
|
# <mozbot> Ok, threw away 2558 messages.
|
|
|
|
# Ahem. So now we limit the diff reporting code to maxInChannel
|
|
# items at a time...
|
|
|
|
if (@output and @output < $self->{'maxInChannel'}) {
|
|
@output = $self->prettyPrint($self->{'preferredLineLength'},
|
|
"Just appeared in $self->{'data'}->{$uri}->{'title'} - $self->{'data'}->{$uri}->{'link'} : ",
|
|
'', ' -- ', @output);
|
|
|
|
my %mutedChannels = ();
|
|
if (defined($self->{'mutes'}->{$uri})) {
|
|
%mutedChannels = map { lc($_) => 1 } split(/\s+/os, $self->{'mutes'}->{$uri});
|
|
}
|
|
if (defined($self->{'mutes'}->{''})) {
|
|
%mutedChannels = (%mutedChannels, map { lc($_) => 1 } split(/\s+/os, $self->{'mutes'}->{''}));
|
|
}
|
|
if ($request eq 'request') {
|
|
$mutedChannels{$event->{'channel'}} = 1;
|
|
}
|
|
foreach (@{$self->{'channels'}}) {
|
|
unless ($mutedChannels{$_}) {
|
|
local $event->{'target'} = $_;
|
|
foreach (@output) {
|
|
$self->say($event, $_);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sub ReportAll {
|
|
my $self = shift;
|
|
my ($event, $uri) = @_;
|
|
my @output;
|
|
foreach (keys(%{$self->{'data'}->{$uri}->{'items'}})) {
|
|
push(@output, $_);
|
|
}
|
|
|
|
@output = $self->prettyPrint($self->{'preferredLineLength'},
|
|
"Items in $self->{'data'}->{$uri}->{'title'} - $self->{'data'}->{$uri}->{'link'}: ",
|
|
"$event->{'from'}: ", ' -- ', @output);
|
|
|
|
if (@output > $self->{'maxInChannel'}) {
|
|
foreach (@output) {
|
|
$self->directSay($event, $_);
|
|
}
|
|
$self->channelSay($event, "$event->{'from'}: /msg'ed");
|
|
} else {
|
|
foreach (@output) {
|
|
$self->say($event, $_);
|
|
}
|
|
}
|
|
}
|