protected function initContent() { $request = $this->getContext()->getRequest(); $this->setTitle("Job status"); $this->setRobots("noindex,nofollow"); $this->bodyScripts[] = swarmpath("js/job.js"); $error = $this->getAction()->getError(); $data = $this->getAction()->getData(); $html = ''; if ($error) { $html .= html_tag('div', array('class' => 'alert alert-error'), $error['info']); } if (!isset($data["jobInfo"])) { return $html; } $this->setSubTitle('#' . $data["jobInfo"]["id"]); $html .= '<h2>' . $data["jobInfo"]["name"] . '</h2>' . '<p><em>Submitted by ' . html_tag("a", array("href" => swarmpath("user/{$data["jobInfo"]["ownerName"]}")), $data["jobInfo"]["ownerName"]) . ' on ' . htmlspecialchars(date("Y-m-d H:i:s", gmstrtotime($data["jobInfo"]["creationTimestamp"]))) . ' (UTC)' . '</em>.</p>'; if ($request->getSessionData("auth") === "yes" && $data["jobInfo"]["ownerName"] == $request->getSessionData("username")) { $html .= '<script>SWARM.jobInfo = ' . json_encode($data["jobInfo"]) . ';</script>' . '<div class="form-actions">' . ' <button id="swarm-job-delete" class="btn btn-danger">Delete job</button>' . ' <button id="swarm-job-reset" class="btn btn-info">Reset job</button>' . '</div>' . '<div class="alert alert-error" id="swarm-wipejob-error" style="display: none;"></div>'; } $html .= '<table class="table table-bordered swarm-results"><thead><tr><th> </th>'; // Header with user agents foreach ($data["userAgents"] as $userAgent) { $html .= '<th><img src="' . swarmpath("img/" . $userAgent["displayicon"]) . '.sm.png" class="swarm-browsericon ' . '" alt="' . htmlspecialchars($userAgent["displaytitle"]) . '" title="' . htmlspecialchars($userAgent["displaytitle"]) . '"><br>' . htmlspecialchars(preg_replace("/\\w+ /", "", $userAgent["displaytitle"])) . '</th>'; } $html .= '</tr></thead><tbody>'; foreach ($data["runs"] as $run) { $html .= '<tr><th><a href="' . htmlspecialchars($run["info"]["url"]) . '">' . $run["info"]["name"] . '</a></th>'; // Looping over $data["userAgents"] instead of $run["uaRuns"], // to avoid shifts in the table (github.com/jquery/testswarm/issues/13) foreach ($data["userAgents"] as $uaID => $uaInfo) { if (isset($run["uaRuns"][$uaID])) { $uaRun = $run["uaRuns"][$uaID]; $html .= html_tag_open("td", array("class" => "swarm-status swarm-status-" . $uaRun["runStatus"], "data-job-id" => $data["jobInfo"]["id"], "data-run-id" => $run["info"]["id"], "data-run-status" => $uaRun["runStatus"], "data-useragent-id" => $uaID, "data-client-id" => isset($uaRun["clientID"]) ? $uaRun["clientID"] : "")); if (isset($uaRun["runResultsUrl"]) && $uaRun["runResultsLabel"]) { $html .= html_tag_open('a', array("rel" => "nofollow", "href" => $uaRun["runResultsUrl"])) . $uaRun["runResultsLabel"] . '<i class="icon-list-alt pull-right" title="' . htmlspecialchars("Open run results for {$data["userAgents"][$uaID]["displaytitle"]}") . '"></i>' . '</a>'; } else { $html .= UserPage::getStatusIconHtml($uaRun["runStatus"]); } $html .= '</td>'; } else { // This run isn't schedules to be ran in this UA $html .= '<td class="swarm-status swarm-status-notscheduled"></td>'; } } } $html .= '</tbody></table>'; return $html; }
protected function initContent() { $request = $this->getContext()->getRequest(); $this->setTitle("Job status"); $this->setRobots("noindex,nofollow"); $this->bodyScripts[] = swarmpath("js/job.js"); $error = $this->getAction()->getError(); $data = $this->getAction()->getData(); $html = ''; if ($error) { $html .= html_tag('div', array('class' => 'alert alert-error'), $error['info']); } if (!isset($data["jobInfo"])) { return $html; } $this->setSubTitle('#' . $data["jobInfo"]["id"]); $html .= '<h2>' . $data["jobInfo"]["name"] . '</h2>' . '<p><em>Submitted by ' . html_tag("a", array("href" => swarmpath("user/{$data["jobInfo"]["ownerName"]}")), $data["jobInfo"]["ownerName"]) . ' on ' . htmlspecialchars(date("Y-m-d H:i:s", gmstrtotime($data["jobInfo"]["creationTimestamp"]))) . ' (UTC)' . '</em>.</p>'; $html .= '<table class="table table-bordered swarm-results"><thead>' . self::getUaHtmlHeader($data['userAgents']) . '</thead><tbody>' . self::getUaRunsHtmlRows($data['runs'], $data['userAgents']) . '</tbody></table>'; if ($request->getSessionData("auth") === "yes" && $data["jobInfo"]["ownerName"] == $request->getSessionData("username")) { $html .= '<script>SWARM.jobInfo = ' . json_encode($data["jobInfo"]) . ';</script>' . '<div class="form-actions swarm-item-actions">' . ' <button id="swarm-job-reset" class="btn btn-info">Reset job</button>' . ' <button id="swarm-job-delete" class="btn btn-danger">Delete job</button>' . '</div>' . '<div class="alert alert-error" id="swarm-wipejob-error" style="display: none;"></div>'; } return $html; }
/** * Central method to create keys in an Action response related to time for consistency. * Adds three keys: * - RawUTC (14-digit timestamp in UTC, as found in the database) * - ISO (naturally in UTC aka Zulu) * - Localized format according to the swarm configuration. * * @param &$target array: The array the keys should be added to, is passed by * reference, so it will be modified! * @param $tsRawUTC string: * @param $prefix string: [optional] If given, this string will be prefixed to * the added keys, and the rest of the name ucfirst'ed resulting in: * "rawUTC" or "prefixRawUTC" respectively. */ protected static final function addTimestampsTo(&$target, $tsRawUTC, $prefix = null) { $tsLocalFormatted = strftime("%c", gmstrtotime($tsRawUTC)); // PHP's "c" claims to be ISO compatible but prettyDateJS disagrees // ("2004-02-12T15:19:21+00:00" vs. "2004-02-12T15:19:21Z"). // Constructing format manually instead. $tsISO = gmdate("Y-m-d\\TH:i:s\\Z", gmstrtotime($tsRawUTC)); if (is_array($target)) { $target[$prefix ? "{$prefix}RawUTC" : "rawUTC"] = $tsRawUTC; $target[$prefix ? "{$prefix}ISO" : "ISO"] = $tsISO; $target[$prefix ? "{$prefix}LocalFormatted" : "localFormatted"] = $tsLocalFormatted; } else { throw SwarmException("Invalid arguments to " . __METHOD__); } }
/** * @actionParam int item: Runresults ID. */ public function doAction() { $context = $this->getContext(); $db = $context->getDB(); $conf = $context->getConf(); $request = $context->getRequest(); $item = $request->getInt('item'); $row = $db->getRow(str_queryf('SELECT id, run_id, client_id, status, updated, created, result_url, build_url FROM runresults WHERE id = %u;', $item)); if (!$row) { $this->setError('invalid-input', 'Runresults ID not found.'); return; } $data = array(); $data['result_url'] = $row->result_url; $data['build_url'] = $row->build_url; // A job can be deleted without nuking the runresults, // this is by design so results stay permanently accessible // under a simple url. // If the job is no longer in existance, properties // 'otherRuns' and 'job' will be set to null. $runRow = $db->getRow(str_queryf('SELECT id, url, name, job_id FROM runs WHERE id = %u;', $row->run_id)); if (!$runRow) { $data['otherRuns'] = null; $data['job'] = null; } else { $data['otherRuns'] = JobAction::getDataFromRunRows($context, array($runRow)); $jobID = intval($runRow->job_id); $data['job'] = array('id' => $jobID, 'url' => swarmpath("job/{$jobID}", "fullurl")); } $clientRow = $db->getRow(str_queryf('SELECT id, name, useragent_id, useragent FROM clients WHERE id = %u;', $row->client_id)); $data['info'] = array('id' => intval($row->id), 'runID' => intval($row->run_id), 'clientID' => intval($row->client_id), 'status' => self::getStatus($row->status)); $data['client'] = array('id' => $clientRow->id, 'name' => $clientRow->name, 'uaID' => $clientRow->useragent_id, 'uaRaw' => $clientRow->useragent, 'viewUrl' => swarmpath('client/' . $clientRow->id)); // If still busy or if the client was lost, then the last update time is irrelevant // Alternatively this could test if $row->updated == $row->created, which would effectively // do the same. if ($row->status == self::$STATE_BUSY || $row->status == self::$STATE_LOST) { $data['info']['runTime'] = null; } else { $data['info']['runTime'] = gmstrtotime($row->updated) - gmstrtotime($row->created); self::addTimestampsTo($data['info'], $row->updated, 'saved'); } self::addTimestampsTo($data['info'], $row->created, 'started'); $this->setData($data); }
<?php // convert form local time to GMT function gmstrtotime($s) { $t = strtotime($s); $zone = intval(JB_GMT_DIF) / 100; $t += $zone * 60 * 60; return $t; } if ($_REQUEST['show'] == "") { //if ($_REQUEST['select_date']!='') { if (JB_GMT_DIF > 0) { $plus = "+"; } $from_time = gmstrtotime($_REQUEST['from_year'] . "-" . $_REQUEST['from_month'] . "-" . $_REQUEST['from_day'] . " 00:00:00"); $to_time = gmstrtotime($_REQUEST['to_year'] . "-" . $_REQUEST['to_month'] . "-" . $_REQUEST['to_day'] . " 23:59:59"); $from_date = "'" . gmdate('Y-m-d H:i:s', $from_time) . "'"; $to_date = "'" . gmdate('Y-m-d H:i:s', $to_time) . "'"; /* In an ideal world, MySQL's CONVERT_TZ work best, but goDaddy does not support them because they use outdated software... */ /* $from_date = "CONVERT_TZ('".$_REQUEST['from_year']."-".$_REQUEST['from_month']."-".$_REQUEST['from_day']." 00:00:00', '".$plus.JB_GMT_DIF.":00', '+00:00')" ; $to_date = "CONVERT_TZ('".$_REQUEST['to_year']."-".$_REQUEST['to_month']."-".$_REQUEST['to_day']." 23:59:59', '".$plus.JB_GMT_DIF.":00', '+00:00')" ; */ $where_date = "WHERE (invoice_date >= {$from_date} AND invoice_date <= {$to_date} ) "; if ($_REQUEST['status'] != '' && $_REQUEST['status'] != 'all') { $where_status = " AND status='" . $_REQUEST['status'] . "' "; } if ($_REQUEST['search_it'] != '') {
/** * @actionParam int item: Runresults ID. */ public function doAction() { $context = $this->getContext(); $db = $context->getDB(); $conf = $context->getConf(); $request = $context->getRequest(); $resultsID = $request->getInt('item'); $row = $db->getRow(str_queryf('SELECT run_id, client_id, status, error, total, fail, updated, created, report_html_size, LENGTH( report_html ) as \'compressed_size\' FROM runresults WHERE id = %u;', $resultsID)); if (!$row) { $this->setError('invalid-input', 'Runresults ID not found.'); return; } $data = array(); // A job can be deleted without nuking the runresults, // this is by design so results stay permanently accessible // under a simple url. // If the job is no longer in existance, properties // 'otherRuns' and 'job' will be set to null. $runRows = $db->getRows(str_queryf('SELECT id, url, name, job_id FROM runs WHERE id = %u;', $row->run_id)); if (!$runRows || !count($runRows)) { $data['otherRuns'] = null; $data['job'] = null; } else { $data['otherRuns'] = JobAction::getDataFromRunRows($db, $runRows); $jobID = intval($runRows[0]->job_id); $data['job'] = array('id' => $jobID, 'url' => swarmpath("job/{$jobID}", "fullurl")); } $clientRow = $db->getRow(str_queryf('SELECT id, user_id, useragent_id, useragent, device_name FROM clients WHERE id = %u;', $row->client_id)); $userRow = $db->getRow(str_queryf('SELECT id, name FROM users WHERE id = %u;', $clientRow->user_id)); $data['client'] = array('id' => $clientRow->id, 'uaID' => $clientRow->useragent_id, 'userAgent' => $clientRow->useragent, 'deviceName' => $clientRow->device_name, 'userID' => $userRow->id, 'userName' => $userRow->name, 'userUrl' => swarmpath('user/' . $userRow->name)); $data['resultInfo'] = array('id' => $resultsID, 'runID' => $row->run_id, 'fail' => $row->fail, 'total' => $row->total, 'error' => $row->error, 'clientID' => $row->client_id, 'status' => self::getStatus($row->status), 'reportHtmlSize' => $row->report_html_size, 'reportHtmlCompressedSize' => $row->compressed_size, 'reportHtmlCompressionRatio' => $row->report_html_size == 0 ? 0 : round(($row->report_html_size - $row->compressed_size) / $row->report_html_size * 100 / 1, 2)); // If still busy or if the client was lost, then the last update time is irrelevant // Alternatively this could test if $row->updated == $row->created, which would effectively // do the same. if ($row->status == self::$STATE_BUSY || $row->status == self::$STATE_LOST) { $data['resultInfo']['runTime'] = null; } else { $data['resultInfo']['runTime'] = gmstrtotime($row->updated) - gmstrtotime($row->created); self::addTimestampsTo($data['resultInfo'], $row->updated, 'saved'); } self::addTimestampsTo($data['resultInfo'], $row->created, 'started'); $this->setData($data); }
} if ($fName) { $zipName = 'gziped/' . $fName . '.gz'; // Do they want gz'd files and do we have one? if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && stristr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && file_exists($zipName)) { $headers[] = 'Content-Encoding: gzip'; $headers[] = 'Vary: Accept-Encoding'; $fName = $zipName; } $handle = @fopen($fName, 'r'); if ($handle) { $mt = filemtime($fName); $mt_str = gmdate("D, d M Y H:i:s", $mt) . " GMT"; if (!empty($_SERVER["HTTP_IF_MODIFIED_SINCE"])) { $cache_mt = $_SERVER["HTTP_IF_MODIFIED_SINCE"]; if (gmstrtotime($cache_mt) >= $mt) { fclose($handle); header("HTTP/1.1 304 Not Modified"); exit; } } $headers[] = "Last-Modified: " . $mt_str; $contents = fread($handle, filesize($fName)); fclose($handle); } else { // AH!! We cannot open the file for some reason!! $cType = $defaultCType; $contents = 'There has been an issue trying to locate the file "' . $fName . '" please contact support.'; } } // If there is nothing here then we are in a bad state
/** * @actionParam string item: Client id. */ public function doAction() { $context = $this->getContext(); $db = $context->getDB(); $request = $context->getRequest(); $item = $request->getInt('item'); if (!$item) { $this->setError('missing-parameters'); return; } // Client information $row = $db->getRow(str_queryf('SELECT id, name, useragent, updated, created FROM clients WHERE id = %u;', $item)); if (!$row) { $this->setError('invalid-input', 'Client not found'); return; } $bi = BrowserInfo::newFromContext($context, $row->useragent); $info = array('id' => intval($row->id), 'name' => $row->name, 'viewUrl' => swarmpath("clients/{$row->name}"), 'uaID' => $bi->getSwarmUaID(), 'uaRaw' => $bi->getRawUA(), 'uaData' => $bi->getUaData(), 'sessionAge' => gmstrtotime($row->updated) - gmstrtotime($row->created)); self::addTimestampsTo($info, $row->created, 'connected'); self::addTimestampsTo($info, $row->updated, 'pinged'); // Run results $results = array(); $rows = $db->getRows(str_queryf('SELECT id, run_id, client_id, status, total, fail, error, updated, created FROM runresults WHERE client_id = %u ORDER BY created DESC;', $item)); if ($rows) { foreach ($rows as $row) { $runRow = $jobRow = false; $result = array('id' => intval($row->id), 'viewUrl' => swarmpath("result/{$row->id}"), 'status' => JobAction::getRunresultsStatus($row)); $runRow = $db->getRow(str_queryf('SELECT name, job_id FROM runs WHERE id = %u;', $row->run_id)); if ($runRow) { $jobRow = $db->getRow(str_queryf('SELECT id, name, project_id FROM jobs WHERE id = %u', $runRow->job_id)); if ($jobRow) { $projectRow = $db->getRow(str_queryf('SELECT display_title FROM projects WHERE id = %s;', $jobRow->project_id)); $result['job'] = array('nameText' => strip_tags($jobRow->name), 'viewUrl' => swarmpath("job/{$jobRow->id}")); $result['run'] = array('name' => $runRow->name); $result['project'] = array('id' => $jobRow->project_id, 'display_title' => $projectRow->display_title, 'viewUrl' => swarmpath("project/{$jobRow->project_id}")); } } // Runs and jobs could be deleted, results are preserved. if (!$jobRow) { $result['job'] = null; $result['run'] = null; $result['project'] = null; } $results[] = $result; } } $this->setData(array('info' => $info, 'results' => $results)); }
/** * GET the call duration * * @param array $row Results from database call in build_item_list * * @return array Returns the whole item array */ function get_duration($row) { if (!empty($row['timestamp_hangup'])) { $to_time = gmstrtotime($row['timestamp_hangup']); } else { $to_time = time(); } if (!empty($row['timestamp_link'])) { $from_time = gmstrtotime($row['timestamp_link']); } else { $from_time = gmstrtotime($row['timestamp_call']); } $duration = number_format(round(abs($to_time - $from_time) / 60, 1), 1); return $duration; }