Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/config/option/PhabricatorAWSConfigOptions.php b/src/applications/config/option/PhabricatorAWSConfigOptions.php
index a7a3a1e2ea..d610e1641c 100644
--- a/src/applications/config/option/PhabricatorAWSConfigOptions.php
+++ b/src/applications/config/option/PhabricatorAWSConfigOptions.php
@@ -1,60 +1,60 @@
<?php
final class PhabricatorAWSConfigOptions
extends PhabricatorApplicationConfigOptions {
public function getName() {
return pht('Amazon Web Services');
}
public function getDescription() {
- return pht('Configure integration with AWS (EC2, SES, S3, etc).');
+ return pht('Configure integration with AWS (EC2, SES, S3, etc.).');
}
public function getIcon() {
return 'fa-server';
}
public function getGroup() {
return 'core';
}
public function getOptions() {
return array(
$this->newOption('amazon-s3.access-key', 'string', null)
->setLocked(true)
->setDescription(pht('Access key for Amazon S3.')),
$this->newOption('amazon-s3.secret-key', 'string', null)
->setHidden(true)
->setDescription(pht('Secret key for Amazon S3.')),
$this->newOption('amazon-s3.region', 'string', null)
->setLocked(true)
->setDescription(
pht(
'Amazon S3 region where your S3 bucket is located. When you '.
'specify a region, you should also specify a corresponding '.
'endpoint with `amazon-s3.endpoint`. You can find a list of '.
'available regions and endpoints in the AWS documentation.'))
->addExample('us-west-1', pht('USWest Region')),
$this->newOption('amazon-s3.endpoint', 'string', null)
->setLocked(true)
->setDescription(
pht(
'Explicit S3 endpoint to use. This should be the endpoint '.
'which corresponds to the region you have selected in '.
'`amazon-s3.region`. This software can not determine the correct '.
'endpoint automatically because some endpoint locations are '.
'irregular.'))
->addExample(
's3-us-west-1.amazonaws.com',
pht('Use specific endpoint')),
$this->newOption('amazon-ec2.access-key', 'string', null)
->setLocked(true)
->setDescription(pht('Access key for Amazon EC2.')),
$this->newOption('amazon-ec2.secret-key', 'string', null)
->setHidden(true)
->setDescription(pht('Secret key for Amazon EC2.')),
);
}
}
diff --git a/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php b/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php
index d80534ce73..87de9ee37b 100644
--- a/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php
+++ b/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php
@@ -1,327 +1,327 @@
<?php
final class PhabricatorBulkManagementExportWorkflow
extends PhabricatorBulkManagementWorkflow {
protected function didConstruct() {
$this
->setName('export')
->setExamples('**export** [options]')
->setSynopsis(
- pht('Export data to a flat file (JSON, CSV, Excel, etc).'))
+ pht('Export data to a flat file (JSON, CSV, Excel, etc.).'))
->setArguments(
array(
array(
'name' => 'class',
'param' => 'class',
'help' => pht(
'SearchEngine class to export data from.'),
),
array(
'name' => 'format',
'param' => 'format',
'help' => pht('Export format.'),
),
array(
'name' => 'query',
'param' => 'key',
'help' => pht(
'Export the data selected by one or more queries.'),
'repeat' => true,
),
array(
'name' => 'output',
'param' => 'path',
'help' => pht(
'Write output to a file. If omitted, output will be sent to '.
'stdout.'),
),
array(
'name' => 'overwrite',
'help' => pht(
'If the output file already exists, overwrite it instead of '.
'raising an error.'),
),
));
}
public function execute(PhutilArgumentParser $args) {
$viewer = $this->getViewer();
list($engine, $queries) = $this->newQueries($args);
$format_key = $args->getArg('format');
if (!phutil_nonempty_string($format_key)) {
throw new PhutilArgumentUsageException(
pht(
'Specify an export format with "--format".'));
}
$all_formats = PhabricatorExportFormat::getAllExportFormats();
$format = idx($all_formats, $format_key);
if (!$format) {
throw new PhutilArgumentUsageException(
pht(
'Unknown export format ("%s"). Known formats are: %s.',
$format_key,
implode(', ', array_keys($all_formats))));
}
if (!$format->isExportFormatEnabled()) {
throw new PhutilArgumentUsageException(
pht(
'Export format ("%s") is not enabled.',
$format_key));
}
$is_overwrite = $args->getArg('overwrite');
$output_path = $args->getArg('output');
if (!phutil_nonempty_string($output_path)) {
throw new PhutilArgumentUsageException(
pht(
'Use "--output <path>" to specify an output file, or "--output -" '.
'to print to stdout.'));
}
if ($output_path === '-') {
$is_stdout = true;
} else {
$is_stdout = false;
}
if ($is_stdout && $is_overwrite) {
throw new PhutilArgumentUsageException(
pht(
'Flag "--overwrite" has no effect when outputting to stdout.'));
}
if (!$is_overwrite) {
if (!$is_stdout && Filesystem::pathExists($output_path)) {
throw new PhutilArgumentUsageException(
pht(
'Output path already exists. Use "--overwrite" to overwrite '.
'it.'));
}
}
// If we have more than one query, execute the queries to figure out which
// results they hit, then build a synthetic query for all those results
// using the IDs.
if (count($queries) > 1) {
$saved_query = $this->newUnionQuery($engine, $queries);
} else {
$saved_query = head($queries);
}
$export_engine = id(new PhabricatorExportEngine())
->setViewer($viewer)
->setTitle(pht('Export'))
->setFilename(pht('export'))
->setSearchEngine($engine)
->setSavedQuery($saved_query)
->setExportFormat($format);
$file = $export_engine->exportFile();
$iterator = $file->getFileDataIterator();
if (!$is_stdout) {
// Empty the file before we start writing to it. Otherwise, "--overwrite"
// will really mean "--append".
Filesystem::writeFile($output_path, '');
foreach ($iterator as $chunk) {
Filesystem::appendFile($output_path, $chunk);
}
echo tsprintf(
"%s\n",
pht(
'Exported data to "%s".',
Filesystem::readablePath($output_path)));
} else {
foreach ($iterator as $chunk) {
echo $chunk;
}
}
return 0;
}
private function newQueries(PhutilArgumentParser $args) {
$viewer = $this->getViewer();
$query_keys = $args->getArg('query');
if (!$query_keys) {
throw new PhutilArgumentUsageException(
pht(
'Specify one or more queries to export with "--query".'));
}
$engine_classes = id(new PhutilClassMapQuery())
->setAncestorClass('PhabricatorApplicationSearchEngine')
->execute();
$class = $args->getArg('class');
if (phutil_nonempty_string($class)) {
$class_list = array();
foreach ($engine_classes as $class_name => $engine_object) {
$can_export = id(clone $engine_object)
->setViewer($viewer)
->canExport();
if ($can_export) {
$class_list[] = $class_name;
}
}
sort($class_list);
$class_list = implode(', ', $class_list);
$matches = array();
foreach ($engine_classes as $class_name => $engine_object) {
if (stripos($class_name, $class) !== false) {
if (strtolower($class_name) == strtolower($class)) {
$matches = array($class_name);
break;
} else {
$matches[] = $class_name;
}
}
}
if (!$matches) {
throw new PhutilArgumentUsageException(
pht(
'No search engines match "%s". Available engines which support '.
'data export are: %s.',
$class,
$class_list));
} else if (count($matches) > 1) {
throw new PhutilArgumentUsageException(
pht(
'Multiple search engines match "%s": %s.',
$class,
implode(', ', $matches)));
} else {
$class = head($matches);
}
$engine = newv($class, array())
->setViewer($viewer);
} else {
$engine = null;
}
$queries = array();
foreach ($query_keys as $query_key) {
if ($engine) {
if ($engine->isBuiltinQuery($query_key)) {
$queries[$query_key] = $engine->buildSavedQueryFromBuiltin(
$query_key);
continue;
}
}
$saved_query = id(new PhabricatorSavedQueryQuery())
->setViewer($viewer)
->withQueryKeys(array($query_key))
->executeOne();
if (!$saved_query) {
if (!$engine) {
throw new PhutilArgumentUsageException(
pht(
'Query "%s" is unknown. To run a builtin query like "all" or '.
'"active", also specify the search engine with "--class".',
$query_key));
} else {
throw new PhutilArgumentUsageException(
pht(
'Query "%s" is not a recognized query for class "%s".',
$query_key,
get_class($engine)));
}
}
$queries[$query_key] = $saved_query;
}
// If we don't have an engine from "--class", fill it in by looking at the
// class of the first query.
if (!$engine) {
foreach ($queries as $query) {
$engine = newv($query->getEngineClassName(), array())
->setViewer($viewer);
break;
}
}
$engine_class = get_class($engine);
foreach ($queries as $query) {
$query_class = $query->getEngineClassName();
if ($query_class !== $engine_class) {
throw new PhutilArgumentUsageException(
pht(
'Specified queries use different engines: query "%s" uses '.
'engine "%s", not "%s". All queries must run on the same '.
'engine.',
$query->getQueryKey(),
$query_class,
$engine_class));
}
}
if (!$engine->canExport()) {
throw new PhutilArgumentUsageException(
pht(
'SearchEngine class ("%s") does not support data export.',
$engine_class));
}
return array($engine, $queries);
}
private function newUnionQuery(
PhabricatorApplicationSearchEngine $engine,
array $queries) {
assert_instances_of($queries, 'PhabricatorSavedQuery');
$engine = clone $engine;
$ids = array();
foreach ($queries as $saved_query) {
$page_size = 1000;
$page_cursor = null;
do {
$query = $engine->buildQueryFromSavedQuery($saved_query);
$pager = $engine->newPagerForSavedQuery($saved_query);
$pager->setPageSize($page_size);
if ($page_cursor !== null) {
$pager->setAfterID($page_cursor);
}
$objects = $engine->executeQuery($query, $pager);
$page_cursor = $pager->getNextPageID();
foreach ($objects as $object) {
$ids[] = $object->getID();
}
} while ($pager->getHasMoreResults());
}
// When we're merging multiple different queries, override any query order
// and just put the combined result list in ID order. At time of writing,
// we can't merge the result sets together while retaining the overall sort
// order even if they all used the same order, and it's meaningless to try
// to retain orders if the queries had different orders in the first place.
rsort($ids);
return id($engine->newSavedQuery())
->setParameter('ids', $ids);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Nov 25, 4:05 AM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1177
Default Alt Text
(12 KB)

Event Timeline