mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-12-01 19:22:41 +01:00
(stable) Promote 2017 Week 14
This commit is contained in:
commit
3512c4ab86
2 changed files with 179 additions and 11 deletions
|
@ -222,15 +222,6 @@ final class ArcanistFileDataRef extends Phobject {
|
||||||
$path));
|
$path));
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash = @sha1_file($path);
|
|
||||||
if ($hash === false) {
|
|
||||||
throw new Exception(
|
|
||||||
pht(
|
|
||||||
'Unable to upload file: failed to calculate file data hash for '.
|
|
||||||
'path "%s".',
|
|
||||||
$path));
|
|
||||||
}
|
|
||||||
|
|
||||||
$size = @filesize($path);
|
$size = @filesize($path);
|
||||||
if ($size === false) {
|
if ($size === false) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
@ -240,11 +231,11 @@ final class ArcanistFileDataRef extends Phobject {
|
||||||
$path));
|
$path));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->hash = $hash;
|
$this->hash = $this->newFileHash($path);
|
||||||
$this->size = $size;
|
$this->size = $size;
|
||||||
} else {
|
} else {
|
||||||
$data = $this->data;
|
$data = $this->data;
|
||||||
$this->hash = sha1($data);
|
$this->hash = $this->newDataHash($data);
|
||||||
$this->size = strlen($data);
|
$this->size = strlen($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,4 +345,24 @@ final class ArcanistFileDataRef extends Phobject {
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function newFileHash($path) {
|
||||||
|
$hash = hash_file('sha256', $path, $raw_output = false);
|
||||||
|
|
||||||
|
if ($hash === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function newDataHash($data) {
|
||||||
|
$hash = hash('sha256', $data, $raw_output = false);
|
||||||
|
|
||||||
|
if ($hash === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hash;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,163 @@ EOTEXT
|
||||||
public function run() {
|
public function run() {
|
||||||
$conduit = $this->getConduit();
|
$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");
|
$this->writeStatusMessage(pht('Getting file information...')."\n");
|
||||||
$info = $conduit->callMethodSynchronous(
|
$info = $conduit->callMethodSynchronous(
|
||||||
'file.info',
|
'file.info',
|
||||||
|
|
Loading…
Reference in a new issue