/** * Compile the given SASS source * * @param Source $source Sass source * @throws Wikia\Sass\Exception * @return string CSS stylesheet */ public function compile(Source $source) { wfProfileIn(__METHOD__); $tempDir = $this->tempDir ?: sys_get_temp_dir(); //replace \ to / is needed because escapeshellcmd() replace \ into spaces (?!!) $outputFile = str_replace('\\', '/', tempnam($tempDir, uniqid('Sass'))); $tempDir = str_replace('\\', '/', $tempDir); $sassVariables = urldecode(http_build_query($this->sassVariables, '', ' ')); $debugMode = $this->useSourceMaps ? '--debug-in' : ''; $hasLocalFile = $source->hasPermanentFile(); $localFile = $source->getLocalFile(); $inputFile = $hasLocalFile ? $localFile : '-s'; $cmd = "{$this->sassExecutable} {$inputFile} {$outputFile} --scss -t {$this->outputStyle} " . "-I {$this->rootDir} {$debugMode} " . "--cache-location {$tempDir}/sass2 -r {$this->rootDir}/extensions/wikia/SASS/wikia_sass.rb {$sassVariables}"; $cmd = escapeshellcmd($cmd) . " 2>&1"; if (!$hasLocalFile) { $cmd = escapeshellcmd("cat {$localFile}") . " | " . $cmd; } $sassOutput = wfShellExec($cmd, $status); if ($status !== 0) { // 0 => success if (file_exists($outputFile)) { unlink($outputFile); } $this->error("SASS rendering failed", ['cmd' => $cmd, 'output' => preg_replace('#\\n\\s+#', ' ', trim($sassOutput)), 'status' => $status]); throw new Wikia\Sass\Exception("SASS compilation failed: {$sassOutput}\nFull commandline: {$cmd}"); } $styles = file_get_contents($outputFile); unlink($outputFile); if ($styles === false) { $this->error("Reading SASS file failed", ['input' => $inputFile, 'output' => $outputFile]); throw new Wikia\Sass\Exception("Reading SASS file failed"); } wfProfileOut(__METHOD__); return $styles; }
/** * * @dataProvider providePixelFormats */ public function testPixelFormatRendering($sourceFile, $pixelFormat, $samplingFactor) { global $wgUseImageMagick, $wgUseImageResize; if (!$wgUseImageMagick) { $this->markTestSkipped("This test is only applicable when using ImageMagick thumbnailing"); } if (!$wgUseImageResize) { $this->markTestSkipped("This test is only applicable when using thumbnailing"); } $fmtStr = var_export($pixelFormat, true); $this->setMwGlobals('wgJpegPixelFormat', $pixelFormat); $file = $this->dataFile($sourceFile, 'image/jpeg'); $params = ['width' => 320]; $thumb = $file->transform($params, File::RENDER_NOW | File::RENDER_FORCE); $this->assertTrue(!$thumb->isError(), "created JPEG thumbnail for pixel format {$fmtStr}"); $path = $thumb->getLocalCopyPath(); $this->assertTrue(is_string($path), "path returned for JPEG thumbnail for {$fmtStr}"); $cmd = ['identify', '-format', '%[jpeg:sampling-factor]', $path]; $retval = null; $output = wfShellExec($cmd, $retval); $this->assertTrue($retval === 0, "ImageMagick's identify command should return success"); $expected = $samplingFactor; $actual = trim($output); $this->assertEquals($expected, trim($output), "IM identify expects JPEG chroma subsampling \"{$expected}\" for {$fmtStr}"); }
protected function __construct() { $idFile = wfTempDir() . '/mw-' . __CLASS__ . '-UID-nodeid'; $nodeId = is_file( $idFile ) ? file_get_contents( $idFile ) : ''; // Try to get some ID that uniquely identifies this machine (RFC 4122)... if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) { wfSuppressWarnings(); if ( wfIsWindows() ) { // http://technet.microsoft.com/en-us/library/bb490913.aspx $csv = trim( wfShellExec( 'getmac /NH /FO CSV' ) ); $line = substr( $csv, 0, strcspn( $csv, "\n" ) ); $info = str_getcsv( $line ); $nodeId = isset( $info[0] ) ? str_replace( '-', '', $info[0] ) : ''; } elseif ( is_executable( '/sbin/ifconfig' ) ) { // Linux/BSD/Solaris/OS X // See http://linux.die.net/man/8/ifconfig $m = array(); preg_match( '/\s([0-9a-f]{2}(:[0-9a-f]{2}){5})\s/', wfShellExec( '/sbin/ifconfig -a' ), $m ); $nodeId = isset( $m[1] ) ? str_replace( ':', '', $m[1] ) : ''; } wfRestoreWarnings(); if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) { $nodeId = MWCryptRand::generateHex( 12, true ); $nodeId[1] = dechex( hexdec( $nodeId[1] ) | 0x1 ); // set multicast bit } file_put_contents( $idFile, $nodeId ); // cache } $this->nodeId32 = wfBaseConvert( substr( sha1( $nodeId ), 0, 8 ), 16, 2, 32 ); $this->nodeId48 = wfBaseConvert( $nodeId, 16, 2, 48 ); // If different processes run as different users, they may have different temp dirs. // This is dealt with by initializing the clock sequence number and counters randomly. $this->lockFile88 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-88'; $this->lockFile128 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-128'; }
function addWatermark($srcPath, $dstPath, $width, $height) { global $IP, $wgImageMagickConvertCommand, $wgImageMagickCompositeCommand; // do not add a watermark if the image is too small if (WatermarkSupport::validImageSize($width, $height) == false) { return; } $wm = $IP . '/skins/WikiHow/images/watermark.svg'; $watermarkWidth = 1074.447; $targetWidth = $width / 8; $density = 72 * $targetWidth / $watermarkWidth; // we have a lower limit on density so the watermark is readable if ($density < 4.0) { $density = 4.0; } $cmd = ""; // make sure image is rgb format so the watermark applies correctly if (WatermarkSupport::isCMYK($srcPath)) { $cmd = wfEscapeShellArg($wgImageMagickConvertCommand) . " " . wfEscapeShellArg($srcPath) . " " . "-colorspace RGB " . wfEscapeShellArg($dstPath) . ";"; $srcPath = $dstPath; } $cmd = $cmd . wfEscapeShellArg($wgImageMagickConvertCommand) . " -density {$density} -background none " . wfEscapeShellArg($wm) . " miff:- | " . wfEscapeShellArg($wgImageMagickCompositeCommand) . " -gravity southeast -quality 100 -geometry +8+10 - " . wfEscapeShellArg($srcPath) . " " . wfEscapeShellArg($dstPath) . " 2>&1"; $beforeExists = file_exists($dstPath); wfDebug(__METHOD__ . ": running ImageMagick: {$cmd}\n"); $err = wfShellExec($cmd, $retval); $afterExists = file_exists($dstPath); $currentDate = `date`; wfErrorLog(trim($currentDate) . " {$cmd} b:" . ($beforeExists ? 't' : 'f') . " a:" . ($afterExists ? 't' : 'f') . "\n", '/tmp/watermark.log'); wfProfileOut('watermark'); }
function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0) { global $wgFLVConverters, $wgFLVConverter, $wgFLVConverterPath; if (!$this->normaliseParams($image, $params)) { return new TransformParameterError($params); } $clientWidth = $params['width']; $clientHeight = $params['height']; $physicalWidth = $params['physicalWidth']; $physicalHeight = $params['physicalHeight']; $srcPath = $image->getPath(); if ($flags & self::TRANSFORM_LATER) { return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath); } if (!wfMkdirParents(dirname($dstPath), null, __METHOD__)) { return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, wfMsg('thumbnail_dest_directory')); } $err = false; if (isset($wgFLVConverters[$wgFLVConverter])) { $cmd = str_replace(array('$path/', '$width', '$height', '$input', '$output'), array($wgFLVConverterPath ? wfEscapeShellArg("{$wgFLVConverterPath}/") : "", intval($physicalWidth), intval($physicalHeight), wfEscapeShellArg($srcPath), wfEscapeShellArg($dstPath)), $wgFLVConverters[$wgFLVConverter]) . " 2>&1"; wfProfileIn('rsvg'); wfDebug(__METHOD__ . ": {$cmd}\n"); $err = wfShellExec($cmd, $retval); wfProfileOut('rsvg'); } $removed = $this->removeBadFile($dstPath, $retval); if ($retval != 0 || $removed) { wfDebugLog('thumbnail', sprintf('thumbnail failed on %s: error %d "%s" from "%s"', wfHostname(), $retval, trim($err), $cmd)); return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, $err); } else { return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath); } }
public function execute($params = null) { global $IP, $wgWikiaLocalSettingsPath; $this->mParams = unserialize($params->task_arguments); $this->users = $this->mParams['users']; $this->time = $this->mParams['time']; $userNames = array(); foreach ($this->users as $u) { $userNames[] = $u['canonical']; } // Save initial log line $processSummary = "Processing UserRollback request:\n"; $processSummary .= " - users: " . implode(', ', $userNames) . "\n"; $processSummary .= " - from: " . $this->time; $this->log($processSummary); // ... $wikiIds = $this->findWikis($this->users); $noErrors = true; $allUsers = implode('|', $userNames); foreach ($wikiIds as $wikiId) { $cmd = "SERVER_ID={$wikiId} php {$IP}/extensions/wikia/UserRollback/maintenance/rollbackEditsMulti.php " . "--users " . escapeshellarg($allUsers) . " --time " . escapeshellarg($this->time) . " --onlyshared --conf {$wgWikiaLocalSettingsPath}"; $this->log("Running {$cmd}"); $exitCode = null; $output = wfShellExec($cmd, $exitCode); if ($exitCode == 1) { $noErrors = false; } $this->log("--- Command output ---\n{$output}\n--- End of command output ---"); $this->log("Finished processing wiki with ID {$wikiId}."); } $this->log("Finished processing work."); return $noErrors; }
/** * @param array $params * @param Config $mainConfig * @return array */ public static function applyDefaultParameters(array $params, Config $mainConfig) { $logger = LoggerFactory::getInstance('Mime'); $params += ['typeFile' => $mainConfig->get('MimeTypeFile'), 'infoFile' => $mainConfig->get('MimeInfoFile'), 'xmlTypes' => $mainConfig->get('XMLMimeTypes'), 'guessCallback' => function ($mimeAnalyzer, &$head, &$tail, $file, &$mime) use($logger) { // Also test DjVu $deja = new DjVuImage($file); if ($deja->isValid()) { $logger->info(__METHOD__ . ": detected {$file} as image/vnd.djvu\n"); $mime = 'image/vnd.djvu'; return; } // Some strings by reference for performance - assuming well-behaved hooks Hooks::run('MimeMagicGuessFromContent', [$mimeAnalyzer, &$head, &$tail, $file, &$mime]); }, 'extCallback' => function ($mimeAnalyzer, $ext, &$mime) { // Media handling extensions can improve the MIME detected Hooks::run('MimeMagicImproveFromExtension', [$mimeAnalyzer, $ext, &$mime]); }, 'initCallback' => function ($mimeAnalyzer) { // Allow media handling extensions adding MIME-types and MIME-info Hooks::run('MimeMagicInit', [$mimeAnalyzer]); }, 'logger' => $logger]; if ($params['infoFile'] === 'includes/mime.info') { $params['infoFile'] = __DIR__ . "/libs/mime/mime.info"; } if ($params['typeFile'] === 'includes/mime.types') { $params['typeFile'] = __DIR__ . "/libs/mime/mime.types"; } $detectorCmd = $mainConfig->get('MimeDetectorCommand'); if ($detectorCmd) { $params['detectCallback'] = function ($file) use($detectorCmd) { return wfShellExec("{$detectorCmd} " . wfEscapeShellArg($file)); }; } return $params; }
/** * execute * * Main entry point, TaskManagerExecutor run this method * * @access public * @author bartek@wikia * @author eloy@wikia * * @param mixed $params default null: task params from wikia_tasks table * * @return boolean: status of operation, true = success, false = failure */ function execute($params = null) { global $wgWikiaLocalSettingsPath; $this->mTaskID = $params->task_id; $this->mParams = $params; $task_arguments = unserialize($params->task_arguments); $this->mSourceTaskId = $task_arguments["source-task-id"]; $this->mTargetWikiId = $task_arguments["target-wiki-id"]; #--- get data for previous task $oPreviousTask = BatchTask::newFromID($this->mSourceTaskId); if (is_null($oPreviousTask)) { $this->addLog("Previous task nr {$this->mSourceTaskId} doesn't exist in database"); return false; } $sWorkDir = $oPreviousTask->getTaskDirectory(); $this->addLog("Opennig {$sWorkDir} directory"); $i = 0; while (file_exists(sprintf("%s/%03d_dump.xml", $sWorkDir, $i))) { $phpFile = "php"; $importDumpFile = $GLOBALS["IP"] . "/maintenance/importDump.php"; $command = sprintf("SERVER_ID=%s %s %s --conf %s %s/%03d_dump.xml", $this->mTargetWikiId, $phpFile, $importDumpFile, $wgWikiaLocalSettingsPath, $sWorkDir, $i); $this->addLog("Running: {$command}"); $out = wfShellExec($command, $retval); $this->addLog($out); $i++; } if (empty($i)) { $this->addLog("Nothing was imported. There is no dump file to process"); } return true; }
function execute($params = null) { global $IP, $wgWikiaLocalSettingsPath; $this->mTaskID = $params->task_id; $oUser = User::newFromId($params->task_user_id); $oUser->load(); $this->mUser = $oUser->getName(); $data = unserialize($params->task_arguments); $articles = $data["articles"]; $username = escapeshellarg($data["username"]); $this->addLog("Starting task."); $this->addLog("List of restored articles (by " . $this->mUser . ' as ' . $username . "):"); for ($i = 0; $i < count($articles); $i++) { $titleobj = Title::makeTitle($articles[$i]["namespace"], $articles[$i]["title"]); $article_to_do = $titleobj->getText(); $namespace = intval($articles[$i]["namespace"]); $reason = $articles[$i]['reason'] ? ' -r ' . escapeshellarg($articles[$i]['reason']) : ''; $sCommand = "SERVER_ID=" . $articles[$i]["wikiid"] . " php {$IP}/maintenance/wikia/restoreOn.php -u " . $username . " -t " . escapeshellarg($article_to_do) . " -n " . $namespace . $reason . " --conf " . escapeshellarg($wgWikiaLocalSettingsPath); $city_url = WikiFactory::getVarValueByName("wgServer", $articles[$i]["wikiid"]); if (empty($city_url)) { $city_url = 'wiki id in WikiFactory: ' . $articles[$i]["wikiid"]; } $city_path = WikiFactory::getVarValueByName("wgScript", $articles[$i]["wikiid"]); $actual_title = wfShellExec($sCommand, $retval); if ($retval) { $this->addLog('Article undeleting error! (' . $city_url . '). Error code returned: ' . $retval . ' Error was: ' . $actual_title); } else { $this->addLog('<a href="' . $city_url . $city_path . '?title=' . $actual_title . '">' . $city_url . $city_path . '?title=' . $actual_title . '</a>'); } } return true; }
protected static function callFontConfig($code) { if (ini_get('open_basedir')) { wfDebugLog('fcfont', 'Disabled because of open_basedir is active'); // Most likely we can't access any fonts we might find return false; } $cache = self::getCache(); $cachekey = wfMemckey('fcfont', $code); $timeout = 60 * 60 * 12; $cached = $cache->get($cachekey); if (is_array($cached)) { return $cached; } elseif ($cached === 'NEGATIVE') { return false; } $code = wfEscapeShellArg(":lang={$code}"); $ok = 0; $cmd = "fc-match {$code}"; $suggestion = wfShellExec($cmd, $ok); wfDebugLog('fcfont', "{$cmd} returned {$ok}"); if ($ok !== 0) { wfDebugLog('fcfont', "fc-match error output: {$suggestion}"); $cache->set($cachekey, 'NEGATIVE', $timeout); return false; } $pattern = '/^(.*?): "(.*)" "(.*)"$/'; $matches = array(); if (!preg_match($pattern, $suggestion, $matches)) { wfDebugLog('fcfont', "fc-match: return format not understood: {$suggestion}"); $cache->set($cachekey, 'NEGATIVE', $timeout); return false; } list(, $file, $family, $type) = $matches; wfDebugLog('fcfont', "fc-match: got {$file}: {$family} {$type}"); $file = wfEscapeShellArg($file); $family = wfEscapeShellArg($family); $type = wfEscapeShellArg($type); $cmd = "fc-list {$family} {$type} {$code} file | grep {$file}"; $candidates = trim(wfShellExec($cmd, $ok)); wfDebugLog('fcfont', "{$cmd} returned {$ok}"); if ($ok !== 0) { wfDebugLog('fcfont', "fc-list error output: {$candidates}"); $cache->set($cachekey, 'NEGATIVE', $timeout); return false; } # trim spaces $files = array_map('trim', explode("\n", $candidates)); $count = count($files); if (!$count) { wfDebugLog('fcfont', "fc-list got zero canditates: {$candidates}"); } # remove the trailing ":" $chosen = substr($files[0], 0, -1); wfDebugLog('fcfont', "fc-list got {$count} candidates; using {$chosen}"); $data = array('family' => $family, 'type' => $type, 'file' => $chosen); $cache->set($cachekey, $data, $timeout); return $data; }
function callScribeProducer($page_id, $page_ns, $rev_id, $user_id) { global $IP, $wgWikiaLocalSettingsPath, $wgCityId; $script_path = $_SERVER['PHP_SELF']; $path = "SERVER_ID={$wgCityId} php {$script_path} --scribe=1 --conf {$wgWikiaLocalSettingsPath} --page_id=$page_id --page_ns=$page_ns --rev_id=$rev_id --user_id=$user_id"; #echo $path . " \n"; $return = wfShellExec( $path ); echo $return; }
public function execute() { global $wgCaptchaSecret, $wgCaptchaDirectoryLevels; $instance = ConfirmEditHooks::getInstance(); if (!$instance instanceof FancyCaptcha) { $this->error("\$wgCaptchaClass is not FancyCaptcha.\n", 1); } $backend = $instance->getBackend(); $countAct = $instance->estimateCaptchaCount(); $this->output("Estimated number of captchas is {$countAct}.\n"); $countGen = (int) $this->getOption('fill') - $countAct; if ($countGen <= 0) { $this->output("No need to generate anymore captchas.\n"); return; } $tmpDir = wfTempDir() . '/mw-fancycaptcha-' . time() . '-' . wfRandomString(6); if (!wfMkdirParents($tmpDir)) { $this->error("Could not create temp directory.\n", 1); } $e = null; // exception try { $cmd = sprintf("python %s --key %s --output %s --count %s --dirs %s", wfEscapeShellArg(__DIR__ . '/../captcha.py'), wfEscapeShellArg($wgCaptchaSecret), wfEscapeShellArg($tmpDir), wfEscapeShellArg($countGen), wfEscapeShellArg($wgCaptchaDirectoryLevels)); foreach (array('wordlist', 'font', 'font-size', 'blacklist', 'verbose') as $par) { if ($this->hasOption($par)) { $cmd .= " --{$par} " . wfEscapeShellArg($this->getOption($par)); } } $this->output("Generating {$countGen} new captchas...\n"); $retVal = 1; wfShellExec($cmd, $retVal, array(), array('time' => 0)); if ($retVal != 0) { wfRecursiveRemoveDir($tmpDir); $this->error("Could not run generation script.\n", 1); } $flags = FilesystemIterator::SKIP_DOTS; $iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tmpDir, $flags), RecursiveIteratorIterator::CHILD_FIRST); $this->output("Copying the new captchas to storage...\n"); foreach ($iter as $fileInfo) { if (!$fileInfo->isFile()) { continue; } list($salt, $hash) = $instance->hashFromImageName($fileInfo->getBasename()); $dest = $instance->imagePath($salt, $hash); $backend->prepare(array('dir' => dirname($dest))); $status = $backend->quickStore(array('src' => $fileInfo->getPathname(), 'dst' => $dest)); if (!$status->isOK()) { $this->error("Could not save file '{$fileInfo->getPathname()}'.\n"); } } } catch (Exception $e) { wfRecursiveRemoveDir($tmpDir); throw $e; } $this->output("Removing temporary files...\n"); wfRecursiveRemoveDir($tmpDir); $this->output("Done.\n"); }
function checkNYAvatar($city_id, $user_id) { global $IP, $wgWikiaLocalSettingsPath; $script_path = $_SERVER['PHP_SELF']; $path = "SERVER_ID={$city_id} php {$script_path} --ny --user={$user_id} --conf {$wgWikiaLocalSettingsPath}"; #echo $path . " \n"; $return = wfShellExec( $path ); return $return; }
public function testBug67870() { $command = wfIsWindows() ? 'for /l %i in (1, 1, 1001) do @echo ' . str_repeat('*', 331) : 'printf "%-333333s" "*"'; // Test several times because it involves a race condition that may randomly succeed or fail for ($i = 0; $i < 10; $i++) { $output = wfShellExec($command); $this->assertEquals(333333, strlen($output)); } }
/** * Perform a rollback of all revisions published by the given user * after the given time * * @param array $identifiers list of user names or IPs whose revisions should be reverted * @param int $timestamp Unix time after which revisions should be reverted */ public function doRollback(array $identifiers, $timestamp) { global $wgCityId, $IP; $phpScript = $IP . '/extensions/wikia/UserRollback/maintenance/rollbackEditsMulti.php'; $cmd = sprintf("SERVER_ID=%d php {$phpScript} --users %s --time %s --onlyshared", $wgCityId, escapeshellarg(implode('|', $identifiers)), escapeshellarg($timestamp)); $this->info("Running {$phpScript}", ['users' => $identifiers, 'time' => $timestamp]); $retval = wfShellExec($cmd, $status); return $retval; }
function execute($params = null) { global $IP, $wgWikiaLocalSettingsPath; /* go with each supplied wiki and delete the supplied article load all configs for particular wikis before doing so (from wikifactory, not by _obsolete_ maintenance scripts and from LocalSettings as worked on fps) */ $this->mTaskID = $params->task_id; $oUser = User::newFromId($params->task_user_id); if ($oUser instanceof User) { $oUser->load(); $this->mUser = $oUser->getName(); } else { $this->log("Invalid user - id: " . $params->task_user_id); return true; } $data = unserialize($params->task_arguments); foreach ($data['page_list'] as $imageData) { $retval = ""; list($wikiId, $imageId) = $imageData; $dbname = WikiFactory::getWikiByID($wikiId); if (!$dbname) { continue; } $title = GlobalTitle::newFromId($imageId, $wikiId); if (!is_object($title)) { $this->log('Apparently the article does not exist anymore'); continue; } $city_url = WikiFactory::getVarValueByName("wgServer", $wikiId); if (empty($city_url)) { continue; } $city_path = WikiFactory::getVarValueByName("wgScript", $wikiId); $city_lang = WikiFactory::getVarValueByName("wgLanguageCode", $wikiId); $reason = wfMsgExt('imagereview-reason', array('language' => $city_lang)); $sCommand = "perl /usr/wikia/backend/bin/run_maintenance --id={$wikiId} --script=wikia/deleteOn.php "; $sCommand .= "-- "; $sCommand .= "-u " . escapeshellarg($this->mUser) . " "; $sCommand .= "-t " . escapeshellarg($title->getPrefixedText()) . " "; if ($reason) { $sCommand .= "-r " . escapeshellarg($reason) . " "; } $actual_title = wfShellExec($sCommand, $retval); if ($retval) { $this->addLog('Article deleting error! (' . $city_url . '). Error code returned: ' . $retval . ' Error was: ' . $actual_title); } else { $this->addLog('Removed: <a href="' . $city_url . $city_path . '?title=' . wfEscapeWikiText($actual_title) . '">' . $city_url . $city_path . '?title=' . $actual_title . '</a>'); } $this->flagUser($imageId, $wikiId); $this->flagWiki($wikiId); } return true; }
/** * execute * * Main entry point. TaskManagerExecutor runs this method. * * @param mixed $params the data for a particular task * @return boolean true on success * @access public */ public function execute($params = null) { $this->mData = $params; $this->log('RebuildLocalisationCacheTask started.'); $out = wfShellExec("pdsh -g all_web 'echo {$this->mTaskID} > /tmp/l10n-rebuild'"); $this->log($out); $out = wfShellExec("pdsh -g all_web 'chown release.www-data /tmp/l10n-rebuild'"); $this->log($out); $this->log('RebuildLocalisationCacheTask completed.'); return true; }
static function tryFfmpegThumb( $options ){ global $wgFFmpegLocation; $cmd = wfEscapeShellArg( $wgFFmpegLocation ); $offset = intval( self::getThumbTime( $options ) ); /* This is a workaround until ffmpegs ogg demuxer properly seeks to keyframes. Seek 2 seconds before offset and seek in decoded stream after that. -ss before input seeks without decode -ss after input seeks in decoded stream */ if($offset > 2) { $cmd .= ' -ss ' . ($offset - 2); $offset = 2; } $srcPath = $options['file']->getLocalRefPath(); $cmd .= ' -y -i ' . wfEscapeShellArg( $srcPath ); $cmd .= ' -ss ' . $offset . ' '; // Set the output size if set in options: if( isset( $options['width'] ) && isset( $options['height'] ) ){ $cmd.= ' -s '. intval( $options['width'] ) . 'x' . intval( $options['height'] ); } # MJPEG, that's the same as JPEG except it's supported by the windows build of ffmpeg # No audio, one frame $cmd .= ' -f mjpeg -an -vframes 1 ' . wfEscapeShellArg( $options['dstPath'] ) . ' 2>&1'; $retval = 0; $returnText = wfShellExec( $cmd, $retval ); // Check if it was successful if ( !$options['file']->getHandler()->removeBadFile( $options['dstPath'], $retval ) ) { return true; } // Filter nonsense $lines = explode( "\n", str_replace( "\r\n", "\n", $returnText ) ); if ( substr( $lines[0], 0, 6 ) == 'FFmpeg' ) { for ( $i = 1; $i < count( $lines ); $i++ ) { if ( substr( $lines[$i], 0, 2 ) != ' ' ) { break; } } $lines = array_slice( $lines, $i ); } // Return error box return new MediaTransformError( 'thumbnail_error', $options['width'], $options['height'], implode( "\n", $lines ) ); }
public function delete($pageList, $suppress = false) { global $IP; $user = \User::newFromId($this->createdBy); $userName = $user->getName(); $articlesDeleted = 0; foreach ($pageList as $imageData) { list($wikiId, $imageId) = $imageData; if (!\WikiFactory::isPublic($wikiId)) { $this->notice('wiki has been disabled', ['wiki_id' => $wikiId]); continue; } $dbname = \WikiFactory::getWikiByID($wikiId); if (!$dbname) { $this->warning('did not find database', ['wiki_id' => $wikiId]); continue; } $cityUrl = \WikiFactory::getVarValueByName('wgServer', $wikiId); if (empty($cityUrl)) { $this->warning('could not determine city url', ['wiki_id' => $wikiId]); continue; } $cityLang = \WikiFactory::getVarValueByName('wgLanguageCode', $wikiId); $reason = wfMsgExt('imagereview-reason', ['language' => $cityLang]); $command = "SERVER_ID={$wikiId} php {$IP}/maintenance/wikia/deleteOn.php" . ' -u ' . escapeshellarg($userName) . ' --id ' . $imageId; if ($reason) { $command .= ' -r ' . escapeshellarg($reason); } if ($suppress) { $command .= ' -s'; } $title = wfShellExec($command, $exitStatus); if ($exitStatus !== 0) { $this->error('article deletion error', ['city_url' => $cityUrl, 'exit_status' => $exitStatus, 'error' => $title]); continue; } $cityPath = \WikiFactory::getVarValueByName('wgScript', $wikiId); $escapedTitle = wfEscapeWikiText($title); $this->info('removed image', ['link' => "{$cityUrl}{$cityPath}?title={$escapedTitle}", 'title' => $escapedTitle]); ++$articlesDeleted; } $success = $articlesDeleted == count($pageList); if (!$success) { $this->sendNotification(); } return $success; }
public function execute() { $max_words = intval( $this->getOption( 'maxwords', 10000 ) ); $indexer = wfEscapeShellArg( $this->getOption( 'indexer', 'indexer' ) ); $index = wfEscapeShellArg( $this->getOption( 'useindex', 'wiki_main' ) ); $conf = wfEscapeShellArg( $this->getOption( 'spinxconf' ) ); $cmd = "$indexer --config $conf $index --buildstops sphinx.dic $max_words"; $this->output( wfShellExec( $cmd, $retval ) ); if ( file_exists( 'sphinx.dic' ) ) { $words = file('sphinx.dic'); $cnt = count($words); if ($cnt) { file_put_contents( 'sphinx.dic', $cnt . "\n" . join( '', $words ) ); file_put_contents( 'sphinx.aff', "SET UTF-8\n" ); } } }
/** * execute * * entry point for TaskExecutor * * @access public * @author eloy@wikia * * @param mixed $params default null - task data from wikia_tasks table * * @return boolean - status of operation */ public function execute($params = null) { global $IP, $wgWikiaLocalSettingsPath, $wgWikiaAdminSettingsPath; $this->mParams = unserialize($params->task_arguments); $city_id = $this->mParams["city_id"]; if ($city_id) { /** * execute maintenance script */ $cmd = sprintf("SERVER_ID={$city_id} php {$IP}/extensions/wikia/Blogs/maintenance.php --conf {$wgWikiaLocalSettingsPath} --aconf {$wgWikiaAdminSettingsPath}"); $this->addLog("Running {$cmd}"); $this->addLog($cmd); $retval = wfShellExec($cmd, $status); $this->addLog($retval); } return true; }
/** * execute * * Main entry point. TaskManagerExecutor runs this method. * * @param mixed $params the data for a particular task * @return boolean true on success * @access public */ public function execute($params = null) { global $IP, $wgWikiaLocalSettingsPath; $this->mData = $params; $this->log('UpdateSpecialPagesTask started.'); $this->mParams = unserialize($this->mData->task_arguments); if (empty($this->mParams['wikiId'])) { $this->log('UpdateSpecialPagesTask: empty wikiId.'); $this->log('UpdateSpecialPagesTask failed.'); return false; } $cmd = "SERVER_ID={$this->mParams['wikiId']} php " . "{$IP}/maintenance/updateSpecialPages.php " . "--conf {$wgWikiaLocalSettingsPath}"; $this->log("Running: {$cmd}"); $out = wfShellExec($cmd); $this->log($out); $this->log('UpdateSpecialPagesTask completed.'); return true; }
public function rasterize($srcPath, $dstPath, $width, $height) { global $wgSVGConverters, $wgSVGConverter, $wgSVGConverterPath; $err = false; if (isset($wgSVGConverters[$wgSVGConverter])) { $cmd = str_replace(array('$path/', '$width', '$height', '$input', '$output'), array($wgSVGConverterPath ? wfEscapeShellArg("{$wgSVGConverterPath}/") : "", intval($width), intval($height), wfEscapeShellArg($srcPath), wfEscapeShellArg($dstPath)), $wgSVGConverters[$wgSVGConverter]) . " 2>&1"; wfProfileIn('rsvg'); wfDebug(__METHOD__ . ": {$cmd}\n"); $err = wfShellExec($cmd, $retval); wfProfileOut('rsvg'); } $removed = $this->removeBadFile($dstPath, $retval); if ($retval != 0 || $removed) { wfDebugLog('thumbnail', sprintf('thumbnail failed on %s: error %d "%s" from "%s"', wfHostname(), $retval, trim($err), $cmd)); return new MediaTransformError('thumbnail_error', $width, $height, $err); } return true; }
/** * @param $file File * @param array $params Rotate parameters. * 'rotation' clockwise rotation in degrees, allowed are multiples of 90 * @since 1.21 * @return bool */ public function rotate($file, $params) { global $wgJpegTran; $rotation = ($params['rotation'] + $this->getRotation($file)) % 360; if ($wgJpegTran && is_file($wgJpegTran)) { $cmd = wfEscapeShellArg($wgJpegTran) . " -rotate " . wfEscapeShellArg($rotation) . " -outfile " . wfEscapeShellArg($params['dstPath']) . " " . wfEscapeShellArg($params['srcPath']) . " 2>&1"; wfDebug(__METHOD__ . ": running jpgtran: {$cmd}\n"); wfProfileIn('jpegtran'); $retval = 0; $err = wfShellExec($cmd, $retval, $env); wfProfileOut('jpegtran'); if ($retval !== 0) { $this->logErrorForExternalProcess($retval, $err, $cmd); return new MediaTransformError('thumbnail_error', 0, 0, $err); } return false; } else { return parent::rotate($file, $params); } }
/** * This task is run when a video is uploaded but the provider does not have a * thumbnail for us to use. This gets triggered the first time a thumbnail * cannot be found, and is queued up again at longer intervals until we either * get a thumbnail from the provider, or exhaust all of our attempts. * @param $title * @param $delayIndex * @param $provider * @param $videoId * @return FileRepoStatus */ public function retryThumbUpload($title, $delayIndex, $provider, $videoId) { global $IP, $wgCityId; /** @var Title $title */ $file = WikiaFileHelper::getVideoFileFromTitle($title); if (empty($file)) { $msg = "File not found on wiki"; if ($title instanceof Title) { $title = $title->getText(); } $this->log("error", $delayIndex, $title, $provider, ["errorMsg" => $msg]); return Status::newFatal($msg); } $delayIndex++; $this->log("start", $delayIndex, $title->getText(), $provider); // IVA requires extra steps to update their thumbnail, use the script we have for that if ($provider == self::IVA) { $cmd = sprintf("SERVER_ID={$wgCityId} php {$IP}/maintenance/wikia/VideoHandlers/updateOoyalaThumbnail.php --videoId={$videoId} --delayIndex={$delayIndex}"); $response = wfShellExec($cmd, $exitStatus); if ($exitStatus == 0) { $msg = "Video thumbnail uploaded successfully"; $status = Status::newGood($msg); } else { $msg = "Error uploading video thumbnail: {$response}"; $status = Status::newFatal($msg); } } else { $helper = new VideoHandlerHelper(); $status = $helper->resetVideoThumb($file, null, $delayIndex); } if ($status->isGood()) { // A good status doesn't necessarily mean we updated the actual thumbnail. A good status is returned for // successfully uploading the default thumb as well. Actually check the img sha to see if the thumb changed if ($file->getSha1() != self::DEFAULT_THUMB_SHA) { $this->log("success", $delayIndex, $title->getText(), $provider, ['thumbnail' => $file->getThumbUrl()]); } } else { $this->log("error", $delayIndex, $title->getText(), $provider, ['errorMsg' => $status->getMessage()]); } return $status; }
/** * CreateWikiProject object * @var CreateWikiProject * @group Infrastructure */ public function testWikiCreation() { global $wgCityId, $wgWikiaLocalSettingsPath, $wgMaxShellMemory, $wgMaxShellTime; $wgMaxShellMemory = 0; $wgMaxShellTime = 0; $languages = array('en', 'pl', 'de', 'pt-br'); $types = array(false, "answers"); foreach ($types as $type) { foreach ($languages as $lang) { $domain = sprintf("test%stest", date('YmdHis')); $this->oCWiki = new CreateWiki("Test Create Wiki", $domain, $lang, 1, $type); $created = $this->oCWiki->create(); $this->assertEquals(0, $created, "CreateWiki failed for language: {$lang} and type: {$type}"); if ($created == 0) { $city_id = $this->oCWiki->getWikiInfo('city_id'); $cmd = sprintf("SERVER_ID=%d %s %s/extensions/wikia/WikiFactory/Close/simpleclose.php --wiki_id=%d --conf %s", $wgCityId, "/usr/bin/php", $this->mIP, $city_id, $wgWikiaLocalSettingsPath); $err = wfShellExec($cmd, $retval); $this->assertEquals(0, $retval, "Drop Wiki failed for id: {$city_id}, language: {$lang} and type: {$type}, err: {$err}"); } } } }
public function execute() { global $wgExternalSharedDB; if (file_exists(self::PIDFILE)) { $sPid = file_get_contents(self::PIDFILE); // Another process already running. if (file_exists("/proc/{$sPid}")) { $this->output("INFO: Another process already running. Terminating.\n"); exit(0); } $this->output("WARNING: No process in pidfile found running.\n"); } file_put_contents(self::PIDFILE, getmypid()); $this->output("INFO: Searching for dump requests to process.\n"); $oDB = wfGetDB(DB_SLAVE, array(), $wgExternalSharedDB); $sWikiaId = (string) $oDB->selectField('dumps', 'dump_wiki_id', array('dump_completed IS NULL', 'dump_hold' => 'N'), __METHOD__, array('ORDER BY' => 'dump_requested ASC', 'LIMIT' => 1)); if (!$sWikiaId) { $this->output("INFO: No pending dump requests. Terminating.\n"); unlink(self::PIDFILE); exit(0); } global $IP, $wgWikiaLocalSettingsPath; $this->output("INFO: Creating dumps for Wikia #{$sWikiaId}.\n"); $sCommand = sprintf('SERVER_ID=177 php %s/extensions/wikia/WikiFactory/Dumps/runBackups.php --conf %s --id=%d --both --tmp --s3', $IP, $wgWikiaLocalSettingsPath, $sWikiaId); wfShellExec($sCommand, $iStatus); $oDB = wfGetDB(DB_MASTER, array(), $wgExternalSharedDB); if ($iStatus) { $this->output("ERROR: Failed creating dumps. Terminating.\n"); $oDB->update('dumps', array('dump_compression' => DumpsOnDemand::DEFAULT_COMPRESSION_FORMAT, 'dump_hold' => 'Y', 'dump_errors' => wfTimestampNow()), array('dump_wiki_id' => $sWikiaId, 'dump_completed IS NULL', 'dump_hold' => 'N'), __METHOD__); unlink(self::PIDFILE); exit($iStatus); } $this->output("INFO: Dumps completed. Updating the status of the request.\n"); $oDB->update('dumps', array('dump_completed' => wfTimestampNow(), 'dump_compression' => DumpsOnDemand::DEFAULT_COMPRESSION_FORMAT), array('dump_wiki_id' => $sWikiaId, 'dump_completed IS NULL', 'dump_hold' => 'N'), __METHOD__); DumpsOnDemand::purgeLatestDumpInfo(intval($sWikiaId)); $this->output("Done.\n"); unlink(self::PIDFILE); exit(0); }
function execute($params = null) { global $wgWikiaLocalSettingsPath, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime; // per moli, seriously frakked $wgMaxShellMemory = 0; $wgMaxShellFileSize = 0; $wgMaxShellTime = 0; $this->mTaskID = $params->task_id; // task params $data = unserialize($params->task_arguments); // start task $this->addLog('Starting task.'); // command $sCommand = "SERVER_ID={$data['wiki']} php " . dirname(__FILE__) . "/awardCreatorBadge.php --conf {$wgWikiaLocalSettingsPath}"; $this->addLog($sCommand); $log = wfShellExec($sCommand, $retval); if ($retval) { $this->log('Achievement awarding error! (City ID: ' . $data['wiki'] . '). Error code returned: ' . $retval . ' Error was: ' . $log); } else { $this->log("Log: \n" . $log . "\n"); } return true; }
function execute($params = null) { global $IP, $wgWikiaLocalSettingsPath; /* go with each supplied wiki and delete the supplied article load all configs for particular wikis before doing so (from wikifactory, not by _obsolete_ maintenance scripts and from LocalSettings as worked on fps) */ $this->mTaskID = $params->task_id; $oUser = User::newFromId($params->task_user_id); $oUser->load(); $this->mUser = $oUser->getName(); $data = unserialize($params->task_arguments); $articlesData = $data['articles']; $username = escapeshellarg($data['username']); $this->addLog('Starting task.'); $this->addLog('List of deleted articles (by ' . $this->mUser . ' as ' . $username . '):'); foreach ($articlesData as $wikiId => $articles) { foreach ($articles as $article) { $namespace = $article['namespace']; $reason = $article['reason'] ? '-r ' . escapeshellarg($article['reason']) : ''; $sCommand = "SERVER_ID={$wikiId} php {$IP}/maintenance/wikia/deleteOn.php -u {$username} -t " . escapeshellarg($article['title']) . " {$reason} --conf " . escapeshellarg($wgWikiaLocalSettingsPath); $city_url = WikiFactory::getVarValueByName('wgServer', $wikiId); if (empty($city_url)) { $city_url = "wiki id in WikiFactory: {$wikiId}"; } $city_path = WikiFactory::getVarValueByName('wgScript', $wikiId); $actual_title = wfShellExec($sCommand, $retval); if ($retval) { $this->addLog('Article deleting error! (' . $city_url . '). Error code returned: ' . $retval . ' Error was: ' . $actual_title); } else { $this->addLog('<a href="' . $city_url . $city_path . '?title=' . $actual_title . '">' . $city_url . $city_path . '?title=' . $actual_title . '</a>'); } } } return true; }
/** * Return an XML string describing the DjVu image * @return string|bool */ function retrieveMetaData() { global $wgDjvuToXML, $wgDjvuDump, $wgDjvuTxt; if (!$this->isValid()) { return false; } if (isset($wgDjvuDump)) { # djvudump is faster as of version 3.5 # http://sourceforge.net/tracker/index.php?func=detail&aid=1704049&group_id=32953&atid=406583 $cmd = wfEscapeShellArg($wgDjvuDump) . ' ' . wfEscapeShellArg($this->mFilename); $dump = wfShellExec($cmd); $xml = $this->convertDumpToXML($dump); } elseif (isset($wgDjvuToXML)) { $cmd = wfEscapeShellArg($wgDjvuToXML) . ' --without-anno --without-text ' . wfEscapeShellArg($this->mFilename); $xml = wfShellExec($cmd); } else { $xml = null; } # Text layer if (isset($wgDjvuTxt)) { $cmd = wfEscapeShellArg($wgDjvuTxt) . ' --detail=page ' . wfEscapeShellArg($this->mFilename); wfDebug(__METHOD__ . ": {$cmd}\n"); $retval = ''; $txt = wfShellExec($cmd, $retval, [], ['memory' => self::DJVUTXT_MEMORY_LIMIT]); if ($retval == 0) { # Strip some control characters $txt = preg_replace("/[\v]/", "", $txt); $reg = <<<EOR \t\t\t\t\t/\\(page\\s[\\d-]*\\s[\\d-]*\\s[\\d-]*\\s[\\d-]*\\s*" \t\t\t\t\t((?> # Text to match is composed of atoms of either: \t\t\t\t\t \\\\. # - any escaped character \t\t\t\t\t | # - any character different from " and \\ \t\t\t\t\t [^"\\\\]+ \t\t\t\t\t)*?) \t\t\t\t\t"\\s*\\) \t\t\t\t\t| # Or page can be empty ; in this case, djvutxt dumps () \t\t\t\t\t\\(\\s*()\\)/sx EOR; $txt = preg_replace_callback($reg, [$this, 'pageTextCallback'], $txt); $txt = "<DjVuTxt>\n<HEAD></HEAD>\n<BODY>\n" . $txt . "</BODY>\n</DjVuTxt>\n"; $xml = preg_replace("/<DjVuXML>/", "<mw-djvu><DjVuXML>", $xml, 1); $xml = $xml . $txt . '</mw-djvu>'; } } return $xml; }