public static function CanEditClarification($user_id, Clarifications $clarification)
 {
     if (is_null($clarification) || !is_a($clarification, 'Clarifications')) {
         return false;
     }
     try {
         $contest = ContestsDAO::getByPK($clarification->getContestId());
         $problem = ProblemsDAO::getByPK($clarification->getProblemId());
     } catch (Exception $e) {
         throw new InvalidDatabaseOperationException($e);
     }
     if (is_null($contest) || is_null($problem)) {
         return false;
     }
     return $problem->getAuthorId() === $user_id || Authorization::IsContestAdmin($user_id, $contest);
 }
Beispiel #2
0
 public static final function IsRunInsideSubmissionGap($contest_id, $problem_id, $user_id)
 {
     // Get last run
     $lastrun = self::GetLastRun($contest_id, $problem_id, $user_id);
     if (is_null($lastrun)) {
         return true;
     }
     $submission_gap = 0;
     if ($contest_id != null) {
         // Get submissions gap
         $contest = ContestsDAO::getByPK($contest_id);
         $submission_gap = (int) $contest->getSubmissionsGap();
     }
     $submission_gap = max($submission_gap, RunController::$defaultSubmissionGap);
     return time() >= strtotime($lastrun->getTime()) + $submission_gap;
 }
Beispiel #3
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);
     }
 }
 /**
  * Get list of contests where the user has admin priviledges
  *
  * @param Request $r
  * @return string
  * @throws InvalidDatabaseOperationException
  */
 public static function apiContests(Request $r)
 {
     self::authenticateRequest($r);
     $response = array();
     $response['contests'] = array();
     try {
         $contest_director_key = new Contests(array('director_id' => $r['current_user_id']));
         $contests_director = ContestsDAO::search($contest_director_key);
         foreach ($contests_director as $contest) {
             $response['contests'][] = $contest->asArray();
         }
         $contest_admin_key = new UserRoles(array('user_id' => $r['current_user_id'], 'role_id' => CONTEST_ADMIN_ROLE));
         $contests_admin = UserRolesDAO::search($contest_admin_key);
         foreach ($contests_admin as $contest_key) {
             $contest = ContestsDAO::getByPK($contest_key->getContestId());
             if (is_null($contest)) {
                 self::$log->error("UserRoles has a invalid contest: {$contest->getContestId()}");
                 continue;
             }
             $response['contests'][] = $contest->asArray();
         }
         usort($response['contests'], function ($a, $b) {
             return $a['contest_id'] > $b['contest_id'] ? -1 : 1;
         });
     } catch (Exception $e) {
         throw new InvalidDatabaseOperationException($e);
     }
     $response['status'] = 'ok';
     return $response;
 }
 /**
  * Details of a scoreboard. Returns a list with all contests that belong to
  * the given scoreboard_alias
  * 
  * @param Request $r
  */
 public static function apiDetails(Request $r)
 {
     self::validateGroupScoreboard($r);
     $response = array();
     // Fill contests
     $response["contests"] = array();
     $response["ranking"] = array();
     try {
         $groupScoreboardContestKey = new GroupsScoreboardsContests(array("group_scoreboard_id" => $r["scoreboard"]->group_scoreboard_id));
         $r["gscs"] = GroupsScoreboardsContestsDAO::search($groupScoreboardContestKey);
         $i = 0;
         $contest_params = array();
         foreach ($r["gscs"] as $gsc) {
             $contest = ContestsDAO::getByPK($gsc->contest_id);
             $response["contests"][$i] = $contest->asArray();
             $response["contests"][$i]["only_ac"] = $gsc->only_ac;
             $response["contests"][$i]["weight"] = $gsc->weight;
             // Fill contest params to pass to scoreboardMerge
             $contest_params[$contest->alias] = array("only_ac" => $gsc->only_ac == 0 ? false : true, "weight" => $gsc->weight);
             $i++;
         }
     } catch (ApiException $ex) {
         throw $ex;
     } catch (Exception $ex) {
         throw new InvalidDatabaseOperationException($ex);
     }
     $r["contest_params"] = $contest_params;
     // Fill details of this scoreboard
     $response["scoreboard"] = $r["scoreboard"]->asArray();
     // If we have contests, calculate merged&filtered scoreboard
     if (count($response["contests"]) > 0) {
         // Get merged scoreboard
         $r["contest_aliases"] = "";
         foreach ($response["contests"] as $contest) {
             $r["contest_aliases"] .= $contest["alias"] . ",";
         }
         $r["contest_aliases"] = rtrim($r["contest_aliases"], ",");
         try {
             $groupUsers = GroupsUsersDAO::search(new GroupsUsers(array("group_id" => $r["scoreboard"]->group_id)));
             $r["usernames_filter"] = "";
             foreach ($groupUsers as $groupUser) {
                 $user = UsersDAO::getByPK($groupUser->user_id);
                 $r["usernames_filter"] .= $user->username . ",";
             }
             $r["usernames_filter"] = rtrim($r["usernames_filter"], ",");
         } catch (Exception $ex) {
             throw new InvalidDatabaseOperationException($ex);
         }
         $mergedScoreboardResponse = ContestController::apiScoreboardMerge($r);
         $response["ranking"] = $mergedScoreboardResponse["ranking"];
     }
     $response["status"] = "ok";
     return $response;
 }
 /**
  * Invalidates relevant caches on run rejudge
  *
  * @param RunsDAO $run
  */
 public static function invalidateCacheOnRejudge(Runs $run)
 {
     try {
         // Expire details of the run
         Cache::deleteFromCache(Cache::RUN_ADMIN_DETAILS, $run->getRunId());
         $contest = ContestsDAO::getByPK($run->getContestId());
         // Now we need to invalidate problem stats
         $problem = ProblemsDAO::getByPK($run->getProblemId());
         if (!is_null($problem)) {
             // Invalidar cache stats
             Cache::deleteFromCache(Cache::PROBLEM_STATS, $problem->getAlias());
         }
     } catch (Exception $e) {
         // We did our best effort to invalidate the cache...
         self::$log->warn('Failed to invalidate cache on Rejudge, skipping: ');
         self::$log->warn($e);
     }
 }
 /**
  * Details of a scoreboard. Returns a list with all contests that belong to
  * the given scoreboard_alias
  *
  * @param Request $r
  */
 public static function apiDetails(Request $r)
 {
     self::validateGroupScoreboard($r);
     $response = array();
     // Fill contests
     $response['contests'] = array();
     $response['ranking'] = array();
     try {
         $groupScoreboardContestKey = new GroupsScoreboardsContests(array('group_scoreboard_id' => $r['scoreboard']->group_scoreboard_id));
         $r['gscs'] = GroupsScoreboardsContestsDAO::search($groupScoreboardContestKey);
         $i = 0;
         $contest_params = array();
         foreach ($r['gscs'] as $gsc) {
             $contest = ContestsDAO::getByPK($gsc->contest_id);
             $response['contests'][$i] = $contest->asArray();
             $response['contests'][$i]['only_ac'] = $gsc->only_ac;
             $response['contests'][$i]['weight'] = $gsc->weight;
             // Fill contest params to pass to scoreboardMerge
             $contest_params[$contest->alias] = array('only_ac' => $gsc->only_ac == 0 ? false : true, 'weight' => $gsc->weight);
             $i++;
         }
     } catch (ApiException $ex) {
         throw $ex;
     } catch (Exception $ex) {
         throw new InvalidDatabaseOperationException($ex);
     }
     $r['contest_params'] = $contest_params;
     // Fill details of this scoreboard
     $response['scoreboard'] = $r['scoreboard']->asArray();
     // If we have contests, calculate merged&filtered scoreboard
     if (count($response['contests']) > 0) {
         // Get merged scoreboard
         $r['contest_aliases'] = '';
         foreach ($response['contests'] as $contest) {
             $r['contest_aliases'] .= $contest['alias'] . ',';
         }
         $r['contest_aliases'] = rtrim($r['contest_aliases'], ',');
         try {
             $groupUsers = GroupsUsersDAO::search(new GroupsUsers(array('group_id' => $r['scoreboard']->group_id)));
             $r['usernames_filter'] = '';
             foreach ($groupUsers as $groupUser) {
                 $user = UsersDAO::getByPK($groupUser->user_id);
                 $r['usernames_filter'] .= $user->username . ',';
             }
             $r['usernames_filter'] = rtrim($r['usernames_filter'], ',');
         } catch (Exception $ex) {
             throw new InvalidDatabaseOperationException($ex);
         }
         $mergedScoreboardResponse = ContestController::apiScoreboardMerge($r);
         $response['ranking'] = $mergedScoreboardResponse['ranking'];
     }
     $response['status'] = 'ok';
     return $response;
 }