Page MenuHomePhabricator

D17614.id42358.diff
No OneTemporary

D17614.id42358.diff

diff --git a/src/workflow/ArcanistDownloadWorkflow.php b/src/workflow/ArcanistDownloadWorkflow.php
--- a/src/workflow/ArcanistDownloadWorkflow.php
+++ b/src/workflow/ArcanistDownloadWorkflow.php
@@ -79,6 +79,163 @@
public function run() {
$conduit = $this->getConduit();
+ $id = $this->id;
+ $display_name = 'F'.$id;
+ $is_show = $this->show;
+ $save_as = $this->saveAs;
+
+ try {
+ $file = $conduit->callMethodSynchronous(
+ 'file.search',
+ array(
+ 'constraints' => array(
+ 'ids' => array($id),
+ ),
+ ));
+
+ $data = $file['data'];
+ if (!$data) {
+ throw new ArcanistUsageException(
+ pht(
+ 'File "%s" is not a valid file, or not visible.',
+ $display_name));
+ }
+
+ $file = head($data);
+ $data_uri = idxv($file, array('fields', 'dataURI'));
+
+ if ($data_uri === null) {
+ throw new ArcanistUsageException(
+ pht(
+ 'File "%s" can not be downloaded.',
+ $display_name));
+ }
+
+ if ($is_show) {
+ // Skip all the file path stuff if we're just going to echo the
+ // file contents.
+ } else {
+ if ($save_as !== null) {
+ $path = Filesystem::resolvePath($save_as);
+
+ $try_unique = false;
+ } else {
+ $path = idxv($file, array('fields', 'name'), $display_name);
+ $path = basename($path);
+ $path = Filesystem::resolvePath($path);
+
+ $try_unique = true;
+ }
+
+ if ($try_unique) {
+ $path = Filesystem::writeUniqueFile($path, '');
+ } else {
+ if (Filesystem::pathExists($path)) {
+ throw new ArcanistUsageException(
+ pht(
+ 'File "%s" already exists.',
+ $save_as));
+ }
+
+ Filesystem::writeFile($path, '');
+ }
+
+ $display_path = Filesystem::readablePath($path);
+ }
+
+ $size = idxv($file, array('fields', 'size'), 0);
+
+ if ($is_show) {
+ $file_handle = null;
+ } else {
+ $file_handle = fopen($path, 'ab+');
+ if ($file_handle === false) {
+ throw new Exception(
+ pht(
+ 'Failed to open file "%s" for writing.',
+ $path));
+ }
+
+ $this->writeInfo(
+ pht('DATA'),
+ pht(
+ 'Downloading "%s" (%s byte(s))...',
+ $display_name,
+ new PhutilNumber($size)));
+ }
+
+ $future = new HTTPSFuture($data_uri);
+
+ // For small files, don't bother drawing a progress bar.
+ $minimum_bar_bytes = (1024 * 1024 * 4);
+
+ if ($is_show || ($size < $minimum_bar_bytes)) {
+ $bar = null;
+ } else {
+ $bar = id(new PhutilConsoleProgressBar())
+ ->setTotal($size);
+ }
+
+ // TODO: We should stream responses to disk, but cURL gives us the raw
+ // HTTP response data and BaseHTTPFuture can not currently parse it in
+ // a stream-oriented way. Until this is resolved, buffer the file data
+ // in memory and write it to disk in one shot.
+
+ list($status, $data) = $future->resolve();
+ if ($status->getStatusCode() !== 200) {
+ throw new Exception(
+ pht(
+ 'Got HTTP %d status response, expected HTTP 200.',
+ $status));
+ }
+
+ if (strlen($data)) {
+ if ($is_show) {
+ echo $data;
+ } else {
+ $ok = fwrite($file_handle, $data);
+ if ($ok === false) {
+ throw new Exception(
+ pht(
+ 'Failed to write file data to "%s".',
+ $path));
+ }
+ }
+ }
+
+ if ($bar) {
+ $bar->update(strlen($data));
+ }
+
+ if ($bar) {
+ $bar->done();
+ }
+
+ if ($file_handle) {
+ $ok = fclose($file_handle);
+ if ($ok === false) {
+ throw new Exception(
+ pht(
+ 'Failed to close file handle for "%s".',
+ $path));
+ }
+ }
+
+ if (!$is_show) {
+ $this->writeOkay(
+ pht('DONE'),
+ pht(
+ 'Saved "%s" as "%s".',
+ $display_name,
+ $display_path));
+ }
+
+ return 0;
+ } catch (Exception $ex) {
+ // If we fail for any reason, fall back to the older mechanism using
+ // "file.info" and "file.download".
+ }
+
$this->writeStatusMessage(pht('Getting file information...')."\n");
$info = $conduit->callMethodSynchronous(
'file.info',

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 11, 3:07 AM (1 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7493628
Default Alt Text
D17614.id42358.diff (4 KB)

Event Timeline