User:Chris G Bot/Source

From Simple English Wikipedia, the free encyclopedia
<?php
/* antivandalbot.php - a basic php bot to help controll vandals on media wiki wiki's
   Copyright (C) 2008  Chris Grant - http://en.wikipedia.org/wiki/User:Chris_G

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    
   Developers (add your self here if you worked on the code):
	Cobi  - [[User:Cobi]]    - Wrote wikibot.classes.php and some of the code used
	Chris - [[User:Chris_G]] - Wrote up the rest of the code
*/

include("wikibot.classes.php"); //Use Cobi's classes - see [[User:Cobi]] and [[User:ClueBot/Source]]
include("ircbot.php"); //My Irc bot framework
include("nickpass.php"); //Contains Nicksev Pass
include("badwords.php"); //The bad words list

//Framework Config
$config = array(
	'server' => 'irc.freenode.net',
 	'port' => 6667,
 	'nick' => 'AntiVandalBot',
	'name' => 'AntiVandalBot',
); 
$irc = new IRCBot($config);

$irc->login($config);
$irc->msg('NickServ', "identify $nickpass");
$irc->join_channel('##Chris_G');

//Setup the classes
$h 	= new http;
$wpapi  = new wikipediaapi;
$wpq    = new wikipediaquery;
$wpi    = new wikipediaindex;

//Setup the url's
$url = 'http://simple.wikipedia.org/w/';
$wpi->indexurl = $url.'index.php';
$wpapi->apiurl = $url.'api.php';
$wpq->queryurl = $url.'query.php';

//All the login stuff
$user = 'Chris_G_Bot';
include('password.php');
$wpapi->login($user,$pass);

//Watch the rc feed
while (1) {
	$feedhost = 'irc.wikimedia.org';
	$feedport = 6667;
	$feedchannel = '#simple.wikipedia';
	
	$feed = fsockopen($feedhost,$feedport);

	if (!$feed) {
		sleep(10);
 		$feed = fsockopen($feedhost,$feedport);
 		if (!$feed) die($feederrstr.' ('.$feederrno.')');
	}

	fwrite($feed,'USER '.$user.' "1" "1" :ClueBot Wikipedia Bot.'."\n");
	fwrite($feed,'NICK '.$user."\n");
	while (true) {
	while (!feof($feed)) {
		$rawline = fgets($feed,1024);
		$line = str_replace(array("\n","\r","\002"),'',$rawline);
		$line = preg_replace('/\003(\d\d?(,\d\d?)?)?/','',$line);
                      echo 'FEED: '.$line."\n";
#		if (!$line) { fclose($feed); break; }
		$linea= explode(' ',$line,4);

		if (strtolower($linea[0]) == 'ping') {
			fwrite($feed,'PONG '.$linea[1]."\n");
		} elseif (($linea[1] == '376') or ($linea[1] == '422')) {
			fwrite($feed,'JOIN '.$feedchannel."\n");
		} elseif ((strtolower($linea[1]) == 'privmsg') and (strtolower($linea[2]) == strtolower($feedchannel))) {
			$message = substr($linea[3],1);
  			if (preg_match('/^\[\[((Talk|User|Wikipedia|Image|MediaWiki|Template|Help|Category|Portal|Special)(( |_)talk)?:)?([^\x5d]*)\]\] (\S*) (http:\/\/simple\.wikipedia\.org\/w\/index\.php\?title=[^&]*&diff=(\d*)&oldid=(\d*)|http:\/\/en\.wikipedia\.org\/wiki\/\S+)? \* ([^*]*) \* (\(([^)]*)\))? (.*)$/S',$message,$m)) {
				$change['namespace'] = $m[1];
				$change['title'] = $m[5];
				$change['flags'] = $m[6];
				$change['url'] = $m[7];
				$change['revid'] = $m[8];
				$change['old_revid'] = $m[9];
				$change['user'] = $m[10];
				$change['length'] = $m[12];
				$change['comment'] = $m[13];
				echo $change['namespace']." ".$change['title']." ".$change['revid']." ".$change['old_revid']."\n";
				$count = $wpq->contribcount($change['user']);
				if ($count < 50 and $change['namespace'] == '' or $count < 50 and $change['namespace'] == 'User:' and $change['user'] != $change['title']) {
					$change['title'] = $change['namespace'].$change['title'];
					$old = $wpq->getpage($change['title'],$change['old_revid']);
					$new = $wpq->getpage($change['title'],$change['revid']); 
					$score = score($obscenelist,$old,$new);
					$msg = 'Edit on: [['.$change['title'].']] changed by '.$change['user'].' score '.$score;
					$irc->msg('##Chris_G', $msg);
					if ($score >= 5) {
						$return = revert($change['user'],$change['title']);
						if ($return) {
							warn($change['user'],$change['title']);
						}
						$msg = 'Chris_G: Possible vandalism: [['.$change['title'].']] changed by '.$change['user'].' score '.$score.".";
						$irc->msg('##Chris_G', $msg);
						echo "$msg\n";
					} 
				}
			}
		}
	}
	usleep(500);
	}
}

function revert($user,$page) {
	global $wpapi, $wpq, $wpi;
	$x = file_get_contents($wpapi->apiurl.'?action=query&prop=revisions&titles='.urlencode($page).'&rvlimit=500&rvprop=user|ids&format=php');
	$hist = unserialize($x);
	foreach ($hist['query']['pages'][$wpq->getpageid($page)]['revisions'] as $x) {
		if ($user != $x['user']) {
			$id = $x['revid'];
			$olduser = $x['user'];
			break;
		}
	}
	$content = $wpq->getpage($page,$id);
	if ($content == $wpq->getpage($page)) {
		return false;
	}
	$summary = "Reverting possible vandalism by [[Special:Contributions/$user|$user]] to last version by $olduser (BOT)";
	$wpi->forcepost($page,$content,$summary,'user',false,null,null,null,false);
	return true;
}

function warn($user,$title) {
	global $h, $wpapi, $wpq, $wpi;
	$warning = 0;
	$tpcontent = $wpq->getpage('User talk:'.$user);
	if (preg_match_all('/<!-- Template:(uw-[a-z]*(\d)(im)?|Blatantvandal \(serious warning\)) -->.*(\d{2}):(\d{2}), (\d+) ([a-zA-Z]+) (\d{4}) \(UTC\)/iU',
		$tpcontent,
		$match,PREG_SET_ORDER)
	) {
	foreach ($match as $m) {
		echo $m[1];
		$month = array('January' => 1, 'February' => 2, 'March' => 3, 
				'April' => 4, 'May' => 5, 'June' => 6, 'July' => 7, 
				'August' => 8, 'September' => 9, 'October' => 10, 
				'November' => 11, 'December' => 12
			);
		if ($m[1] == 'Blatantvandal (serious warning)') $m[2] = 4;
			if ((time() - gmmktime($m[4],$m[5],0,$month[$m[7]],$m[6],$m[8])) <= (2*24*60*60)) {
				if ($m[2] > $warning) { $warning = $m[2]; }
		}
	}
	}
	$warning++;
	if ($warning > 4) {
		//report to aiv
		$page = "Wikipedia:Vandalism in progress/Bot";
		$content = $wpq->getpage($page);
		if (preg_match('/^[0-9.]+$/',$user)) {
			if (!preg_match("/\{\{ipvandal\|$user\}\}/i",$content)) {
				$data = "{{ipvandal|$user}} has been vandalising [[$title]] --~~~~\n".$content;
			}
		}
		else {
			if (!preg_match("/\{\{vandal\|$user\}\}/i",$content)) {
				$data = "{{vandal|$user}} has been vandalising [[$title]] --~~~~\n".$content;
			}
		}
		if ($data != $content) {
			$summary = "Reporting [[Special:Contributions/$user|$user]] (BOT)";
			$wpi->forcepost($page,$data,$summary);
		}
	}
	else {
		if (empty($tpcontent)) {
			$data = "{{subst:User:Chris G/Uw-vandalism{$warning}|$title}} --~~~~";
		}
		else {
			$data = $tpcontent . "\n\n{{subst:User:Chris G/Uw-vandalism{$warning}|$title}} --~~~~";
		}
		$summary = "Adding level $warning warning about possible vandalism on [[$title]] (BOT)";
		$wpi->forcepost('User talk:'.$user,$data,$summary);
	}
}  

function score ($list,$old,$new) {
	$ret = 0;
	foreach ($list as $reg => $score) {
		if (preg_match($reg,$new) and !preg_match($reg,$old)) {
			$ret += $score;
		}
	}
	return $ret;
}
?>