User:Jim Carter/Bot
Classes (JimmyBot.classes.php)
<?PHP
/**
* @author Jim Carter
**/
/**
* This class is designed to provide a simplified interface to cURL which maintains cookies.
* @author Jim
**/
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, $proxytype;
$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,isset( $proxytype ) ? $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 $queryurl = 'http://en.wikipedia.org/w/query.php'; //Obsolete, but kept for compatibility purposes.
/**
* This is our constructor.
* @return void
**/
function __construct () {
global $__wp__http;
if (!isset($__wp__http)) {
$__wp__http = new http;
}
$this->http = &$__wp__http;
$this->api = new wikipediaapi;
}
/**
* 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);
return $ret[0]['*'];
}
/**
* 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;
private $user, $pass;
public $apiurl = 'http://en.wikipedia.org/w/api.php';
/**
* This is our constructor.
* @return void
**/
function __construct () {
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 corrisponds to the username.
* @return void
**/
function login ($user,$pass) {
$this->user = $user;
$this->pass = $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'];
$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; $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;
if ($x['error']['code'] == 'badtoken') {
if($this->login($this->user,$this->pass)) {
$this->gettokens('Main Page',true);
return $this->edit($page,$data,$summary,$minor,$bot,$wpStarttime,$wpEdittime,$checkrun);
} else
return false;
}
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']) and isset( $x[ 'rollback' ][ 'revid' ] ) and $x[ 'rollback' ][ 'revid' ] )
? true
: false;
}
}
/**
* This class is for interacting with Wikipedia's browser interface, index.php.
* Many of these functions are deprecated.
**/
class wikipediaindex {
private $http;
public $indexurl = 'http://en.wikipedia.org/w/index.php';
private $postinterval = 0;
private $lastpost;
private $edittoken;
/**
* This is our constructor.
* @return void
**/
function __construct () {
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; $wpq->queryurl = str_replace('index.php','query.php',$this->indexurl);
$wpapi = new wikipediaapi; $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('/\&\;(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\&\;from\=.*\&\;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; $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; $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; $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);
}
}
?>
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.