r66060 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r66059‎ | r66060 | r66061 >
Date:11:21, 8 May 2010
Author:tisane
Status:deferred
Tags:
Comment:
Add IRC bot, PHP version of FileReader, config file, wikibot classes which are slight modification of ClueBot source and require URL change to be operational on your wiki
Modified paths:
  • /trunk/extensions/RPED/RPED.config.php (added) (history)
  • /trunk/extensions/RPED/RPEDFileReader.php (added) (history)
  • /trunk/extensions/RPED/RPEDIRCBot.php (added) (history)
  • /trunk/extensions/RPED/wikibot.classes.php (added) (history)

Diff [purge]

Index: trunk/extensions/RPED/RPEDFileReader.php
@@ -0,0 +1,65 @@
 2+<?php
 3+# RPEDFileReader.php by Tisane, http://www.mediawiki.org/wiki/User:Tisane
 4+#
 5+# This script is free software that is available under the terms of the Creative Commons
 6+# Attribution-ShareAlike 3.0 license and the current version of the GNU General Public License.
 7+#
 8+# The purpose of this script is to read a text file (specifically, the list of page titles from
 9+# Wikipedia's data dump) and add each page title to a database table.
 10+
 11+include 'wikibot.classes.php'; /* The wikipedia classes. */
 12+include 'RPED.config.php'; /* This file is very simple, but it contains sensitive information, we just define $user, $ircserver, $ircport, $ircchannel, $pass, $owner, and $status. */
 13+
 14+$wpapi = new wikipediaapi;
 15+$wpq = new wikipediaquery;
 16+$wpi = new wikipediaindex;
 17+if ($wpapi->login($user,$pass)!='true'){
 18+ die();
 19+}
 20+
 21+$searching=false;
 22+
 23+if (isset($argv[1]) && $argv[1]!=''){
 24+ $searching=true;
 25+}
 26+
 27+$handle = @fopen("enwiki-20100312-all-titles-in-ns0", "r");
 28+$lineNumber=0;
 29+$line="";
 30+
 31+if ($handle) {
 32+ # Launch daemon!
 33+ $pid = pcntl_fork(); // fork
 34+ if ($pid < 0)
 35+ exit;
 36+ else if ($pid) // parent
 37+ exit;
 38+ else { // child
 39+
 40+ $sid = posix_setsid();
 41+
 42+ if ($sid < 0)
 43+ exit;
 44+
 45+ while (!feof($handle)) {
 46+ $buffer = fgets($handle, 4096);
 47+ $buffer=str_replace("\n","",$buffer);
 48+ if ($searching==true){
 49+ if ($buffer==$argv[1]){
 50+ $searching=false;
 51+ }
 52+ } else {
 53+ $buffer=urlencode ( $buffer );
 54+ if ($line!=""){
 55+ $line.="|";
 56+ }
 57+ if (strlen($line)+strlen($buffer)>200){
 58+ $wpapi->rpedInsert($line);
 59+ $line="";
 60+ }
 61+ $line.=$buffer;
 62+ }
 63+ }
 64+ fclose($handle);
 65+ }
 66+}
\ No newline at end of file
Property changes on: trunk/extensions/RPED/RPEDFileReader.php
___________________________________________________________________
Added: svn:eol-style
167 + native
Index: trunk/extensions/RPED/RPEDIRCBot.php
@@ -0,0 +1,85 @@
 2+<?php
 3+# RPEDIRC.php by Tisane, http://www.mediawiki.org/wiki/User:Tisane
 4+#
 5+# This script is free software that is available under the terms of the Creative Commons
 6+# Attribution 3.0 license and the current version of the GNU General Public License.
 7+#
 8+# The purpose of this script is to get the titles of all new, deleted and restored
 9+# pages from #en.wikipedia and add/delete them from the rped_table.
 10+
 11+ini_set('include_path', ini_get('include_path').':..');
 12+
 13+// Include Class
 14+error_reporting(E_ALL);
 15+
 16+include 'wikibot.classes.php'; /* The wikipedia classes. */
 17+include 'RPED.config.php'; /* This file is very simple, but it contains sensitive information, we just define $user, $ircserver, $ircport, $ircchannel, $pass, $owner, and $status. */
 18+
 19+$wpapi = new wikipediaapi;
 20+$wpq = new wikipediaquery;
 21+$wpi = new wikipediaindex;
 22+if ($wpapi->login($user,$pass)!='true'){
 23+ die();
 24+}
 25+
 26+$readbuffer="";
 27+$startSep="[[";
 28+$endSep="]]";
 29+
 30+
 31+// open a socket connection to the IRC server
 32+$fp = fsockopen($host, $port, $erno, $errstr, 30);
 33+
 34+// print the error if there is no connection
 35+if (!$fp) {
 36+ echo $errstr." (".$errno.")<br />\n";
 37+} else {
 38+ // write data through the socket to join the channel
 39+ fwrite($fp, "NICK ".$nick."\r\n");
 40+ fwrite($fp, "USER ".$ident." ".$host." bla :".$realname."\r\n");
 41+ fwrite($fp, "JOIN :".$chan."\r\n");
 42+
 43+ # Launch daemon!
 44+ $pid = pcntl_fork(); // fork
 45+ if ($pid < 0)
 46+ exit;
 47+ else if ($pid) // parent
 48+ exit;
 49+ else { // child
 50+
 51+ $sid = posix_setsid();
 52+
 53+ if ($sid < 0)
 54+ exit;
 55+
 56+ while (!feof($fp)) {
 57+
 58+ $line = fgets($fp, 512);
 59+ $pingLine = explode(' ', $line);
 60+ if(strtolower($pingLine[0]) == 'ping'){
 61+ $response="PONG ".$pingLine[1]."\n";
 62+ fwrite($fp, "PONG ".$response);
 63+ }
 64+ usleep(10);
 65+ $startPos=strpos($line,$startSep);
 66+ $endPos=strpos($line,$endSep);
 67+ $subLine=substr($line,$startPos+5,$endPos-$startPos-8);
 68+ if ($subLine=="Special:Log/delete"){
 69+ $delstartPos=strpos($line,$startSep,$endPos);
 70+ $delendPos=strpos($line,$endSep,$endPos+1);
 71+ $delLine=substr($line,$delstartPos+5,$delendPos-$delstartPos-8);
 72+ $action=substr($line,$delstartPos-9,7);
 73+ if ($action=="deleted"){
 74+ $wpapi->rpedDelete($delLine);
 75+ } else {
 76+ $wpapi->rpedInsert($delLine);
 77+ }
 78+ }
 79+ if (substr($line,$endPos+5,1)=="N" || substr($line,$endPos+6,1)=="N"){
 80+ $wpapi->rpedInsert($subLine);
 81+ }
 82+ }
 83+
 84+ fclose($fp);
 85+ }
 86+}
\ No newline at end of file
Property changes on: trunk/extensions/RPED/RPEDIRCBot.php
___________________________________________________________________
Added: svn:eol-style
187 + native
Index: trunk/extensions/RPED/RPED.config.php
@@ -0,0 +1,16 @@
 2+<?php
 3+$user='WikiSysop'; // Your username on your local wiki (must have RPED rights)
 4+$ircserver='irc.mediawiki.org';
 5+$ircport='6667';
 6+$ircchannel='en.wikipedia';
 7+$pass='password'; // Your password on your local wiki
 8+$owner=$user;
 9+$status='';
 10+
 11+#RPECIRC variables
 12+$nick="YourNick"; // e.g. Awesome
 13+$ident="YourIdent"; // For IRC identification purposes; e.g. AwesomeBot
 14+$chan="#en.wikipedia";
 15+$realname = "Your Real Name";
 16+$port=6667;
 17+$host = "irc.wikimedia.org";
\ No newline at end of file
Property changes on: trunk/extensions/RPED/RPED.config.php
___________________________________________________________________
Added: svn:eol-style
118 + native
Index: trunk/extensions/RPED/wikibot.classes.php
@@ -0,0 +1,971 @@
 2+<?PHP
 3+ /**
 4+ * @author Cobi Carter
 5+ **/
 6+
 7+ /**
 8+ * This class is designed to provide a simplified interface to cURL which maintains cookies.
 9+ * @author Cobi
 10+ **/
 11+ class http {
 12+ private $ch;
 13+ private $uid;
 14+ public $postfollowredirs;
 15+ public $getfollowredirs;
 16+
 17+ /**
 18+ * Our constructor function. This just does basic cURL initialization.
 19+ * @return void
 20+ **/
 21+ function __construct () {
 22+ global $proxyhost, $proxyport;
 23+ $this->ch = curl_init();
 24+ $this->uid = dechex(rand(0,99999999));
 25+ curl_setopt($this->ch,CURLOPT_COOKIEJAR,'/tmp/cluewikibot.cookies.'.$this->uid.'.dat');
 26+ curl_setopt($this->ch,CURLOPT_COOKIEFILE,'/tmp/cluewikibot.cookies.'.$this->uid.'.dat');
 27+ curl_setopt($this->ch,CURLOPT_MAXCONNECTS,100);
 28+ curl_setopt($this->ch,CURLOPT_CLOSEPOLICY,CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
 29+ curl_setopt($this->ch,CURLOPT_USERAGENT,'ClueBot/1.1');
 30+ if (isset($proxyhost) and isset($proxyport) and ($proxyport != null) and ($proxyhost != null)) {
 31+ curl_setopt($this->ch,CURLOPT_PROXYTYPE,CURLPROXY_HTTP);
 32+ curl_setopt($this->ch,CURLOPT_PROXY,$proxyhost);
 33+ curl_setopt($this->ch,CURLOPT_PROXYPORT,$proxyport);
 34+ }
 35+ $this->postfollowredirs = 0;
 36+ $this->getfollowredirs = 1;
 37+ }
 38+
 39+ /**
 40+ * Post to a URL.
 41+ * @param $url The URL to post to.
 42+ * @param $data The post-data to post, should be an array of key => value pairs.
 43+ * @return Data retrieved from the POST request.
 44+ **/
 45+ function post ($url,$data) {
 46+ $time = microtime(1);
 47+ curl_setopt($this->ch,CURLOPT_URL,$url);
 48+ curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->postfollowredirs);
 49+ curl_setopt($this->ch,CURLOPT_MAXREDIRS,10);
 50+ curl_setopt($this->ch,CURLOPT_HEADER,0);
 51+ curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,1);
 52+ curl_setopt($this->ch,CURLOPT_TIMEOUT,30);
 53+ curl_setopt($this->ch,CURLOPT_CONNECTTIMEOUT,10);
 54+ curl_setopt($this->ch,CURLOPT_POST,1);
 55+ curl_setopt($this->ch,CURLOPT_POSTFIELDS, $data);
 56+ curl_setopt($this->ch,CURLOPT_HTTPHEADER, array('Expect:'));
 57+ $data = curl_exec($this->ch);
 58+ #global $logfd; if (!is_resource($logfd)) $logfd = fopen('php://stderr','w'); fwrite($logfd,'POST: '.$url.' ('.(microtime(1) - $time).' s) ('.strlen($data)." b)\n");
 59+ return $data;
 60+ }
 61+
 62+ /**
 63+ * Get a URL.
 64+ * @param $url The URL to get.
 65+ * @return Data retrieved from the GET request.
 66+ **/
 67+ function get ($url) {
 68+ $time = microtime(1);
 69+ curl_setopt($this->ch,CURLOPT_URL,$url);
 70+ curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->getfollowredirs);
 71+ curl_setopt($this->ch,CURLOPT_MAXREDIRS,10);
 72+ curl_setopt($this->ch,CURLOPT_HEADER,0);
 73+ curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,1);
 74+ curl_setopt($this->ch,CURLOPT_TIMEOUT,30);
 75+ curl_setopt($this->ch,CURLOPT_CONNECTTIMEOUT,10);
 76+ curl_setopt($this->ch,CURLOPT_HTTPGET,1);
 77+ $data = curl_exec($this->ch);
 78+ #$global $logfd; if (!is_resource($logfd)) $logfd = fopen('php://stderr','w'); fwrite($logfd,'GET: '.$url.' ('.(microtime(1) - $time).' s) ('.strlen($data)." b)\n");
 79+ return $data;
 80+ }
 81+
 82+ /**
 83+ * Our destructor. Cleans up cURL and unlinks temporary files.
 84+ **/
 85+ function __destruct () {
 86+ curl_close($this->ch);
 87+ @unlink('/tmp/cluewikibot.cookies.'.$this->uid.'.dat');
 88+ }
 89+ }
 90+
 91+ /**
 92+ * This class is a deprecated wrapper class which allows legacy code written for Wikipedia's query.php API to still work with wikipediaapi::.
 93+ **/
 94+ class wikipediaquery {
 95+ private $http;
 96+ private $api;
 97+ public $queryurl = 'http://rped.org/beta2/query.php'; //Obsolete, but kept for compatibility purposes.
 98+
 99+ /**
 100+ * This is our constructor.
 101+ * @return void
 102+ **/
 103+ function __construct () {
 104+ global $__wp__http;
 105+ if (!isset($__wp__http)) {
 106+ $__wp__http = new http;
 107+ }
 108+ $this->http = &$__wp__http;
 109+ $this->api = new wikipediaapi;
 110+ }
 111+
 112+ /**
 113+ * Reinitializes the queryurl.
 114+ * @private
 115+ * @return void
 116+ **/
 117+ private function checkurl() {
 118+ $this->api->apiurl = str_replace('query.php','api.php',$this->queryurl);
 119+ }
 120+
 121+ /**
 122+ * Gets the content of a page.
 123+ * @param $page The wikipedia page to fetch.
 124+ * @return The wikitext for the page.
 125+ **/
 126+ function getpage ($page) {
 127+ $this->checkurl();
 128+ $ret = $this->api->revisions($page,1,'older',true,null,true,false,false,false);
 129+ return $ret[0]['*'];
 130+ }
 131+
 132+ /**
 133+ * Gets the page id for a page.
 134+ * @param $page The wikipedia page to get the id for.
 135+ * @return The page id of the page.
 136+ **/
 137+ function getpageid ($page) {
 138+ $this->checkurl();
 139+ $ret = $this->api->revisions($page,1,'older',false,null,true,false,false,false);
 140+ return $ret['pageid'];
 141+ }
 142+
 143+ /**
 144+ * Gets the number of contributions a user has.
 145+ * @param $user The username for which to get the edit count.
 146+ * @return The number of contributions the user has.
 147+ **/
 148+ function contribcount ($user) {
 149+ $this->checkurl();
 150+ $ret = $this->api->users($user,1,null,true);
 151+ if ($ret !== false) return $ret[0]['editcount'];
 152+ return false;
 153+ }
 154+ }
 155+
 156+ /**
 157+ * This class is for interacting with Wikipedia's api.php API.
 158+ **/
 159+ class wikipediaapi {
 160+ private $http;
 161+ private $edittoken;
 162+ private $tokencache;
 163+ public $apiurl = 'http://rped.org/beta2/api.php';
 164+
 165+ /**
 166+ * This is our constructor.
 167+ * @return void
 168+ **/
 169+ function __construct () {
 170+ global $__wp__http;
 171+ if (!isset($__wp__http)) {
 172+ $__wp__http = new http;
 173+ }
 174+ $this->http = &$__wp__http;
 175+ }
 176+
 177+ function rpedInsert ($page){
 178+
 179+ $params = Array(
 180+ 'action' => 'rped',
 181+ 'format' => 'php',
 182+ 'insert' => $page,
 183+ );
 184+
 185+ $x = $this->http->post($this->apiurl,$params);
 186+ $x = unserialize($x);
 187+ #var_export($x);
 188+ return true;
 189+ }
 190+
 191+ function rpedDelete ($page){
 192+
 193+ $params = Array(
 194+ 'action' => 'rped',
 195+ 'format' => 'php',
 196+ 'delete' => $page,
 197+ );
 198+
 199+ $x = $this->http->post($this->apiurl,$params);
 200+ $x = unserialize($x);
 201+ #var_export($x);
 202+ return true;
 203+ }
 204+
 205+
 206+ /**
 207+ * This function takes a username and password and logs you into wikipedia.
 208+ * @param $user Username to login as.
 209+ * @param $pass Password that corrisponds to the username.
 210+ * @return void
 211+ **/
 212+ function login ($user,$pass) {
 213+ $x = unserialize($this->http->post($this->apiurl.'?action=login&format=php',array('lgname' => $user, 'lgpassword' => $pass)));
 214+ if($x['login']['result'] == 'Success')
 215+ return true;
 216+ if($x['login']['result'] == 'NeedToken') {
 217+ $x = unserialize($this->http->post($this->apiurl.'?action=login&format=php',array('lgname' => $user, 'lgpassword' => $pass, 'lgtoken' => $x['login']['token'])));
 218+ if($x['login']['result'] == 'Success')
 219+ return true;
 220+ }
 221+ return false;
 222+ }
 223+
 224+ /**
 225+ * This function returns the edit token.
 226+ * @return Edit token.
 227+ **/
 228+ function getedittoken () {
 229+ $tokens = $this->gettokens('Main Page');
 230+ if ($tokens['edittoken'] == '') $tokens = $this->gettokens('Main Page',true);
 231+ $this->edittoken = $tokens['edittoken'];
 232+ return $tokens['edittoken'];
 233+ }
 234+
 235+ /**
 236+ * This function returns the various tokens for a certain page.
 237+ * @param $title Page to get the tokens for.
 238+ * @param $flush Optional - internal use only. Flushes the token cache.
 239+ * @return An associative array of tokens for the page.
 240+ **/
 241+ function gettokens ($title,$flush = false) {
 242+ if (!is_array($this->tokencache)) $this->tokencache = array();
 243+ foreach ($this->tokencache as $t => $data) if (time() - $data['timestamp'] > 6*60*60) unset($this->tokencache[$t]);
 244+ if (isset($this->tokencache[$title]) && (!$flush)) {
 245+ return $this->tokencache[$title]['tokens'];
 246+ } else {
 247+ $tokens = array();
 248+ $x = $this->http->get($this->apiurl.'?action=query&format=php&prop=info&intoken=edit|delete|protect|move|block|unblock|email&titles='.urlencode($title));
 249+ $x = unserialize($x);
 250+ foreach ($x['query']['pages'] as $y) {
 251+ $tokens['edittoken'] = $y['edittoken'];
 252+ $tokens['deletetoken'] = $y['deletetoken'];
 253+ $tokens['protecttoken'] = $y['protecttoken'];
 254+ $tokens['movetoken'] = $y['movetoken'];
 255+ $tokens['blocktoken'] = $y['blocktoken'];
 256+ $tokens['unblocktoken'] = $y['unblocktoken'];
 257+ $tokens['emailtoken'] = $y['emailtoken'];
 258+ $this->tokencache[$title] = array(
 259+ 'timestamp' => time(),
 260+ 'tokens' => $tokens
 261+ );
 262+ return $tokens;
 263+ }
 264+ }
 265+ }
 266+
 267+ /**
 268+ * This function returns the recent changes for the wiki.
 269+ * @param $count The number of items to return. (Default 10)
 270+ * @param $namespace The namespace ID to filter items on. Null for no filtering. (Default null)
 271+ * @param $dir The direction to pull items. "older" or "newer". (Default 'older')
 272+ * @param $ts The timestamp to start at. Null for the beginning/end (depending on direction). (Default null)
 273+ * @return Associative array of recent changes metadata.
 274+ **/
 275+ function recentchanges ($count = 10,$namespace = null,$dir = 'older',$ts = null) {
 276+ $append = '';
 277+ if ($ts !== null) { $append .= '&rcstart='.urlencode($ts); }
 278+ $append .= '&rcdir='.urlencode($dir);
 279+ if ($namespace !== null) { $append .= '&rcnamespace='.urlencode($namespace); }
 280+ $x = $this->http->get($this->apiurl.'?action=query&list=recentchanges&rcprop=user|comment|flags|timestamp|title|ids|sizes&format=php&rclimit='.$count.$append);
 281+ $x = unserialize($x);
 282+ return $x['query']['recentchanges'];
 283+ }
 284+
 285+ /**
 286+ * This function returns search results from Wikipedia's internal search engine.
 287+ * @param $search The query string to search for.
 288+ * @param $limit The number of results to return. (Default 10)
 289+ * @param $offset The number to start at. (Default 0)
 290+ * @param $namespace The namespace ID to filter by. Null means no filtering. (Default 0)
 291+ * @param $what What to search, 'text' or 'title'. (Default 'text')
 292+ * @param $redirs Whether or not to list redirects. (Default false)
 293+ * @return Associative array of search result metadata.
 294+ **/
 295+ function search ($search,$limit = 10,$offset = 0,$namespace = 0,$what = 'text',$redirs = false) {
 296+ $append = '';
 297+ if ($limit != null) $append .= '&srlimit='.urlencode($limit);
 298+ if ($offset != null) $append .= '&sroffset='.urlencode($offset);
 299+ if ($namespace != null) $append .= '&srnamespace='.urlencode($namespace);
 300+ if ($what != null) $append .= '&srwhat='.urlencode($what);
 301+ if ($redirs == true) $append .= '&srredirects=1';
 302+ else $append .= '&srredirects=0';
 303+ $x = $this->http->get($this->apiurl.'?action=query&list=search&format=php&srsearch='.urlencode($search).$append);
 304+ $x = unserialize($x);
 305+ return $x['query']['search'];
 306+ }
 307+
 308+ /**
 309+ * Retrieve entries from the WikiLog.
 310+ * @param $user Username who caused the entry. Null means anyone. (Default null)
 311+ * @param $title Object to which the entry refers. Null means anything. (Default null)
 312+ * @param $limit Number of entries to return. (Default 50)
 313+ * @param $type Type of logs. Null means any type. (Default null)
 314+ * @param $start Date to start enumerating logs. Null means beginning/end depending on $dir. (Default null)
 315+ * @param $end Where to stop enumerating logs. Null means whenever limit is satisfied or there are no more logs. (Default null)
 316+ * @param $dir Direction to enumerate logs. "older" or "newer". (Default 'older')
 317+ * @return Associative array of logs metadata.
 318+ **/
 319+ function logs ($user = null,$title = null,$limit = 50,$type = null,$start = null,$end = null,$dir = 'older') {
 320+ $append = '';
 321+ if ($user != null) $append.= '&leuser='.urlencode($user);
 322+ if ($title != null) $append.= '&letitle='.urlencode($title);
 323+ if ($limit != null) $append.= '&lelimit='.urlencode($limit);
 324+ if ($type != null) $append.= '&letype='.urlencode($type);
 325+ if ($start != null) $append.= '&lestart='.urlencode($start);
 326+ if ($end != null) $append.= '&leend='.urlencode($end);
 327+ if ($dir != null) $append.= '&ledir='.urlencode($dir);
 328+ $x = $this->http->get($this->apiurl.'?action=query&format=php&list=logevents&leprop=ids|title|type|user|timestamp|comment|details'.$append);
 329+ $x = unserialize($x);
 330+ return $x['query']['logevents'];
 331+ }
 332+
 333+ /**
 334+ * Retrieves metadata about a user's contributions.
 335+ * @param $user Username whose contributions we want to retrieve.
 336+ * @param $count Number of entries to return. (Default 50)
 337+ * @param[in,out] $continue Where to continue enumerating if part of a larger, split request. This is filled with the next logical continuation value. (Default null)
 338+ * @param $dir Which direction to enumerate from, "older" or "newer". (Default 'older')
 339+ * @return Associative array of contributions metadata.
 340+ **/
 341+ function usercontribs ($user,$count = 50,&$continue = null,$dir = 'older') {
 342+ if ($continue != null) {
 343+ $append = '&ucstart='.urlencode($continue);
 344+ } else {
 345+ $append = '';
 346+ }
 347+ $x = $this->http->get($this->apiurl.'?action=query&format=php&list=usercontribs&ucuser='.urlencode($user).'&uclimit='.urlencode($count).'&ucdir='.urlencode($dir).$append);
 348+ $x = unserialize($x);
 349+ $continue = $x['query-continue']['usercontribs']['ucstart'];
 350+ return $x['query']['usercontribs'];
 351+ }
 352+
 353+ /**
 354+ * Returns revision data (meta and/or actual).
 355+ * @param $page Page for which to return revision data for.
 356+ * @param $count Number of revisions to return. (Default 1)
 357+ * @param $dir Direction to start enumerating multiple revisions from, "older" or "newer". (Default 'older')
 358+ * @param $content Whether to return actual revision content, true or false. (Default false)
 359+ * @param $revid Revision ID to start at. (Default null)
 360+ * @param $wait Whether or not to wait a few seconds for the specific revision to become available. (Default true)
 361+ * @param $getrbtok Whether or not to retrieve a rollback token for the revision. (Default false)
 362+ * @param $dieonerror Whether or not to kill the process with an error if an error occurs. (Default false)
 363+ * @param $redirects Whether or not to follow redirects. (Default false)
 364+ * @return Associative array of revision data.
 365+ **/
 366+ function revisions ($page,$count = 1,$dir = 'older',$content = false,$revid = null,$wait = true,$getrbtok = false,$dieonerror = true,$redirects = false) {
 367+ $x = $this->http->get($this->apiurl.'?action=query&prop=revisions&titles='.urlencode($page).'&rvlimit='.urlencode($count).'&rvprop=timestamp|ids|user|comment'.(($content)?'|content':'').'&format=php&meta=userinfo&rvdir='.urlencode($dir).(($revid !== null)?'&rvstartid='.urlencode($revid):'').(($getrbtok == true)?'&rvtoken=rollback':'').(($redirects == true)?'&redirects':''));
 368+ $x = unserialize($x);
 369+ if ($revid !== null) {
 370+ $found = false;
 371+ if (!isset($x['query']['pages']) or !is_array($x['query']['pages'])) {
 372+ if ($dieonerror == true) die('No such page.'."\n");
 373+ else return false;
 374+ }
 375+ foreach ($x['query']['pages'] as $data) {
 376+ if (!isset($data['revisions']) or !is_array($data['revisions'])) {
 377+ if ($dieonerror == true) die('No such page.'."\n");
 378+ else return false;
 379+ }
 380+ foreach ($data['revisions'] as $data2) if ($data2['revid'] == $revid) $found = true;
 381+ unset($data,$data2);
 382+ break;
 383+ }
 384+
 385+ if ($found == false) {
 386+ if ($wait == true) {
 387+ sleep(1);
 388+ return $this->revisions($page,$count,$dir,$content,$revid,false,$getrbtok,$dieonerror);
 389+ } else {
 390+ if ($dieonerror == true) die('Revision error.'."\n");
 391+ }
 392+ }
 393+ }
 394+ foreach ($x['query']['pages'] as $key => $data) {
 395+ $data['revisions']['ns'] = $data['ns'];
 396+ $data['revisions']['title'] = $data['title'];
 397+ $data['revisions']['currentuser'] = $x['query']['userinfo']['name'];
 398+// $data['revisions']['currentuser'] = $x['query']['userinfo']['currentuser']['name'];
 399+ $data['revisions']['continue'] = $x['query-continue']['revisions']['rvstartid'];
 400+ $data['revisions']['pageid'] = $key;
 401+ return $data['revisions'];
 402+ }
 403+ }
 404+
 405+ /**
 406+ * Enumerates user metadata.
 407+ * @param $start The username to start enumerating from. Null means from the beginning. (Default null)
 408+ * @param $limit The number of users to enumerate. (Default 1)
 409+ * @param $group The usergroup to filter by. Null means no filtering. (Default null)
 410+ * @param $requirestart Whether or not to require that $start be a valid username. (Default false)
 411+ * @param[out] $continue This is filled with the name to continue from next query. (Default null)
 412+ * @return Associative array of user metadata.
 413+ **/
 414+ function users ($start = null,$limit = 1,$group = null,$requirestart = false,&$continue = null) {
 415+ $append = '';
 416+ if ($start != null) $append .= '&aufrom='.urlencode($start);
 417+ if ($group != null) $append .= '&augroup='.urlencode($group);
 418+ $x = $this->http->get($this->apiurl.'?action=query&list=allusers&format=php&auprop=blockinfo|editcount|registration|groups&aulimit='.urlencode($limit).$append);
 419+ $x = unserialize($x);
 420+ $continue = $x['query-continue']['allusers']['aufrom'];
 421+ if (($requirestart == true) and ($x['query']['allusers'][0]['name'] != $start)) return false;
 422+ return $x['query']['allusers'];
 423+ }
 424+
 425+ /**
 426+ * Get members of a category.
 427+ * @param $category Category to enumerate from.
 428+ * @param $count Number of members to enumerate. (Default 500)
 429+ * @param[in,out] $continue Where to continue enumerating from. This is automatically filled in when run. (Default null)
 430+ * @return Associative array of category member metadata.
 431+ **/
 432+ function categorymembers ($category,$count = 500,&$continue = null) {
 433+ if ($continue != null) {
 434+ $append = '&cmcontinue='.urlencode($continue);
 435+ } else {
 436+ $append = '';
 437+ }
 438+ $category = 'Category:'.str_ireplace('category:','',$category);
 439+ $x = $this->http->get($this->apiurl.'?action=query&list=categorymembers&cmtitle='.urlencode($category).'&format=php&cmlimit='.$count.$append);
 440+ $x = unserialize($x);
 441+ $continue = $x['query-continue']['categorymembers']['cmcontinue'];
 442+ return $x['query']['categorymembers'];
 443+ }
 444+
 445+ /**
 446+ * Enumerate all categories.
 447+ * @param[in,out] $start Where to start enumerating. This is updated automatically with the value to continue from. (Default null)
 448+ * @param $limit Number of categories to enumerate. (Default 50)
 449+ * @param $dir Direction to enumerate in. 'ascending' or 'descending'. (Default 'ascending')
 450+ * @param $prefix Only enumerate categories with this prefix. (Default null)
 451+ * @return Associative array of category list metadata.
 452+ **/
 453+ function listcategories (&$start = null,$limit = 50,$dir = 'ascending',$prefix = null) {
 454+ $append = '';
 455+ if ($start != null) $append .= '&acfrom='.urlencode($start);
 456+ if ($limit != null) $append .= '&aclimit='.urlencode($limit);
 457+ if ($dir != null) $append .= '&acdir='.urlencode($dir);
 458+ if ($prefix != null) $append .= '&acprefix='.urlencode($prefix);
 459+
 460+ $x = $this->http->get($this->apiurl.'?action=query&list=allcategories&acprop=size&format=php'.$append);
 461+ $x = unserialize($x);
 462+
 463+ $start = $x['query-continue']['allcategories']['acfrom'];
 464+
 465+ return $x['query']['allcategories'];
 466+ }
 467+
 468+ /**
 469+ * Enumerate all backlinks to a page.
 470+ * @param $page Page to search for backlinks to.
 471+ * @param $count Number of backlinks to list. (Default 500)
 472+ * @param[in,out] $continue Where to start enumerating from. This is automatically filled in. (Default null)
 473+ * @param $filter Whether or not to include redirects. Acceptible values are 'all', 'redirects', and 'nonredirects'. (Default null)
 474+ * @return Associative array of backlink metadata.
 475+ **/
 476+ function backlinks ($page,$count = 500,&$continue = null,$filter = null) {
 477+ if ($continue != null) {
 478+ $append = '&blcontinue='.urlencode($continue);
 479+ } else {
 480+ $append = '';
 481+ }
 482+ if ($filter != null) {
 483+ $append .= '&blfilterredir='.urlencode($filter);
 484+ }
 485+
 486+ $x = $this->http->get($this->apiurl.'?action=query&list=backlinks&bltitle='.urlencode($page).'&format=php&bllimit='.$count.$append);
 487+ $x = unserialize($x);
 488+ $continue = $x['query-continue']['backlinks']['blcontinue'];
 489+ return $x['query']['backlinks'];
 490+ }
 491+
 492+ /**
 493+ * Gets a list of transcludes embedded in a page.
 494+ * @param $page Page to look for transcludes in.
 495+ * @param $count Number of transcludes to list. (Default 500)
 496+ * @param[in,out] $continue Where to start enumerating from. This is automatically filled in. (Default null)
 497+ * @return Associative array of transclude metadata.
 498+ **/
 499+ function embeddedin ($page,$count = 500,&$continue = null) {
 500+ if ($continue != null) {
 501+ $append = '&eicontinue='.urlencode($continue);
 502+ } else {
 503+ $append = '';
 504+ }
 505+ $x = $this->http->get($this->apiurl.'?action=query&list=embeddedin&eititle='.urlencode($page).'&format=php&eilimit='.$count.$append);
 506+ $x = unserialize($x);
 507+ $continue = $x['query-continue']['embeddedin']['eicontinue'];
 508+ return $x['query']['embeddedin'];
 509+ }
 510+
 511+ /**
 512+ * Gets a list of pages with a common prefix.
 513+ * @param $prefix Common prefix to search for.
 514+ * @param $namespace Numeric namespace to filter on. (Default 0)
 515+ * @param $count Number of pages to list. (Default 500)
 516+ * @param[in,out] $continue Where to start enumerating from. This is automatically filled in. (Default null)
 517+ * @return Associative array of page metadata.
 518+ **/
 519+ function listprefix ($prefix,$namespace = 0,$count = 500,&$continue = null) {
 520+ $append = '&apnamespace='.urlencode($namespace);
 521+ if ($continue != null) {
 522+ $append .= '&apfrom='.urlencode($continue);
 523+ }
 524+ $x = $this->http->get($this->apiurl.'?action=query&list=allpages&apprefix='.urlencode($prefix).'&format=php&aplimit='.$count.$append);
 525+ $x = unserialize($x);
 526+ $continue = $x['query-continue']['allpages']['apfrom'];
 527+ return $x['query']['allpages'];
 528+ }
 529+
 530+ /**
 531+ * Edits a page.
 532+ * @param $page Page name to edit.
 533+ * @param $data Data to post to page.
 534+ * @param $summary Edit summary to use.
 535+ * @param $minor Whether or not to mark edit as minor. (Default false)
 536+ * @param $bot Whether or not to mark edit as a bot edit. (Default true)
 537+ * @param $wpStarttime Time in MW TS format of beginning of edit. (Default now)
 538+ * @param $wpEdittime Time in MW TS format of last edit to that page. (Default correct)
 539+ * @return boolean True on success, false on failure.
 540+ **/
 541+ function edit ($page,$data,$summary = '',$minor = false,$bot = true,$wpStarttime = null,$wpEdittime = null,$checkrun = true) {
 542+ global $run, $user;
 543+
 544+ $wpq = new wikipediaquery; $wpq->queryurl = str_replace('api.php','query.php',$this->apiurl);
 545+
 546+ if ($checkrun == true)
 547+ if (!preg_match('/(yes|enable|true)/iS',((isset($run))?$run:$wpq->getpage('User:'.$user.'/Run'))))
 548+ return false; /* Check /Run page */
 549+
 550+ $params = Array(
 551+ 'action' => 'edit',
 552+ 'format' => 'php',
 553+ 'assert' => 'bot',
 554+ 'title' => $page,
 555+ 'text' => $data,
 556+ 'token' => $this->getedittoken(),
 557+ 'summary' => $summary,
 558+ ($minor?'minor':'notminor') => '1',
 559+ ($bot?'bot':'notbot') => '1'
 560+ );
 561+
 562+ if ($wpStarttime !== null) $params['starttimestamp'] = $wpStarttime;
 563+ if ($wpEdittime !== null) $params['basetimestamp'] = $wpEdittime;
 564+
 565+ $x = $this->http->post($this->apiurl,$params);
 566+ $x = unserialize($x);
 567+ var_export($x);
 568+ if ($x['edit']['result'] == 'Success') return true;
 569+ else return false;
 570+ }
 571+
 572+ /**
 573+ * Moves a page.
 574+ * @param $old Name of page to move.
 575+ * @param $new New page title.
 576+ * @param $reason Move summary to use.
 577+ * @return void
 578+ **/
 579+ function move ($old,$new,$reason) {
 580+ $tokens = $this->gettokens($old);
 581+ $params = array(
 582+ 'action' => 'move',
 583+ 'format' => 'php',
 584+ 'from' => $old,
 585+ 'to' => $new,
 586+ 'token' => $tokens['movetoken'],
 587+ 'reason' => $reason
 588+ );
 589+
 590+ $x = $this->http->post($this->apiurl,$params);
 591+ $x = unserialize($x);
 592+ var_export($x);
 593+ }
 594+
 595+ /**
 596+ * Rollback an edit.
 597+ * @param $title Title of page to rollback.
 598+ * @param $user Username of last edit to the page to rollback.
 599+ * @param $reason Edit summary to use for rollback.
 600+ * @param $token Rollback token. If not given, it will be fetched. (Default null)
 601+ * @return void
 602+ **/
 603+ function rollback ($title,$user,$reason,$token = null) {
 604+ if (($token == null) or ($token == '')) {
 605+ $token = $this->revisions($title,1,'older',false,null,true,true);
 606+ print_r($token);
 607+ if ($token[0]['user'] == $user) {
 608+ $token = $token[0]['rollbacktoken'];
 609+ } else {
 610+ return false;
 611+ }
 612+ }
 613+ $params = array(
 614+ 'action' => 'rollback',
 615+ 'format' => 'php',
 616+ 'title' => $title,
 617+ 'user' => $user,
 618+ 'summary' => $reason,
 619+ 'token' => $token,
 620+ 'markbot' => 0
 621+ );
 622+
 623+ echo 'Posting to API: ';
 624+ var_export($params);
 625+
 626+ $x = $this->http->post($this->apiurl,$params);
 627+ $x = unserialize($x);
 628+ var_export($x);
 629+ return (isset($x['rollback']['summary'])?true:false);
 630+ }
 631+ }
 632+
 633+ /**
 634+ * This class is for interacting with Wikipedia's browser interface, index.php.
 635+ * Many of these functions are deprecated.
 636+ **/
 637+ class wikipediaindex {
 638+ private $http;
 639+ public $indexurl = 'http://rped.org/beta2/index.php';
 640+ private $postinterval = 0;
 641+ private $lastpost;
 642+ private $edittoken;
 643+
 644+ /**
 645+ * This is our constructor.
 646+ * @return void
 647+ **/
 648+ function __construct () {
 649+ global $__wp__http;
 650+ if (!isset($__wp__http)) {
 651+ $__wp__http = new http;
 652+ }
 653+ $this->http = &$__wp__http;
 654+ }
 655+
 656+ /**
 657+ * Post data to a page, nicely.
 658+ * @param $page Page title.
 659+ * @param $data Data to post to page.
 660+ * @param $summery Edit summary. (Default '')
 661+ * @param $minor Whether to mark edit as minor. (Default false)
 662+ * @param $rv Revision data. If not given, it will be fetched. (Default null)
 663+ * @param $bot Whether to mark edit as bot. (Default true)
 664+ * @return HTML data from the page.
 665+ * @deprecated
 666+ * @see wikipediaapi::edit
 667+ **/
 668+ function post ($page,$data,$summery = '',$minor = false,$rv = null,$bot = true) {
 669+ global $user;
 670+ global $maxlag;
 671+ global $irc;
 672+ global $irctechchannel;
 673+ global $run;
 674+ global $maxlagkeepgoing;
 675+
 676+ $wpq = new wikipediaquery; $wpq->queryurl = str_replace('index.php','query.php',$this->indexurl);
 677+ $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);
 678+
 679+ if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken();
 680+ if ($rv == null) $rv = $wpapi->revisions($page,1,'older',true);
 681+ if (!$rv[0]['*']) $rv[0]['*'] = $wpq->getpage($page);
 682+
 683+ //Fake the edit form.
 684+ $now = gmdate('YmdHis', time());
 685+ $token = htmlspecialchars($this->edittoken);
 686+ $tmp = date_parse($rv[0]['timestamp']);
 687+ $edittime = gmdate('YmdHis', gmmktime($tmp['hour'],$tmp['minute'],$tmp['second'],$tmp['month'],$tmp['day'],$tmp['year']));
 688+ $html = "<input type='hidden' value=\"{$now}\" name=\"wpStarttime\" />\n";
 689+ $html.= "<input type='hidden' value=\"{$edittime}\" name=\"wpEdittime\" />\n";
 690+ $html.= "<input type='hidden' value=\"{$token}\" name=\"wpEditToken\" />\n";
 691+ $html.= '<input name="wpAutoSummary" type="hidden" value="'.md5('').'" />'."\n";
 692+
 693+ if (preg_match('/'.preg_quote('{{nobots}}','/').'/iS',$rv[0]['*'])) { return false; } /* Honor the bots flags */
 694+ if (preg_match('/'.preg_quote('{{bots|allow=none}}','/').'/iS',$rv[0]['*'])) { return false; }
 695+ if (preg_match('/'.preg_quote('{{bots|deny=all}}','/').'/iS',$rv[0]['*'])) { return false; }
 696+ if (preg_match('/'.preg_quote('{{bots|deny=','/').'(.*)'.preg_quote('}}','/').'/iS',$rv[0]['*'],$m)) { if (in_array(explode(',',$m[1]),$user)) { return false; } } /* /Honor the bots flags */
 697+ if (!preg_match('/'.preg_quote($user,'/').'/iS',$rv['currentuser'])) { return false; } /* We need to be logged in */
 698+// if (preg_match('/'.preg_quote('You have new messages','/').'/iS',$rv[0]['*'])) { return false; } /* Check talk page */
 699+ if (!preg_match('/(yes|enable|true)/iS',((isset($run))?$run:$wpq->getpage('User:'.$user.'/Run')))) { return false; } /* Check /Run page */
 700+
 701+ $x = $this->forcepost($page,$data,$summery,$minor,$html,$maxlag,$maxlagkeepgoing,$bot); /* Go ahead and post. */
 702+ $this->lastpost = time();
 703+ return $x;
 704+ }
 705+
 706+ /**
 707+ * Post data to a page.
 708+ * @param $page Page title.
 709+ * @param $data Data to post to page.
 710+ * @param $summery Edit summary. (Default '')
 711+ * @param $minor Whether to mark edit as minor. (Default false)
 712+ * @param $edithtml HTML from the edit form. If not given, it will be fetched. (Default null)
 713+ * @param $maxlag Maxlag for posting. (Default null)
 714+ * @param $mlkg Whether to keep going after encountering a maxlag error and sleeping or not. (Default null)
 715+ * @param $bot Whether to mark edit as bot. (Default true)
 716+ * @return HTML data from the page.
 717+ * @deprecated
 718+ * @see wikipediaapi::edit
 719+ **/
 720+ function forcepost ($page,$data,$summery = '',$minor = false,$edithtml = null,$maxlag = null,$mlkg = null,$bot = true) {
 721+ $post['wpSection'] = '';
 722+ $post['wpScrolltop'] = '';
 723+ if ($minor == true) { $post['wpMinoredit'] = 1; }
 724+ $post['wpTextbox1'] = $data;
 725+ $post['wpSummary'] = $summery;
 726+ if ($edithtml == null) {
 727+ $html = $this->http->get($this->indexurl.'?title='.urlencode($page).'&action=edit');
 728+ } else {
 729+ $html = $edithtml;
 730+ }
 731+ preg_match('|\<input type\=\\\'hidden\\\' value\=\"(.*)\" name\=\"wpStarttime\" /\>|U',$html,$m);
 732+ $post['wpStarttime'] = $m[1];
 733+ preg_match('|\<input type\=\\\'hidden\\\' value\=\"(.*)\" name\=\"wpEdittime\" /\>|U',$html,$m);
 734+ $post['wpEdittime'] = $m[1];
 735+ preg_match('|\<input type\=\\\'hidden\\\' value\=\"(.*)\" name\=\"wpEditToken\" /\>|U',$html,$m);
 736+ $post['wpEditToken'] = $m[1];
 737+ preg_match('|\<input name\=\"wpAutoSummary\" type\=\"hidden\" value\=\"(.*)\" /\>|U',$html,$m);
 738+ $post['wpAutoSummary'] = $m[1];
 739+ if ($maxlag != null) {
 740+ $x = $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&maxlag='.urlencode($maxlag).'&bot='.(($bot == true)?'1':'0'),$post);
 741+ if (preg_match('/Waiting for ([^ ]*): ([0-9.-]+) seconds lagged/S',$x,$lagged)) {
 742+ global $irc;
 743+ if (is_resource($irc)) {
 744+ global $irctechchannel;
 745+ foreach(explode(',',$irctechchannel) as $y) {
 746+ #fwrite($irc,'PRIVMSG '.$y.' :'.$lagged[1].' is lagged out by '.$lagged[2].' seconds. ('.$lagged[0].')'."\n");
 747+ }
 748+ }
 749+ sleep(10);
 750+ if ($mlkg != true) { return false; }
 751+ else { $x = $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&bot='.(($bot == true)?'1':'0'),$post); }
 752+ }
 753+ return $x;
 754+ } else {
 755+ return $this->http->post($this->indexurl.'?title='.urlencode($page).'&action=submit&bot='.(($bot == true)?'1':'0'),$post);
 756+ }
 757+ }
 758+
 759+ /**
 760+ * Get a diff.
 761+ * @param $title Page title to get the diff of.
 762+ * @param $oldid Old revision ID.
 763+ * @param $id New revision ID.
 764+ * @param $wait Whether or not to wait for the diff to become available. (Default true)
 765+ * @return Array of added data, removed data, and a rollback token if one was fetchable.
 766+ **/
 767+ function diff ($title,$oldid,$id,$wait = true) {
 768+ $deleted = '';
 769+ $added = '';
 770+
 771+ $html = $this->http->get($this->indexurl.'?title='.urlencode($title).'&action=render&diff='.urlencode($id).'&oldid='.urlencode($oldid).'&diffonly=1');
 772+
 773+ if (preg_match_all('/\&amp\;(oldid\=)(\d*)\\\'\>(Revision as of|Current revision as of)/USs', $html, $m, PREG_SET_ORDER)) {
 774+ //print_r($m);
 775+ if ((($oldid != $m[0][2]) and (is_numeric($oldid))) or (($id != $m[1][2]) and (is_numeric($id)))) {
 776+ if ($wait == true) {
 777+ sleep(1);
 778+ return $this->diff($title,$oldid,$id,false);
 779+ } else {
 780+ echo 'OLDID as detected: '.$m[0][2].' Wanted: '.$oldid."\n";
 781+ echo 'NEWID as detected: '.$m[1][2].' Wanted: '.$id."\n";
 782+ echo $html;
 783+ die('Revision error.'."\n");
 784+ }
 785+ }
 786+ }
 787+
 788+ if (preg_match_all('/\<td class\=(\"|\\\')diff-addedline\1\>\<div\>(.*)\<\/div\>\<\/td\>/USs', $html, $m, PREG_SET_ORDER)) {
 789+ //print_r($m);
 790+ foreach ($m as $x) {
 791+ $added .= htmlspecialchars_decode(strip_tags($x[2]))."\n";
 792+ }
 793+ }
 794+
 795+ if (preg_match_all('/\<td class\=(\"|\\\')diff-deletedline\1\>\<div\>(.*)\<\/div\>\<\/td\>/USs', $html, $m, PREG_SET_ORDER)) {
 796+ //print_r($m);
 797+ foreach ($m as $x) {
 798+ $deleted .= htmlspecialchars_decode(strip_tags($x[2]))."\n";
 799+ }
 800+ }
 801+
 802+ //echo $added."\n".$deleted."\n";
 803+
 804+ if (preg_match('/action\=rollback\&amp\;from\=.*\&amp\;token\=(.*)\"/US', $html, $m)) {
 805+ $rbtoken = $m[1];
 806+ $rbtoken = urldecode($rbtoken);
 807+// echo 'rbtoken: '.$rbtoken.' -- '; print_r($m); echo "\n\n";
 808+ return array($added,$deleted,$rbtoken);
 809+ }
 810+
 811+ return array($added,$deleted);
 812+ }
 813+
 814+ /**
 815+ * Rollback an edit.
 816+ * @param $title Page title to rollback.
 817+ * @param $user Username of last edit to the page to rollback.
 818+ * @param $reason Reason to rollback. If null, default is generated. (Default null)
 819+ * @param $token Rollback token to use. If null, it is fetched. (Default null)
 820+ * @param $bot Whether or not to mark as bot. (Default true)
 821+ * @return HTML or false if failure.
 822+ * @deprecated
 823+ * @see wikipediaapi::rollback
 824+ **/
 825+ function rollback ($title,$user,$reason = null,$token = null,$bot = true) {
 826+ if (($token == null) or (!$token)) {
 827+ $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);
 828+ $token = $wpapi->revisions($title,1,'older',false,null,true,true);
 829+ if ($token[0]['user'] == $user) {
 830+// echo 'Token: '; print_r($token); echo "\n\n";
 831+ $token = $token[0]['rollbacktoken'];
 832+ } else {
 833+ return false;
 834+ }
 835+ }
 836+ $x = $this->http->get($this->indexurl.'?title='.urlencode($title).'&action=rollback&from='.urlencode($user).'&token='.urlencode($token).(($reason != null)?'&summary='.urlencode($reason):'').'&bot='.(($bot == true)?'1':'0'));
 837+ #global $logfd; if (!is_resource($logfd)) $logfd = fopen('php://stderr','w'); fwrite($logfd,'Rollback return: '.$x."\n");
 838+ if (!preg_match('/action complete/iS',$x)) return false;
 839+ return $x;
 840+ }
 841+
 842+ /**
 843+ * Move a page.
 844+ * @param $old Page title to move.
 845+ * @param $new New title to move to.
 846+ * @param $reason Move page summary.
 847+ * @return HTML page.
 848+ * @deprecated
 849+ * @see wikipediaapi::move
 850+ **/
 851+ function move ($old,$new,$reason) {
 852+ $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);
 853+ if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken();
 854+
 855+ $token = htmlspecialchars($this->edittoken);
 856+
 857+ $post = array
 858+ (
 859+ 'wpOldTitle' => $old,
 860+ 'wpNewTitle' => $new,
 861+ 'wpReason' => $reason,
 862+ 'wpWatch' => '0',
 863+ 'wpEditToken' => $token,
 864+ 'wpMove' => 'Move page'
 865+ );
 866+ return $this->http->post($this->indexurl.'?title=Special:Movepage&action=submit',$post);
 867+ }
 868+
 869+ /**
 870+ * Uploads a file.
 871+ * @param $page Name of page on the wiki to upload as.
 872+ * @param $file Name of local file to upload.
 873+ * @param $desc Content of the file description page.
 874+ * @return HTML content.
 875+ **/
 876+ function upload ($page,$file,$desc) {
 877+ $post = array
 878+ (
 879+ 'wpUploadFile' => '@'.$file,
 880+ 'wpSourceType' => 'file',
 881+ 'wpDestFile' => $page,
 882+ 'wpUploadDescription' => $desc,
 883+ 'wpLicense' => '',
 884+ 'wpWatchthis' => '0',
 885+ 'wpIgnoreWarning' => '1',
 886+ 'wpUpload' => 'Upload file'
 887+ );
 888+ return $this->http->post($this->indexurl.'?title=Special:Upload&action=submit',$post);
 889+ }
 890+
 891+ /**
 892+ * Check if a user has email enabled.
 893+ * @param $user Username to check whether or not the user has email enabled.
 894+ * @return True or false depending on whether or not the user has email enabled.
 895+ **/
 896+ function hasemail ($user) {
 897+ $tmp = $this->http->get($this->indexurl.'?title=Special:EmailUser&target='.urlencode($user));
 898+ if (stripos($tmp,"No e-mail address") !== false) return false;
 899+ return true;
 900+ }
 901+
 902+ /**
 903+ * Sends an email to a user.
 904+ * @param $user Username to send email to.
 905+ * @param $subject Subject of email to send.
 906+ * @param $body Body of email to send.
 907+ * @return HTML content.
 908+ **/
 909+ function email ($user,$subject,$body) {
 910+ $wpapi = new wikipediaapi; $wpapi->apiurl = str_replace('index.php','api.php',$this->indexurl);
 911+ if ((!$this->edittoken) or ($this->edittoken == '')) $this->edittoken = $wpapi->getedittoken();
 912+
 913+ $post = array
 914+ (
 915+ 'wpSubject' => $subject,
 916+ 'wpText' => $body,
 917+ 'wpCCMe' => 0,
 918+ 'wpSend' => 'Send',
 919+ 'wpEditToken' => $this->edittoken
 920+ );
 921+
 922+ return $this->http->post($this->indexurl.'?title=Special:EmailUser&target='.urlencode($user).'&action=submit',$post);
 923+ }
 924+ }
 925+?>
 926+
 927+
 928+[edit] Diff function (diff.function.php)
 929+
 930+<?PHP
 931+ function diff ($old,$new,$nret = true,$inline = false) {
 932+// if ($inline) {
 933+// return str_replace(array("\n",chr(92).chr(92),'\n'),array(' ',chr(92),"\n"),diff(implode("\n",explode(' ',str_replace(array(chr(92),"\n"),array(chr(92).chr(92),'\n'),$old))),implode("\n",explode(' ',str_replace(array(chr(92),"\n"),array(chr(92).chr(92),'\n'),$new))),$nret,false));
 934+// }
 935+ $file1 = tempnam('/tmp','diff_');
 936+ $file2 = tempnam('/tmp','diff_');
 937+ file_put_contents($file1,$old);
 938+ file_put_contents($file2,$new);
 939+ $out = array();
 940+ if ($inline) {
 941+// echo 'EXEC: wdiff -3'.(($nret)?'1':'2').' '.escapeshellarg($file1).' '.escapeshellarg($file2)."\n";
 942+ @exec('wdiff -3'.(($nret)?'1':'2').' '.escapeshellarg($file1).' '.escapeshellarg($file2),$out);
 943+ foreach ($out as $key => $line) {
 944+ if ($line == '======================================================================') unset($out[$key]);
 945+ elseif ($nret) $out[$key] = '> '.$line;
 946+ else $out[$key] = '< '.$line;
 947+ }
 948+ } else {
 949+ @exec('diff -d --suppress-common-lines '.escapeshellarg($file1).' '.escapeshellarg($file2),$out);
 950+ }
 951+ $out2 = array();
 952+ foreach ($out as $line) {
 953+ if (
 954+ (
 955+ ($nret)
 956+ and (preg_match('/^\> .*$/',$line))
 957+ )
 958+ or (
 959+ (!$nret)
 960+ and (preg_match('/^\< .*$/',$line))
 961+ )
 962+ ) {
 963+ $out2[] = substr($line,2);
 964+ }
 965+ }
 966+ $out = $out2;
 967+ unset($out2);
 968+ unlink($file1);
 969+ unlink($file2);
 970+ return implode("\n",$out);
 971+ }
 972+?>
\ No newline at end of file
Property changes on: trunk/extensions/RPED/wikibot.classes.php
___________________________________________________________________
Added: svn:eol-style
1973 + native

Status & tagging log