/** * Scale a file with a remote "scaler", as exists on the Wikimedia Foundation * cluster, and output it to STDOUT. * Note: Unlike the usual thumbnail process, the web client never sees the * cluster URL; we do the whole HTTP transaction to the scaler ourselves * and cat the results out. * Note: We rely on NFS to have propagated the file contents to the scaler. * However, we do not rely on the thumbnail being created in NFS and then * propagated back to our filesystem. Instead we take the results of the * HTTP request instead. * Note: No caching is being done here, although we are instructing the * client to cache it forever. * * @param File $file * @param array $params Scaling parameters ( e.g. array( width => '50' ) ); * @param int $flags Scaling flags ( see File:: constants ) * @throws MWException * @return bool Success */ private function outputRemoteScaledThumb($file, $params, $flags) { // This option probably looks something like // '//upload.wikimedia.org/wikipedia/test/thumb/temp'. Do not use // trailing slash. $scalerBaseUrl = $this->getConfig()->get('UploadStashScalerBaseUrl'); if (preg_match('/^\\/\\//', $scalerBaseUrl)) { // this is apparently a protocol-relative URL, which makes no sense in this context, // since this is used for communication that's internal to the application. // default to http. $scalerBaseUrl = wfExpandUrl($scalerBaseUrl, PROTO_CANONICAL); } // We need to use generateThumbName() instead of thumbName(), because // the suffix needs to match the file name for the remote thumbnailer // to work $scalerThumbName = $file->generateThumbName($file->getName(), $params); $scalerThumbUrl = $scalerBaseUrl . '/' . $file->getUrlRel() . '/' . rawurlencode($scalerThumbName); // make a curl call to the scaler to create a thumbnail $httpOptions = array('method' => 'GET', 'timeout' => 5); $req = MWHttpRequest::factory($scalerThumbUrl, $httpOptions, __METHOD__); $status = $req->execute(); if (!$status->isOK()) { $errors = $status->getErrorsArray(); $errorStr = "Fetching thumbnail failed: " . print_r($errors, 1); $errorStr .= "\nurl = {$scalerThumbUrl}\n"; throw new MWException($errorStr); } $contentType = $req->getResponseHeader("content-type"); if (!$contentType) { throw new MWException("Missing content-type header"); } return $this->outputContents($req->getContent(), $contentType); }
/** * @param File $file * @returns string */ private function fileLine($file) { global $wgLang, $wgTitle; $target = $this->page->getPrefixedText(); $date = $wgLang->timeanddate($file->getTimestamp(), true); $del = ''; # Hidden files... if ($file->isDeleted(File::DELETED_FILE)) { $del = ' <tt>' . wfMsgHtml('deletedrev') . '</tt>'; if (!$file->userCan(File::DELETED_FILE)) { $pageLink = $date; } else { $pageLink = $this->skin->makeKnownLinkObj($wgTitle, $date, "target={$target}&file={$file->sha1}." . $file->getExtension()); } $pageLink = '<span class="history-deleted">' . $pageLink . '</span>'; # Regular files... } else { $url = $file->getUrlRel(); $pageLink = "<a href=\"{$url}\">{$date}</a>"; } $data = wfMsg('widthheight', $wgLang->formatNum($file->getWidth()), $wgLang->formatNum($file->getHeight())) . ' (' . wfMsgExt('nbytes', 'parsemag', $wgLang->formatNum($file->getSize())) . ')'; $data = htmlspecialchars($data); return "<li>{$pageLink} " . $this->fileUserTools($file) . " {$data} " . $this->fileComment($file) . "{$del}</li>"; }
/** * @param LocalFile $file file to check * @return int RESULT_* flag * @see BAC-731 */ private function processMissingFile(File $file) { global $wgUploadDirectory, $wgCityId; try { $exists = $this->repo->fileExists($file->getPath()); } catch (Exception $ex) { $exists = true; $this->error(sprintf("%s caught: %s", get_class($ex), $ex->getMessage())); } // file is fine, continue... if ($exists) { return self::RESULT_EXISTS; } $restored = false; $this->output(sprintf("'%s' doesn't exist (%s)\n", $file->getTitle(), $file->getUrlRel())); // let's assume that given file was moved from A // let's get all possible A's and try to find images for them $candidates = $this->getCandidates($file); if (empty($candidates) && !empty($this->otherLocation)) { # check other location - maybe this file is there :) $candidates = $this->checkOtherLocation($file); } if (!empty($candidates)) { $this->output(sprintf(" %d candidate(s) found...\n", count($candidates))); foreach ($candidates as $candidate) { $srcFile = LocalFile::newFromTitle($candidate, $this->repo); $srcPath = $wgUploadDirectory . '/' . $srcFile->getUrlRel(); // check on FS storage $foundOnFS = file_exists($srcPath); $this->output(sprintf(" '%s' -> <%s> [%s]\n", $srcFile->getName(), $srcPath, $foundOnFS ? 'found' : 'not found')); // check the next candidate (or if --dry-run) if (!$foundOnFS || $this->isDryRun) { continue; } // upload found image to Swift $swift = \Wikia\SwiftStorage::newFromWiki($wgCityId); $metadata = ['Sha1Base36' => $file->getSha1()]; $status = $swift->store($srcPath, $file->getUrlRel(), $metadata, $file->getMimeType()); if ($status->isOK()) { self::log('restored', $file->getName()); $restored = true; break; } } $this->output("\n"); } // remove an image if it can't be restored if (!$restored && !$this->isDryRun) { $file->delete(self::REASON); $this->output(sprintf(" Removed '%s'!\n", $file->getName())); self::log('removed', $file->getName()); } return $restored ? self::RESULT_RESTORED : self::RESULT_NOT_RESTORED; }