public static function sourceExport(RequestContext $context, TranslateTask $task = null, MessageGroup $group, array $options) { if ($task || $options['taction'] !== 'export' || !$group instanceof WikiPageMessageGroup) { return true; } $page = TranslatablePage::newFromTitle($group->getTitle()); $collection = $group->initCollection($options['language']); $collection->loadTranslations(DB_MASTER); $text = $page->getParse()->getTranslationPageText($collection); $display = $page->getPageDisplayTitle($options['language']); if ($display) { $text = "{{DISPLAYTITLE:{$display}}}{$text}"; } $output = Html::element('textarea', array('rows' => 25), $text); $context->getOutput()->addHtml($output); return false; }
/** * @param MessageGroup $group * @param string $code Language code * @return int[] ( total, translated, fuzzy, proofread ) */ protected static function calculateGroup($group, $code) { global $wgTranslateDocumentationLanguageCode; # Calculate if missing and store in the db $collection = $group->initCollection($code); if ($code === $wgTranslateDocumentationLanguageCode) { $ffs = $group->getFFS(); if ($ffs instanceof GettextFFS) { $template = $ffs->read('en'); $infile = array(); foreach ($template['TEMPLATE'] as $key => $data) { if (isset($data['comments']['.'])) { $infile[$key] = '1'; } } $collection->setInFile($infile); } } $collection->filter('ignored'); $collection->filter('optional'); // Store the count of real messages for later calculation. $total = count($collection); // Count fuzzy first. $collection->filter('fuzzy'); $fuzzy = $total - count($collection); // Count the completed translations. $collection->filter('hastranslation', false); $translated = count($collection); // Count how many of the completed translations // have been proofread $collection->filter('reviewer', false); $proofread = count($collection); return array(self::TOTAL => $total, self::TRANSLATED => $translated, self::FUZZY => $fuzzy, self::PROOFREAD => $proofread); }
protected function exportGroup(MessageGroup $group, $multi = false) { // Make sure all existing connections are dead, // we can't use them in forked children. LBFactory::destroyInstance(); $server = TTMServer::primary(); $id = $group->getId(); $sourceLanguage = $group->getSourceLanguage(); if ($multi) { $stats = MessageGroupStats::forGroup($id); $this->statusLine("Loaded stats for {$id}\n"); } else { $this->statusLine("Loading stats... ", 4); $stats = MessageGroupStats::forGroup($id); $this->output("done!", 4); $this->statusLine("Inserting sources: ", 5); } $collection = $group->initCollection($sourceLanguage); $collection->filter('ignored'); $collection->filter('optional'); $collection->initMessages(); $sids = array(); $counter = 0; foreach ($collection->keys() as $mkey => $title) { $def = $collection[$mkey]->definition(); $sids[$mkey] = $server->insertSource($title, $sourceLanguage, $def); if (++$counter % $this->mBatchSize === 0 && !$multi) { wfWaitForSlaves(10); $this->output('.', 5); } } $total = count($sids); if ($multi) { $this->statusLine("Inserted {$total} source entries for {$id}\n"); } else { $this->output("{$total} entries", 5); $this->statusLine("Inserting translations...", 6); } $dbw = $server->getDB(DB_MASTER); foreach ($stats as $targetLanguage => $numbers) { if ($targetLanguage === $sourceLanguage) { continue; } if ($numbers[MessageGroupStats::TRANSLATED] === 0) { continue; } if (!$multi) { $this->output(sprintf("%19s ", $targetLanguage), $targetLanguage); } $collection->resetForNewLanguage($targetLanguage); $collection->filter('ignored'); $collection->filter('optional'); $collection->filter('translated', false); $collection->loadTranslations(); $inserts = array(); foreach ($collection->keys() as $mkey => $title) { $inserts[] = array('tmt_sid' => $sids[$mkey], 'tmt_lang' => $targetLanguage, 'tmt_text' => $collection[$mkey]->translation()); } do { $batch = array_splice($inserts, 0, $this->mBatchSize); $dbw->insert('translate_tmt', $batch, __METHOD__); if (!$multi) { $this->output('.', $targetLanguage); } wfWaitForSlaves(10); } while (count($inserts)); } if ($multi) { $this->statusLine("Inserted translations for {$id}\n"); } }
/** * Do some conflict resolution for translations. * @param string $code Language code. * @param bool|int $startTs Time of the last export (changes in wiki after * this will conflict) * @param bool|int $endTs Time of the last export (changes in source before * this won't conflict) * @param bool|int $changeTs When change happened in the source. */ public function checkConflicts($code, $startTs = false, $endTs = false, $changeTs = false) { $messages = $this->group->load($code); if (!count($messages)) { return; } $collection = $this->group->initCollection($code); $collection->filter('ignored'); $collection->loadTranslations(); foreach ($messages as $key => $translation) { if (!isset($collection[$key])) { continue; } // @todo Temporary exception. Should be fixed elsewhere more generically. if ($translation == '{{PLURAL:GETTEXT|}}') { return; } $title = Title::makeTitleSafe($this->group->getNamespace(), "{$key}/{$code}"); $page = $title->getPrefixedText(); if ($collection[$key]->translation() === null) { $this->reportProgress("Importing {$page} as a new translation\n", 'importing'); $this->import($title, $translation, 'Importing a new translation'); continue; } $current = str_replace(TRANSLATE_FUZZY, '', $collection[$key]->translation()); $translation = str_replace(TRANSLATE_FUZZY, '', $translation); if ($translation === $current) { continue; } $this->reportProgress("Conflict in " . $this->color('bold', $page) . "!", $page); $iso = 'xnY-xnm-xnd"T"xnH:xni:xns'; $lang = RequestContext::getMain()->getLanguage(); // Finally all is ok, now lets start comparing timestamps // Make sure we are comparing timestamps in same format $wikiTs = $this->getLastGoodChange($title, $startTs); if ($wikiTs) { $wikiTs = wfTimestamp(TS_UNIX, $wikiTs); $wikiDate = $lang->sprintfDate($iso, wfTimestamp(TS_MW, $wikiTs)); } else { $wikiDate = 'Unknown'; } if ($startTs) { $startTs = wfTimestamp(TS_UNIX, $startTs); } if ($endTs) { $endTs = wfTimestamp(TS_UNIX, $endTs); } if ($changeTs) { $changeTs = wfTimestamp(TS_UNIX, $changeTs); $changeDate = $lang->sprintfDate($iso, wfTimestamp(TS_MW, $changeTs)); } else { $changeDate = 'Unknown'; } if ($changeTs) { if ($wikiTs > $startTs && $changeTs <= $endTs) { $this->reportProgress(" →Changed in wiki after export: IGNORE", $page); continue; } elseif (!$wikiTs || $changeTs > $endTs && $wikiTs < $startTs) { $this->reportProgress(" →Changed in source after export: IMPORT", $page); $this->import($title, $translation, 'Updating translation from external source'); continue; } } if (!$this->interactive) { continue; } $this->reportProgress(" →Needs manual resolution", $page); $this->reportProgress("Source translation at {$changeDate}:", 'source'); $this->reportProgress($this->color('blue', $translation), 'source'); $this->reportProgress("Wiki translation at {$wikiDate}:", 'translation'); $this->reportProgress($this->color('green', $current), 'translation'); do { $this->reportProgress("Resolution: [S]kip [I]mport [C]onflict: ", 'foo'); // @todo Find an elegant way to use Maintenance::readconsole(). $action = fgets(STDIN); $action = strtoupper(trim($action)); if ($action === 'S') { break; } if ($action === 'I') { $this->import($title, $translation, 'Updating translation from external source'); break; } if ($action === 'C') { $this->import($title, TRANSLATE_FUZZY . $translation, 'Edit conflict between wiki and source'); break; } } while (true); } }
protected function exportGroup(MessageGroup $group, $config) { $server = TTMServer::factory($config); $server->setLogger($this); $id = $group->getId(); $sourceLanguage = $group->getSourceLanguage(); $stats = MessageGroupStats::forGroup($id); $collection = $group->initCollection($sourceLanguage); $collection->filter('ignored'); $collection->initMessages(); $server->beginBatch(); $inserts = array(); foreach ($collection->keys() as $mkey => $title) { $handle = new MessageHandle($title); $inserts[] = array($handle, $sourceLanguage, $collection[$mkey]->definition()); } while ($inserts !== array()) { $batch = array_splice($inserts, 0, $this->mBatchSize); $server->batchInsertDefinitions($batch); } $inserts = array(); foreach ($stats as $targetLanguage => $numbers) { if ($targetLanguage === $sourceLanguage) { continue; } if ($numbers[MessageGroupStats::TRANSLATED] === 0) { continue; } $collection->resetForNewLanguage($targetLanguage); $collection->filter('ignored'); $collection->filter('translated', false); $collection->loadTranslations(); foreach ($collection->keys() as $mkey => $title) { $handle = new MessageHandle($title); $inserts[] = array($handle, $sourceLanguage, $collection[$mkey]->translation()); } while (count($inserts) >= $this->mBatchSize) { $batch = array_splice($inserts, 0, $this->mBatchSize); $server->batchInsertTranslations($batch); } } while ($inserts !== array()) { $batch = array_splice($inserts, 0, $this->mBatchSize); $server->batchInsertTranslations($batch); } $server->endBatch(); }