http://www.mediawiki.org/wiki/Special:Code/MediaWiki/67244

Revision: 67244
Author:   tisane
Date:     2010-06-02 20:50:44 +0000 (Wed, 02 Jun 2010)

Log Message:
-----------
Readding wikibot

Added Paths:
-----------
    trunk/tools/wikibot/
    trunk/tools/wikibot/RPEDFileReader.php
    trunk/tools/wikibot/RPEDIRCBot.php
    trunk/tools/wikibot/testbot.php
    trunk/tools/wikibot/wikibot.classes.php
    trunk/tools/wikibot/wikibot.config.php

Added: trunk/tools/wikibot/RPEDFileReader.php
===================================================================
--- trunk/tools/wikibot/RPEDFileReader.php                              (rev 0)
+++ trunk/tools/wikibot/RPEDFileReader.php      2010-06-02 20:50:44 UTC (rev 
67244)
@@ -0,0 +1,80 @@
+<?php
+# RPEDFileReader.php by Tisane, http://www.mediawiki.org/wiki/User:Tisane
+#
+# This script is free software that is available under the terms of the 
Creative Commons
+# Attribution-ShareAlike 3.0 license and the current version of the GNU 
General Public License.
+#
+# The purpose of this script is to read a text file (specifically, the list of 
page titles from
+# Wikipedia's data dump) and add each page title to a database table.
+
+error_reporting( E_ALL | E_STRICT );
+include 'wikibot.classes.php'; /* The wikipedia classes. */
+
+$bot = $argv[1];
+$wiki = $argv[2];
+$fileName = $argv[3];
+$searching = false;
+if ( isset( $argv[4] ) && $argv[4] != '' ) {
+    $searching = true;
+}
+if ( !isset( $argv[5] ) || $argv[5] != "nodaemon" ) {
+    $daemonize = true;
+}
+
+$user = getWikibotSetting( 'user', $bot, $wiki );
+$pass = getWikibotSetting( 'pass', $bot, $wiki );
+$maxURLLength = getWikibotSetting( 'maxurllength', $bot, $wiki );
+
+$wpapi = new wikipediaapi ( '', '', '', $bot, $wiki, true );
+$wpq   = new wikipediaquery ( '', '', '', $bot, $wiki, true );
+$wpi   = new wikipediaindex ( '', '', '', $bot, $wiki, true );
+if ( $wpapi->login( $user, $pass ) != 'true' ) {
+    echo "Login failure\n";
+    die();
+}
+
+$handle = @fopen( $fileName, "r" );
+$lineNumber = 0;
+$line = "";
+
+if ( isset( $daemonize ) ) {
+
+    $pid = pcntl_fork(); // fork
+    if ( $pid < 0 ) {
+        exit;
+    }
+    else if ( $pid ) { // parent
+        exit;
+    }
+    // child
+    $sid = posix_setsid();
+    if ( $sid < 0 ) {
+            exit;
+    }
+}
+     
+if ( $handle ) {
+    while ( !feof( $handle ) ) {
+        $buffer = fgets( $handle, 4096 );
+        $buffer = str_replace( "\n", "", $buffer );
+        if ( $searching == true ) {
+            if ( $buffer == $argv[4] ) {
+                $searching = false;
+            }
+        } else {
+            $buffer = urlencode  (  $buffer  );
+            if ( $line != "" ) {
+                $line .= "|";
+            }
+            if ( strlen( $line ) + strlen( $buffer ) > $maxURLLength ) {
+                $wpapi->rpedInsert( $line );
+                $line = "";
+            }
+            $line .= $buffer;
+        }
+    }
+    $wpapi->rpedInsert( $line );
+    fclose( $handle );
+} else {
+    echo "No handle!\n";
+}

Added: trunk/tools/wikibot/RPEDIRCBot.php
===================================================================
--- trunk/tools/wikibot/RPEDIRCBot.php                          (rev 0)
+++ trunk/tools/wikibot/RPEDIRCBot.php  2010-06-02 20:50:44 UTC (rev 67244)
@@ -0,0 +1,111 @@
+<?php
+# RPEDIRC.php by Tisane, http://www.mediawiki.org/wiki/User:Tisane
+#
+# This script is free software that is available under the terms of the 
Creative Commons
+# Attribution 3.0 license and the current version of the GNU General Public 
License.
+#
+# The purpose of this script is to get the titles of all new, moved, deleted 
and restored
+# pages from #en.wikipedia and add/delete them from the rped_table.
+
+error_reporting( E_ALL | E_STRICT );
+
+include 'wikibot.classes.php'; /* The wikipedia classes. */
+
+$bot = $argv[1];
+$wiki = $argv[2];
+if ( !isset( $argv[3] ) || $argv[3] != "nodaemon" ){
+    $daemonize = true;
+}
+
+$wpapi = new wikipediaapi ( '', '', '', $bot, $wiki, true );
+$wpq   = new wikipediaquery ( '', '', '', $bot, $wiki, true );
+$wpi   = new wikipediaindex ( '', '', '', $bot, $wiki, true );
+$user = getWikibotSetting( 'user', $bot, $wiki );
+$pass = getWikibotSetting( 'pass', $bot, $wiki );
+$host = getWikibotSetting( 'host', $bot, $wiki );
+$port = getWikibotSetting( 'port', $bot, $wiki );
+$nick = getWikibotSetting( 'nick', $bot, $wiki );
+$ident = getWikibotSetting( 'ident', $bot, $wiki );
+$realname = getWikibotSetting( 'realname', $bot, $wiki );
+$chan = getWikibotSetting( 'chan', $bot, $wiki );
+$deleteLine = getWikibotSetting( 'deleteline', $bot, $wiki );
+$moveLine = getWikibotSetting( 'moveline', $bot, $wiki );
+$deletedWord = getWikibotSetting( 'deletedword', $bot, $wiki );
+$newCharacter = getWikibotSetting( 'thenewcharacter', $bot, $wiki );
+
+if ( $wpapi->login( $user, $pass ) != 'true' ) {
+    echo "Login failure\n";
+    die();
+}
+
+$readbuffer = "";
+$startSep = "[[";
+$endSep = "]]";
+
+// open a socket connection to the IRC server
+$fp = fsockopen( $host, $port, $erno, $errstr, 30 );
+
+// print the error if there is no connection
+if ( !$fp ) {
+    echo $errstr . " (" . $errno . ")<br />\n";
+    die();
+}
+
+// write data through the socket to join the channel
+fwrite( $fp, "NICK " . $nick . "\r\n" );
+fwrite( $fp, "USER " . $ident . " " . $host . " bla :" . $realname . "\r\n" );
+fwrite( $fp, "JOIN :" . $chan . "\r\n" );
+
+# Launch daemon!
+if ( isset( $daemonize ) ) {
+
+    $pid = pcntl_fork(); // fork
+    if ( $pid < 0 ) {
+        exit;
+    }
+    else if ( $pid ){ // parent
+        exit;
+    }
+    // child
+    $sid = posix_setsid();
+    if ( $sid < 0 ) {
+            exit;
+    }
+}
+
+while ( !feof( $fp ) ) {
+    $line =  fgets( $fp, 512 );
+    $pingLine = explode( ' ', $line );
+    if ( strtolower( $pingLine[0] ) == 'ping' ) {
+        $response = "PONG " . $pingLine[1] . "\n";
+        fwrite( $fp, "PONG " . $response );
+    }
+    usleep( 10 );
+    $startPos = strpos( $line, $startSep );
+    $endPos = strpos( $line, $endSep );
+    $subLine = substr( $line, $startPos + 5, $endPos -$startPos -8 );
+    if ( $subLine == $deleteLine ) {
+        $delstartPos = strpos( $line, $startSep, $endPos );
+        $delendPos = strpos( $line, $endSep, $endPos + 1 );
+        $delLine = substr( $line, $delstartPos + 5, $delendPos -$delstartPos 
-8 );
+        $action = substr( $line, $delstartPos -9, 7 );
+        if ( $action == $deletedWord ) {
+            $wpapi->rpedDelete( $delLine );
+        } else {
+            $wpapi->rpedInsert( $delLine );
+        }
+    }
+    if ( $subLine == $moveLine ) {
+        $delstartPos = strpos( $line, $startSep, $endPos );
+        $delendPos = strpos( $line, $endSep, $endPos + 1 );
+        $delstartPos = strpos( $line, $startSep, $delstartPos + 1 );
+        $delendPos = strpos( $line, $endSep, $delendPos + 1 );
+        $delLine = substr( $line, $delstartPos + 2, $delendPos -$delstartPos 
-2 );
+        $wpapi->rpedInsert( $delLine );
+    }
+    if ( substr( $line, $endPos + 5, 1 ) == $newCharacter || substr( $line, 
$endPos + 6, 1 ) == $newCharacter ) {
+        $wpapi->rpedInsert( $subLine );
+    }
+}
+
+fclose( $fp );
\ No newline at end of file

Added: trunk/tools/wikibot/testbot.php
===================================================================
--- trunk/tools/wikibot/testbot.php                             (rev 0)
+++ trunk/tools/wikibot/testbot.php     2010-06-02 20:50:44 UTC (rev 67244)
@@ -0,0 +1,21 @@
+<?php
+# This bot logs in to testwiki.org and edits the sandbox to say "Hello world!"
+
+error_reporting( E_ALL | E_STRICT );
+include 'wikibot.classes.php'; /* The wikipedia classes. */
+
+$bot = 'TestBot';
+$wiki = 'Testwiki';
+
+$wpapi = new wikipediaapi ( '', '', '', $bot, $wiki, true );
+$wpq   = new wikipediaquery ( '', '', '', $bot, $wiki, true );
+$wpi   = new wikipediaindex ( '', '', '', $bot, $wiki, true );
+$user = getWikibotSetting( 'user', $bot, $wiki );
+$pass = getWikibotSetting( 'pass', $bot, $wiki );
+if ( $wpapi->login( $user, $pass ) != 'true' ) {
+    echo "Login failure";
+    die();
+}
+sleep( 1 );
+
+var_dump( $wpapi->edit( 'Sandbox', 'Hello world!', 'This is a test', false, 
false, null, null, false ) );
\ No newline at end of file

Added: trunk/tools/wikibot/wikibot.classes.php
===================================================================
--- trunk/tools/wikibot/wikibot.classes.php                             (rev 0)
+++ trunk/tools/wikibot/wikibot.classes.php     2010-06-02 20:50:44 UTC (rev 
67244)
@@ -0,0 +1,1091 @@
+<?PHP
+       /**
+        * @author Cobi Carter, Tisane
+        * 
+        * This script is free software that is available under the terms of the
+        * current version of the GNU General Public License.
+        *
+        * This is a configurable MediaWiki bot framework.
+        **/
+       
+       require( 'wikibot.config.php' );
+
+       function getWikibotSetting( $setting, $bot, $wiki ) {
+               global $wikibotSetting;
+               $permutation = 0;
+               while ( !isset( $result ) && $permutation < 4 ) {
+                       
+                       switch ( $permutation ) {
+                               case 0:
+                                       if ( isset( 
$wikibotSetting[$setting][$bot][$wiki] ) ) {
+                                               $result = 
$wikibotSetting[$setting][$bot][$wiki];
+                                       }
+                                       break;
+                               case 1:
+                                       if ( isset( 
$wikibotSetting[$setting][$bot]['*'] ) ) {
+                                               $result = 
$wikibotSetting[$setting][$bot]['*'];
+                                       }
+                               case 2:
+                                       if ( isset( 
$wikibotSetting[$setting]['*'][$wiki] ) ) {
+                                               $result = 
$wikibotSetting[$setting]['*'][$wiki];
+                                       }
+                                       break;
+                               case 3:
+                                       if ( isset( 
$wikibotSetting[$setting]['*']['*'] ) ) {
+                                               $result = 
$wikibotSetting[$setting]['*']['*'];
+                                       }
+                                       break;
+                       }
+                       $permutation++;
+               }
+               if ( isset( $result ) ) {
+                       return $result;
+               } else {
+                       return false;
+               }
+       }
+       
+       /**
+        * This class is designed to provide a simplified interface to cURL 
which maintains cookies.
+        * @author Cobi
+        **/
+       class http {
+               private $ch;
+               private $uid;
+               public $postfollowredirs;
+               public $getfollowredirs;
+
+               /**
+                * Our constructor function.  This just does basic cURL 
initialization.
+                * @return void
+                **/
+               function __construct () {
+                       global $proxyhost, $proxyport;
+                       $this->ch = curl_init();
+                       $this->uid = dechex( rand( 0, 99999999 ) );
+                       curl_setopt( $this->ch, CURLOPT_COOKIEJAR, 
'/tmp/cluewikibot.cookies.' . $this->uid . '.dat' );
+                       curl_setopt( $this->ch, CURLOPT_COOKIEFILE, 
'/tmp/cluewikibot.cookies.' . $this->uid . '.dat' );
+                       curl_setopt( $this->ch, CURLOPT_MAXCONNECTS, 100 );
+                       curl_setopt( $this->ch, CURLOPT_CLOSEPOLICY, 
CURLCLOSEPOLICY_LEAST_RECENTLY_USED );
+                       curl_setopt( $this->ch, CURLOPT_USERAGENT, 
'ClueBot/1.1' );
+                       if ( isset( $proxyhost ) and isset( $proxyport ) and ( 
$proxyport != null ) and ( $proxyhost != null ) ) {
+                               curl_setopt( $this->ch, CURLOPT_PROXYTYPE, 
CURLPROXY_HTTP );
+                               curl_setopt( $this->ch, CURLOPT_PROXY, 
$proxyhost );
+                               curl_setopt( $this->ch, CURLOPT_PROXYPORT, 
$proxyport );
+                       }
+                       $this->postfollowredirs = 0;
+                       $this->getfollowredirs = 1;
+               }
+
+               /**
+                * Post to a URL.
+                * @param $url The URL to post to.
+                * @param $data The post-data to post, should be an array of 
key => value pairs.
+                * @return Data retrieved from the POST request.
+                **/
+               function post ( $url, $data ) {
+                       $time = microtime( 1 );
+                       curl_setopt( $this->ch, CURLOPT_URL, $url );
+                       curl_setopt( $this->ch, CURLOPT_FOLLOWLOCATION, 
$this->postfollowredirs );
+                       curl_setopt( $this->ch, CURLOPT_MAXREDIRS, 10 );
+                       curl_setopt( $this->ch, CURLOPT_HEADER, 0 );
+                       curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, 1 );
+                       curl_setopt( $this->ch, CURLOPT_TIMEOUT, 30 );
+                       curl_setopt( $this->ch, CURLOPT_CONNECTTIMEOUT, 10 );
+                       curl_setopt( $this->ch, CURLOPT_POST, 1 );
+                       curl_setopt( $this->ch, CURLOPT_POSTFIELDS, $data );
+                       curl_setopt( $this->ch, CURLOPT_HTTPHEADER, array( 
'Expect:' ) );
+                       $data = curl_exec( $this->ch );
+                       # global $logfd; if (!is_resource($logfd)) $logfd = 
fopen('php://stderr','w'); fwrite($logfd,'POST: '.$url.' ('.(microtime(1) - 
$time).' s) ('.strlen($data)." b)\n");
+                       return $data;
+               }
+
+               /**
+                * Get a URL.
+                * @param $url The URL to get.
+                * @return Data retrieved from the GET request.
+                **/
+               function get ( $url ) {
+                       $time = microtime( 1 );
+                       curl_setopt( $this->ch, CURLOPT_URL, $url );
+                       curl_setopt( $this->ch, CURLOPT_FOLLOWLOCATION, 
$this->getfollowredirs );
+                       curl_setopt( $this->ch, CURLOPT_MAXREDIRS, 10 );
+                       curl_setopt( $this->ch, CURLOPT_HEADER, 0 );
+                       curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, 1 );
+                       curl_setopt( $this->ch, CURLOPT_TIMEOUT, 30 );
+                       curl_setopt( $this->ch, CURLOPT_CONNECTTIMEOUT, 10 );
+                       curl_setopt( $this->ch, CURLOPT_HTTPGET, 1 );
+                       $data = curl_exec( $this->ch );
+                       # $global $logfd; if (!is_resource($logfd)) $logfd = 
fopen('php://stderr','w'); fwrite($logfd,'GET: '.$url.' ('.(microtime(1) - 
$time).' s) ('.strlen($data)." b)\n");
+                       return $data;
+               }
+
+               /**
+                * Our destructor.  Cleans up cURL and unlinks temporary files.
+                **/
+               function __destruct () {
+                       curl_close( $this->ch );
+                       @unlink( '/tmp/cluewikibot.cookies.' . $this->uid . 
'.dat' );
+               }
+       }
+
+       /**
+        * This class is a deprecated wrapper class which allows legacy code 
written for Wikipedia's query.php API to still work with wikipediaapi::.
+        **/
+       class wikipediaquery {
+               private $http;
+               private $api;
+               public $apiurl;
+               public $queryurl;
+               public $indexurl;
+
+               /**
+                * This is our constructor.
+                * @param $myApiurl API url; used if $fromFile is false
+                * @param $myQueryurl Query url; used if $fromFile is false
+                * @param $myIndexurl Index url; used if $fromFile is false
+                * @param $bot Bot name; used if $fromFile is true
+                * @param $wiki Wiki name; used if $fromFile is true
+                * @param $fromFile If true, load settings from 
wikibot.config.php
+                * @return void
+                **/
+               function __construct ( $myApiurl, $myQueryurl, $myIndexurl, 
$bot = '', $wiki = '', $fromFile = false ) {
+                       global $queryFunctionFile;
+                       if ( $fromFile == true ) {
+                               $this->apiurl = getWikibotSetting( 'apiurl', 
$bot, $wiki );
+                               $this->queryurl = getWikibotSetting( 
'queryurl', $bot, $wiki ); // Obsolete, but kept for compatibility purposes.
+                               $this->indexurl = getWikibotSetting( 
'indexurl', $bot, $wiki );
+                       } else {
+                               $this->apiurl = $myApiurl;
+                               $this->queryurl = $myQueryurl; // Obsolete, but 
kept for compatibility purposes.
+                               $this->indexurl = $myIndexurl;
+                       }
+                       if ( isset( $queryFunctionFile ) ) {
+                               foreach ( $queryFunctionFile as $item ) {
+                                       require_once( $item );
+                               }
+                       }
+                       global $__wp__http;
+                       if ( !isset( $__wp__http ) ) {
+                               $__wp__http = new http;
+                       }
+                       $this->http = &$__wp__http;
+                       $this->api = new wikipediaapi ( $this->apiurl, 
$this->queryurl, $this->indexurl );
+               }
+
+               /**
+                * Reinitializes the queryurl.
+                * @private
+                * @return void
+                **/
+               private function checkurl() {
+                       $this->api->apiurl = str_replace( 'query.php', 
'api.php', $this->queryurl );
+               }
+
+               /**
+                * Gets the content of a page.
+                * @param $page The wikipedia page to fetch.
+                * @return The wikitext for the page.
+                **/
+               function getpage ( $page ) {
+                       $this->checkurl();
+                       $ret = $this->api->revisions( $page, 1, 'older', true, 
null, true, false, false, false );
+                       if (isset($ret[0]['*'])){
+                               return $ret[0]['*'];
+                       } else{
+                               return;
+                       }
+               }
+
+               /**
+                * Gets the page id for a page.
+                * @param $page The wikipedia page to get the id for.
+                * @return The page id of the page.
+                **/
+               function getpageid ( $page ) {
+                       $this->checkurl();
+                       $ret = $this->api->revisions( $page, 1, 'older', false, 
null, true, false, false, false );
+                       return $ret['pageid'];
+               }
+
+               /**
+                * Gets the number of contributions a user has.
+                * @param $user The username for which to get the edit count.
+                * @return The number of contributions the user has.
+                **/
+               function contribcount ( $user ) {
+                       $this->checkurl();
+                       $ret = $this->api->users( $user, 1, null, true );
+                       if ( $ret !== false ) return $ret[0]['editcount'];
+                       return false;
+               }
+       }
+
+       /**
+        * This class is for interacting with Wikipedia's api.php API.
+        **/
+       class wikipediaapi {
+               private $http;
+               private $edittoken;
+               private $tokencache;
+               public $apiurl;
+               public $queryurl;
+               public $indexurl;
+
+               /**
+                * This is our constructor.
+                * @param $myApiurl API url; used if $fromFile is false
+                * @param $myQueryurl Query url; used if $fromFile is false
+                * @param $myIndexurl Index url; used if $fromFile is false
+                * @param $bot Bot name; used if $fromFile is true
+                * @param $wiki Wiki name; used if $fromFile is true
+                * @param $fromFile If true, load settings from 
wikibot.config.php
+                * @return void
+                **/
+               function __construct ( $myApiurl, $myQueryurl, $myIndexurl, 
$bot = '', $wiki = '', $fromFile = false ) {
+                       global $apiFunctionFile;
+                       if ( $fromFile == true ) {
+                               $this->apiurl = getWikibotSetting( 'apiurl', 
$bot, $wiki );
+                               $this->queryurl = getWikibotSetting( 
'queryurl', $bot, $wiki ); // Obsolete, but kept for compatibility purposes.
+                               $this->indexurl = getWikibotSetting( 
'indexurl', $bot, $wiki );
+                       } else {
+                               $this->apiurl = $myApiurl;
+                               $this->queryurl = $myQueryurl; // Obsolete, but 
kept for compatibility purposes.
+                               $this->indexurl = $myIndexurl;
+                       }
+                       if ( isset( $queryFunctionFile ) ) {
+                               foreach ( $apiFunctionFile as $item ) {
+       
+                                       require_once( $item );
+                               }
+                       }
+                       global $__wp__http;
+                       if ( !isset( $__wp__http ) ) {
+                               $__wp__http = new http;
+                       }
+                       $this->http = &$__wp__http;
+               }
+                
+                /**
+                * This function takes a username and password and logs you 
into wikipedia.
+                * @param $user Username to login as.
+                * @param $pass Password that corresponds to the username.
+                * @return void
+                **/
+               function login ( $user, $pass ) {
+                       $x = unserialize( $this->http->post( $this->apiurl . 
'?action=login&format=php', array( 'lgname' => $user, 'lgpassword' => $pass ) ) 
);
+                       if ( $x['login']['result'] == 'Success' )
+                               return true;
+                       if ( $x['login']['result'] == 'NeedToken' ) {
+                               $x = unserialize( $this->http->post( 
$this->apiurl . '?action=login&format=php', array( 'lgname' => $user, 
'lgpassword' => $pass, 'lgtoken' => $x['login']['token'] ) ) );
+                               if ( $x['login']['result'] == 'Success' )
+                                       return true;
+                       }
+                       return false;
+               }
+
+               /**
+                * This function returns the edit token.
+                * @return Edit token.
+                **/
+               function getedittoken () {
+                       $tokens = $this->gettokens( 'Main Page' );
+                       if ( $tokens['edittoken'] == '' ) $tokens = 
$this->gettokens( 'Main Page', true );
+                       $this->edittoken = $tokens['edittoken'];
+                       return $tokens['edittoken'];
+               }
+
+               /**
+                * This function returns the various tokens for a certain page.
+                * @param $title Page to get the tokens for.
+                * @param $flush Optional - internal use only.  Flushes the 
token cache.
+                * @return An associative array of tokens for the page.
+                **/
+               function gettokens ( $title, $flush = false ) {
+                       if ( !is_array( $this->tokencache ) ) $this->tokencache 
= array();
+                       foreach ( $this->tokencache as $t => $data ) if ( 
time() - $data['timestamp'] > 6 * 60 * 60 ) unset( $this->tokencache[$t] );
+                       if ( isset( $this->tokencache[$title] ) && ( !$flush ) 
) {
+                               return $this->tokencache[$title]['tokens'];
+                       } else {
+                               $tokens = array();
+                               $x = $this->http->get( $this->apiurl . 
'?action=query&format=php&prop=info&intoken=edit|delete|protect|move|block|unblock|email&titles='
 . urlencode( $title ) );
+                               $x = unserialize( $x );
+                               foreach ( $x['query']['pages'] as $y ) {
+                                       $tokens['edittoken'] = $y['edittoken'];
+                                       $tokens['deletetoken'] = 
$y['deletetoken'];
+                                       $tokens['protecttoken'] = 
$y['protecttoken'];
+                                       $tokens['movetoken'] = $y['movetoken'];
+                                       $tokens['blocktoken'] = 
$y['blocktoken'];
+                                       $tokens['unblocktoken'] = 
$y['unblocktoken'];
+                                       # $tokens['emailtoken'] = 
$y['emailtoken'];
+                                       $this->tokencache[$title] = array(
+                                                       'timestamp' => time(),
+                                                       'tokens' => $tokens
+                                                                        );
+                                       return $tokens;
+                               }
+                       }
+               }
+
+               /**
+                * This function returns the recent changes for the wiki.
+                * @param $count The number of items to return. (Default 10)
+                * @param $namespace The namespace ID to filter items on. Null 
for no filtering. (Default null)
+                * @param $dir The direction to pull items.  "older" or 
"newer".  (Default 'older')
+                * @param $ts The timestamp to start at.  Null for the 
beginning/end (depending on direction).  (Default null)
+                * @return Associative array of recent changes metadata.
+                **/
+               function recentchanges ( $count = 10, $namespace = null, $dir = 
'older', $ts = null ) {
+                       $append = '';
+                       if ( $ts !== null ) { $append .= '&rcstart=' . 
urlencode( $ts ); }
+                       $append .= '&rcdir=' . urlencode( $dir );
+                       if ( $namespace !== null ) { $append .= '&rcnamespace=' 
. urlencode( $namespace ); }
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&list=recentchanges&rcprop=user|comment|flags|timestamp|title|ids|sizes&format=php&rclimit='
 . $count . $append );
+                       $x = unserialize( $x );
+                       return $x['query']['recentchanges'];
+               }
+
+               /**
+                * This function returns search results from Wikipedia's 
internal search engine.
+                * @param $search The query string to search for.
+                * @param $limit The number of results to return. (Default 10)
+                * @param $offset The number to start at.  (Default 0)
+                * @param $namespace The namespace ID to filter by.  Null means 
no filtering.  (Default 0)
+                * @param $what What to search, 'text' or 'title'.  (Default 
'text')
+                * @param $redirs Whether or not to list redirects.  (Default 
false)
+                * @return Associative array of search result metadata.
+                **/
+               function search ( $search, $limit = 10, $offset = 0, $namespace 
= 0, $what = 'text', $redirs = false ) {
+                       $append = '';
+                       if ( $limit != null ) $append .= '&srlimit=' . 
urlencode( $limit );
+                       if ( $offset != null ) $append .= '&sroffset=' . 
urlencode( $offset );
+                       if ( $namespace != null ) $append .= '&srnamespace=' . 
urlencode( $namespace );
+                       if ( $what != null ) $append .= '&srwhat=' . urlencode( 
$what );
+                       if ( $redirs == true ) $append .= '&srredirects=1';
+                       else $append .= '&srredirects=0';
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&list=search&format=php&srsearch=' . urlencode( $search ) . 
$append );
+                       $x = unserialize( $x );
+                       return $x['query']['search'];
+               }
+
+               /**
+                * Retrieve entries from the WikiLog.
+                * @param $user Username who caused the entry.  Null means 
anyone.  (Default null)
+                * @param $title Object to which the entry refers.  Null means 
anything.  (Default null)
+                * @param $limit Number of entries to return.  (Default 50)
+                * @param $type Type of logs.  Null means any type.  (Default 
null)
+                * @param $start Date to start enumerating logs.  Null means 
beginning/end depending on $dir.  (Default null)
+                * @param $end Where to stop enumerating logs.  Null means 
whenever limit is satisfied or there are no more logs.  (Default null)
+                * @param $dir Direction to enumerate logs.  "older" or 
"newer".  (Default 'older')
+                * @return Associative array of logs metadata.
+                **/
+               function logs ( $user = null, $title = null, $limit = 50, $type 
= null, $start = null, $end = null, $dir = 'older' ) {
+                       $append = '';
+                       if ( $user != null ) $append .= '&leuser=' . urlencode( 
$user );
+                       if ( $title != null ) $append .= '&letitle=' . 
urlencode( $title );
+                       if ( $limit != null ) $append .= '&lelimit=' . 
urlencode( $limit );
+                       if ( $type != null ) $append .= '&letype=' . urlencode( 
$type );
+                       if ( $start != null ) $append .= '&lestart=' . 
urlencode( $start );
+                       if ( $end != null ) $append .= '&leend=' . urlencode( 
$end );
+                       if ( $dir != null ) $append .= '&ledir=' . urlencode( 
$dir );
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&format=php&list=logevents&leprop=ids|title|type|user|timestamp|comment|details'
 . $append );
+                       $x = unserialize( $x );
+                       return $x['query']['logevents'];
+               }
+
+               /**
+                * Retrieves metadata about a user's contributions.
+                * @param $user Username whose contributions we want to 
retrieve.
+                * @param $count Number of entries to return.  (Default 50)
+                * @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)
+                * @param $dir Which direction to enumerate from, "older" or 
"newer".  (Default 'older')
+                * @return Associative array of contributions metadata.
+                **/
+               function usercontribs ( $user, $count = 50, &$continue = null, 
$dir = 'older' ) {
+                       if ( $continue != null ) {
+                               $append = '&ucstart=' . urlencode( $continue );
+                       } else {
+                               $append = '';
+                       }
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&format=php&list=usercontribs&ucuser=' . urlencode( $user ) . 
'&uclimit=' . urlencode( $count ) . '&ucdir=' . urlencode( $dir ) . $append );
+                       $x = unserialize( $x );
+                       $continue = 
$x['query-continue']['usercontribs']['ucstart'];
+                       return $x['query']['usercontribs'];
+               }
+
+               /**
+                * Returns revision data (meta and/or actual).
+                * @param $page Page for which to return revision data for.
+                * @param $count Number of revisions to return. (Default 1)
+                * @param $dir Direction to start enumerating multiple 
revisions from, "older" or "newer". (Default 'older')
+                * @param $content Whether to return actual revision content, 
true or false.  (Default false)
+                * @param $revid Revision ID to start at.  (Default null)
+                * @param $wait Whether or not to wait a few seconds for the 
specific revision to become available.  (Default true)
+                * @param $getrbtok Whether or not to retrieve a rollback token 
for the revision.  (Default false)
+                * @param $dieonerror Whether or not to kill the process with 
an error if an error occurs.  (Default false)
+                * @param $redirects Whether or not to follow redirects.  
(Default false)
+                * @return Associative array of revision data.
+                **/
+               function revisions ( $page, $count = 1, $dir = 'older', 
$content = false, $revid = null, $wait = true, $getrbtok = false, $dieonerror = 
true, $redirects = false ) {
+                       $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':'' 
) );
+                       $x = unserialize( $x );
+                       if ( $revid !== null ) {
+                               $found = false;
+                               if ( !isset( $x['query']['pages'] ) or 
!is_array( $x['query']['pages'] ) ) {
+                                       if ( $dieonerror == true ) die( 'No 
such page.' . "\n" );
+                                       else return false;
+                               }
+                               foreach ( $x['query']['pages'] as $data ) {
+                                       if ( !isset( $data['revisions'] ) or 
!is_array( $data['revisions'] ) ) {
+                                               if ( $dieonerror == true ) die( 
'No such page.' . "\n" );
+                                               else return false;
+                                       }
+                                       foreach ( $data['revisions'] as $data2 
) if ( $data2['revid'] == $revid ) $found = true;
+                                       unset( $data, $data2 );
+                                       break;
+                               }
+
+                               if ( $found == false ) {
+                                       if ( $wait == true ) {
+                                               sleep( 1 );
+                                               return $this->revisions( $page, 
$count, $dir, $content, $revid, false, $getrbtok, $dieonerror );
+                                       } else {
+                                               if ( $dieonerror == true ) die( 
'Revision error.' . "\n" );
+                                       }
+                               }
+                       }
+                       foreach ( $x['query']['pages'] as $key => $data ) {
+                               $data['revisions']['ns'] = $data['ns'];
+                               $data['revisions']['title'] = $data['title'];
+                               $data['revisions']['currentuser'] = 
$x['query']['userinfo']['name'];
+//                             $data['revisions']['currentuser'] = 
$x['query']['userinfo']['currentuser']['name'];
+                               if ( isset( $x['query-continue'] ) ) {
+                                       $data['revisions']['continue'] = 
$x['query-continue']['revisions']['rvstartid'];
+                               }
+                               $data['revisions']['pageid'] = $key;
+                               return $data['revisions'];
+                       }
+               }
+
+               /**
+                * Enumerates user metadata.
+                * @param $start The username to start enumerating from.  Null 
means from the beginning.  (Default null)
+                * @param $limit The number of users to enumerate.  (Default 1)
+                * @param $group The usergroup to filter by.  Null means no 
filtering.  (Default null)
+                * @param $requirestart Whether or not to require that $start 
be a valid username.  (Default false)
+                * @param[out] $continue This is filled with the name to 
continue from next query.  (Default null)
+                * @return Associative array of user metadata.
+                **/
+               function users ( $start = null, $limit = 1, $group = null, 
$requirestart = false, &$continue = null ) {
+                       $append = '';
+                       if ( $start != null ) $append .= '&aufrom=' . 
urlencode( $start );
+                       if ( $group != null ) $append .= '&augroup=' . 
urlencode( $group );
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&list=allusers&format=php&auprop=blockinfo|editcount|registration|groups&aulimit='
 . urlencode( $limit ) . $append );
+                       $x = unserialize( $x );
+                       $continue = $x['query-continue']['allusers']['aufrom'];
+                       if ( ( $requirestart == true ) and ( 
$x['query']['allusers'][0]['name'] != $start ) ) return false;
+                       return $x['query']['allusers'];
+               }
+
+               /**
+                * Get members of a category.
+                * @param $category Category to enumerate from.
+                * @param $count Number of members to enumerate.  (Default 500)
+                * @param[in,out] $continue Where to continue enumerating from. 
 This is automatically filled in when run.  (Default null)
+                * @return Associative array of category member metadata.
+                **/
+               function categorymembers ( $category, $count = 500, &$continue 
= null ) {
+                       if ( $continue != null ) {
+                               $append = '&cmcontinue=' . urlencode( $continue 
);
+                       } else {
+                               $append = '';
+                       }
+                       $category = 'Category:' . str_ireplace( 'category:', 
'', $category );
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&list=categorymembers&cmtitle=' . urlencode( $category ) . 
'&format=php&cmlimit=' . $count . $append );
+                       $x = unserialize( $x );
+                       $continue = 
$x['query-continue']['categorymembers']['cmcontinue'];
+                       return $x['query']['categorymembers'];
+               }
+
+               /**
+                * Enumerate all categories.
+                * @param[in,out] $start Where to start enumerating.  This is 
updated automatically with the value to continue from.  (Default null)
+                * @param $limit Number of categories to enumerate.  (Default 
50)
+                * @param $dir Direction to enumerate in.  'ascending' or 
'descending'.  (Default 'ascending')
+                * @param $prefix Only enumerate categories with this prefix.  
(Default null)
+                * @return Associative array of category list metadata.
+                **/
+               function listcategories ( &$start = null, $limit = 50, $dir = 
'ascending', $prefix = null ) {
+                       $append = '';
+                       if ( $start != null ) $append .= '&acfrom=' . 
urlencode( $start );
+                       if ( $limit != null ) $append .= '&aclimit=' . 
urlencode( $limit );
+                       if ( $dir != null ) $append .= '&acdir=' . urlencode( 
$dir );
+                       if ( $prefix != null ) $append .= '&acprefix=' . 
urlencode( $prefix );
+
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&list=allcategories&acprop=size&format=php' . $append );
+                       $x = unserialize( $x );
+
+                       $start = 
$x['query-continue']['allcategories']['acfrom'];
+
+                       return $x['query']['allcategories'];
+               }
+
+               /**
+                * Enumerate all backlinks to a page.
+                * @param $page Page to search for backlinks to.
+                * @param $count Number of backlinks to list.  (Default 500)
+                * @param[in,out] $continue Where to start enumerating from.  
This is automatically filled in.  (Default null)
+                * @param $filter Whether or not to include redirects.  
Acceptible values are 'all', 'redirects', and 'nonredirects'.  (Default null)
+                * @return Associative array of backlink metadata.
+                **/
+               function backlinks ( $page, $count = 500, &$continue = null, 
$filter = null ) {
+                       if ( $continue != null ) {
+                               $append = '&blcontinue=' . urlencode( $continue 
);
+                       } else {
+                               $append = '';
+                       }
+                       if ( $filter != null ) {
+                               $append .= '&blfilterredir=' . urlencode( 
$filter );
+                       }
+
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&list=backlinks&bltitle=' . urlencode( $page ) . 
'&format=php&bllimit=' . $count . $append );
+                       $x = unserialize( $x );
+                       $continue = 
$x['query-continue']['backlinks']['blcontinue'];
+                       return $x['query']['backlinks'];
+               }
+
+               /**
+                * Gets a list of transcludes embedded in a page.
+                * @param $page Page to look for transcludes in.
+                * @param $count Number of transcludes to list.  (Default 500)
+                * @param[in,out] $continue Where to start enumerating from.  
This is automatically filled in.  (Default null)
+                * @return Associative array of transclude metadata.
+                **/
+               function embeddedin ( $page, $count = 500, &$continue = null ) {
+                       if ( $continue != null ) {
+                               $append = '&eicontinue=' . urlencode( $continue 
);
+                       } else {
+                               $append = '';
+                       }
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&list=embeddedin&eititle=' . urlencode( $page ) . 
'&format=php&eilimit=' . $count . $append );
+                       $x = unserialize( $x );
+                       $continue = 
$x['query-continue']['embeddedin']['eicontinue'];
+                       return $x['query']['embeddedin'];
+               }
+
+               /**
+                * Gets a list of pages with a common prefix.
+                * @param $prefix Common prefix to search for.
+                * @param $namespace Numeric namespace to filter on.  (Default 
0)
+                * @param $count Number of pages to list.  (Default 500)
+                * @param[in,out] $continue Where to start enumerating from.  
This is automatically filled in.  (Default null)
+                * @return Associative array of page metadata.
+                **/
+               function listprefix ( $prefix, $namespace = 0, $count = 500, 
&$continue = null ) {
+                       $append = '&apnamespace=' . urlencode( $namespace );
+                       if ( $continue != null ) {
+                               $append .= '&apfrom=' . urlencode( $continue );
+                       }
+                       $x = $this->http->get( $this->apiurl . 
'?action=query&list=allpages&apprefix=' . urlencode( $prefix ) . 
'&format=php&aplimit=' . $count . $append );
+                       $x = unserialize( $x );
+                       $continue = $x['query-continue']['allpages']['apfrom'];
+                       return $x['query']['allpages'];
+               }
+
+               /**
+                * Edits a page.
+                * @param $page Page name to edit.
+                * @param $data Data to post to page.
+                * @param $summary Edit summary to use.
+                * @param $minor Whether or not to mark edit as minor.  
(Default false)
+                * @param $bot Whether or not to mark edit as a bot edit.  
(Default true)
+                * @param $wpStarttime Time in MW TS format of beginning of 
edit.  (Default now)
+                * @param $wpEdittime Time in MW TS format of last edit to that 
page.  (Default correct)
+                * @return boolean True on success, false on failure.
+                **/
+               function edit ( $page, $data, $summary = '', $minor = false, 
$bot = true, $wpStarttime = null, $wpEdittime = null, $checkrun = true ) {
+                       global $run, $user;
+
+                       $wpq = new wikipediaquery( $this->apiurl, 
$this->queryurl, $this->indexurl ); $wpq->queryurl = str_replace( 'api.php', 
'query.php', $this->apiurl );
+
+                       if ( $checkrun == true )
+                               if ( !preg_match( '/(yes|enable|true)/iS', ( ( 
isset( $run ) ) ? $run:$wpq->getpage( 'User:' . $user . '/Run' ) ) ) )
+                                       return false; /* Check /Run page */
+
+                       $params = Array(
+                               'action' => 'edit',
+                               'format' => 'php',
+                               'assert' => 'bot',
+                               'title' => $page,
+                               'text' => $data,
+                               'token' => $this->getedittoken(),
+                               'summary' => $summary,
+                               ( $minor ? 'minor':'notminor' ) => '1',
+                               ( $bot ? 'bot':'notbot' ) => '1'
+                       );
+
+                       if ( $wpStarttime !== null ) $params['starttimestamp'] 
= $wpStarttime;
+                       if ( $wpEdittime !== null ) $params['basetimestamp'] = 
$wpEdittime;
+
+                       $x = $this->http->post( $this->apiurl, $params );
+                       $x = unserialize( $x );
+                       var_export( $x );
+                       if ( $x['edit']['result'] == 'Success' ) return true;
+                       else return false;
+               }
+                
+                /**
+                * Uploads a file
+                * @param $page Page name to edit.
+                * @param $data Data to post to page.
+                * @param $summary Edit summary to use.
+                * @param $minor Whether or not to mark edit as minor.  
(Default false)
+                * @param $bot Whether or not to mark edit as a bot edit.  
(Default true)
+                * @param $wpStarttime Time in MW TS format of beginning of 
edit.  (Default now)
+                * @param $wpEdittime Time in MW TS format of last edit to that 
page.  (Default correct)
+                * @return boolean True on success, false on failure.
+                **/
+               function uploadFromString ( $page, $data, $summary = '', 
$checkrun = true ) {
+                       global $run, $user;
+
+                       $wpq = new wikipediaquery( $this->apiurl, 
$this->queryurl, $this->indexurl ); $wpq->queryurl = str_replace( 'api.php', 
'query.php', $this->apiurl );
+
+                       /*if ($checkrun == true)
+                               if 
(!preg_match('/(yes|enable|true)/iS',((isset($run))?$run:$wpq->getpage('User:'.$user.'/Run'))))
+                                       return false; /* Check /Run page */
+                                       
+
+                       /*$params = Array(
+                               'action' => 'upload',
+                               'filename' => $page,
+                               'file' => $data,
+                               'token' => $this->getedittoken(),
+                               'comment' => $summary
+                       );*/
+                       
+                       $params = Array(
+                               'action' => 'upload',
+                               'filename' => 'grokstar420',
+                               'file' => 'foo',
+                               'token' => $this->getedittoken(),
+                               'text' => 'yoyo',
+                               'comment' => 'yo'
+                       );
+
+                       $x = $this->http->post( $this->apiurl, $params );
+                       # $x = unserialize($x);
+                       # var_export($x);
+                       # if ($x['edit']['result'] == 'Success') return true;
+                       # else return false;
+               }
+
+               /**
+                * Moves a page.
+                * @param $old Name of page to move.
+                * @param $new New page title.
+                * @param $reason Move summary to use.
+                * @return void
+                **/
+               function move ( $old, $new, $reason ) {
+                       $tokens = $this->gettokens( $old );
+                       $params = array(
+                               'action' => 'move',
+                               'format' => 'php',
+                               'from' => $old,
+                               'to' => $new,
+                               'token' => $tokens['movetoken'],
+                               'reason' => $reason
+                       );
+
+                       $x = $this->http->post( $this->apiurl, $params );
+                       $x = unserialize( $x );
+                       var_export( $x );
+               }
+
+               /**
+                * Rollback an edit.
+                * @param $title Title of page to rollback.
+                * @param $user Username of last edit to the page to rollback.
+                * @param $reason Edit summary to use for rollback.
+                * @param $token Rollback token.  If not given, it will be 
fetched.  (Default null)
+                * @return void
+                **/
+               function rollback ( $title, $user, $reason, $token = null ) {
+                       if ( ( $token == null ) or ( $token == '' ) ) {
+                               $token = $this->revisions( $title, 1, 'older', 
false, null, true, true );
+                               print_r( $token );
+                               if ( $token[0]['user'] == $user ) {
+                                       $token = $token[0]['rollbacktoken'];
+                               } else {
+                                       return false;
+                               }
+                       }
+                       $params = array(
+                               'action' => 'rollback',
+                               'format' => 'php',
+                               'title' => $title,
+                               'user' => $user,
+                               'summary' => $reason,
+                               'token' => $token,
+                               'markbot' => 0
+                       );
+
+                       echo 'Posting to API: ';
+                       var_export( $params );
+                       
+                       $x = $this->http->post( $this->apiurl, $params );
+                       $x = unserialize( $x );
+                       var_export( $x );
+                       return ( isset( $x['rollback']['summary'] ) ? 
true:false );
+               }
+               
+               /**
+                * Inserts one or more page into the RPED table.
+                * @return True.
+                **/
+               function rpedInsert ( $page ) {
+                       $params = Array(
+                           'action' => 'rped',
+                           'format' => 'php',
+                           'insert' => $page,
+                               );
+       
+                               $x = $this->http->post( $this->apiurl, $params 
);
+                               $x = unserialize( $x );
+                               # var_export($x);
+                               return true;
+               }
+                
+               /**
+                * Deletes one or more pages from the RPED table.
+                * @return True.
+                **/
+               function rpedDelete ( $page ) {
+                       $params = Array(
+                           'action' => 'rped',
+                           'format' => 'php',
+                           'delete' => $page,
+                               );
+       
+                               $x = $this->http->post( $this->apiurl, $params 
);
+                               $x = unserialize( $x );
+                               # var_export($x);
+                               return true;
+               }
+       }
+
+       /**
+        * This class is for interacting with Wikipedia's browser interface, 
index.php.
+        * Many of these functions are deprecated.
+        **/
+       class wikipediaindex {
+               private $http;
+               private $postinterval = 0;
+               private $lastpost;
+               private $edittoken;
+               public $apiurl;
+               public $queryurl;
+               public $indexurl;
+
+               /**
+                * This is our constructor.
+                * @param $myApiurl API url; used if $fromFile is false
+                * @param $myQueryurl Query url; used if $fromFile is false
+                * @param $myIndexurl Index url; used if $fromFile is false
+                * @param $bot Bot name; used if $fromFile is true
+                * @param $wiki Wiki name; used if $fromFile is true
+                * @param $fromFile If true, load settings from 
wikibot.config.php
+                * @return void
+                **/
+               function __construct ( $myApiurl, $myQueryurl, $myIndexurl, 
$bot = '', $wiki = '', $fromFile = false ) {
+                       global $indexFunctionFile;
+                       if ( $fromFile == true ) {
+                               $this->apiurl = getWikibotSetting( 'apiurl', 
$bot, $wiki );
+                               $this->queryurl = getWikibotSetting( 
'queryurl', $bot, $wiki ); // Obsolete, but kept for compatibility purposes.
+                               $this->indexurl = getWikibotSetting( 
'indexurl', $bot, $wiki );
+                       } else {
+                               $this->apiurl = $myApiurl;
+                               $this->queryurl = $myQueryurl; // Obsolete, but 
kept for compatibility purposes.
+                               $this->indexurl = $myIndexurl;
+                       }
+                       if ( isset( $indexFunctionFile ) ) {
+                               foreach ( $indexFunctionFile as $item ) {
+                                       require_once( $item );
+                               }
+                       }
+                       global $__wp__http;
+                       if ( !isset( $__wp__http ) ) {
+                               $__wp__http = new http;
+                       }
+                       $this->http = &$__wp__http;
+               }
+
+               /**
+                * Post data to a page, nicely.
+                * @param $page Page title.
+                * @param $data Data to post to page.
+                * @param $summery Edit summary.  (Default '')
+                * @param $minor Whether to mark edit as minor.  (Default false)
+                * @param $rv Revision data.  If not given, it will be fetched. 
 (Default null)
+                * @param $bot Whether to mark edit as bot.  (Default true)
+                * @return HTML data from the page.
+                * @deprecated
+                * @see wikipediaapi::edit
+                **/
+               function post ( $page, $data, $summery = '', $minor = false, 
$rv = null, $bot = true ) {
+                       global $user;
+                       global $maxlag;
+                       global $irc;
+                       global $irctechchannel;
+                       global $run;
+                       global $maxlagkeepgoing;
+
+                       $wpq = new wikipediaquery ( $this->apiurl, 
$this->queryurl, $this->indexurl ); $wpq->queryurl = str_replace( 'index.php', 
'query.php', $this->indexurl );
+                       $wpapi = new wikipediaapi ( $this->apiurl, 
$this->queryurl, $this->indexurl ); $wpapi->apiurl = str_replace( 'index.php', 
'api.php', $this->indexurl );
+
+                       if ( ( !$this->edittoken ) or ( $this->edittoken == '' 
) ) $this->edittoken = $wpapi->getedittoken();
+                       if ( $rv == null ) $rv = $wpapi->revisions( $page, 1, 
'older', true );
+                       if ( !$rv[0]['*'] ) $rv[0]['*'] = $wpq->getpage( $page 
);
+
+                       // Fake the edit form.
+                       $now = gmdate( 'YmdHis', time() );
+                       $token = htmlspecialchars( $this->edittoken );
+                       $tmp = date_parse( $rv[0]['timestamp'] );
+                       $edittime = gmdate( 'YmdHis', gmmktime( $tmp['hour'], 
$tmp['minute'], $tmp['second'], $tmp['month'], $tmp['day'], $tmp['year'] ) );
+                       $html = "<input type='hidden' value=\"{$now}\" 
name=\"wpStarttime\" />\n";
+                       $html .= "<input type='hidden' value=\"{$edittime}\" 
name=\"wpEdittime\" />\n";
+                       $html .= "<input type='hidden' value=\"{$token}\" 
name=\"wpEditToken\" />\n";
+                       $html .= '<input name="wpAutoSummary" type="hidden" 
value="' . md5( '' ) . '" />' . "\n";
+
+                       if ( preg_match( '/' . preg_quote( '{{nobots}}', '/' ) 
. '/iS', $rv[0]['*'] ) ) { return false; }               /* Honor the bots 
flags */
+                       if ( preg_match( '/' . preg_quote( 
'{{bots|allow=none}}', '/' ) . '/iS', $rv[0]['*'] ) ) { return false; }
+                       if ( preg_match( '/' . preg_quote( '{{bots|deny=all}}', 
'/' ) . '/iS', $rv[0]['*'] ) ) { return false; }
+                       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 */
+                       if ( !preg_match( '/' . preg_quote( $user, '/' ) . 
'/iS', $rv['currentuser'] ) ) { return false; } /* We need to be logged in */
+//                     if (preg_match('/'.preg_quote('You have new 
messages','/').'/iS',$rv[0]['*'])) { return false; } /* Check talk page */
+                       if ( !preg_match( '/(yes|enable|true)/iS', ( ( isset( 
$run ) ) ? $run:$wpq->getpage( 'User:' . $user . '/Run' ) ) ) ) { return false; 
} /* Check /Run page */
+
+                       $x = $this->forcepost( $page, $data, $summery, $minor, 
$html, $maxlag, $maxlagkeepgoing, $bot ); /* Go ahead and post. */
+                       $this->lastpost = time();
+                       return $x;
+               }
+
+               /**
+                * Post data to a page.
+                * @param $page Page title.
+                * @param $data Data to post to page.
+                * @param $summery Edit summary.  (Default '')
+                * @param $minor Whether to mark edit as minor.  (Default false)
+                * @param $edithtml HTML from the edit form.  If not given, it 
will be fetched.  (Default null)
+                * @param $maxlag Maxlag for posting.  (Default null)
+                * @param $mlkg Whether to keep going after encountering a 
maxlag error and sleeping or not.  (Default null)
+                * @param $bot Whether to mark edit as bot.  (Default true)
+                * @return HTML data from the page.
+                * @deprecated
+                * @see wikipediaapi::edit
+                **/
+               function forcepost ( $page, $data, $summery = '', $minor = 
false, $edithtml = null, $maxlag = null, $mlkg = null, $bot = true ) {
+                       $post['wpSection'] = '';
+                       $post['wpScrolltop'] = '';
+                       if ( $minor == true ) { $post['wpMinoredit'] = 1; }
+                       $post['wpTextbox1'] = $data;
+                       $post['wpSummary'] = $summery;
+                       if ( $edithtml == null ) {
+                               $html = $this->http->get( $this->indexurl . 
'?title=' . urlencode( $page ) . '&action=edit' );
+                       } else {
+                               $html = $edithtml;
+                       }
+                       preg_match( '|\<input type\=\\\'hidden\\\' 
value\=\"(.*)\" name\=\"wpStarttime\" /\>|U', $html, $m );
+                       $post['wpStarttime'] = $m[1];
+                       preg_match( '|\<input type\=\\\'hidden\\\' 
value\=\"(.*)\" name\=\"wpEdittime\" /\>|U', $html, $m );
+                       $post['wpEdittime'] = $m[1];
+                       preg_match( '|\<input type\=\\\'hidden\\\' 
value\=\"(.*)\" name\=\"wpEditToken\" /\>|U', $html, $m );
+                       $post['wpEditToken'] = $m[1];
+                       preg_match( '|\<input name\=\"wpAutoSummary\" 
type\=\"hidden\" value\=\"(.*)\" /\>|U', $html, $m );
+                       $post['wpAutoSummary'] = $m[1];
+                       if ( $maxlag != null ) {
+                               $x = $this->http->post( $this->indexurl . 
'?title=' . urlencode( $page ) . '&action=submit&maxlag=' . urlencode( $maxlag 
) . '&bot=' . ( ( $bot == true ) ? '1':'0' ), $post );
+                               if ( preg_match( '/Waiting for ([^ ]*): 
([0-9.-]+) seconds lagged/S', $x, $lagged ) ) {
+                                       global $irc;
+                                       if ( is_resource( $irc ) ) {
+                                               global $irctechchannel;
+                                               foreach ( explode( ',', 
$irctechchannel ) as $y ) {
+                                                       # fwrite($irc,'PRIVMSG 
'.$y.' :'.$lagged[1].' is lagged out by '.$lagged[2].' seconds. 
('.$lagged[0].')'."\n");
+                                               }
+                                       }
+                                       sleep( 10 );
+                                       if ( $mlkg != true ) { return false; }
+                                       else { $x = $this->http->post( 
$this->indexurl . '?title=' . urlencode( $page ) . '&action=submit&bot=' . ( ( 
$bot == true ) ? '1':'0' ), $post ); }
+                               }
+                               return $x;
+                       } else {
+                               return $this->http->post( $this->indexurl . 
'?title=' . urlencode( $page ) . '&action=submit&bot=' . ( ( $bot == true ) ? 
'1':'0' ), $post );
+                       }
+               }
+
+               /**
+                * Get a diff.
+                * @param $title Page title to get the diff of.
+                * @param $oldid Old revision ID.
+                * @param $id New revision ID.
+                * @param $wait Whether or not to wait for the diff to become 
available.  (Default true)
+                * @return Array of added data, removed data, and a rollback 
token if one was fetchable.
+                **/
+               function diff ( $title, $oldid, $id, $wait = true ) {
+                       $deleted = '';
+                       $added = '';
+
+                       $html = $this->http->get( $this->indexurl . '?title=' . 
urlencode( $title ) . '&action=render&diff=' . urlencode( $id ) . '&oldid=' . 
urlencode( $oldid ) . '&diffonly=1' );
+
+                       if ( preg_match_all( 
'/\&amp\;(oldid\=)(\d*)\\\'\>(Revision as of|Current revision as of)/USs', 
$html, $m, PREG_SET_ORDER ) ) {
+                               // print_r($m);
+                               if ( ( ( $oldid != $m[0][2] ) and ( is_numeric( 
$oldid ) ) ) or ( ( $id != $m[1][2] ) and ( is_numeric( $id ) ) ) ) {
+                                       if ( $wait == true ) {
+                                               sleep( 1 );
+                                               return $this->diff( $title, 
$oldid, $id, false );
+                                       } else {
+                                               echo 'OLDID as detected: ' . 
$m[0][2] . ' Wanted: ' . $oldid . "\n";
+                                               echo 'NEWID as detected: ' . 
$m[1][2] . ' Wanted: ' . $id . "\n";
+                                               echo $html;
+                                               die( 'Revision error.' . "\n" );
+                                       }
+                               }
+                       }
+                       
+                       if ( preg_match_all( '/\<td 
class\=(\"|\\\')diff-addedline\1\>\<div\>(.*)\<\/div\>\<\/td\>/USs', $html, $m, 
PREG_SET_ORDER ) ) {
+                               // print_r($m);
+                               foreach ( $m as $x ) {
+                                       $added .= htmlspecialchars_decode( 
strip_tags( $x[2] ) ) . "\n";
+                               }
+                       }
+
+                       if ( preg_match_all( '/\<td 
class\=(\"|\\\')diff-deletedline\1\>\<div\>(.*)\<\/div\>\<\/td\>/USs', $html, 
$m, PREG_SET_ORDER ) ) {
+                               // print_r($m);
+                               foreach ( $m as $x ) {
+                                       $deleted .= htmlspecialchars_decode( 
strip_tags( $x[2] ) ) . "\n";
+                               }
+                       }
+
+                       // echo $added."\n".$deleted."\n";
+
+                       if ( preg_match( 
'/action\=rollback\&amp\;from\=.*\&amp\;token\=(.*)\"/US', $html, $m ) ) {
+                               $rbtoken = $m[1];
+                               $rbtoken = urldecode( $rbtoken );
+//                             echo 'rbtoken: '.$rbtoken.' -- '; print_r($m); 
echo "\n\n";
+                               return array( $added, $deleted, $rbtoken );
+                       }
+
+                       return array( $added, $deleted );
+               }
+
+               /**
+                * Rollback an edit.
+                * @param $title Page title to rollback.
+                * @param $user Username of last edit to the page to rollback.
+                * @param $reason Reason to rollback.  If null, default is 
generated.  (Default null)
+                * @param $token Rollback token to use.  If null, it is 
fetched.  (Default null)
+                * @param $bot Whether or not to mark as bot.  (Default true)
+                * @return HTML or false if failure.
+                * @deprecated
+                * @see wikipediaapi::rollback
+                **/
+               function rollback ( $title, $user, $reason = null, $token = 
null, $bot = true ) {
+                       if ( ( $token == null ) or ( !$token ) ) {
+                               $wpapi = new wikipediaapi( $this->apiurl, 
$this->queryurl, $this->indexurl ); $wpapi->apiurl = str_replace( 'index.php', 
'api.php', $this->indexurl );
+                               $token = $wpapi->revisions( $title, 1, 'older', 
false, null, true, true );
+                               if ( $token[0]['user'] == $user ) {
+//                                     echo 'Token: '; print_r($token); echo 
"\n\n";
+                                       $token = $token[0]['rollbacktoken'];
+                               } else {
+                                       return false;
+                               }
+                       }
+                       $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' ) );
+                       # global $logfd; if (!is_resource($logfd)) $logfd = 
fopen('php://stderr','w'); fwrite($logfd,'Rollback return: '.$x."\n");
+                       if ( !preg_match( '/action complete/iS', $x ) ) return 
false;
+                       return $x;
+               }
+
+               /**
+                * Move a page.
+                * @param $old Page title to move.
+                * @param $new New title to move to.
+                * @param $reason Move page summary.
+                * @return HTML page.
+                * @deprecated
+                * @see wikipediaapi::move
+                **/
+               function move ( $old, $new, $reason ) {
+                       $wpapi = new wikipediaapi( $this->apiurl, 
$this->queryurl, $this->indexurl ); $wpapi->apiurl = str_replace( 'index.php', 
'api.php', $this->indexurl );
+                       if ( ( !$this->edittoken ) or ( $this->edittoken == '' 
) ) $this->edittoken = $wpapi->getedittoken();
+
+                       $token = htmlspecialchars( $this->edittoken );
+
+                       $post = array
+                               (
+                                       'wpOldTitle'    => $old,
+                                       'wpNewTitle'    => $new,
+                                       'wpReason'      => $reason,
+                                       'wpWatch'       => '0',
+                                       'wpEditToken'   => $token,
+                                       'wpMove'        => 'Move page'
+                               );
+                       return $this->http->post( $this->indexurl . 
'?title=Special:Movepage&action=submit', $post );
+               }
+
+               /**
+                * Uploads a file.
+                * @param $page Name of page on the wiki to upload as.
+                * @param $file Name of local file to upload.
+                * @param $desc Content of the file description page.
+                * @return HTML content.
+                **/
+               function upload ( $page, $file, $desc ) {
+                       $post = array
+                               (
+                                       'wpUploadFile'          => '@' . $file,
+                                       'wpSourceType'          => 'file',
+                                       'wpDestFile'            => $page,
+                                       'wpUploadDescription'   => $desc,
+                                       'wpLicense'             => '',
+                                       'wpWatchthis'           => '0',
+                                       'wpIgnoreWarning'       => '1',
+                                       'wpUpload'              => 'Upload file'
+                               );
+                       return $this->http->post( $this->indexurl . 
'?title=Special:Upload&action=submit', $post );
+               }
+                
+               /**
+                * Check if a user has email enabled.
+                * @param $user Username to check whether or not the user has 
email enabled.
+                * @return True or false depending on whether or not the user 
has email enabled.
+                **/
+               function hasemail ( $user ) {
+                       $tmp = $this->http->get( $this->indexurl . 
'?title=Special:EmailUser&target=' . urlencode( $user ) );
+                       if ( stripos( $tmp, "No e-mail address" ) !== false ) 
return false;
+                       return true;
+               }
+
+               /**
+                * Sends an email to a user.
+                * @param $user Username to send email to.
+                * @param $subject Subject of email to send.
+                * @param $body Body of email to send.
+                * @return HTML content.
+                **/
+               function email ( $user, $subject, $body ) {
+                       $wpapi = new wikipediaapi( $this->apiurl, 
$this->queryurl, $this->indexurl ); $wpapi->apiurl = str_replace( 'index.php', 
'api.php', $this->indexurl );
+                       if ( ( !$this->edittoken ) or ( $this->edittoken == '' 
) ) $this->edittoken = $wpapi->getedittoken();
+
+                       $post = array
+                               (
+                                       'wpSubject'     => $subject,
+                                       'wpText'        => $body,
+                                       'wpCCMe'        => 0,
+                                       'wpSend'        => 'Send',
+                                       'wpEditToken'   => $this->edittoken
+                               );
+
+                       return $this->http->post( $this->indexurl . 
'?title=Special:EmailUser&target=' . urlencode( $user ) . '&action=submit', 
$post );
+               }
+       }
\ No newline at end of file

Added: trunk/tools/wikibot/wikibot.config.php
===================================================================
--- trunk/tools/wikibot/wikibot.config.php                              (rev 0)
+++ trunk/tools/wikibot/wikibot.config.php      2010-06-02 20:50:44 UTC (rev 
67244)
@@ -0,0 +1,6 @@
+<?php
+$wikibotSetting['user']['TestBot']['Testwiki'] = 'TestBot';
+$wikibotSetting['pass']['TestBot']['Testwiki'] = 'password';
+$wikibotSetting['apiurl']['*']['Testwiki'] = 'http://testwiki.org/w/api.php';
+$wikibotSetting['queryurl']['*']['Testwiki'] = 
'http://testwiki.org/w/query.php';
+$wikibotSetting['indexurl']['*']['Testwiki'] = 
'http://testwiki.org/w/index.php';
\ No newline at end of file



_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to