Example #1
0
 public function execute()
 {
     $action = JobAction::newFromContext($this->getContext());
     $action->doAction();
     $this->setAction($action);
     $this->content = $this->initContent();
 }
Example #2
0
    /**
     * @param string|bool $name
     */
    protected function getActiveClients($name = false)
    {
        $context = $this->getContext();
        $db = $context->getDB();
        $nameQuery = $name ? 'AND name = \'' . $db->strEncode($name) . '\'' : '';
        $results = array();
        $rows = $db->getRows(str_queryf("SELECT\n\t\t\t\tid,\n\t\t\t\tname,\n\t\t\t\tuseragent,\n\t\t\t\tupdated,\n\t\t\t\tcreated\n\t\t\tFROM\n\t\t\t\tclients\n\t\t\tWHERE updated >= %s\n\t\t\t{$nameQuery}\n\t\t\tORDER BY created DESC;", swarmdb_dateformat(Client::getMaxAge($context))));
        if ($rows) {
            foreach ($rows as $row) {
                $bi = BrowserInfo::newFromContext($this->getContext(), $row->useragent);
                $resultRow = $db->getRow(str_queryf('SELECT
						id,
						run_id,
						client_id,
						status,
						total,
						fail,
						error,
						updated,
						created
					FROM runresults
					WHERE client_id = %u
					ORDER BY created DESC
					LIMIT 1;', $row->id));
                $client = array('id' => $row->id, 'name' => $row->name, 'uaID' => $bi->getSwarmUaID(), 'uaRaw' => $bi->getRawUA(), 'uaData' => $bi->getUaData(), 'viewUrl' => swarmpath("client/{$row->id}"), 'lastResult' => !$resultRow ? null : array('id' => intval($resultRow->id), 'viewUrl' => swarmpath("result/{$resultRow->id}"), 'status' => JobAction::getRunresultsStatus($resultRow)));
                self::addTimestampsTo($client, $row->created, 'connected');
                self::addTimestampsTo($client, $row->updated, 'pinged');
                $results[$row->id] = $client;
            }
        }
        return $results;
    }
Example #3
0
 /**
  * @actionParam string sort: [optional] What to sort the results by.
  *  Must be one of "title", "id" or "creation". Defaults to "title".
  * @actionParam string sort_dir: [optional]
  *  Must be one of "asc" (ascending) or "desc" (decending). Defaults to "asc".
  */
 public function doAction()
 {
     $db = $this->getContext()->getDB();
     $request = $this->getContext()->getRequest();
     $sortField = $request->getVal('sort', 'title');
     $sortDir = $request->getVal('sort_dir', 'asc');
     if (!in_array($sortField, array('title', 'id', 'creation'))) {
         $this->setError('invalid-input', "Unknown sort `{$sortField}`.");
         return;
     }
     if (!in_array($sortDir, array('asc', 'desc'))) {
         $this->setError('invalid-input', "Unknown sort direction `{$sortDir}`.");
         return;
     }
     $sortDirQuery = '';
     switch ($sortDir) {
         case 'asc':
             $sortDirQuery = 'ASC';
             break;
         case 'desc':
             $sortDirQuery = 'DESC';
             break;
     }
     $sortFieldQuery = '';
     switch ($sortField) {
         case 'title':
             $sortFieldQuery = "ORDER BY display_title {$sortDirQuery}";
             break;
         case 'id':
             $sortFieldQuery = "ORDER BY id {$sortDirQuery}";
             break;
         case 'creation':
             $sortFieldQuery = "ORDER BY created {$sortDirQuery}";
             break;
     }
     $projects = array();
     $projectRows = $db->getRows("SELECT\n\t\t\t\tid,\n\t\t\t\tdisplay_title,\n\t\t\t\tcreated\n\t\t\tFROM projects\n\t\t\t{$sortFieldQuery};");
     if ($projectRows) {
         foreach ($projectRows as $projectRow) {
             // Get information about the latest job (if any)
             $jobRow = $db->getRow(str_queryf('SELECT id FROM jobs WHERE project_id = %s ORDER BY id DESC LIMIT 1;', $projectRow->id));
             if (!$jobRow) {
                 $job = false;
             } else {
                 $jobAction = JobAction::newFromContext($this->getContext()->createDerivedRequestContext(array('item' => $jobRow->id)));
                 $jobAction->doAction();
                 $job = $jobAction->getData();
             }
             $project = array('id' => $projectRow->id, 'displayTitle' => $projectRow->display_title, 'job' => $job);
             self::addTimestampsTo($project, $projectRow->created, 'created');
             $projects[] = $project;
         }
     }
     $this->setData($projects);
 }
Example #4
0
    /**
     * @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);
    }
Example #5
0
 public function doAction()
 {
     $db = $this->getContext()->getDB();
     $request = $this->getContext()->getRequest();
     $userName = $request->getVal("item");
     if (!$userName) {
         $this->setError("missing-parameters");
         return;
     }
     $userID = $db->getOne(str_queryf("SELECT id FROM users WHERE name = %s;", $userName));
     $userID = intval($userID);
     if (!$userID) {
         $this->setError("invalid-input", "User does not exist");
         return;
     }
     $uaIndex = BrowserInfo::getSwarmUAIndex();
     // Active clients
     $activeClients = array();
     $clientRows = $db->getRows(str_queryf("SELECT\n\t\t\t\tuseragent_id,\n\t\t\t\tuseragent,\n\t\t\t\tcreated\n\t\t\tFROM\n\t\t\t\tclients\n\t\t\tWHERE user_id = %u\n\t\t\tAND   updated > %s\n\t\t\tORDER BY created DESC;", $userID, swarmdb_dateformat(strtotime("1 minutes ago"))));
     if ($clientRows) {
         foreach ($clientRows as $clientRow) {
             $bi = BrowserInfo::newFromContext($this->getContext(), $clientRow->useragent);
             $activeClient = array("uaID" => $clientRow->useragent_id, "uaRaw" => $bi->getRawUA(), "uaData" => $bi->getSwarmUaItem(), "uaBrowscap" => $bi->getBrowscap());
             self::addTimestampsTo($activeClient, $clientRow->created, "connected");
             $activeClients[] = $activeClient;
         }
     }
     // Recent jobs
     $recentJobs = array();
     // List of all user agents used in recent jobs
     // This is as helper allow creating proper gaps when iterating
     // over jobs.
     $userAgents = array();
     $jobRows = $db->getRows(str_queryf("SELECT\n\t\t\t\tid,\n\t\t\t\tname\n\t\t\tFROM\n\t\t\t\tjobs\n\t\t\tWHERE jobs.user_id = %u\n\t\t\tORDER BY jobs.created DESC\n\t\t\tLIMIT 15;", $userID));
     if ($jobRows) {
         $uaRunStatusStrength = array_flip(array("passed", "new", "progress", "failed", "timedout", "error"));
         foreach ($jobRows as $jobRow) {
             $jobID = intval($jobRow->id);
             $jobActionContext = $this->getContext()->createDerivedRequestContext(array("action" => "job", "item" => $jobID), "GET");
             $jobAction = JobAction::newFromContext($jobActionContext);
             $jobAction->doAction();
             if ($jobAction->getError()) {
                 $this->setError($jobAction->getError());
                 return;
             }
             $jobActionData = $jobAction->getData();
             // Add user agents array of this job to the overal user agents list.
             // php array+ automatically fixes clashing keys. The values are always the same
             // so it doesn't matter whether or not it overwrites.
             $userAgents += $jobActionData["userAgents"];
             // The summerized status for each user agent run
             // of this job. e.g. if all are new except one,
             // then it will be on "progress", if all are complete
             // then the worst failure is put in the summary
             $uaSummary = array();
             $uaNotNew = array();
             $uaHasIncomplete = array();
             $uaStrongestStatus = array();
             foreach ($jobActionData["runs"] as $run) {
                 foreach ($run["uaRuns"] as $uaID => $uaRun) {
                     if ($uaRun["runStatus"] !== "new" && !in_array($uaID, $uaNotNew)) {
                         $uaNotNew[] = $uaID;
                     }
                     if ($uaRun["runStatus"] === "new" || $uaRun["runStatus"] === "progress") {
                         if (!in_array($uaID, $uaHasIncomplete)) {
                             $uaHasIncomplete[] = $uaID;
                         }
                     }
                     if (!isset($uaStrongestStatus[$uaID]) || $uaRunStatusStrength[$uaRun["runStatus"]] > $uaRunStatusStrength[$uaStrongestStatus[$uaID]]) {
                         $uaStrongestStatus[$uaID] = $uaRun["runStatus"];
                     }
                     $uaSummary[$uaID] = !in_array($uaID, $uaNotNew) ? "new" : (in_array($uaID, $uaHasIncomplete) ? "progress" : $uaStrongestStatus[$uaID]);
                 }
             }
             $recentJobs[] = array("id" => $jobID, "name" => $jobRow->name, "url" => swarmpath("job/{$jobID}", "fullurl"), "uaSummary" => $uaSummary);
         }
     }
     natcaseksort($userAgents);
     $this->setData(array("userName" => $userName, "activeClients" => $activeClients, "recentJobs" => $recentJobs, "uasInJobs" => $userAgents));
 }
Example #6
0
    /**
     * @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);
    }
Example #7
0
    /**
     * @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));
    }
Example #8
0
    /**
     * @actionParam string item: Project ID.
     */
    public function doAction()
    {
        $conf = $this->getContext()->getConf();
        $db = $this->getContext()->getDB();
        $request = $this->getContext()->getRequest();
        $projectID = $request->getVal('item');
        if (!$projectID) {
            $this->setError('missing-parameters');
            return;
        }
        // Note: The job list is reverse chronologic (descending).
        // To query the "next" page, you get the jobs with an id
        // that is lower than the last entry on the current page.
        // Parameters for navigation of job list in this project
        $dir = $request->getVal('dir', '');
        $offset = $request->getInt('offset');
        $limit = $request->getInt('limit', $this->defaultLimit);
        if (!in_array($dir, array('', 'back')) || $limit < 1 || $limit > 100) {
            $this->setError('invalid-input');
            return;
        }
        // Get project info
        $projectRow = $db->getRow(str_queryf('SELECT
				id,
				display_title,
				site_url,
				updated,
				created
			FROM projects
			WHERE id = %s;', $projectID));
        if (!$projectRow) {
            $this->setError('invalid-input', 'Project does not exist');
            return;
        }
        $conds = '';
        if ($offset) {
            if ($dir === 'back') {
                $conds = 'AND id > ' . intval($offset);
            } else {
                $conds = 'AND id < ' . intval($offset);
            }
        }
        // Get list of jobs
        $jobRows = $db->getRows(str_queryf('SELECT
				id,
				name
			FROM
				jobs
			WHERE project_id = %s
			' . $conds . '
			ORDER BY id ' . ($dir === 'back' ? 'ASC' : 'DESC') . '
			LIMIT %u;', $projectID, $limit + 1));
        $jobs = array();
        // List of all user agents used in recent jobs
        // This is as helper to allow easy creation of placeholder gaps in a UI
        // when iterating over jobs, because not all jobs have the same user agents.
        $userAgents = array();
        if (!$jobRows) {
            $pagination = array();
        } else {
            $pagination = $this->getPaginationData($dir, $offset, $limit, $jobRows, $projectID);
            if ($dir === 'back') {
                $jobRows = array_reverse($jobRows);
            }
            foreach ($jobRows as $jobRow) {
                $jobID = intval($jobRow->id);
                $jobAction = JobAction::newFromContext($this->getContext()->createDerivedRequestContext(array('item' => $jobID)));
                $jobAction->doAction();
                if ($jobAction->getError()) {
                    $this->setError($jobAction->getError());
                    return;
                }
                $jobActionData = $jobAction->getData();
                // Add user agents array of this job to the overal user agents list.
                // php array+ automatically fixes clashing keys. The values are always the same
                // so it doesn't matter whether or not it overwrites.
                $userAgents += $jobActionData['userAgents'];
                $jobs[] = array('info' => $jobActionData['info'], 'name' => $jobRow->name, 'summaries' => $jobActionData['uaSummaries']);
            }
        }
        uasort($userAgents, 'BrowserInfo::sortUaData');
        $projectInfo = (array) $projectRow;
        unset($projectInfo['updated'], $projectInfo['created']);
        self::addTimestampsTo($projectInfo, $projectRow->updated, 'updated');
        self::addTimestampsTo($projectInfo, $projectRow->created, 'created');
        $this->setData(array('info' => $projectInfo, 'jobs' => $jobs, 'pagination' => $pagination, 'userAgents' => $userAgents));
    }