Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/controller/DiffusionBrowseController.php
| Show First 20 Lines • Show All 186 Lines • ▼ Show 20 Lines | if ($hit_byte_limit) { | ||||
| throw new Exception(pht('Failed to load content file!')); | throw new Exception(pht('Failed to load content file!')); | ||||
| } | } | ||||
| if ($view === 'raw') { | if ($view === 'raw') { | ||||
| return $file->getRedirectResponse(); | return $file->getRedirectResponse(); | ||||
| } | } | ||||
| $data = $file->loadFileData(); | $data = $file->loadFileData(); | ||||
| if (ArcanistDiffUtils::isHeuristicBinaryFile($data)) { | |||||
| $ref = $this->getGitLFSRef($repository, $data); | |||||
| if ($ref) { | |||||
| if ($view == 'git-lfs') { | |||||
| $file = $this->loadGitLFSFile($ref); | |||||
| // Rename the file locally so we generate a better vanity URI for | |||||
| // it. In storage, it just has a name like "lfs-13f9a94c0923...", | |||||
| // since we don't get any hints about possible human-readable names | |||||
| // at upload time. | |||||
| $basename = basename($drequest->getPath()); | |||||
| $file->makeEphemeral(); | |||||
| $file->setName($basename); | |||||
| return $file->getRedirectResponse(); | |||||
| } else { | |||||
| $corpus = $this->buildGitLFSCorpus($ref); | |||||
| } | |||||
| } else if (ArcanistDiffUtils::isHeuristicBinaryFile($data)) { | |||||
| $file_uri = $file->getBestURI(); | $file_uri = $file->getBestURI(); | ||||
| if ($file->isViewableImage()) { | if ($file->isViewableImage()) { | ||||
| $corpus = $this->buildImageCorpus($file_uri); | $corpus = $this->buildImageCorpus($file_uri); | ||||
| } else { | } else { | ||||
| $corpus = $this->buildBinaryCorpus($file_uri, $data); | $corpus = $this->buildBinaryCorpus($file_uri, $data); | ||||
| } | } | ||||
| } else { | } else { | ||||
| ▲ Show 20 Lines • Show All 721 Lines • ▼ Show 20 Lines | $button = id(new PHUIButtonView()) | ||||
| ->setIcon('fa-pencil') | ->setIcon('fa-pencil') | ||||
| ->setID('editor_link') | ->setID('editor_link') | ||||
| ->setMetadata(array('link_template' => $template)) | ->setMetadata(array('link_template' => $template)) | ||||
| ->setDisabled(!$editor_link); | ->setDisabled(!$editor_link); | ||||
| return $button; | return $button; | ||||
| } | } | ||||
| private function renderFileButton($file_uri = null) { | private function renderFileButton($file_uri = null, $label = null) { | ||||
| $base_uri = $this->getRequest()->getRequestURI(); | $base_uri = $this->getRequest()->getRequestURI(); | ||||
| if ($file_uri) { | if ($file_uri) { | ||||
| $text = pht('Download Raw File'); | $text = pht('Download Raw File'); | ||||
| $href = $file_uri; | $href = $file_uri; | ||||
| $icon = 'fa-download'; | $icon = 'fa-download'; | ||||
| } else { | } else { | ||||
| $text = pht('View Raw File'); | $text = pht('View Raw File'); | ||||
| $href = $base_uri->alter('view', 'raw'); | $href = $base_uri->alter('view', 'raw'); | ||||
| $icon = 'fa-file-text'; | $icon = 'fa-file-text'; | ||||
| } | } | ||||
| if ($label !== null) { | |||||
| $text = $label; | |||||
| } | |||||
| $button = id(new PHUIButtonView()) | $button = id(new PHUIButtonView()) | ||||
| ->setTag('a') | ->setTag('a') | ||||
| ->setText($text) | ->setText($text) | ||||
| ->setHref($href) | ->setHref($href) | ||||
| ->setIcon($icon); | ->setIcon($icon); | ||||
| return $button; | return $button; | ||||
| } | } | ||||
| private function renderGitLFSButton() { | |||||
| $viewer = $this->getViewer(); | |||||
| $uri = $this->getRequest()->getRequestURI(); | |||||
| $href = $uri->alter('view', 'git-lfs'); | |||||
| $text = pht('Download from Git LFS'); | |||||
| $icon = 'fa-download'; | |||||
| return id(new PHUIButtonView()) | |||||
| ->setTag('a') | |||||
| ->setText($text) | |||||
| ->setHref($href) | |||||
| ->setIcon($icon); | |||||
| } | |||||
| private function buildDisplayRows( | private function buildDisplayRows( | ||||
| array $lines, | array $lines, | ||||
| array $blame_list, | array $blame_list, | ||||
| array $blame_commits, | array $blame_commits, | ||||
| $show_color, | $show_color, | ||||
| $show_blame) { | $show_blame) { | ||||
| ▲ Show 20 Lines • Show All 920 Lines • ▼ Show 20 Lines | return phutil_tag( | ||||
| 'textarea', | 'textarea', | ||||
| array( | array( | ||||
| 'style' => 'border: none; width: 100%; height: 80em; '. | 'style' => 'border: none; width: 100%; height: 80em; '. | ||||
| 'font-family: monospace', | 'font-family: monospace', | ||||
| ), | ), | ||||
| $corpus); | $corpus); | ||||
| } | } | ||||
| private function getGitLFSRef(PhabricatorRepository $repository, $data) { | |||||
| if (!$repository->canUseGitLFS()) { | |||||
| return null; | |||||
| } | |||||
| $lfs_pattern = '(^version https://git-lfs\\.github\\.com/spec/v1[\r\n])'; | |||||
| if (!preg_match($lfs_pattern, $data)) { | |||||
| return null; | |||||
| } | |||||
| $matches = null; | |||||
| if (!preg_match('(^oid sha256:(.*)$)m', $data, $matches)) { | |||||
| return null; | |||||
| } | |||||
| $hash = $matches[1]; | |||||
| $hash = trim($hash); | |||||
| return id(new PhabricatorRepositoryGitLFSRefQuery()) | |||||
| ->setViewer($this->getViewer()) | |||||
| ->withRepositoryPHIDs(array($repository->getPHID())) | |||||
| ->withObjectHashes(array($hash)) | |||||
| ->executeOne(); | |||||
| } | |||||
| private function buildGitLFSCorpus(PhabricatorRepositoryGitLFSRef $ref) { | |||||
| // TODO: We should probably test if we can load the file PHID here and | |||||
Lint: TODO Comment: This comment has a TODO. | |||||
| // show the user an error if we can't, rather than making them click | |||||
| // through to hit an error. | |||||
| $header = id(new PHUIHeaderView()) | |||||
| ->setHeader(basename($this->getDiffusionRequest()->getPath())) | |||||
| ->setHeaderIcon('fa-archive'); | |||||
| $severity = PHUIInfoView::SEVERITY_NOTICE; | |||||
| $messages = array(); | |||||
| $messages[] = pht( | |||||
| 'This %s file is stored in Git Large File Storage.', | |||||
| phutil_format_bytes($ref->getByteSize())); | |||||
| try { | |||||
| $file = $this->loadGitLFSFile($ref); | |||||
| $data = $this->renderGitLFSButton(); | |||||
| $header->addActionLink($data); | |||||
| } catch (Exception $ex) { | |||||
| $severity = PHUIInfoView::SEVERITY_ERROR; | |||||
| $messages[] = pht('The data for this file could not be loaded.'); | |||||
| } | |||||
| $raw = $this->renderFileButton(null, pht('View Raw LFS Pointer')); | |||||
| $header->addActionLink($raw); | |||||
| $corpus = id(new PHUIObjectBoxView()) | |||||
| ->setHeader($header) | |||||
| ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) | |||||
| ->setCollapsed(true); | |||||
| if ($messages) { | |||||
| $corpus->setInfoView( | |||||
| id(new PHUIInfoView()) | |||||
| ->setSeverity($severity) | |||||
| ->setErrors($messages)); | |||||
| } | |||||
| return $corpus; | |||||
| } | |||||
| private function loadGitLFSFile(PhabricatorRepositoryGitLFSRef $ref) { | |||||
| $viewer = $this->getViewer(); | |||||
| $file = id(new PhabricatorFileQuery()) | |||||
| ->setViewer($viewer) | |||||
| ->withPHIDs(array($ref->getFilePHID())) | |||||
| ->executeOne(); | |||||
| if (!$file) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Failed to load file object for Git LFS ref "%s"!', | |||||
| $ref->getObjectHash())); | |||||
| } | |||||
| return $file; | |||||
| } | |||||
| } | } | ||||
This comment has a TODO.