00001 <?php
00012
00013 if ( getenv( 'MW_INSTALL_PATH' ) !== false ) {
00014 $IP = getenv( 'MW_INSTALL_PATH' );
00015 } else {
00016 $dir = __DIR__;
00017 $IP = "$dir/../../..";
00018 }
00019 require_once "$IP/maintenance/Maintenance.php";
00020
00021 # Override the memory limit for wfShellExec, 100 MB appears to be too little
00022 $wgMaxShellMemory = 1024 * 200;
00023
00024 class Fuzzy extends Maintenance {
00025 public function __construct() {
00026 parent::__construct();
00027 $this->mDescription = 'Fuzzy bot command line script.';
00028 $this->addArg(
00029 'messages',
00030 'Message to fuzzy'
00031 );
00032 $this->addOption(
00033 'really',
00034 '(optional) Really fuzzy, no dry-run'
00035 );
00036 $this->addOption(
00037 'skiplanguages',
00038 '(optional) Skip some languages (comma separated)',
00039 false,
00040 true
00041 );
00042 $this->addOption(
00043 'comment',
00044 '(optional) Comment for updating',
00045 false,
00046 true
00047 );
00048 }
00049
00050 public function execute() {
00051 $bot = new FuzzyScript( $this->getArg( 0 ) );
00052
00053 if ( $this->hasOption( 'skiplanguages' ) ) {
00054 $bot->skipLanguages = array_map(
00055 'trim',
00056 explode( ',', $this->getOption( 'skiplanguages' ) )
00057 );
00058 }
00059
00060 $bot->comment = $this->getOption( 'comment' );
00061 $bot->dryrun = !$this->hasOption( 'really' );
00062 $bot->setProgressCallback( array( $this, 'myOutput' ) );
00063 $bot->execute();
00064 }
00065
00073 public function myOutput( $text, $channel = null, $error = false ) {
00074 if ( $error ) {
00075 $this->error( $text, $channel );
00076 } else {
00077 $this->output( $text, $channel );
00078 }
00079 }
00080 }
00081
00085 class FuzzyScript {
00089 private $titles = array();
00090
00094 private $allclear = false;
00095
00097 protected $progressCallback;
00098
00102 public $dryrun = true;
00103
00107 public $comment = null;
00108
00112 public $skipLanguages = array();
00113
00117 public function __construct( $titles ) {
00118 $this->titles = (array)$titles;
00119 $this->allclear = true;
00120 }
00121
00122 public function setProgressCallback( $callback ) {
00123 $this->progressCallback = $callback;
00124 }
00125
00127 protected function reportProgress( $text, $channel, $severity = 'status' ) {
00128 if ( is_callable( $this->progressCallback ) ) {
00129 $useErrorOutput = $severity === 'error';
00130 call_user_func( $this->progressCallback, $text, $channel, $useErrorOutput );
00131 }
00132 }
00133
00134 public function execute() {
00135 if ( !$this->allclear ) {
00136 return;
00137 }
00138
00139 $msgs = $this->getPages();
00140 $count = count( $msgs );
00141 $this->reportProgress( "Found $count pages to update.", 'pagecount' );
00142
00143 foreach ( $msgs as $phpIsStupid ) {
00144 list( $title, $text ) = $phpIsStupid;
00145 $this->updateMessage( $title, TRANSLATE_FUZZY . $text, $this->dryrun, $this->comment );
00146 unset( $phpIsStupid );
00147 }
00148 }
00149
00151 private function getPages() {
00152 global $wgTranslateMessageNamespaces;
00153 $dbr = wfGetDB( DB_SLAVE );
00154
00155 $search = array();
00156 foreach ( $this->titles as $title ) {
00157 $title = Title::newFromText( $title );
00158 $ns = $title->getNamespace();
00159 if ( !isset( $search[$ns] ) ) {
00160 $search[$ns] = array();
00161 }
00162 $search[$ns][] = 'page_title' . $dbr->buildLike( $title->getDBKey(), $dbr->anyString() );
00163 }
00164
00165 $title_conds = array();
00166 foreach ( $search as $ns => $names ) {
00167 if ( $ns == NS_MAIN ) {
00168 $ns = $wgTranslateMessageNamespaces;
00169 }
00170 $titles = $dbr->makeList( $names, LIST_OR );
00171 $title_conds[] = $dbr->makeList( array( 'page_namespace' => $ns, $titles ), LIST_AND );
00172 }
00173
00174 $conds = array(
00175 'page_latest=rev_id',
00176 'rev_text_id=old_id',
00177 $dbr->makeList( $title_conds, LIST_OR ),
00178 );
00179
00180 if ( count( $this->skipLanguages ) ) {
00181 $skiplist = $dbr->makeList( $this->skipLanguages );
00182 $conds[] = "substring_index(page_title, '/', -1) NOT IN ($skiplist)";
00183 }
00184
00185 $rows = $dbr->select(
00186 array( 'page', 'revision', 'text' ),
00187 array( 'page_title', 'page_namespace', 'old_text', 'old_flags' ),
00188 $conds,
00189 __METHOD__
00190 );
00191
00192 $messagesContents = array();
00193 foreach ( $rows as $row ) {
00194 $title = Title::makeTitle( $row->page_namespace, $row->page_title );
00195 $messagesContents[] = array( $title, Revision::getRevisionText( $row ) );
00196 }
00197
00198 $rows->free();
00199
00200 return $messagesContents;
00201 }
00202
00210 private function updateMessage( $title, $text, $dryrun, $comment = null ) {
00211 global $wgTranslateDocumentationLanguageCode;
00212
00213 $this->reportProgress( "Updating {$title->getPrefixedText()}... ", $title );
00214 if ( !$title instanceof Title ) {
00215 $this->reportProgress( "INVALID TITLE!", $title );
00216
00217 return;
00218 }
00219
00220 $items = explode( '/', $title->getText(), 2 );
00221 if ( isset( $items[1] ) && $items[1] === $wgTranslateDocumentationLanguageCode ) {
00222 $this->reportProgress( "IGNORED!", $title );
00223
00224 return;
00225 }
00226
00227 if ( $dryrun ) {
00228 $this->reportProgress( "DRY RUN!", $title );
00229
00230 return;
00231 }
00232
00233 $wikipage = new WikiPage( $title );
00234
00235 $status = $wikipage->doEdit(
00236 $text,
00237 $comment ? $comment : 'Marking as fuzzy',
00238 EDIT_FORCE_BOT | EDIT_UPDATE,
00239 false,
00240 FuzzyBot::getUser()
00241 );
00242
00243 $success = $status === true || ( is_object( $status ) && $status->isOK() );
00244 $this->reportProgress( $success ? 'OK' : 'FAILED', $title );
00245 }
00246 }
00247
00248 $maintClass = 'Fuzzy';
00249 require_once RUN_MAINTENANCE_IF_MAIN;