public function testCoderOfTheMonthCalc()
 {
     $user = UserFactory::createUser();
     $contest = ContestsFactory::createContest();
     $problem = ProblemsFactory::createProblem();
     ContestsFactory::addProblemToContest($problem, $contest);
     ContestsFactory::addUser($contest, $user);
     // Creating 10 AC runs for our user in the last month
     $n = 10;
     $lastMonth = intval(date('m')) - 1;
     $runCreationDate = null;
     if ($lastMonth == 0) {
         $runCreationDate = date(intval(date('Y') - 1) . '-12-01');
     } else {
         $runCreationDate = date('Y-' . $lastMonth . '-01');
     }
     for ($i = 0; $i < $n; $i++) {
         $runData = RunsFactory::createRun($problem, $contest, $user);
         RunsFactory::gradeRun($runData);
         // Force the run to be in last month
         $run = RunsDAO::getByAlias($runData['response']['guid']);
         $run->setTime($runCreationDate);
         RunsDAO::save($run);
     }
     $response = UserController::apiCoderOfTheMonth(new Request());
     $this->assertEquals($user->getUsername(), $response['userinfo']['username']);
 }
예제 #2
0
 /**
  * Validate a run
  *
  * @param type $r
  * @param type $response
  */
 private function assertRun($r, $response)
 {
     // Validate
     $this->assertEquals("ok", $response["status"]);
     $this->assertArrayHasKey("guid", $response);
     // Get run from DB
     $run = RunsDAO::getByAlias($response["guid"]);
     $this->assertNotNull($run);
     // Get contest from DB to check times with respect to contest start
     $contest = ContestsDAO::getByAlias($r["contest_alias"]);
     // Validate data
     $this->assertEquals($r["language"], $run->getLanguage());
     $this->assertNotNull($run->getGuid());
     // Validate file created
     $filename = RunController::getSubmissionPath($run);
     $this->assertFileExists($filename);
     $fileContent = file_get_contents($filename);
     $this->assertEquals($r["source"], $fileContent);
     // Validate defaults
     $this->assertEquals("new", $run->getStatus());
     $this->assertEquals(0, $run->getRuntime());
     $this->assertEquals(0, $run->getMemory());
     $this->assertEquals(0, $run->getScore());
     $this->assertEquals(0, $run->getContestScore());
     $this->assertEquals("127.0.0.1", $run->getIp());
     if (!is_null($contest)) {
         $this->assertEquals((time() - intval(strtotime($contest->getStartTime()))) / 60, $run->penalty, '', 0.5);
     }
     $this->assertEquals("JE", $run->getVerdict());
 }
예제 #3
0
 /**
  * Validate a run
  *
  * @param type $r
  * @param type $response
  */
 private function assertRun($r, $response)
 {
     // Validate
     $this->assertEquals('ok', $response['status']);
     $this->assertArrayHasKey('guid', $response);
     // Get run from DB
     $run = RunsDAO::getByAlias($response['guid']);
     $this->assertNotNull($run);
     // Get contest from DB to check times with respect to contest start
     $contest = ContestsDAO::getByAlias($r['contest_alias']);
     // Validate data
     $this->assertEquals($r['language'], $run->getLanguage());
     $this->assertNotNull($run->getGuid());
     // Validate file created
     $filename = RunController::getSubmissionPath($run);
     $this->assertFileExists($filename);
     $fileContent = file_get_contents($filename);
     $this->assertEquals($r['source'], $fileContent);
     // Validate defaults
     $this->assertEquals('new', $run->getStatus());
     $this->assertEquals(0, $run->getRuntime());
     $this->assertEquals(0, $run->getMemory());
     $this->assertEquals(0, $run->getScore());
     $this->assertEquals(0, $run->getContestScore());
     $logs = SubmissionLogDAO::search(array('run_id' => $run->run_id));
     $this->assertEquals(1, count($logs));
     $this->assertEquals(ip2long('127.0.0.1'), $logs[0]->ip);
     if (!is_null($contest)) {
         $this->assertEquals((time() - intval(strtotime($contest->getStartTime()))) / 60, $run->penalty, '', 0.5);
     }
     $this->assertEquals('JE', $run->getVerdict());
 }
예제 #4
0
 public function testRunTotals()
 {
     // 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 a run
     $runData = RunsFactory::createRun($problemData, $contestData, $contestant);
     $runDataOld = RunsFactory::createRun($problemData, $contestData, $contestant);
     $run = RunsDAO::getByAlias($runDataOld['response']['guid']);
     $run->setTime(date('Y-m-d H:i:s', strtotime('-72 hours')));
     RunsDAO::save($run);
     $response = RunController::apiCounts(new Request());
     $this->assertGreaterThan(1, count($response));
 }
예제 #5
0
 /**
  * Given a run id, set a score to a given run
  *
  * @param type $runData
  * @param int $points
  * @param string $verdict
  */
 public static function gradeRun($runData, $points = 1, $verdict = 'AC', $submitDelay = null)
 {
     $run = RunsDAO::getByAlias($runData['response']['guid']);
     $run->setVerdict($verdict);
     $run->setScore($points);
     $run->setContestScore($points * 100);
     $run->setStatus('ready');
     $run->judged_by = 'J1';
     if (!is_null($submitDelay)) {
         $run->submit_delay = $submitDelay;
         $run->penalty = $submitDelay;
     }
     RunsDAO::save($run);
 }
예제 #6
0
 public static function RefreshScoreboardCache($contest_id)
 {
     try {
         $contest = ContestsDAO::getByPK($contest_id);
         $contest_runs = RunsDAO::GetContestRuns($contest_id);
         // Get all distinct contestants participating in the contest given contest_id
         $raw_contest_users = RunsDAO::GetAllRelevantUsers($contest_id, true, null);
         // Get all problems given contest_id
         $raw_contest_problems = ContestProblemsDAO::GetRelevantProblems($contest_id);
     } catch (Exception $e) {
         throw new InvalidDatabaseOperationException($e);
     }
     $problem_mapping = array();
     $order = 0;
     foreach ($raw_contest_problems as $problem) {
         $problem_mapping[$problem->problem_id] = array('order' => $order++, 'alias' => $problem->alias);
     }
     $scoreboardLimit = Scoreboard::getScoreboardTimeLimitUnixTimestamp($contest);
     // Cache scoreboard until the contest ends (or forever if it has already ended).
     $timeout = max(0, strtotime($contest->getFinishTime()) - time());
     $contestantScoreboardCache = new Cache(Cache::CONTESTANT_SCOREBOARD_PREFIX, $contest_id);
     $contestantScoreboard = Scoreboard::getScoreboardFromRuns($contest_runs, $raw_contest_users, $problem_mapping, $contest->getPenalty(), $scoreboardLimit, $contest, false, false);
     $contestantScoreboardCache->set($contestantScoreboard, $timeout);
     $adminScoreboardCache = new Cache(Cache::ADMIN_SCOREBOARD_PREFIX, $contest_id);
     $scoreboardLimit = Scoreboard::getScoreboardTimeLimitUnixTimestamp($contest, true);
     $adminScoreboard = Scoreboard::getScoreboardFromRuns($contest_runs, $raw_contest_users, $problem_mapping, $contest->getPenalty(), $scoreboardLimit, $contest, true, false);
     $adminScoreboardCache->set($adminScoreboard, $timeout);
     $contestantEventCache = new Cache(Cache::CONTESTANT_SCOREBOARD_EVENTS_PREFIX, $contest_id);
     $contestantEventCache->set(Scoreboard::calculateEvents($contest, $contest_runs, $raw_contest_users, $problem_mapping, false), $timeout);
     $adminEventCache = new Cache(Cache::ADMIN_SCOREBOARD_EVENTS_PREFIX, $contest_id);
     $adminEventCache->set(Scoreboard::calculateEvents($contest, $contest_runs, $raw_contest_users, $problem_mapping, true), $timeout);
     // Try to broadcast the updated scoreboards:
     $log = Logger::getLogger('Scoreboard');
     try {
         $grader = new Grader();
         $log->debug('Sending updated scoreboards');
         $grader->broadcast($contest->alias, json_encode(array('message' => '/scoreboard/update/', 'scoreboard' => $adminScoreboard)), false, -1, false);
         $grader->broadcast($contest->alias, json_encode(array('message' => '/scoreboard/update/', 'scoreboard' => $contestantScoreboard)), true, -1, true);
     } catch (Exception $e) {
         $log->error('Error broadcasting scoreboard: ' . $e);
     }
 }
예제 #7
0
 /**
  * Get stats
  *
  * @param Request $r
  */
 public static function apiStats(Request $r)
 {
     self::authenticateOrAllowUnauthenticatedRequest($r);
     $user = self::resolveTargetUser($r);
     try {
         $totalRunsCount = RunsDAO::CountTotalRunsOfUser($user->getUserId());
         // List of verdicts
         $verdict_counts = array();
         foreach (self::$verdicts as $verdict) {
             $verdict_counts[$verdict] = RunsDAO::CountTotalRunsOfUserByVerdict($user->getUserId(), $verdict);
         }
     } catch (Exception $e) {
         throw new InvalidDatabaseOperationException($e);
     }
     return array('verdict_counts' => $verdict_counts, 'total_runs' => $totalRunsCount, 'status' => 'ok');
 }
예제 #8
0
 /**
  * Gets a list of latest runs overall
  *
  * @param Request $r
  * @return string
  * @throws InvalidDatabaseOperationException
  */
 public static function apiList(Request $r)
 {
     // Authenticate request
     self::authenticateRequest($r);
     self::validateList($r);
     try {
         $runs = RunsDAO::GetAllRuns(null, $r['status'], $r['verdict'], !is_null($r['problem']) ? $r['problem']->getProblemId() : null, $r['language'], !is_null($r['user']) ? $r['user']->getUserId() : null, $r['offset'], $r['rowcount']);
     } catch (Exception $e) {
         // Operation failed in the data layer
         throw new InvalidDatabaseOperationException($e);
     }
     $result = array();
     foreach ($runs as $run) {
         $run['time'] = (int) $run['time'];
         $run['score'] = round((double) $run['score'], 4);
         if ($run['contest_score'] != null) {
             $run['contest_score'] = round((double) $run['contest_score'], 2);
         }
         array_push($result, $run);
     }
     $response = array();
     $response['runs'] = $result;
     $response['status'] = 'ok';
     return $response;
 }
예제 #9
0
 public static function apiDownload(Request $r)
 {
     self::authenticateRequest($r);
     self::validateStats($r);
     // Get our runs
     $relevant_columns = array("run_id", "guid", "language", "status", "verdict", "runtime", "penalty", "memory", "score", "contest_score", "time", "submit_delay", "Users.username", "Problems.alias");
     try {
         $runs = RunsDAO::search(new Runs(array("contest_id" => $r["contest"]->getContestId())), "time", "DESC", $relevant_columns);
     } catch (Exception $e) {
         // Operation failed in the data layer
         throw new InvalidDatabaseOperationException($e);
     }
     $zip = new ZipStream($r["contest_alias"] . '.zip');
     // Add runs to zip
     $table = "guid,user,problem,verdict,points\n";
     foreach ($runs as $run) {
         $zip->add_file_from_path("runs/" . $run->getGuid(), RunController::getSubmissionPath($run));
         $columns[0] = 'username';
         $columns[1] = 'alias';
         $usernameProblemData = $run->asFilteredArray($columns);
         $table .= $run->getGuid() . "," . $usernameProblemData['username'] . "," . $usernameProblemData['alias'] . "," . $run->getVerdict() . "," . $run->getContestScore();
         $table .= "\n";
     }
     $zip->add_file("summary.csv", $table);
     // Add problem cases to zip
     $contest_problems = ContestProblemsDAO::GetRelevantProblems($r["contest"]->getContestId());
     foreach ($contest_problems as $problem) {
         $zip->add_file_from_path($problem->getAlias() . "_cases.zip", PROBLEMS_PATH . "/" . $problem->getAlias() . "/cases.zip");
     }
     // Return zip
     $zip->finish();
     die;
 }
예제 #10
0
 public static function apiDownload(Request $r)
 {
     self::authenticateRequest($r);
     self::validateStats($r);
     // Get our runs
     $relevant_columns = array('run_id', 'guid', 'language', 'status', 'verdict', 'runtime', 'penalty', 'memory', 'score', 'contest_score', 'time', 'submit_delay', 'Users.username', 'Problems.alias');
     try {
         $runs = RunsDAO::search(new Runs(array('contest_id' => $r['contest']->getContestId())), 'time', 'DESC', $relevant_columns);
     } catch (Exception $e) {
         // Operation failed in the data layer
         throw new InvalidDatabaseOperationException($e);
     }
     $zip = new ZipStream($r['contest_alias'] . '.zip');
     // Add runs to zip
     $table = "guid,user,problem,verdict,points\n";
     foreach ($runs as $run) {
         $zip->add_file_from_path('runs/' . $run->getGuid(), RunController::getSubmissionPath($run));
         $columns[0] = 'username';
         $columns[1] = 'alias';
         $usernameProblemData = $run->asFilteredArray($columns);
         $table .= $run->getGuid() . ',' . $usernameProblemData['username'] . ',' . $usernameProblemData['alias'] . ',' . $run->getVerdict() . ',' . $run->getContestScore();
         $table .= "\n";
     }
     $zip->add_file('summary.csv', $table);
     // Add problem cases to zip
     $contest_problems = ContestProblemsDAO::GetRelevantProblems($r['contest']->getContestId());
     foreach ($contest_problems as $problem) {
         $zip->add_file_from_path($problem->getAlias() . '_cases.zip', PROBLEMS_PATH . '/' . $problem->getAlias() . '/cases.zip');
     }
     // Return zip
     $zip->finish();
     die;
 }
예제 #11
0
 /**
  * Returns the best score of a problem.
  * Problem must be loadad in $r["problem"]
  * Contest could be loadad in $r["contest"]. If set, will only look for
  * runs inside that contest.
  *
  * Authentication is expected to be performed earlier.
  *
  * @param Request $r
  * @return float
  * @throws InvalidDatabaseOperationException
  */
 private static function bestScore(Request $r, Users $user = null)
 {
     $current_user_id = is_null($user) ? $r['current_user_id'] : $user->getUserId();
     if (is_null($current_user_id)) {
         return 0;
     }
     $score = 0;
     try {
         // Add best score info
         if (is_null($r['contest'])) {
             $score = RunsDAO::GetBestScore($r['problem']->getProblemId(), $current_user_id);
         } else {
             $bestRun = RunsDAO::GetBestRun($r['contest']->getContestId(), $r['problem']->getProblemId(), $current_user_id, strtotime($r['contest']->getFinishTime()), false);
             $score = is_null($bestRun->getContestScore()) ? 0 : $bestRun->getContestScore();
         }
     } catch (Exception $e) {
         throw new InvalidDatabaseOperationException($e);
     }
     return $score;
 }
예제 #12
0
 /**
  * Given a run id, set a score to a given run
  * 
  * @param type $runData
  * @param int $points
  * @param string $verdict
  */
 public static function gradeRun($runData, $points = 1, $verdict = "AC", $submitDelay = null)
 {
     $run = RunsDAO::getByAlias($runData["response"]["guid"]);
     $run->setVerdict($verdict);
     $run->setScore($points);
     $run->setContestScore($points * 100);
     $run->setStatus("ready");
     $run->judged_by = "J1";
     if (!is_null($submitDelay)) {
         $run->submit_delay = $submitDelay;
         $run->penalty = $submitDelay;
     }
     RunsDAO::save($run);
 }