示例#1
0
 /**
  * Check stats are ok for WA, AC, PA and total counts
  * Also validates the max wait time guid
  */
 public function testGetStats()
 {
     // Get a problem
     $problemData = ProblemsFactory::createProblem();
     // Get a contest
     $contestData = ContestsFactory::createContest();
     // Add the problem to the contest
     ContestsFactory::addProblemToContest($problemData, $contestData);
     // Create our contestant
     $contestant = UserFactory::createUser();
     // Create some runs to be pending
     $pendingRunsCount = 5;
     $pendingRunsData = array();
     for ($i = 0; $i < $pendingRunsCount; $i++) {
         $pendingRunsData[$i] = RunsFactory::createRun($problemData, $contestData, $contestant);
     }
     $ACRunsCount = 2;
     $ACRunsData = array();
     for ($i = 0; $i < $ACRunsCount; $i++) {
         $ACRunsData[$i] = RunsFactory::createRun($problemData, $contestData, $contestant);
         // Grade the run
         RunsFactory::gradeRun($ACRunsData[$i]);
     }
     $WARunsCount = 1;
     $WARunsData = array();
     for ($i = 0; $i < $WARunsCount; $i++) {
         $WARunsData[$i] = RunsFactory::createRun($problemData, $contestData, $contestant);
         // Grade the run with WA
         RunsFactory::gradeRun($WARunsData[$i], 0, "WA");
     }
     // Create request
     $r = new Request();
     $r["problem_alias"] = $problemData["request"]["alias"];
     $r["auth_token"] = $this->login($problemData["author"]);
     // Call API
     $response = ProblemController::apiStats($r);
     // Check number of pending runs
     $this->assertEquals(count($pendingRunsData), count($response["pending_runs"]));
     $this->assertEquals(count($ACRunsData), $response["verdict_counts"]["AC"]);
     $this->assertEquals(count($WARunsData), $response["verdict_counts"]["WA"]);
     $this->assertEquals($pendingRunsCount + $ACRunsCount + $WARunsCount, $response["total_runs"]);
 }
示例#2
0
 /**
  * Generates a CSV for contest report
  *
  * @param Request $r
  * @return array
  */
 public static function apiCsvReport(Request $r)
 {
     self::authenticateRequest($r);
     self::validateStats($r);
     // Get full Report API of the contest
     $reportRequest = new Request(array("contest_alias" => $r["contest_alias"], "auth_token" => $r["auth_token"]));
     $contestReport = self::apiReport($reportRequest);
     // Get problem stats for each contest problem so we can
     // have the full list of cases
     $problemStats = array();
     $i = 0;
     foreach ($contestReport["problems"] as $entry) {
         $problem_alias = $entry["alias"];
         $problemStatsRequest = new Request(array("problem_alias" => $problem_alias, "auth_token" => $r["auth_token"]));
         $problemStats[$i] = ProblemController::apiStats($problemStatsRequest);
         $problemStats[$problem_alias] = $problemStats[$i];
         $i++;
     }
     // Build a csv
     $csvData = array();
     // Build titles
     $csvRow = array();
     $csvRow[] = "username";
     foreach ($contestReport["problems"] as $entry) {
         foreach ($problemStats[$entry["alias"]]["cases_stats"] as $caseName => $counts) {
             $csvRow[] = $caseName;
         }
         $csvRow[] = $entry["alias"] . " total";
     }
     $csvRow[] = "total";
     $csvData[] = $csvRow;
     foreach ($contestReport["ranking"] as $userData) {
         if ($userData === "ok") {
             continue;
         }
         $csvRow = array();
         $csvRow[] = $userData["username"];
         foreach ($userData["problems"] as $key => $problemData) {
             // If the user don't have these details then he didn't submit,
             // we need to fill the report with 0s for completeness
             if (!isset($problemData["run_details"]["cases"]) || count($problemData["run_details"]["cases"]) === 0) {
                 for ($i = 0; $i < count($problemStats[$key]["cases_stats"]); $i++) {
                     $csvRow[] = '0';
                 }
                 // And adding the total for this problem
                 $csvRow[] = '0';
             } else {
                 // for each case
                 foreach ($problemData["run_details"]["cases"] as $caseData) {
                     // If case is correct
                     if (strcmp($caseData["meta"]["status"], "OK") === 0 && strcmp($caseData["out_diff"], "") === 0) {
                         $csvRow[] = '1';
                     } else {
                         $csvRow[] = '0';
                     }
                 }
                 $csvRow[] = $problemData["points"];
             }
         }
         $csvRow[] = $userData["total"]["points"];
         $csvData[] = $csvRow;
     }
     // Set headers to auto-download file
     header("Pragma: public");
     header("Expires: 0");
     header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
     header("Content-Type: application/force-download");
     header("Content-Type: application/octet-stream");
     header("Content-Type: application/download");
     header("Content-Disposition: attachment;filename=" . $r["contest_alias"] . "_report.csv");
     header("Content-Transfer-Encoding: binary");
     // Write contents to a csv raw string
     // TODO(https://github.com/omegaup/omegaup/issues/628): Escape = to prevent applications from inadvertently executing code
     // http://contextis.co.uk/blog/comma-separated-vulnerabilities/
     $out = fopen('php://output', 'w');
     foreach ($csvData as $csvRow) {
         fputcsv($out, ContestController::escapeCsv($csvRow));
     }
     fclose($out);
     // X_X
     die;
 }