User:XLinkBot/Code/LinkWatcher.pl
From Wikipedia, the free encyclopedia
< User:XLinkBot | Code
#!/usr/bin/perl
use strict;
use POE qw(Component::IRC Component::IRC::Plugin::BotAddressed Component::Server::TCP);
use Socket;
use DBI;
use Data::Dumper;
use perlwikipedia;
my %settings;
my @editQueue;
my $username = "LinkWatcher";
my $editor=Perlwikipedia->new($username,$username);
my $counter=0;
my $editcounter=0;
my $watchedspacecounter=0;
my $totallinks=0;
my $whitelinks=0;
my $linkadditions=0;
my $blacklinks=0;
my $redlinks=0;
my $whiteuser=0;
my $ratio1=0;
my $ratio2=0;
my $ratio3=0;
my $ratio4=0;
my $ratio5=0;
my $ratio6=0;
my $ratio7=0;
my $ratio8=0;
my $ratio9=0;
my $ratio10=0;
my $starttime = time();
print "Reading config file...";
open (CONFIG,"<linkwatcher-config") or die "Can't open LinkWatcher config: $!";
foreach (<CONFIG>) {
unless (/^#/) {
if(/(.+?)=(.+)/) {
$settings{$1}=$2;
}
}
}
close (CONFIG);
print "done\n";
print "Initializing IRC subsystem...";
my $ircsettings= {
$settings{'rcserver'} => { port => 6667, },
$settings{'ircserver'} => { port => $settings{'ircport'}, channels=> [ $settings{'ircreportchannel'}, $settings{'ircbotchannel'} ], },
};
foreach my $server ( keys %{ $ircsettings } ) {
POE::Component::IRC->spawn(
alias => $server,
nick => $settings{'ircnick'},
ircname => $settings{'ircname'},
username=> $settings{'ircusername'},
);
}
my @rcchannels = split( /\s,?/, $settings{'rcchannels'} );
print "RC channels are: " . join(' ',@rcchannels) . "\n";
print "done\n";
foreach my $parserNumber ( 1 .. $settings{'numberofparsers'} ) {
print "Starting slave $parserNumber...";
system("perl","LinkParser.pl",$settings{'serverport'});
print "done\n";
}
print "Initializing LinkWatcher2 master server on port $settings{'serverport'}...";
POE::Component::Server::TCP->new(
Port => $settings{'serverport'},
ClientInput => \&slave_input,
ClientDisconnected => \&slave_disconnect,
);
print "done\n";
POE::Session->create(
package_states => [
'main' => [ qw(_start irc_registered irc_001 irc_public irc_bot_addressed irc_disconnected) ],
],
heap => { config => $ircsettings },
);
print "Connecting to MySQL...";
my $mysql;
my $mysql=DBI->connect("dbi:mysql:$settings{'mysqldb'};$settings{'mysqlhost'}",$settings{'mysqluser'},$settings{'mysqlpassword'}) or die "Can't connect to MySQL: $DBI::errstr";
$mysql->{mysql_auto_reconnect} = 1;
print "done\n";
my $rulespage=$editor->get_text($settings{'blacklist'});
my @wikiblacklist = split(/\n/,$rulespage);
print "Starting LinkWatcher2...\n";
POE::Kernel->run();
exit 0;
sub _start {
my ($kernel,$session) = @_[KERNEL,SESSION];
# Send a POCOIRC_REGISTER signal to all poco-ircs
$kernel->signal( $kernel, 'POCOIRC_REGISTER', $session->ID(), 'all' );
undef;
}
sub irc_registered {
my ($kernel,$heap,$sender,$irc_object) = @_[KERNEL,HEAP,SENDER,ARG0];
my $alias = $irc_object->session_alias();
$irc_object->plugin_add( 'BotAddressed', POE::Component::IRC::Plugin::BotAddressed->new( eat=> 1 ) );
my %conn_hash = (
server => $alias,
port => $heap->{config}->{ $alias }->{port},
);
# In any irc_* events SENDER will be the PoCo-IRC session
$kernel->post( $sender, 'connect', \%conn_hash );
undef;
}
sub irc_001 {
my ($kernel,$heap,$sender) = @_[KERNEL,HEAP,SENDER];
# Get the component's object at any time by accessing the heap of
# the SENDER
my $poco_object = $sender->get_heap();
print "Connected to ", $poco_object->server_name(), "\n";
if ($poco_object->server_name() eq $settings{'rcserver'}) {
my $alias = $poco_object->session_alias();
$kernel->post( $sender => join => $_ ) for @rcchannels;
}
elsif ($poco_object->server_name() eq $settings{'ircserver'}) {
$kernel->post( $sender => privmsg => 'NickServ',"identify $settings{'ircpassword'}" );
sleep 4;
$kernel->post( $sender => join => $settings{'ircreportchannel'} ) if $settings{'ircreportchannel'};
$kernel->post( $sender => join => $settings{'ircbotchannel'} ) if $settings{'ircbotchannel'};
}
undef;
}
sub irc_public {
my ($kernel,$sender,$who,$where,$message) = @_[KERNEL,SENDER,ARG0,ARG1,ARG2];
my $nick = ( split /!/, $who )[0];
my $cloak = ( split /@/, $who )[1];
$message=~ s/\cC\d{1,2}(?:,\d{1,2})?|[\cC\cB\cI\cU\cR\cO]//g;
my $page;
my $lang;
my $diffurl;
my $user;
my $size;
my $space;
my $domain1;
my $domain;
my $domainpage;
my $garbage;
$counter++;
if ($settings{'source'} eq "Wiki") {
if ($counter > $settings{'refreshevery'}) {
my $rulespage=$editor->get_text($settings{'blacklist'});
my @wikiblacklist = split(/\n/,$rulespage);
$counter=0;
}
if (($message =~ m/$settings{'blacklist'}/) && ($nick eq "rc")) {
my $rulespage=$editor->get_text($settings{'blacklist'});
my @wikiblacklist = split(/\n/,$rulespage);
$counter=0;
$kernel->post( $settings{'ircserver'} => privmsg => $settings{'ircreportchannel'} => "[[$settings{'blacklist'}]] edited." );
}
if ( $message =~ m/^!refresh/) {
my $rulespage=$editor->get_text($settings{'blacklist'});
my @wikiblacklist = split(/\n/,$rulespage);
$counter=0;
}
}
if ( $message =~ m/!info/) {
my $currenttime = time();
my $timedifference = $currenttime - $starttime;
$timedifference = $timedifference/60;
my $printtimedifference = int($timedifference);
my $ratio1 = int(10000 * $watchedspacecounter/$editcounter)/100 unless ($editcounter == 0);
my $ratio2 = int(10000 * $whiteuser/$watchedspacecounter)/100 unless ($watchedspacecounter == 0);
my $ratio3 = int(10000 * $linkadditions/$watchedspacecounter)/100 unless ($watchedspacecounter == 0);
my $ratio4 = int(10000 * $whitelinks/$totallinks)/100 unless ($totallinks == 0);
my $ratio5 = int(10000 * $redlinks/$totallinks)/100 unless ($totallinks == 0);
my $ratio6 = int(10000 * $blacklinks/$totallinks)/100 unless ($totallinks == 0);
my $editsperminute = int($editcounter/$timedifference) unless ($timedifference == 0);
my $watchededitsperminute = int($watchedspacecounter/$timedifference) unless ($timedifference == 0);
my $linksperminute = int($totallinks/$timedifference) unless ($timedifference == 0);
my $blacklinksperminute = int($blacklinks/$timedifference) unless ($timedifference == 0);
my $whitelinksperminute = int($whitelinks/$timedifference) unless ($timedifference == 0);
my $redlinksperminute = int($redlinks/$timedifference) unless ($timedifference == 0);
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "LinkWatcher info: $printtimedifference minutes active: E(T): $editcounter ($editsperminute PM); E(W): $watchedspacecounter ($ratio1%; $watchededitsperminute PM); E(L): $linkadditions ($ratio3%); U(W): $whiteuser ($ratio2%); L(T) $totallinks ($linksperminute PM); L(W): $whitelinks ($ratio4%; $whitelinksperminute PM); L(R): $redlinks ($ratio5%; $redlinksperminute PM); L(B): $blacklinks ($ratio6%; $blacklinksperminute PM). Sourcing: $settings{'source'}" );
}
if ($message=~m/\[\[(.+?)\]\] M?\s*?http:\/\/(.+?)\.(.+?)\/(.+?) \* (.+?) \* \(([^)]+)\)/) {
$editcounter++;
$page = $1;
$lang = $2;
$domain1 = $3;
$diffurl = "http://$lang.$domain1/$4";
$user = $5;
$size = $6;
if ($domain1 eq "org") {
$domain1 = "$lang.$domain";
$lang = "";
}
($space,$garbage) = split(/:/,$1,2);
if ($garbage eq "") {
$space = "";
}
$domain = "";
if ($domain1 eq "wiktionary.org") {
$domain = "wikt:";
}
if ($domain1 eq "wikibooks.org") {
$domain = "b:";
}
if ($domain1 eq "wikinews.org") {
$domain = "n:";
}
if ($domain1 eq "wikisource.org") {
$domain = "s:";
}
if ($domain1 eq "wikiquote.org") {
$domain = "q:";
}
if ($domain1 eq "wikimedia.org") {
if ($space eq "species") {
$domain = "wikispecies:";
} elsif ($space eq "") {
$domain = "";
}
}
print ("Read: $domain1 - $domain - $page - $lang - $space - $diffurl - $user - $size\n");
$domainpage = "$domain$lang:$page";
if ( ($space eq "") || ($space eq "Category") || ($space eq "Template") || ($space eq "Categorie") || ($space eq "Sjabloon") ) {
$watchedspacecounter++;
unshift(@editQueue,{pagename=>$page,domain=>$domain,lang=>$lang,diffurl=>$diffurl,user=>$user,size=>$size});
}
}
}
sub irc_bot_addressed {
my ( $kernel, $sender, $who, $where, $message ) = @_[ KERNEL, SENDER, ARG0, ARG1, ARG2 ];
my $nick = ( split /!/, $who)[0];
my $cloak = ( split /@/, $who )[1];
my $channels;
my $channel;
my $channel2;
my $oldchannel;
my $newchannel;
unless ( $where->[0] eq $settings{'ircreportchannel'} ) {
return;
}
if ( $message =~m/link (.+?) (.{1,3}) (.+?) (.+)/ ) {
my $list = $1;
my $operation = $2;
my $link = $mysql->quote($3);
my $reason;
my $link = $mysql->quote($4);
my $query;
if ( $operation eq 'add' ) {
$query = "INSERT INTO ";
}
elsif ( $operation eq 'del' ) {
$query = "DELETE FROM ";
}
if ( $list eq 'wl' ) {
$query .= "$settings{'mysqltableprefix'}whitelist ";
}
elsif ( $list eq 'rl' ) {
$query .= "$settings{'mysqltableprefix'}redlist ";
}
elsif ( $list eq 'bl' ) {
$query .= "$settings{'mysqltableprefix'}blacklist ";
}
else {
return;
}
if ( $operation eq 'add' ) {
$query .= "(rule,cloak,reason) VALUES ($link,$cloak,$reason)";
}
elsif ( $operation eq 'del' ) {
$query .= "WHERE rule=$link";
}
&query($query);
if ( $operation eq 'add' ) {
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "Item $link added to $list" );
}
elsif ( $operation eq 'del' ) {
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "Item $link removed from $list" );
}
}
if ( $message =~m/user (.+?) (.+)/ ) {
my $operation = $1;
my $user;
my $user = $mysql->quote($2);
my $query;
if ( $operation eq 'add' ) {
$query = "INSERT INTO ";
}
elsif ( $operation eq 'del' ) {
$query = "DELETE FROM ";
}
$query .= "$settings{'mysqltableprefix'}users ";
if ( $operation eq 'add' ) {
$query .= "(username,status) VALUES ($user,'ignore')";
}
elsif ( $operation eq 'del' ) {
$query .= "WHERE username=$user";
}
&query($query);
if ( $operation eq 'add' ) {
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "user $user added to whitelist" );
}
elsif ( $operation eq 'del' ) {
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "user $user removed from whitelist" );
}
}
if ( $message =~ m/^refresh/) {
my $rulespage=$editor->get_text("User:XLinkBot/RevertList");
my @wikiblacklist = split(/\n/,$rulespage);
$counter=0;
}
if ( $message =~ m/^source (.+)/ ) {
my $revertfrom = $1;
if (lc($cloak) eq "wikimedia/beetstra" || lc($cloak) eq "wikimedia/versageek") {
if ($revertfrom =~ m/(SQL|Wiki)/) {
$settings{'source'} = $revertfrom;
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "Blacklist source is now $revertfrom." );
} else {
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "'$revertfrom' is not a valid Blacklist source." );
}
}
else {
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "I only trust Versageek and Beetstra to issue this command." );
}
my $rulespage=$editor->get_text("User:XLinkBot/RevertList");
my @wikiblacklist = split(/\n/,$rulespage);
$counter=0;
}
if ($message=~ m/^quit$/) {
my $currenttime = time();
my $timedifference = $currenttime - $starttime;
$timedifference = $timedifference/60;
my $printtimedifference = int($timedifference);
my $ratio1 = int(10000 * $watchedspacecounter/$editcounter)/100 unless ($editcounter == 0);
my $ratio2 = int(10000 * $whiteuser/$watchedspacecounter)/100 unless ($watchedspacecounter == 0);
my $ratio3 = int(10000 * $linkadditions/$watchedspacecounter)/100 unless ($watchedspacecounter == 0);
my $ratio4 = int(10000 * $whitelinks/$totallinks)/100 unless ($totallinks == 0);
my $ratio5 = int(10000 * $redlinks/$totallinks)/100 unless ($totallinks == 0);
my $ratio6 = int(10000 * $blacklinks/$totallinks)/100 unless ($totallinks == 0);
my $editsperminute = int($editcounter/$timedifference) unless ($timedifference == 0);
my $watchededitsperminute = int($watchedspacecounter/$timedifference) unless ($timedifference == 0);
my $linksperminute = int($totallinks/$timedifference) unless ($timedifference == 0);
my $blacklinksperminute = int($blacklinks/$timedifference) unless ($timedifference == 0);
my $whitelinksperminute = int($whitelinks/$timedifference) unless ($timedifference == 0);
my $redlinksperminute = int($redlinks/$timedifference) unless ($timedifference == 0);
$kernel->post( $settings{'ircserver'} => privmsg => $where->[0] => "Quiting: $printtimedifference minutes active: E(T): $editcounter ($editsperminute PM); E(W): $watchedspacecounter ($ratio1%; $watchededitsperminute PM); E(L): $linkadditions ($ratio3%); U(W): $whiteuser ($ratio2%); L(T) $totallinks ($linksperminute PM); L(W): $whitelinks ($ratio4%; $whitelinksperminute PM); L(R): $redlinks ($ratio5%; $redlinksperminute PM); L(B): $blacklinks ($ratio6%; $blacklinksperminute PM). Sourcing: $settings{'source'}" );
if (($cloak eq 'wikimedia/Versageek') || ($cloak eq 'Wikimedia/Beetstra') ) {
$kernel->signal($kernel, 'POCOIRC_SHUTDOWN', "Bye!");
die "\nDied after quit!\n";
}
}
if ($message=~ m/^channels/ ) { # ask for which channels LinkWatcher is on
$channels = join(", ",@rcchannels);
$kernel->post( $sender => privmsg => $where->[0] => "$settings{ircname} listens on irc.wikimedia.org to $channels." );
}
if ($message=~ m/^show whitelisted users/ ) {
$settings{'showwhitelistedusers'}=1;
$kernel->post( $sender => privmsg => $where->[0] => "Showing whitelisted users" );
}
if ($message=~ m/^hide whitelisted users/ ) {
$settings{'showwhitelistedusers'}=0;
$kernel->post( $sender => privmsg => $where->[0] => "Hiding whitelisted users" );
}
if ($message=~ m/^show whitelisted links/ ) {
$settings{'showwhitelistedlinks'}=1;
$kernel->post( $sender => privmsg => $where->[0] => "Showing whitelisted links" );
}
if ($message=~ m/^hide whitelisted links/ ) {
$settings{'showwhitelistedlinks'}=0;
$kernel->post( $sender => privmsg => $where->[0] => "Hiding whitelisted links" );
}
if ($message=~ m/^add channel (.+)/ || $message=~ m/^join channel (.+)/ ) {
if (($cloak = 'wikimedia/Versageek') || ($cloak eq 'Wikimedia/Beetstra') ) {
$newchannel = $1;
unless ($newchannel eq '#en.wikipedia') {
if (grep(/$newchannel/,@rcchannels)) {
$kernel->post( $sender => privmsg => $where->[0] => "Channel $newchannel already joined." );
} else {
push (@rcchannels,$newchannel);
$kernel->post( 'irc.wikimedia.org' => join => $newchannel );
$kernel->post( $sender => privmsg => $where->[0] => "$settings{ircname} is now also parsing $newchannel." );
print "Connected to $newchannel.\n";
}
}
}
}
if ($message=~ m/^part channel (.+)/ ) {
if (($cloak = 'wikimedia/Versageek') || ($cloak eq 'Wikimedia/Beetstra') ) {
$oldchannel = $1;
$channel2 = join(",",@rcchannels);
$channel = "!!$channel2";
if ($channel =~ m/$oldchannel/) {
$kernel->post( $settings{reportserver} => part => $oldchannel );
$channel =~ s/,$oldchannel//;
$channel =~ s/!$oldchannel//;
$channel =~ s/!,//g;
$channel =~ s/!//g;
@rcchannels = split(/,/,$channel);
$kernel->post( $sender => privmsg => $where->[0] => "$settings{ircname} has parted $oldchannel." );
print "Parted $oldchannel on freenode.\n";
} else {
$kernel->post( $sender => privmsg => $where->[0] => "Channel $oldchannel not in list." );
}
}
}
}
sub slave_input {
my ( $kernel, $heap, $input ) = @_[ KERNEL, HEAP, ARG0 ];
if ($input=~m/REQUEST/) {
my $editref = pop(@editQueue);
if ($editref) {
my $message = "EDIT [[" . $editref->{pagename} . "]] [[" . $editref->{domain} . $editref->{lang} . ":User:" . $editref->{user} . "]] " . $editref->{diffurl} . " " . $editref->{size};
print (" message request: $message\n");
$heap->{client}->put($message);
}
else {
$heap->{client}->put("NOEDIT");
}
}
elsif ($input=~m{PARSED \[\[(.+)\]\] (http://.+?) (.+) \[\[(.+):User:(.+)\]\] \|(.+)\|}) {
my $pagename = $1;
my $diffurl = $2;
my $size = $3;
my $lang = $4;
my $username = $5;
my $links = $6;
my $count = 0;
print (" message parsed: $1 - $2 - $3 - $4 - $5 - $6\n");
if ($settings{'loglinks'}) {
my $query="INSERT INTO $settings{'mysqltableprefix'}log (pagename,diff,user,links) VALUES(";
$query .= $mysql->quote($pagename) . ",";
$query .= $mysql->quote($diffurl) . ",";
$query .= $mysql->quote($username) . ",";
$query .= $mysql->quote($links) . ")";
&query($query);
$query="SELECT COUNT(*) as total_record FROM $settings{'mysqltableprefix'}log WHERE user=" . $mysql->quote($username);
$count = &query($query);
$count = @{ $count }[0]->{total_record};
}
my $sql;
my $sql="SELECT status FROM $settings{'mysqltableprefix'}users WHERE username=" . $mysql->quote($username);
my $whitelisted = 0;
$sql=&query($sql);
if (defined $sql) {
if (@{$sql}[0]->{status} eq 'ignore') {
$whitelisted = 1;
$whiteuser++;
}
}
if ($whitelisted) {
if ($settings{'showwhitelistedusers'}) {
my $message=&build_output($kernel,$pagename,$diffurl,$size,$lang,$username,$whitelisted,$links);
unless (length($message) < 2) {
$kernel->post($settings{'ircserver'}=>privmsg=>$settings{'ircreportchannel'}=>$message) unless ($settings{'spambotfeeder'});
}
}
} else {
my $message=&build_output($kernel,$pagename,$diffurl,$size,$lang,$username,$whitelisted,$links);
print ("$message\n");
unless (length($message) < 2) {
$kernel->post($settings{'ircserver'}=>privmsg=>$settings{'ircreportchannel'}=>$message) unless ($settings{'spambotfeeder'});
if ($count > $settings{'warninglevel'} ) {
$kernel->post($settings{'ircserver'}=>privmsg=>$settings{'ircreportchannel'}=>"\x034WARNING! [[$lang:user:$username]] ([[$lang:Special:Contributions/$username]]) has added $count links.\x03") unless ($settings{'spambotfeeder'});
}
}
}
print("Found: [[$lang:$pagename]] $diffurl [[$lang:User:$username]] $links\n");
my @split_links = split( /\s/, $links );
my @resolved_ips;
if (@split_links) {
$linkadditions++;
}
foreach my $link ( @split_links ) {
$totallinks++;
my $link_spare = $link;
$link =~ s{https?://}{}i;
$link =~ s{([^/]+)/.+}{$1};
my $ip = &resolve( $link );
push ( @resolved_ips, { name=>$link_spare, ip=>$ip } );
}
if ($whitelisted) {
foreach my $entry ( @resolved_ips ) {
if ($settings{'showwhitelistedusers'}) {
my $query = "SELECT id FROM $settings{'mysqltableprefix'}blacklist WHERE rule='resolve ".$entry->{ip}."'";
$query = &query($query);
if (defined $query) {
if (defined @{ $query }[0]->{id}) {
my $message = "\x034WARNING! Link ".$entry->{name}." resolved to blacklisted IP address ".$entry->{ip}." on $diffurl\x03" unless ($settings{'spambotfeeder'});
$kernel->post($settings{'ircserver'}=>privmsg=>$settings{'ircreportchannel'}=>$message) unless ($settings{'spambotfeeder'});
&generate_alert( $pagename, $diffurl, $size, $lang, $username, 'resolve '.$entry->{ip}, $kernel )
}
}
}
}
} else {
foreach my $entry ( @resolved_ips ) {
my $query = "SELECT id FROM $settings{'mysqltableprefix'}blacklist WHERE rule='resolve ".$entry->{ip}."'";
$query = &query($query);
if (defined $query) {
if (defined @{ $query }[0]->{id}) {
my $message = "\x034WARNING! Link ".$entry->{name}." resolved to blacklisted IP address ".$entry->{ip}." on $diffurl\x03" unless ($settings{'spambotfeeder'});
$kernel->post($settings{'ircserver'}=>privmsg=>$settings{'ircreportchannel'}=>$message) unless ($settings{'spambotfeeder'});
&generate_alert( $pagename, $diffurl, $size, $lang, $username, 'resolve '.$entry->{ip}, $kernel )
}
}
}
}
}
}
sub slave_disconnect {
system("perl","LinkParser.pl",$settings{'serverport'});
}
sub irc_disconnected {
my ( $kernel, $sender, $server_name ) = @_[ KERNEL, SENDER, ARG0 ];
if ( $server_name eq $settings{'ircserver'} ) {
$kernel->post( $sender => 'connect' => { server=>$settings{'ircserver'}, port=>$settings{'ircport'}, } );
}
elsif ( $server_name eq $settings{'rcserver'} ) {
$kernel->post( $sender => 'connect' => { server=>$settings{'rcserver'}, port=>$settings{'ircport'}, } );
}
}
sub query {
my $query=shift;
if ( $query !~ m/^select/i ) {
my $status=$mysql->do($query);
return $status;
}
else {
my $query_handle=$mysql->prepare($query);
$query_handle->execute;
my $results=$query_handle->fetchall_arrayref( {} );
if ( $query_handle->rows > 0 ) {
return $results;
}
else {
return undef;
}
}
}
sub build_output {
my ( $kernel, $pagename, $diffurl, $size, $lang, $username, $whitelisted, $links_pre ) = @_;
my $message="\x034[[$lang:$pagename]]\x03 \x033$diffurl\x03 \x0312[[$lang:User:$username]]\x03 ";
my @links = split( /\s/, $links_pre );
my %links_hash;
foreach (@links) {
$links_hash{$_}='';
}
my $query_handle;
my $blacklistrule;
my $rule;
my $blacklisted;
unless ($settings{'spambotfeeder'}) {
$query_handle=$mysql->prepare("SELECT rule FROM $settings{'mysqltableprefix'}whitelist");
$query_handle->execute;
while (my $rule=$query_handle->fetchrow_array) {
foreach my $link (@links) {
if($link=~m/$rule/) {
$links_hash{$link}.="\x039(WL: $rule)\x03 ";
$whitelinks++
}
}
undef $rule;
}
$query_handle=$mysql->prepare("SELECT rule FROM $settings{'mysqltableprefix'}redlist");
$query_handle->execute;
while (my $rule=$query_handle->fetchrow_array) {
foreach my $link (@links) {
if($link=~m/$rule/) {
$links_hash{$link}.="\x034(RL: $rule)\x03 ";
$redlinks++;
}
}
undef $rule;
}
}
if ($settings{source} eq "SQL") {
$query_handle=$mysql->prepare("SELECT rule FROM $settings{'mysqltableprefix'}blacklist");
$query_handle->execute;
my $blacklisted=0;
while (my $rule=$query_handle->fetchrow_array) {
foreach my $link (@links) {
if($link=~m/$rule/i) {
unless ($whitelisted) {
&generate_alert( $pagename, $diffurl, $size, $lang, $username, $rule, $kernel ) unless $blacklisted;
}
$links_hash{$link}.="\x035(BL: $rule)\x03 ";
$blacklisted=1;
$blacklinks++;
}
}
undef $rule
}
} elsif ($settings{source} eq "Wiki") {
foreach $blacklistrule (@wikiblacklist) {
foreach my $link (@links) {
my $garbage;
$blacklistrule .= "#";
($blacklistrule,$garbage) = split(/#/,$blacklistrule);
$blacklistrule .= " ";
($blacklistrule,$garbage) = split(/\s/,$blacklistrule);
if($link=~m/$blacklistrule/i) {
unless ($whitelisted) {
&generate_alert( $pagename, $diffurl, $size, $lang, $username, $blacklistrule, $kernel ) unless $blacklisted;
}
$links_hash{$link}.="\x035(BL: $blacklistrule)\x03 ";
$blacklisted=1;
$blacklinks++;
}
}
undef $rule;
}
} else {
$kernel->post($settings{'ircserver'}=>privmsg=>$settings{'ircreportchannel'}=>"Incorrect setting for $settings{source}");
}
my $links = "";
foreach my $link (keys %links_hash) {
if ($settings{'showwhitelistedlinks'}) {
$links.="$link " . $links_hash{$link};
} else {
unless ($links_hash{$link} =~ m/WL:/) {
$links.="$link " . $links_hash{$link};
}
}
}
if (length($links)>0) {
$message .= $links;
} else {
$message = "";
}
return $message;
}
sub generate_alert {
my ( $pagename, $diffurl, $size, $lang, $username, $rule, $kernel ) = @_;
my $message="diff=<$diffurl> user=<$username> title=<$pagename> size=<$size> rule=<$rule>";
$kernel->post( $settings{'ircserver'} => privmsg => $settings{'ircbotchannel'} => $message );
}
sub resolve {
my $link = shift;
my $ip_address = inet_aton( $link );
if( length( $ip_address ) != 4 ) {
print "$link didn't resolve properly, bailing out\n";
return 0;
}
$ip_address = inet_ntoa( $ip_address );
print "Resolved $link -> $ip_address\n";
return $ip_address;
}

