public function run() { static $color_map = array('Closed' => 'cyan', 'Needs Review' => 'magenta', 'Needs Revision' => 'red', 'Changes Planned' => 'red', 'Accepted' => 'green', 'No Revision' => 'blue', 'Abandoned' => 'default'); $revisions = $this->getConduit()->callMethodSynchronous('differential.query', array('authors' => array($this->getUserPHID()), 'status' => 'status-open')); if (!$revisions) { echo pht('You have no open Differential revisions.') . "\n"; return 0; } $repository_api = $this->getRepositoryAPI(); $info = array(); foreach ($revisions as $key => $revision) { $revision_path = Filesystem::resolvePath($revision['sourcePath']); $current_path = Filesystem::resolvePath($repository_api->getPath()); if ($revision_path == $current_path) { $info[$key]['exists'] = 1; } else { $info[$key]['exists'] = 0; } $info[$key]['sort'] = sprintf('%d%04d%08d', $info[$key]['exists'], $revision['status'], $revision['id']); $info[$key]['statusName'] = $revision['statusName']; $info[$key]['color'] = idx($color_map, $revision['statusName'], 'default'); } $table = id(new PhutilConsoleTable())->setShowHeader(false)->addColumn('exists', array('title' => ''))->addColumn('status', array('title' => pht('Status')))->addColumn('title', array('title' => pht('Title'))); $info = isort($info, 'sort'); foreach ($info as $key => $spec) { $revision = $revisions[$key]; $table->addRow(array('exists' => $spec['exists'] ? phutil_console_format('**%s**', '*') : '', 'status' => phutil_console_format("<fg:{$spec['color']}>%s</fg>", $spec['statusName']), 'title' => phutil_console_format('**D%d:** %s', $revision['id'], $revision['title']))); } $table->draw(); return 0; }
public static function sortAndGroupInlines(array $inlines, array $changesets) { assert_instances_of($inlines, 'DifferentialTransaction'); assert_instances_of($changesets, 'DifferentialChangeset'); $changesets = mpull($changesets, null, 'getID'); $changesets = msort($changesets, 'getFilename'); // Group the changesets by file and reorder them by display order. $inline_groups = array(); foreach ($inlines as $inline) { $changeset_id = $inline->getComment()->getChangesetID(); $inline_groups[$changeset_id][] = $inline; } $inline_groups = array_select_keys($inline_groups, array_keys($changesets)); foreach ($inline_groups as $changeset_id => $group) { // Sort the group of inlines by line number. $items = array(); foreach ($group as $inline) { $comment = $inline->getComment(); $num = $comment->getLineNumber(); $len = $comment->getLineLength(); $id = $comment->getID(); $items[] = array('inline' => $inline, 'sort' => sprintf('~%010d%010d%010d', $num, $len, $id)); } $items = isort($items, 'sort'); $items = ipull($items, 'inline'); $inline_groups[$changeset_id] = $items; } return $inline_groups; }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $commit = $drequest->loadCommit(); $raw_changes = queryfx_all($repository->establishConnection('r'), 'SELECT c.*, p.path pathName, t.path targetPathName FROM %T c LEFT JOIN %T p ON c.pathID = p.id LEFT JOIN %T t on c.targetPathID = t.id WHERE c.commitID = %d AND isDirect = 1', PhabricatorRepository::TABLE_PATHCHANGE, PhabricatorRepository::TABLE_PATH, PhabricatorRepository::TABLE_PATH, $commit->getID()); $changes = array(); $raw_changes = isort($raw_changes, 'pathName'); foreach ($raw_changes as $raw_change) { $type = $raw_change['changeType']; if ($type == DifferentialChangeType::TYPE_CHILD) { continue; } $change = new DiffusionPathChange(); $change->setPath(ltrim($raw_change['pathName'], '/')); $change->setChangeType($raw_change['changeType']); $change->setFileType($raw_change['fileType']); $change->setCommitIdentifier($commit->getCommitIdentifier()); $changes[] = $change; } return $changes; }
public static function getPatchList() { $root = dirname(phutil_get_library_root('phabricator')); // Find the patch files $patches_dir = $root . '/resources/sql/patches/'; $finder = new FileFinder($patches_dir); $results = $finder->find(); $versions = array(); $patches = array(); foreach ($results as $path) { $matches = array(); if (!preg_match('/(\\d+)\\..*\\.(sql|php)$/', $path, $matches)) { continue; } $version = (int) $matches[1]; $patches[] = array('version' => $version, 'path' => $patches_dir . $path); if (empty($versions[$version])) { $versions[$version] = true; } else { throw new Exception("Two patches have version {$version}!"); } } // Files are in some 'random' order returned by the operating system // We need to apply them in proper order $patches = isort($patches, 'version'); return $patches; }
public function run() { $revisions = $this->getConduit()->callMethodSynchronous('differential.query', array('authors' => array($this->getUserPHID()), 'status' => 'status-open')); if (!$revisions) { echo "You have no open Differential revisions.\n"; return 0; } $repository_api = $this->getRepositoryAPI(); $info = array(); $status_len = 0; foreach ($revisions as $key => $revision) { $revision_path = Filesystem::resolvePath($revision['sourcePath']); $current_path = Filesystem::resolvePath($repository_api->getPath()); if ($revision_path == $current_path) { $info[$key]['here'] = 1; } else { $info[$key]['here'] = 0; } $info[$key]['sort'] = sprintf('%d%04d%08d', $info[$key]['here'], $revision['status'], $revision['id']); $info[$key]['statusColorized'] = BranchInfo::renderColorizedRevisionStatus($revision['statusName']); $status_len = max($status_len, strlen($info[$key]['statusColorized'])); } $info = isort($info, 'sort'); foreach ($info as $key => $spec) { $revision = $revisions[$key]; printf("%s %-" . ($status_len + 4) . "s D%d: %s\n", $spec['here'] ? phutil_console_format('**%s**', '*') : ' ', $spec['statusColorized'], $revision['id'], $revision['title']); } return 0; }
public function processRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $user = $this->getUser(); $preferences = $this->getPreferences(); $value_email = PhabricatorEmailTagsSetting::VALUE_EMAIL; $errors = array(); if ($request->isFormPost()) { $new_tags = $request->getArr('mailtags'); $mailtags = $preferences->getPreference('mailtags', array()); $all_tags = $this->getAllTags($user); foreach ($all_tags as $key => $label) { $mailtags[$key] = (int) idx($new_tags, $key, $value_email); } $this->writeSetting($preferences, PhabricatorEmailTagsSetting::SETTINGKEY, $mailtags); return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true')); } $mailtags = $preferences->getSettingValue(PhabricatorEmailTagsSetting::SETTINGKEY); $form = id(new AphrontFormView())->setUser($viewer); $form->appendRemarkupInstructions(pht('You can adjust **Application Settings** here to customize when ' . 'you are emailed and notified.' . "\n\n" . "| Setting | Effect\n" . "| ------- | -------\n" . "| Email | You will receive an email and a notification, but the " . "notification will be marked \"read\".\n" . "| Notify | You will receive an unread notification only.\n" . "| Ignore | You will receive nothing.\n" . "\n\n" . 'If an update makes several changes (like adding CCs to a task, ' . 'closing it, and adding a comment) you will receive the strongest ' . 'notification any of the changes is configured to deliver.' . "\n\n" . 'These preferences **only** apply to objects you are connected to ' . '(for example, Revisions where you are a reviewer or tasks you are ' . 'CC\'d on). To receive email alerts when other objects are created, ' . 'configure [[ /herald/ | Herald Rules ]].')); $editors = $this->getAllEditorsWithTags($user); // Find all the tags shared by more than one application, and put them // in a "common" group. $all_tags = array(); foreach ($editors as $editor) { foreach ($editor->getMailTagsMap() as $tag => $name) { if (empty($all_tags[$tag])) { $all_tags[$tag] = array('count' => 0, 'name' => $name); } $all_tags[$tag]['count']; } } $common_tags = array(); foreach ($all_tags as $tag => $info) { if ($info['count'] > 1) { $common_tags[$tag] = $info['name']; } } // Build up the groups of application-specific options. $tag_groups = array(); foreach ($editors as $editor) { $tag_groups[] = array($editor->getEditorObjectsDescription(), array_diff_key($editor->getMailTagsMap(), $common_tags)); } // Sort them, then put "Common" at the top. $tag_groups = isort($tag_groups, 0); if ($common_tags) { array_unshift($tag_groups, array(pht('Common'), $common_tags)); } // Finally, build the controls. foreach ($tag_groups as $spec) { list($label, $map) = $spec; $control = $this->buildMailTagControl($label, $map, $mailtags); $form->appendChild($control); } $form->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preferences'))); $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Email Preferences'))->setFormSaved($request->getStr('saved'))->setFormErrors($errors)->setForm($form); return $form_box; }
public function renderValueForRevisionView() { $diff = $this->getDiff(); $ustar = DifferentialRevisionUpdateHistoryView::renderDiffUnitStar($diff); $umsg = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff); $rows = array(); $rows[] = array('style' => 'star', 'name' => $ustar, 'value' => $umsg, 'show' => true); $excuse = $this->getUnitExcuse(); if ($excuse) { $rows[] = array('style' => 'excuse', 'name' => 'Excuse', 'value' => nl2br(phutil_escape_html($excuse)), 'show' => true); } $show_limit = 10; $hidden = array(); $udata = $this->getDiffProperty('arc:unit'); if ($udata) { $sort_map = array(ArcanistUnitTestResult::RESULT_BROKEN => 0, ArcanistUnitTestResult::RESULT_FAIL => 1, ArcanistUnitTestResult::RESULT_UNSOUND => 2, ArcanistUnitTestResult::RESULT_SKIP => 3, ArcanistUnitTestResult::RESULT_POSTPONED => 4, ArcanistUnitTestResult::RESULT_PASS => 5); foreach ($udata as $key => $test) { $udata[$key]['sort'] = idx($sort_map, idx($test, 'result')); } $udata = isort($udata, 'sort'); foreach ($udata as $test) { $result = idx($test, 'result'); $default_hide = false; switch ($result) { case ArcanistUnitTestResult::RESULT_POSTPONED: case ArcanistUnitTestResult::RESULT_PASS: $default_hide = true; break; } if ($show_limit && !$default_hide) { --$show_limit; $show = true; } else { $show = false; if (empty($hidden[$result])) { $hidden[$result] = 0; } $hidden[$result]++; } $rows[] = array('style' => $this->getResultStyle($result), 'name' => phutil_escape_html(ucwords($result)), 'value' => phutil_escape_html(idx($test, 'name')), 'show' => $show); $userdata = idx($test, 'userdata'); if ($userdata) { $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine(); $userdata = $engine->markupText($userdata); $rows[] = array('style' => 'details', 'value' => $userdata, 'show' => false); if (empty($hidden['details'])) { $hidden['details'] = 0; } $hidden['details']++; } } } $show_string = $this->renderShowString($hidden); $view = new DifferentialResultsTableView(); $view->setRows($rows); $view->setShowMoreString($show_string); return $view->render(); }
protected function executeQuery() { $drequest = $this->getRequest(); $repository = $drequest->getRepository(); $commit = $drequest->loadCommit(); $conn_r = $repository->establishConnection('r'); $limit = ''; if ($this->limit) { $limit = qsprintf($conn_r, 'LIMIT %d', $this->limit + 1); } $raw_changes = queryfx_all($conn_r, 'SELECT c.*, p.path pathName, t.path targetPathName, i.commitIdentifier targetCommitIdentifier FROM %T c LEFT JOIN %T p ON c.pathID = p.id LEFT JOIN %T t ON c.targetPathID = t.id LEFT JOIN %T i ON c.targetCommitID = i.id WHERE c.commitID = %d AND isDirect = 1 %Q', PhabricatorRepository::TABLE_PATHCHANGE, PhabricatorRepository::TABLE_PATH, PhabricatorRepository::TABLE_PATH, $commit->getTableName(), $commit->getID(), $limit); $limited = $this->limit && count($raw_changes) > $this->limit; if ($limited) { $raw_changes = array_slice($raw_changes, 0, $this->limit); } $changes = array(); $raw_changes = isort($raw_changes, 'pathName'); foreach ($raw_changes as $raw_change) { $type = $raw_change['changeType']; if ($type == DifferentialChangeType::TYPE_CHILD) { continue; } $change = new DiffusionPathChange(); $change->setPath(ltrim($raw_change['pathName'], '/')); $change->setChangeType($raw_change['changeType']); $change->setFileType($raw_change['fileType']); $change->setCommitIdentifier($commit->getCommitIdentifier()); $change->setTargetPath(ltrim($raw_change['targetPathName'], '/')); $change->setTargetCommitIdentifier($raw_change['targetCommitIdentifier']); $id = $raw_change['pathID']; $changes[$id] = $change; } // Deduce the away paths by examining all the changes, if we loaded them // all. if (!$limited) { $away = array(); foreach ($changes as $change) { if ($change->getTargetPath()) { $away[$change->getTargetPath()][] = $change->getPath(); } } foreach ($changes as $change) { if (isset($away[$change->getPath()])) { $change->setAwayPaths($away[$change->getPath()]); } } } return $changes; }
function start() { $this->tpl->setBlock("breadcrumb", '<a href="/parser">Freelance.ru parser</a>'); $pQ = new Engine\pQuery(); $pages = 5; $host = "https://freelance.ru"; $main_url = "https://freelance.ru/projects/"; $url = "https://freelance.ru/projects/?spec=4"; $only_pub = true; $dom = $pQ->file_get_html($url); $pagination = $dom->find("ul.pagination li a"); $array = []; for ($i = 0; $i <= $pages; $i++) { $array[] = $main_url . str_replace(".", "", $pagination[$i]->href); } $dom = null; $info_array = []; foreach ($array as $url) { $array = ""; $str = file_get_contents($url); $str = iconv('cp1251', 'utf-8', $str); $dom = $pQ->str_get_html($str); $proj_list = $dom->find("div.projects .proj"); foreach ($proj_list as $value) { $type = str_replace("proj ", "", $value->class); if ($type == "public" and $only_pub === true or $only_pub === false) { } else { continue; } $array[] = ["id" => str_replace(" ", "", str_replace("/", "", str_replace("projects", "", $value->find("a.descr")[0]->href))), "title" => $value->find("a.ptitle span")[0]->plaintext, "avatr" => $host . $value->find("a.avatr img")[0]->src, "cost" => $value->find("span.cost")[0]->plaintext, "href" => $host . $value->find("a.descr")[0]->href, "date" => $value->find("ul li.pdata")[0]->title, "replies" => $value->find("ul li.messages a i")[0]->plaintext, "descr" => $value->find("a.descr")[0]->plaintext, "type" => $type]; } $dom = null; $info_array = array_merge($info_array, $array); } function isort(&$a, $field, $dir = true) { $t = call_user_func_array('array_merge_recursive', $a); asort($t[$field]); $so = array_keys($t[$field]); asort($so); # исправлено 2012-08-31 $so = array_keys($so); $a = array_combine($so, $a); $dir ? ksort($a) : krsort($a); } isort($info_array, 'date', false); $content = ""; foreach ($info_array as $val) { $this->tpl->setAll(['avatr' => $val['avatr'], 'title' => $val['title'], 'cost' => $val['cost'], 'href' => $val['href'], 'date' => $val['date'], 'reply' => $val['replies'], 'descr' => $val['descr']]); $content .= $this->tpl->subLoad('parser.tpl'); } $this->tpl->setBlock('content', $content); }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $data = $this->profileData; $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($data, $totals); unset($GLOBALS['display_calls']); $symbol = $this->symbol; $children = array(); $parents = array(); foreach ($this->profileData as $key => $counters) { if (strpos($key, '==>') !== false) { list($parent, $child) = explode('==>', $key, 2); } else { continue; } if ($parent == $symbol) { $children[$key] = $child; } else { if ($child == $symbol) { $parents[$key] = $parent; } } } $base_uri = $this->baseURI; $rows = array(); $rows[] = array('Metrics for this Call', '', '', ''); $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $symbol), phutil_escape_html($symbol)), $flat[$symbol]['ct'], $flat[$symbol]['wt'], '100%'); $rows[] = array('Parent Calls', '', '', ''); foreach ($parents as $key => $name) { $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $name), phutil_escape_html($name)), $data[$key]['ct'], $data[$key]['wt'], ''); } $rows[] = array('Child Calls', '', '', ''); $child_rows = array(); foreach ($children as $key => $name) { $child_rows[] = array($name, $data[$key]['ct'], $data[$key]['wt'], $data[$key]['wt'] / $flat[$symbol]['wt']); } $child_rows = isort($child_rows, 2); $child_rows = array_reverse($child_rows); $rows = array_merge($rows, $this->formatRows($child_rows)); $table = new AphrontTableView($rows); $table->setHeaders(array('Symbol', 'Count', 'Wall Time', '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n')); $panel = new AphrontPanelView(); $panel->setHeader('XHProf Profile'); $panel->appendChild($table); return $panel->render(); }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $data = $this->profileData; $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($data, $totals); unset($GLOBALS['display_calls']); $symbol = $this->symbol; $children = array(); $parents = array(); foreach ($this->profileData as $key => $counters) { if (strpos($key, '==>') !== false) { list($parent, $child) = explode('==>', $key, 2); } else { continue; } if ($parent == $symbol) { $children[$key] = $child; } else { if ($child == $symbol) { $parents[$key] = $parent; } } } $rows = array(); $rows[] = array(pht('Metrics for this Call'), '', '', ''); $rows[] = $this->formatRow(array($symbol, $flat[$symbol]['ct'], $flat[$symbol]['wt'], 1.0)); $rows[] = array(pht('Parent Calls'), '', '', ''); foreach ($parents as $key => $name) { $rows[] = $this->formatRow(array($name, $data[$key]['ct'], $data[$key]['wt'], '')); } $rows[] = array(pht('Child Calls'), '', '', ''); $child_rows = array(); foreach ($children as $key => $name) { $child_rows[] = array($name, $data[$key]['ct'], $data[$key]['wt'], $data[$key]['wt'] / $flat[$symbol]['wt']); } $child_rows = isort($child_rows, 2); $child_rows = array_reverse($child_rows); $rows = array_merge($rows, array_map(array($this, 'formatRow'), $child_rows)); $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Symbol'), pht('Count'), pht('Wall Time'), '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n')); $panel = new PHUIObjectBoxView(); $panel->setHeaderText(pht('XHProf Profile')); $panel->setTable($table); return $panel->render(); }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($this->profileData, $totals); unset($GLOBALS['display_calls']); $aggregated = array(); foreach ($flat as $call => $counters) { $parts = explode('@', $call, 2); $agg_call = reset($parts); if (empty($aggregated[$agg_call])) { $aggregated[$agg_call] = $counters; } else { foreach ($aggregated[$agg_call] as $key => $val) { if ($key != 'wt') { $aggregated[$agg_call][$key] += $counters[$key]; } } } } $flat = $aggregated; $flat = isort($flat, 'wt'); $flat = array_reverse($flat); $rows = array(); $rows[] = array(pht('Total'), number_format($totals['ct']), number_format($totals['wt']) . ' us', '100.0%', number_format($totals['wt']) . ' us', '100.0%'); if ($this->limit) { $flat = array_slice($flat, 0, $this->limit); } foreach ($flat as $call => $counters) { $rows[] = array($this->renderSymbolLink($call), number_format($counters['ct']), number_format($counters['wt']) . ' us', sprintf('%.1f%%', 100 * $counters['wt'] / $totals['wt']), number_format($counters['excl_wt']) . ' us', sprintf('%.1f%%', 100 * $counters['excl_wt'] / $totals['wt'])); } Javelin::initBehavior('phabricator-tooltips'); $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Symbol'), pht('Count'), javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Total wall time spent in this function and all of ' . 'its children (children are other functions it called ' . 'while executing).'), 'size' => 200)), pht('Wall Time (Inclusive)')), '%', javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Wall time spent in this function, excluding time ' . 'spent in children (children are other functions it ' . 'called while executing).'), 'size' => 200)), pht('Wall Time (Exclusive)')), '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n', 'n', 'n')); $panel = new PHUIObjectBoxView(); $header = id(new PHUIHeaderView())->setHeader(pht('XHProf Profile')); if ($this->file) { $button = id(new PHUIButtonView())->setHref($this->file->getBestURI())->setText(pht('Download %s Profile', '.xhprof'))->setTag('a'); $header->addActionLink($button); } $panel->setHeader($header); $panel->appendChild($table); return $panel->render(); }
private function renderDataBox() { $cache = PhabricatorDataCacheSpec::getActiveCacheSpec(); $properties = id(new PHUIPropertyListView()); $this->renderCommonProperties($properties, $cache); $table = null; if ($cache->getName() !== null) { $total_memory = $cache->getTotalMemory(); $summary = $cache->getCacheSummary(); $summary = isort($summary, 'total'); $summary = array_reverse($summary, true); $rows = array(); foreach ($summary as $key => $info) { $rows[] = array($key, pht('%s', new PhutilNumber($info['count'])), phutil_format_bytes($info['max']), phutil_format_bytes($info['total']), sprintf('%.1f%%', 100 * ($info['total'] / $total_memory))); } $table = id(new AphrontTableView($rows))->setHeaders(array(pht('Pattern'), pht('Count'), pht('Largest'), pht('Total'), pht('Usage')))->setColumnClasses(array('wide', 'n', 'n', 'n', 'n')); } return id(new PHUIObjectBoxView())->setHeaderText(pht('Data Cache'))->addPropertyList($properties)->setTable($table); }
private function renderTable() { $rows = array(); foreach ($this->groups as $group => $items) { $has_where = false; foreach ($items as $item) { if (!empty($item['where'])) { $has_where = true; break; } } $rows[] = '<tr>' . '<th colspan="3">' . phutil_escape_html($group) . '</th>' . '</tr>'; foreach ($items as $item) { $items = isort($items, 'line'); $line = $item['line']; $length = $item['length']; if ($length) { $lines = $line . "–" . ($line + $length); } else { $lines = $line; } if (isset($item['href'])) { $href = $item['href']; $target = '_blank'; $tail = " ↗"; } else { $href = '#inline-' . $item['id']; $target = null; $tail = null; } $lines = phutil_escape_html($lines); if ($href) { $lines = phutil_render_tag('a', array('href' => $href, 'target' => $target, 'class' => 'num'), $lines . $tail); } $where = idx($item, 'where'); $colspan = $has_where ? '' : ' colspan="2"'; $rows[] = '<tr>' . '<td class="inline-line-number">' . $lines . '</td>' . ($has_where ? '<td class="inline-which-diff">' . phutil_escape_html($where) . '</td>' : null) . '<td class="inline-summary-content"' . $colspan . '>' . '<div class="phabricator-remarkup">' . $item['content'] . '</div>' . '</td>' . '</tr>'; } } return phutil_render_tag('table', array('class' => 'phabricator-inline-summary-table'), implode("\n", $rows)); }
public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $console->writeErr("%s\n", pht('Analyzing table sizes (this may take a moment)...')); $api = $this->getAPI(); $patches = $this->getPatches(); $databases = $api->getDatabaseList($patches, $only_living = true); $conn_r = $api->getConn(null); $data = array(); foreach ($databases as $database) { queryfx($conn_r, 'USE %C', $database); $tables = queryfx_all($conn_r, 'SHOW TABLE STATUS'); $tables = ipull($tables, null, 'Name'); $data[$database] = $tables; } $totals = array_fill_keys(array_keys($data), 0); $overall = 0; foreach ($data as $db => $tables) { foreach ($tables as $table => $info) { $table_size = $info['Data_length'] + $info['Index_length']; $data[$db][$table]['_totalSize'] = $table_size; $totals[$db] += $table_size; $overall += $table_size; } } asort($totals); $table = id(new PhutilConsoleTable())->setShowHeader(false)->setPadding(2)->addColumn('name', array('title' => pht('Database / Table')))->addColumn('size', array('title' => pht('Size')))->addColumn('percentage', array('title' => pht('Percentage'))); foreach ($totals as $db => $size) { list($database_size, $database_percentage) = $this->formatSize($totals[$db], $overall); $table->addRow(array('name' => tsprintf('**%s**', $db), 'size' => tsprintf('**%s**', $database_size), 'percentage' => tsprintf('**%s**', $database_percentage))); $data[$db] = isort($data[$db], '_totalSize'); foreach ($data[$db] as $table_name => $info) { list($table_size, $table_percentage) = $this->formatSize($info['_totalSize'], $overall); $table->addRow(array('name' => ' ' . $table_name, 'size' => $table_size, 'percentage' => $table_percentage)); } } list($overall_size, $overall_percentage) = $this->formatSize($overall, $overall); $table->addRow(array('name' => tsprintf('**%s**', pht('TOTAL')), 'size' => tsprintf('**%s**', $overall_size), 'percentage' => tsprintf('**%s**', $overall_percentage))); $table->draw(); return 0; }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($this->profileData, $totals); unset($GLOBALS['display_calls']); $aggregated = array(); foreach ($flat as $call => $counters) { $parts = explode('@', $call, 2); $agg_call = reset($parts); if (empty($aggregated[$agg_call])) { $aggregated[$agg_call] = $counters; } else { foreach ($aggregated[$agg_call] as $key => $val) { if ($key != 'wt') { $aggregated[$agg_call][$key] += $counters[$key]; } } } } $flat = $aggregated; $flat = isort($flat, 'wt'); $flat = array_reverse($flat); $rows = array(); $rows[] = array('Total', number_format($totals['ct']), number_format($totals['wt']) . ' us', '100.0%', number_format($totals['wt']) . ' us', '100.0%'); if ($this->limit) { $flat = array_slice($flat, 0, $this->limit); } $base_uri = $this->baseURI; foreach ($flat as $call => $counters) { $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $call), phutil_escape_html($call)), number_format($counters['ct']), number_format($counters['wt']) . ' us', sprintf('%.1f%%', 100 * $counters['wt'] / $totals['wt']), number_format($counters['excl_wt']) . ' us', sprintf('%.1f%%', 100 * $counters['excl_wt'] / $totals['wt'])); } $table = new AphrontTableView($rows); $table->setHeaders(array('Symbol', 'Count', 'Incl Wall Time', '%', 'Excl Wall Time', '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n', 'n', 'n')); $panel = new AphrontPanelView(); $panel->setHeader('XHProf Profile'); $panel->appendChild($table); return $panel->render(); }
public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $console->writeErr("%s\n", pht('Analyzing table sizes (this may take a moment)...')); $api = $this->getAPI(); $patches = $this->getPatches(); $databases = $api->getDatabaseList($patches, $only_living = true); $conn_r = $api->getConn(null); $data = array(); foreach ($databases as $database) { queryfx($conn_r, 'USE %C', $database); $tables = queryfx_all($conn_r, 'SHOW TABLE STATUS'); $tables = ipull($tables, null, 'Name'); $data[$database] = $tables; } $totals = array_fill_keys(array_keys($data), 0); $overall = 0; foreach ($data as $db => $tables) { foreach ($tables as $table => $info) { $table_size = $info['Data_length'] + $info['Index_length']; $data[$db][$table]['_totalSize'] = $table_size; $totals[$db] += $table_size; $overall += $table_size; } } $console->writeOut("%s\n", pht('APPROXIMATE TABLE SIZES')); asort($totals); foreach ($totals as $db => $size) { $database_size = $this->formatSize($totals[$db], $overall); $console->writeOut("**%s**\n", sprintf('%-32.32s %18s', $db, $database_size)); $data[$db] = isort($data[$db], '_totalSize'); foreach ($data[$db] as $table => $info) { $table_size = $this->formatSize($info['_totalSize'], $overall); $console->writeOut("%s\n", sprintf(' %-28.28s %18s', $table, $table_size)); } } $overall_size = $this->formatSize($overall, $overall); $console->writeOut("**%s**\n", sprintf('%-32.32s %18s', pht('TOTAL'), $overall_size)); return 0; }
public function renderExample() { $rows = array(array('make' => 'Honda', 'model' => 'Civic', 'year' => 2004, 'price' => 3199, 'color' => pht('Blue')), array('make' => 'Ford', 'model' => 'Focus', 'year' => 2001, 'price' => 2549, 'color' => pht('Red')), array('make' => 'Toyota', 'model' => 'Camry', 'year' => 2009, 'price' => 4299, 'color' => pht('Black')), array('make' => 'NASA', 'model' => 'Shuttle', 'year' => 1998, 'price' => 1000000000, 'color' => pht('White'))); $request = $this->getRequest(); $orders = array('make', 'model', 'year', 'price'); $sort = $request->getStr('sort'); list($sort, $reverse) = AphrontTableView::parseSort($sort); if (!in_array($sort, $orders)) { $sort = 'make'; } $rows = isort($rows, $sort); if ($reverse) { $rows = array_reverse($rows); } $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Make'), pht('Model'), pht('Year'), pht('Price'), pht('Color'))); $table->setColumnClasses(array('', 'wide', 'n', 'n', '')); $table->makeSortable($request->getRequestURI(), 'sort', $sort, $reverse, $orders); $panel = new PHUIObjectBoxView(); $panel->setHeaderText(pht('Sortable Table of Vehicles')); $panel->appendChild($table); return $panel; }
private function generate() { if ($this->generated) { return; } $multi_row = true; $multi_col = true; $margin_w = 1; $margin_h = 1; $type = $this->type; switch ($type) { case self::TYPE_STANDARD: break; case self::TYPE_REPEAT_X: $multi_col = false; $margin_w = 0; $width = null; foreach ($this->sprites as $sprite) { if ($width === null) { $width = $sprite->getSourceW(); } else { if ($width !== $sprite->getSourceW()) { throw new Exception(pht("All sprites in a '%s' sheet must have the same width.", 'repeat-x')); } } } break; case self::TYPE_REPEAT_Y: $multi_row = false; $margin_h = 0; $height = null; foreach ($this->sprites as $sprite) { if ($height === null) { $height = $sprite->getSourceH(); } else { if ($height !== $sprite->getSourceH()) { throw new Exception(pht("All sprites in a '%s' sheet must have the same height.", 'repeat-y')); } } } break; default: throw new Exception(pht("Unknown sprite sheet type '%s'!", $type)); } $css = array(); if ($this->cssHeader) { $css[] = $this->cssHeader; } $out_w = 0; $out_h = 0; // Lay out the sprite sheet. We attempt to build a roughly square sheet // so it's easier to manage, since 2000x20 is more cumbersome for humans // to deal with than 200x200. // // To do this, we use a simple greedy algorithm, adding sprites one at a // time. For each sprite, if the sheet is at least as wide as it is tall // we create a new row. Otherwise, we try to add it to an existing row. // // This isn't optimal, but does a reasonable job in most cases and isn't // too messy. // Group the sprites by their sizes. We lay them out in the sheet as // boxes, but then put them into the boxes in the order they were added // so similar sprites end up nearby on the final sheet. $boxes = array(); foreach (array_reverse($this->sprites) as $sprite) { $s_w = $sprite->getSourceW() + $margin_w; $s_h = $sprite->getSourceH() + $margin_h; $boxes[$s_w][$s_h][] = $sprite; } $rows = array(); foreach ($this->sprites as $sprite) { $s_w = $sprite->getSourceW() + $margin_w; $s_h = $sprite->getSourceH() + $margin_h; // Choose a row for this sprite. $maybe = array(); foreach ($rows as $key => $row) { if ($row['h'] < $s_h) { // We can only add it to a row if the row is at least as tall as the // sprite. continue; } // We prefer rows which have the same height as the sprite, and then // rows which aren't yet very wide. $wasted_v = $row['h'] - $s_h; $wasted_h = $row['w'] / $out_w; $maybe[$key] = $wasted_v + $wasted_h; } $row_key = null; if ($maybe && $multi_col) { // If there were any candidate rows, pick the best one. asort($maybe); $row_key = head_key($maybe); } if ($row_key !== null && $multi_row) { // If there's a candidate row, but adding the sprite to it would make // the sprite wider than it is tall, create a new row instead. This // generally keeps the sprite square-ish. if ($rows[$row_key]['w'] + $s_w > $out_h) { $row_key = null; } } if ($row_key === null) { // Add a new row. $rows[] = array('w' => 0, 'h' => $s_h, 'boxes' => array()); $row_key = last_key($rows); $out_h += $s_h; } // Add the sprite box to the row. $row = $rows[$row_key]; $row['w'] += $s_w; $row['boxes'][] = array($s_w, $s_h); $rows[$row_key] = $row; $out_w = max($row['w'], $out_w); } $images = array(); foreach ($this->scales as $scale) { $img = imagecreatetruecolor($out_w * $scale, $out_h * $scale); imagesavealpha($img, true); imagefill($img, 0, 0, imagecolorallocatealpha($img, 0, 0, 0, 127)); $images[$scale] = $img; } // Put the shorter rows first. At the same height, put the wider rows first. // This makes the resulting sheet more human-readable. foreach ($rows as $key => $row) { $rows[$key]['sort'] = $row['h'] + (1 - $row['w'] / $out_w); } $rows = isort($rows, 'sort'); $pos_x = 0; $pos_y = 0; $rules = array(); foreach ($rows as $row) { $max_h = 0; foreach ($row['boxes'] as $box) { $sprite = array_pop($boxes[$box[0]][$box[1]]); foreach ($images as $scale => $img) { $src = $this->loadSource($sprite, $scale); imagecopy($img, $src, $scale * $pos_x, $scale * $pos_y, $scale * $sprite->getSourceX(), $scale * $sprite->getSourceY(), $scale * $sprite->getSourceW(), $scale * $sprite->getSourceH()); } $rule = $sprite->getTargetCSS(); $cssx = -$pos_x . 'px'; $cssy = -$pos_y . 'px'; $rules[$sprite->getName()] = "{$rule} {\n" . " background-position: {$cssx} {$cssy};\n}"; $pos_x += $sprite->getSourceW() + $margin_w; $max_h = max($max_h, $sprite->getSourceH()); } $pos_x = 0; $pos_y += $max_h + $margin_h; } // Generate CSS rules in input order. foreach ($this->sprites as $sprite) { $css[] = $rules[$sprite->getName()]; } $this->images = $images; $this->css = implode("\n\n", $css) . "\n"; $this->generated = true; }
private function loadRevisionFromHash($hash) { // TODO -- de-hack this as permissions become more clear with things // like T848 (add scope to OAuth) if (!$this->isConduitAuthenticated()) { return null; } $conduit = $this->getConduit(); $revisions = $conduit->callMethodSynchronous('differential.query', array('commitHashes' => array($hash))); // grab the latest closed revision only $found_revision = null; $revisions = isort($revisions, 'dateModified'); foreach ($revisions as $revision) { if ($revision['status'] == ArcanistDifferentialRevisionStatus::CLOSED) { $found_revision = $revision; } } return $found_revision; }
public function loadActualSchema() { $databases = $this->getDatabaseNames(); $conn = $this->getConn(); $tables = queryfx_all($conn, 'SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA IN (%Ls)', $databases); $database_info = queryfx_all($conn, 'SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME IN (%Ls)', $databases); $database_info = ipull($database_info, null, 'SCHEMA_NAME'); // Find databases which exist, but which the user does not have permission // to see. $invisible_databases = array(); foreach ($databases as $database_name) { if (isset($database_info[$database_name])) { continue; } try { queryfx($conn, 'SHOW TABLES IN %T', $database_name); } catch (AphrontAccessDeniedQueryException $ex) { // This database exists, the user just doesn't have permission to // see it. $invisible_databases[] = $database_name; } catch (AphrontSchemaQueryException $ex) { // This database is legitimately missing. } } $sql = array(); foreach ($tables as $table) { $sql[] = qsprintf($conn, '(TABLE_SCHEMA = %s AND TABLE_NAME = %s)', $table['TABLE_SCHEMA'], $table['TABLE_NAME']); } if ($sql) { $column_info = queryfx_all($conn, 'SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME, COLUMN_TYPE, IS_NULLABLE, EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE (%Q)', '(' . implode(') OR (', $sql) . ')'); $column_info = igroup($column_info, 'TABLE_SCHEMA'); } else { $column_info = array(); } // NOTE: Tables like KEY_COLUMN_USAGE and TABLE_CONSTRAINTS only contain // primary, unique, and foreign keys, so we can't use them here. We pull // indexes later on using SHOW INDEXES. $server_schema = new PhabricatorConfigServerSchema(); $tables = igroup($tables, 'TABLE_SCHEMA'); foreach ($tables as $database_name => $database_tables) { $info = $database_info[$database_name]; $database_schema = id(new PhabricatorConfigDatabaseSchema())->setName($database_name)->setCharacterSet($info['DEFAULT_CHARACTER_SET_NAME'])->setCollation($info['DEFAULT_COLLATION_NAME']); $database_column_info = idx($column_info, $database_name, array()); $database_column_info = igroup($database_column_info, 'TABLE_NAME'); foreach ($database_tables as $table) { $table_name = $table['TABLE_NAME']; $table_schema = id(new PhabricatorConfigTableSchema())->setName($table_name)->setCollation($table['TABLE_COLLATION']); $columns = idx($database_column_info, $table_name, array()); foreach ($columns as $column) { if (strpos($column['EXTRA'], 'auto_increment') === false) { $auto_increment = false; } else { $auto_increment = true; } $column_schema = id(new PhabricatorConfigColumnSchema())->setName($column['COLUMN_NAME'])->setCharacterSet($column['CHARACTER_SET_NAME'])->setCollation($column['COLLATION_NAME'])->setColumnType($column['COLUMN_TYPE'])->setNullable($column['IS_NULLABLE'] == 'YES')->setAutoIncrement($auto_increment); $table_schema->addColumn($column_schema); } $key_parts = queryfx_all($conn, 'SHOW INDEXES FROM %T.%T', $database_name, $table_name); $keys = igroup($key_parts, 'Key_name'); foreach ($keys as $key_name => $key_pieces) { $key_pieces = isort($key_pieces, 'Seq_in_index'); $head = head($key_pieces); // This handles string indexes which index only a prefix of a field. $column_names = array(); foreach ($key_pieces as $piece) { $name = $piece['Column_name']; if ($piece['Sub_part']) { $name = $name . '(' . $piece['Sub_part'] . ')'; } $column_names[] = $name; } $key_schema = id(new PhabricatorConfigKeySchema())->setName($key_name)->setColumnNames($column_names)->setUnique(!$head['Non_unique'])->setIndexType($head['Index_type']); $table_schema->addKey($key_schema); } $database_schema->addTable($table_schema); } $server_schema->addDatabase($database_schema); } foreach ($invisible_databases as $database_name) { $server_schema->addDatabase(id(new PhabricatorConfigDatabaseSchema())->setName($database_name)->setAccessDenied(true)); } return $server_schema; }
public function testIsort() { $list = ['b' => ['name' => 'b', 'value' => 2], 'a' => ['name' => 'a', 'value' => 1], 'c' => ['name' => 'c', 'value' => 3]]; $expected = ['a' => ['name' => 'a', 'value' => 1], 'b' => ['name' => 'b', 'value' => 2], 'c' => ['name' => 'c', 'value' => 3]]; $this->assertEquals($expected, isort($list, 'name')); }
private function getLintersInfo(array $linters, array $built) { // Note that an engine can emit multiple linters of the same class to run // different rulesets on different groups of files, so these linters do not // necessarily have unique classes or types. $groups = array(); foreach ($built as $linter) { $groups[get_class($linter)][] = $linter; } $linter_info = array(); foreach ($linters as $key => $linter) { $installed = idx($groups, $key, array()); $exception = null; if ($installed) { $status = 'configured'; try { $version = head($installed)->getVersion(); } catch (Exception $ex) { $status = 'error'; $exception = $ex; } } else { $status = 'available'; $version = null; } $linter_info[$key] = array('name' => $linter->getLinterConfigurationName(), 'class' => get_class($linter), 'status' => $status, 'version' => $version, 'short' => $linter->getInfoName(), 'uri' => $linter->getInfoURI(), 'description' => $linter->getInfoDescription(), 'exception' => $exception, 'options' => $linter->getLinterConfigurationOptions()); } return isort($linter_info, 'short'); }
/** * Get a list of all packages which control a path or its parent directories, * ordered from weakest to strongest. * * The first package has the most specific claim on the path; the last * package has the most general claim. Multiple packages may have claims of * equal strength, so this ordering is primarily one of usability and * convenience. * * @return list<PhabricatorOwnersPackage> List of controlling packages. */ public function getControllingPackagesForPath($repository_phid, $path) { $path = (string) $path; if (!isset($this->controlMap[$repository_phid][$path])) { throw new PhutilInvalidStateException('withControl'); } if ($this->controlResults === null) { throw new PhutilInvalidStateException('execute'); } $packages = $this->controlResults; $weak_dominion = PhabricatorOwnersPackage::DOMINION_WEAK; $matches = array(); foreach ($packages as $package_id => $package) { $best_match = null; $include = false; // If this package is archived, it's no longer a controlling package // for the given path. In particular, it can not force active packages // with weak dominion to give up control. if ($package->isArchived()) { continue; } foreach ($package->getPaths() as $package_path) { if ($package_path->getRepositoryPHID() != $repository_phid) { // If this path is for some other repository, skip it. continue; } $strength = $package_path->getPathMatchStrength($path); if ($strength > $best_match) { $best_match = $strength; $include = !$package_path->getExcluded(); } } if ($best_match && $include) { $matches[$package_id] = array('strength' => $best_match, 'weak' => $package->getDominion() == $weak_dominion, 'package' => $package); } } $matches = isort($matches, 'strength'); $matches = array_reverse($matches); $first_id = null; foreach ($matches as $package_id => $match) { if ($first_id === null) { $first_id = $package_id; continue; } if ($match['weak']) { unset($matches[$package_id]); } } return array_values(ipull($matches, 'package')); }
public function renderOpenTasks() { $request = $this->getRequest(); $user = $request->getUser(); $query = id(new ManiphestTaskQuery())->withStatus(ManiphestTaskQuery::STATUS_OPEN); $project_phid = $request->getStr('project'); $project_handle = null; if ($project_phid) { $phids = array($project_phid); $handles = $this->loadViewerHandles($phids); $project_handle = $handles[$project_phid]; $query->withAnyProjects($phids); } $tasks = $query->execute(); $recently_closed = $this->loadRecentlyClosedTasks(); $date = phabricator_date(time(), $user); switch ($this->view) { case 'user': $result = mgroup($tasks, 'getOwnerPHID'); $leftover = idx($result, '', array()); unset($result['']); $result_closed = mgroup($recently_closed, 'getOwnerPHID'); $leftover_closed = idx($result_closed, '', array()); unset($result_closed['']); $base_link = '/maniphest/?users='; $leftover_name = phutil_render_tag('a', array('href' => $base_link . ManiphestTaskOwner::OWNER_UP_FOR_GRABS), '<em>(Up For Grabs)</em>'); $col_header = 'User'; $header = 'Open Tasks by User and Priority (' . $date . ')'; break; case 'project': $result = array(); $leftover = array(); foreach ($tasks as $task) { $phids = $task->getProjectPHIDs(); if ($phids) { foreach ($phids as $project_phid) { $result[$project_phid][] = $task; } } else { $leftover[] = $task; } } $result_closed = array(); $leftover_closed = array(); foreach ($recently_closed as $task) { $phids = $task->getProjectPHIDs(); if ($phids) { foreach ($phids as $project_phid) { $result_closed[$project_phid][] = $task; } } else { $leftover_closed[] = $task; } } $base_link = '/maniphest/view/all/?projects='; $leftover_name = phutil_render_tag('a', array('href' => $base_link . ManiphestTaskOwner::PROJECT_NO_PROJECT), '<em>(No Project)</em>'); $col_header = 'Project'; $header = 'Open Tasks by Project and Priority (' . $date . ')'; break; } $phids = array_keys($result); $handles = $this->loadViewerHandles($phids); $handles = msort($handles, 'getName'); $order = $request->getStr('order', 'name'); list($order, $reverse) = AphrontTableView::parseSort($order); require_celerity_resource('aphront-tooltip-css'); Javelin::initBehavior('phabricator-tooltips', array()); $rows = array(); $pri_total = array(); foreach (array_merge($handles, array(null)) as $handle) { if ($handle) { if ($project_handle && $project_handle->getPHID() == $handle->getPHID()) { // If filtering by, e.g., "bugs", don't show a "bugs" group. continue; } $tasks = idx($result, $handle->getPHID(), array()); $name = phutil_render_tag('a', array('href' => $base_link . $handle->getPHID()), phutil_escape_html($handle->getName())); $closed = idx($result_closed, $handle->getPHID(), array()); } else { $tasks = $leftover; $name = $leftover_name; $closed = $leftover_closed; } $taskv = $tasks; $tasks = mgroup($tasks, 'getPriority'); $row = array(); $row[] = $name; $total = 0; foreach (ManiphestTaskPriority::getTaskPriorityMap() as $pri => $label) { $n = count(idx($tasks, $pri, array())); if ($n == 0) { $row[] = '-'; } else { $row[] = number_format($n); } $total += $n; } $row[] = number_format($total); list($link, $oldest_all) = $this->renderOldest($taskv); $row[] = $link; $normal_or_better = array(); foreach ($taskv as $id => $task) { if ($task->getPriority() < ManiphestTaskPriority::PRIORITY_NORMAL) { continue; } $normal_or_better[$id] = $task; } list($link, $oldest_pri) = $this->renderOldest($normal_or_better); $row[] = $link; if ($closed) { $task_ids = implode(',', mpull($closed, 'getID')); $row[] = phutil_render_tag('a', array('href' => '/maniphest/view/custom/?s=oc&tasks=' . $task_ids, 'target' => '_blank'), phutil_escape_html(number_format(count($closed)))); } else { $row[] = '-'; } switch ($order) { case 'total': $row['sort'] = $total; break; case 'oldest-all': $row['sort'] = $oldest_all; break; case 'oldest-pri': $row['sort'] = $oldest_pri; break; case 'closed': $row['sort'] = count($closed); break; case 'name': default: $row['sort'] = $handle ? $handle->getName() : '~'; break; } $rows[] = $row; } $rows = isort($rows, 'sort'); foreach ($rows as $k => $row) { unset($rows[$k]['sort']); } if ($reverse) { $rows = array_reverse($rows); } $cname = array($col_header); $cclass = array('pri right wide'); $pri_map = ManiphestTaskPriority::getTaskBriefPriorityMap(); foreach ($pri_map as $pri => $label) { $cname[] = $label; $cclass[] = 'n'; } $cname[] = 'Total'; $cclass[] = 'n'; $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Oldest open task.', 'size' => 200)), 'Oldest (All)'); $cclass[] = 'n'; $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Oldest open task, excluding those with Low or Wishlist ' . 'priority.', 'size' => 200)), 'Oldest (Pri)'); $cclass[] = 'n'; list($ignored, $window_epoch) = $this->getWindow(); $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Closed after ' . phabricator_datetime($window_epoch, $user), 'size' => 260)), 'Recently Closed'); $cclass[] = 'n'; $table = new AphrontTableView($rows); $table->setHeaders($cname); $table->setColumnClasses($cclass); $table->makeSortable($request->getRequestURI(), 'order', $order, $reverse, array('name', null, null, null, null, null, null, 'total', 'oldest-all', 'oldest-pri', 'closed')); $panel = new AphrontPanelView(); $panel->setHeader($header); $panel->appendChild($table); $tokens = array(); if ($project_handle) { $tokens = array($project_handle->getPHID() => $project_handle->getFullName()); } $filter = $this->renderReportFilters($tokens, $has_window = true); return array($filter, $panel); }
throw new Exception("Package specification for '{$name}' mixes resources of type " . "'{$type}' with resources of type '{$ntype}'. Each package may only " . "contain one type of resource."); } } $hashes[] = $symbol . ':' . $hash_map[$symbol]; } $key = substr(md5(implode("\n", $hashes)), 0, 8); $package_map['packages'][$key] = array('name' => $name, 'symbols' => $package, 'uri' => '/res/pkg/' . $key . '/' . $name, 'type' => $type); foreach ($package as $symbol) { $package_map['reverse'][$symbol] = $key; } } ksort($runtime_map); $runtime_map = var_export($runtime_map, true); $runtime_map = preg_replace('/\\s+$/m', '', $runtime_map); $runtime_map = preg_replace('/array \\(/', 'array(', $runtime_map); $package_map['packages'] = isort($package_map['packages'], 'name'); ksort($package_map['reverse']); $package_map = var_export($package_map, true); $package_map = preg_replace('/\\s+$/m', '', $package_map); $package_map = preg_replace('/array \\(/', 'array(', $package_map); $generated = '@' . 'generated'; $resource_map = <<<EOFILE <?php /** * This file is automatically generated. Use 'celerity_mapper.php' to rebuild * it. * {$generated} */ celerity_register_resource_map({$runtime_map}, {$package_map});
public function renderOpenTasks() { $request = $this->getRequest(); $viewer = $request->getUser(); $query = id(new ManiphestTaskQuery())->setViewer($viewer)->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()); switch ($this->view) { case 'project': $query->needProjectPHIDs(true); break; } $project_phid = $request->getStr('project'); $project_handle = null; if ($project_phid) { $phids = array($project_phid); $handles = $this->loadViewerHandles($phids); $project_handle = $handles[$project_phid]; $query->withEdgeLogicPHIDs(PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, PhabricatorQueryConstraint::OPERATOR_OR, $phids); } $tasks = $query->execute(); $recently_closed = $this->loadRecentlyClosedTasks(); $date = phabricator_date(time(), $viewer); switch ($this->view) { case 'user': $result = mgroup($tasks, 'getOwnerPHID'); $leftover = idx($result, '', array()); unset($result['']); $result_closed = mgroup($recently_closed, 'getOwnerPHID'); $leftover_closed = idx($result_closed, '', array()); unset($result_closed['']); $base_link = '/maniphest/?assigned='; $leftover_name = phutil_tag('em', array(), pht('(Up For Grabs)')); $col_header = pht('User'); $header = pht('Open Tasks by User and Priority (%s)', $date); break; case 'project': $result = array(); $leftover = array(); foreach ($tasks as $task) { $phids = $task->getProjectPHIDs(); if ($phids) { foreach ($phids as $project_phid) { $result[$project_phid][] = $task; } } else { $leftover[] = $task; } } $result_closed = array(); $leftover_closed = array(); foreach ($recently_closed as $task) { $phids = $task->getProjectPHIDs(); if ($phids) { foreach ($phids as $project_phid) { $result_closed[$project_phid][] = $task; } } else { $leftover_closed[] = $task; } } $base_link = '/maniphest/?projects='; $leftover_name = phutil_tag('em', array(), pht('(No Project)')); $col_header = pht('Project'); $header = pht('Open Tasks by Project and Priority (%s)', $date); break; } $phids = array_keys($result); $handles = $this->loadViewerHandles($phids); $handles = msort($handles, 'getName'); $order = $request->getStr('order', 'name'); list($order, $reverse) = AphrontTableView::parseSort($order); require_celerity_resource('aphront-tooltip-css'); Javelin::initBehavior('phabricator-tooltips', array()); $rows = array(); $pri_total = array(); foreach (array_merge($handles, array(null)) as $handle) { if ($handle) { if ($project_handle && $project_handle->getPHID() == $handle->getPHID()) { // If filtering by, e.g., "bugs", don't show a "bugs" group. continue; } $tasks = idx($result, $handle->getPHID(), array()); $name = phutil_tag('a', array('href' => $base_link . $handle->getPHID()), $handle->getName()); $closed = idx($result_closed, $handle->getPHID(), array()); } else { $tasks = $leftover; $name = $leftover_name; $closed = $leftover_closed; } $taskv = $tasks; $tasks = mgroup($tasks, 'getPriority'); $row = array(); $row[] = $name; $total = 0; foreach (ManiphestTaskPriority::getTaskPriorityMap() as $pri => $label) { $n = count(idx($tasks, $pri, array())); if ($n == 0) { $row[] = '-'; } else { $row[] = number_format($n); } $total += $n; } $row[] = number_format($total); list($link, $oldest_all) = $this->renderOldest($taskv); $row[] = $link; $normal_or_better = array(); foreach ($taskv as $id => $task) { // TODO: This is sort of a hard-code for the default "normal" status. // When reports are more powerful, this should be made more general. if ($task->getPriority() < 50) { continue; } $normal_or_better[$id] = $task; } list($link, $oldest_pri) = $this->renderOldest($normal_or_better); $row[] = $link; if ($closed) { $task_ids = implode(',', mpull($closed, 'getID')); $row[] = phutil_tag('a', array('href' => '/maniphest/?ids=' . $task_ids, 'target' => '_blank'), number_format(count($closed))); } else { $row[] = '-'; } switch ($order) { case 'total': $row['sort'] = $total; break; case 'oldest-all': $row['sort'] = $oldest_all; break; case 'oldest-pri': $row['sort'] = $oldest_pri; break; case 'closed': $row['sort'] = count($closed); break; case 'name': default: $row['sort'] = $handle ? $handle->getName() : '~'; break; } $rows[] = $row; } $rows = isort($rows, 'sort'); foreach ($rows as $k => $row) { unset($rows[$k]['sort']); } if ($reverse) { $rows = array_reverse($rows); } $cname = array($col_header); $cclass = array('pri right wide'); $pri_map = ManiphestTaskPriority::getShortNameMap(); foreach ($pri_map as $pri => $label) { $cname[] = $label; $cclass[] = 'n'; } $cname[] = pht('Total'); $cclass[] = 'n'; $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task.'), 'size' => 200)), pht('Oldest (All)')); $cclass[] = 'n'; $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task, excluding those with Low or Wishlist priority.'), 'size' => 200)), pht('Oldest (Pri)')); $cclass[] = 'n'; list($ignored, $window_epoch) = $this->getWindow(); $edate = phabricator_datetime($window_epoch, $viewer); $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Closed after %s', $edate), 'size' => 260)), pht('Recently Closed')); $cclass[] = 'n'; $table = new AphrontTableView($rows); $table->setHeaders($cname); $table->setColumnClasses($cclass); $table->makeSortable($request->getRequestURI(), 'order', $order, $reverse, array('name', null, null, null, null, null, null, 'total', 'oldest-all', 'oldest-pri', 'closed')); $panel = new PHUIObjectBoxView(); $panel->setHeaderText($header); $panel->setTable($table); $tokens = array(); if ($project_handle) { $tokens = array($project_handle); } $filter = $this->renderReportFilters($tokens, $has_window = true); return array($filter, $panel); }
public function run() { $console = PhutilConsole::getConsole(); $linters = id(new PhutilSymbolLoader())->setAncestorClass('ArcanistLinter')->loadObjects(); try { $built = $this->newLintEngine()->buildLinters(); } catch (ArcanistNoEngineException $ex) { $built = array(); } // Note that an engine can emit multiple linters of the same class to run // different rulesets on different groups of files, so these linters do not // necessarily have unique classes or types. $groups = array(); foreach ($built as $linter) { $groups[get_class($linter)][] = $linter; } $linter_info = array(); foreach ($linters as $key => $linter) { $installed = idx($groups, $key, array()); $exception = null; if ($installed) { $status = 'configured'; try { $version = head($installed)->getVersion(); } catch (Exception $ex) { $status = 'error'; $exception = $ex; } } else { $status = 'available'; $version = null; } $linter_info[$key] = array('short' => $linter->getLinterConfigurationName(), 'class' => get_class($linter), 'status' => $status, 'version' => $version, 'name' => $linter->getInfoName(), 'uri' => $linter->getInfoURI(), 'description' => $linter->getInfoDescription(), 'exception' => $exception, 'options' => $linter->getLinterConfigurationOptions()); } $linter_info = isort($linter_info, 'short'); $status_map = $this->getStatusMap(); $pad = ' '; $color_map = array('configured' => 'green', 'available' => 'yellow', 'error' => 'red'); foreach ($linter_info as $key => $linter) { $status = $linter['status']; $color = $color_map[$status]; $text = $status_map[$status]; $print_tail = false; $console->writeOut("<bg:" . $color . ">** %s **</bg> **%s** (%s)\n", $text, nonempty($linter['short'], '-'), $linter['name']); if ($linter['exception']) { $console->writeOut("\n%s**%s**\n%s\n", $pad, get_class($linter['exception']), phutil_console_wrap($linter['exception']->getMessage(), strlen($pad))); $print_tail = true; } $version = $linter['version']; $uri = $linter['uri']; if ($version || $uri) { $console->writeOut("\n"); $print_tail = true; } if ($version) { $console->writeOut("%s%s **%s**\n", $pad, pht('Version'), $version); } if ($uri) { $console->writeOut("%s__%s__\n", $pad, $linter['uri']); } $description = $linter['description']; if ($description) { $console->writeOut("\n%s\n", phutil_console_wrap($linter['description'], strlen($pad))); $print_tail = true; } $options = $linter['options']; if ($options && $this->getArgument('verbose')) { $console->writeOut("\n%s**%s**\n\n", $pad, pht('Configuration Options')); $last_option = last_key($options); foreach ($options as $option => $option_spec) { $console->writeOut("%s__%s__ (%s)\n", $pad, $option, $option_spec['type']); $console->writeOut("%s\n", phutil_console_wrap($option_spec['help'], strlen($pad) + 2)); if ($option != $last_option) { $console->writeOut("\n"); } } $print_tail = true; } if ($print_tail) { $console->writeOut("\n"); } } if (!$this->getArgument('verbose')) { $console->writeOut("%s\n", pht('(Run `%s` for more details.)', 'arc linters --verbose')); } }
/** * To get paging to work for "group by project", we need to do a bunch of * server-side magic since there's currently no way to sort by project name on * the database. * * TODO: Move this all to the database. */ private function applyGroupByProject(array $tasks) { assert_instances_of($tasks, 'ManiphestTask'); $project_phids = array(); foreach ($tasks as $task) { foreach ($task->getProjectPHIDs() as $phid) { $project_phids[$phid] = true; } } $handles = id(new PhabricatorObjectHandleData(array_keys($project_phids)))->loadHandles(); $max = 1; foreach ($handles as $handle) { $max = max($max, strlen($handle->getName())); } $items = array(); $ii = 0; foreach ($tasks as $key => $task) { $phids = $task->getProjectPHIDs(); if (!$this->anyProject && $this->projectPHIDs) { $phids = array_diff($phids, $this->projectPHIDs); } if ($phids) { foreach ($phids as $phid) { $items[] = array('key' => $key, 'seq' => sprintf('%' . $max . 's%d', $handles[$phid]->getName(), $ii)); } } else { // Sort "no project" tasks first. $items[] = array('key' => $key, 'seq' => ''); } ++$ii; } $items = isort($items, 'seq'); $items = array_slice($items, nonempty($this->offset), nonempty($this->limit, self::DEFAULT_PAGE_SIZE)); $result = array(); foreach ($items as $item) { $result[] = $tasks[$item['key']]; } return $result; }
private function printBranches(array $branches, array $revisions) { $revisions = ipull($revisions, null, 'id'); static $color_map = array('Closed' => 'cyan', 'Needs Review' => 'magenta', 'Needs Revision' => 'red', 'Accepted' => 'green', 'No Revision' => 'blue', 'Abandoned' => 'default'); static $ssort_map = array('Closed' => 1, 'No Revision' => 2, 'Needs Review' => 3, 'Needs Revision' => 4, 'Accepted' => 5); $out = array(); foreach ($branches as $branch) { $revision = idx($revisions, idx($branch, 'revisionID')); // If we haven't identified a revision by ID, try to identify it by hash. if (!$revision) { foreach ($revisions as $rev) { $hashes = idx($rev, 'hashes', array()); foreach ($hashes as $hash) { if ($hash[0] == 'gtcm' && $hash[1] == $branch['hash'] || $hash[0] == 'gttr' && $hash[1] == $branch['tree']) { $revision = $rev; break; } } } } if ($revision) { $desc = 'D' . $revision['id'] . ': ' . $revision['title']; $status = $revision['statusName']; } else { $desc = $branch['desc']; $status = 'No Revision'; } if (!$this->getArgument('view-all') && !$branch['current']) { if ($status == 'Closed' || $status == 'Abandoned') { continue; } } $epoch = $branch['epoch']; $color = idx($color_map, $status, 'default'); $ssort = sprintf('%d%012d', idx($ssort_map, $status, 0), $epoch); $out[] = array('name' => $branch['name'], 'current' => $branch['current'], 'status' => $status, 'desc' => $desc, 'color' => $color, 'esort' => $epoch, 'ssort' => $ssort); } $len_name = max(array_map('strlen', ipull($out, 'name'))) + 2; $len_status = max(array_map('strlen', ipull($out, 'status'))) + 2; if ($this->getArgument('by-status')) { $out = isort($out, 'ssort'); } else { $out = isort($out, 'esort'); } $console = PhutilConsole::getConsole(); foreach ($out as $line) { $color = $line['color']; $console->writeOut("%s **%s** <fg:{$color}>%s</fg> %s\n", $line['current'] ? '* ' : ' ', str_pad($line['name'], $len_name), str_pad($line['status'], $len_status), $line['desc']); } }