User:Leucosticte/mirrorPushBot.php

 * version 1.0.2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html */

// "q" (queue) Three options: -qrev, qus // "r" (repeat) Three options: -ro (onetime), -rd (continuous, using defaults), // r $usage = 'Usage: php mirrorpushbot.php -q' . '[-r]' . "\n"; $options = getopt( 'q:r:'); $allowableOptions['q'] = array( 'rc', 'rev', 'us', 'all' ); $allowableOptions['r'] = array( 'o', 'd', ); if ( !isset ( $options['q'] ) ) {     $options['q'] = 'all'; } if ( !in_array ( $options[ 'q' ], $allowableOptions['q'] ) ) {      die ( $usage ); } if ( !isset ( $options['r'] ) ) {      $options['r'] = 'd'; // Default to continuous, using defaults } elseif ( !in_array ( $options[ 'r' ], $allowableOptions['r'] ) ) {      if ( !is_int ( $options['r'] ) ) { // Microseconds option            die ( $usage );      } else {            $sleepMicroseconds = $options['r'];      } }

/* Set up bot classes. */ require_once( 'mirrorInitializeDb.php' ); require_once( "$botClassesPath/botclasses.php" ); $wiki     = new wikipedia; $wiki->setUserAgent( $userAgent ); $wiki->url = $localWikiUrl[$localWikiName]; $wiki->login( $pushUser, $pushPass ); $token = urlencode ( $wiki->getedittoken ); // Some long URLs will cause problems if we try to display the whole thing $wiki->__set('quiet','soft');

$keepGoing = true; $offset = 0; while ( $keepGoing ) { $query = "SELECT * FROM mb_queue WHERE mbq_status<>'pushed' AND " . "mbq_status<>'needsundeletion' LIMIT 1 ORDER BY mbq_timestamp ASC"; if ( $offset > 0 ) { $query .= " OFFSET $offset"; }     $mbRet = $db->query( $query ); if ( !$mbRet || !$mbRet->num_rows ) { echo( "No more rows to push! Waiting for mirrorPullBot to add more unpushed "                . "rows...\n"); usleep( $defaultMicroseconds['push'] ); continue; }     $row = $mbRet->fetch_assoc; if ( $row['mbq_status'] == 'needsrev' ) { echo "Reached a needsrev row! Waiting for mirrorPullBot to add the necessary " . "data...\n"; usleep( $defaultMicroseconds['push'] ); continue; }     if ( $row['mbq_status'] == 'needscheckpresence' ) { echo "Reached a needscheckpresence row! Queueing up 500\n"; usleep( $defaultMicroseconds['push'] ); continue; }     $action = $row['mbq_action']; $pushMapping = null; $continueThis = false; $data = array; switch ( $row['mbq_action'] ) { case 'mirrorlogentry': $pushMapping = getMirrorLogEntryPushMapping( $row ); $row['mbq_user'] = '0'; break; case 'mirrormove': $pushMapping = getMirrorMovePushMapping( $row ); break; case 'mirrordelete': $pushMapping = getMirrorDeletePushMapping( $row ); break; case 'mirroredit': $pushMapping = getMirrorEditPushMapping( $row ); $query = "SELECT * FROM mb_text WHERE mbt_id=". $row['mbq_text_id']; $textRet = $db->query( $query ); if ( !$textRet || !$textRet->num_rows ) { die( "mbt_id " . $row['mbq_text_id'] . " not found in mb_text!\n" ); }                 $textRow = $textRet->fetch_assoc; $data['oldtext'] = $textRow['mbt_text']; break; case 'mirrorundelete': // Get 500 rows of these $query = "SELECT * FROM mb_queue WHERE mbq_status='mirrorundelete' " . "LIMIT 500 ORDER BY mbq_timestamp ASC"; $checkPresenceRet = $db->query( $query ); $value = array; $revIds = array; while ( $value = $ret->fetch_assoc ) { $revIds[] = $value[ 'mbq_rev_id' ]; }                 $firstRevId = true; $queryChunk = ''; foreach( $revIds as $revId ) { if( !$firstRevId ) { $queryChunk .= '|'; }                       $firstRevId = false; $queryChunk .= $revId; }                 $query = "?action=query&prop=revisions&rvprop=user|comment|content|ids" . "|contentmodel&revids=". $queryChunk. '&format=php'; $ret = $wiki->query( $query, true ); if ( !$ret ) { echo "Did not retrieve any revisions from query; skipping back around\n"; break; }

// TODO: Finish all this. The revisions should be marked as pushed or needsrev // based on the results returned by the API. Then we should skip back around. default: $offset = $row['mbq_id']; $continueThis = true; }     if ( $continueThis ) { continue; }     $query = "?action=$action&format=php&token=$token"; foreach( $pushMapping as $pushMappingKey => $pushMappingValue ) { $data[$pushMappingKey] = $row[$pushMappingValue]; }     $localRet = $wiki->query ( $query, $data ); // POST var_dump ( $localRet ); if ( !$localRet ) { die ( "Nothing was returned\n" ); }     if ( isset( $localRet['error' ] ) ) { die( "The $localWikiName API returned an error message!\n" ); }     if ( isset( $localRet['mirrorlogentry']['timestamp'] ) ) { $pushTimestamp = $localRet['mirrorlogentry']['timestamp']; }     if ( isset( $localRet['mirroredit']['timestamp'] ) ) { $pushTimestamp = $localRet['mirroredit']['timestamp']; }     if ( isset( $localRet['mirrormove']['timestamp'] ) ) { $pushTimestamp = $localRet['mirrormove']['timestamp']; }     if ( isset( $localRet['mirrordelete']['timestamp'] ) ) { $pushTimestamp = $localRet['mirrormove']['timestamp']; }     $pushStatusQuery = "UPDATE mb_queue SET mbq_status='pushed', mbq_push_timestamp='" . $pushTimestamp . "' WHERE mbq_id=". $row['mbq_id']; $pushResult = $db->query ( $pushStatusQuery ); if ( !$pushResult ) { logFailure( "Failure updating mb_queue with push timestamp $pushTimestamp\n" ); logFailure ( $db->error_list ); echo "\n"; } } function getMirrorLogEntryPushMapping( $row ) { $pushMapping = array(	   'logid' => 'mbq_log_id',	    'logtype' => 'mbq_log_type',	    'logaction' => 'mbq_log_action',	    'logtimestamp' => 'mbq_timestamp',	    'loguser' => 'mbq_user', // This will actually be left as zero	    'lognamespace' => 'mbq_namespace',	    'logusertext' => 'mbq_user_text',	    'logtitle' => 'mbq_title',	    'logcomment' => 'mbq_comment',	    'logparams' => 'mbq_log_params',	    'logpage' => 'mbq_page_id',            'logdeleted' => 'mbq_deleted',            'tstags' => 'mbq_tags'      ); return $pushMapping; }

function getMirrorMovePushMapping ( $row ) { $pushMapping = array(	   'logid' => 'mbq_log_id',	    'logtimestamp' => 'mbq_timestamp',	    'loguser' => 'mbq_user', // This will actually be left as zero            'logusertext' => 'mbq_user_text',	    'lognamespace' => 'mbq_namespace',	    'logtitle' => 'mbq_title',	    'logcomment' => 'mbq_comment',	    'logparams' => 'mbq_log_params',	    'logpage' => 'mbq_page_id',            'logdeleted' => 'mbq_deleted',            'tstags' => 'mbq_tags',            'rcid' => 'mbq_rc_id',            'rcbot' => 'mbq_rc_bot',            'rcpatrolled' => 'mbq_rc_patrolled',            'comment2' => 'mbq_comment2', // Comment to use in the redirect and null revision            'nullrevid' => 'mbq_rev_id',            'nullrevparentid' => 'mbq_rc_last_oldid',            'redirrevid' => 'mbq_rev_id2'      ); return $pushMapping; }

function getMirrorDeletePushMapping ( $row ) { $pushMapping = array(	   'logid' => 'mbq_log_id',	    'logtimestamp' => 'mbq_timestamp',	    'loguser' => 'mbq_user', // This will actually be left as zero            'logusertext' => 'mbq_user_text',	    'lognamespace' => 'mbq_namespace',	    'logtitle' => 'mbq_title',	    'logcomment' => 'mbq_comment',	    'logparams' => 'mbq_log_params',	    'logpage' => 'mbq_page_id',            'logdeleted' => 'mbq_deleted',            'tstags' => 'mbq_tags',            'rcid' => 'mbq_rc_id',            'rcbot' => 'mbq_rc_bot',            'rcpatrolled' => 'mbq_rc_patrolled',      ); return $pushMapping; }

function getMirrorEditPushMapping ( $row ) { $pushMapping = array(           'revid' => 'mbq_rev_id',            'revpage' => 'mbq_page_id',            'revcomment' => 'mbq_comment',            'revuser' => 'mbq_user',            'revusertext' => 'mbq_user_text',            'revtimestamp' => 'mbq_timestamp',            'revminoredit' => 'mbq_minor',            'revlen' => 'mbq_len',            'revsha1' => 'mbq_rev_sha1',            'revcontentmodel' => 'mbq_rev_content_model',            'revcontentformat' => 'mbq_rev_content_format',            'revdeleted' => 'mbq_deleted',            'rcid' => 'mbq_rc_id',            'rcnamespace' => 'mbq_namespace',            'rctitle' => 'mbq_title',            'rcbot' => 'mbq_rc_bot',            'rcnew' => 'mbq_rc_new',            'rcoldlen' => 'mbq_rc_old_len',            'rclastoldid' => 'mbq_rc_last_oldid',            'rctype' => 'mbq_rc_type',            'rcsource' => 'mbq_rc_source', 'rcpatrolled' => 'mbq_rc_patrolled', 'tstags' => 'mbq_tags' );     return $pushMapping; }