/** * Validates the request for AddToContest and returns an array with * the problem and contest DAOs * * @throws InvalidDatabaseOperationException * @throws InvalidParameterException * @throws ForbiddenAccessException */ private static function validateAddToContestRequest(Request $r) { Validators::isStringNonEmpty($r["contest_alias"], "contest_alias"); // Only director is allowed to create problems in contest try { $contest = ContestsDAO::getByAlias($r["contest_alias"]); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } if (is_null($contest)) { throw new InvalidParameterException("parameterNotFound", "contest_alias"); } // Only contest admin is allowed to create problems in contest if (!Authorization::IsContestAdmin($r["current_user_id"], $contest)) { throw new ForbiddenAccessException("cannotAddProb"); } Validators::isStringNonEmpty($r["problem_alias"], "problem_alias"); try { $problem = ProblemsDAO::getByAlias($r["problem_alias"]); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } if (is_null($problem)) { throw new InvalidParameterException("parameterNotFound", "problem_alias"); } if ($problem->getPublic() == '0' && !Authorization::CanEditProblem($r["current_user_id"], $problem)) { throw new ForbiddenAccessException("problemIsPrivate"); } Validators::isNumberInRange($r["points"], "points", 0, INF); Validators::isNumberInRange($r["order_in_contest"], "order_in_contest", 0, INF, false); return array("contest" => $contest, "problem" => $problem); }
$r['show_solvers'] = true; try { $result = ProblemController::apiDetails($r); $problem = ProblemsDAO::GetByAlias($result['alias']); } catch (ApiException $e) { header('HTTP/1.1 404 Not Found'); die(file_get_contents('../404.html')); } $smarty->assign('problem_statement', $result['problem_statement']); $smarty->assign('problem_statement_language', $result['problem_statement_language']); $smarty->assign('problem_alias', $result['alias']); $smarty->assign('public', $result['public']); $smarty->assign('source', $result['source']); $smarty->assign('title', $result['title']); $smarty->assign('points', $result['points']); $smarty->assign('validator', $result['validator']); $smarty->assign('time_limit', $result['time_limit'] / 1000 . 's'); $smarty->assign('validator_time_limit', $result['validator_time_limit'] / 1000 . 's'); $smarty->assign('overall_wall_time_limit', $result['overall_wall_time_limit'] / 1000 . 's'); $smarty->assign('memory_limit', $result['memory_limit'] / 1024 . 'MB'); $smarty->assign('solvers', $result['solvers']); $smarty->assign('karel_problem', count(array_intersect(explode(',', $result['languages']), array('kp', 'kj'))) == 2); if (isset($result['sample_input'])) { $smarty->assign('sample_input', $result['sample_input']); } $result['user'] = array('logged_in' => $session['valid'], 'admin' => Authorization::CanEditProblem($session['id'], $problem)); $smarty->assign('problem_admin', $result['user']['admin']); // Remove the largest element to reduce the payload. unset($result['problem_statement']); $smarty->assign('problem', json_encode($result)); $smarty->display('../../templates/arena.problem.tpl');
/** * Stats of a problem * * @param Request $r * @return array * @throws ForbiddenAccessException * @throws InvalidDatabaseOperationException */ public static function apiStats(Request $r) { // Get user self::authenticateRequest($r); // Validate request self::validateRuns($r); // We need to check that the user has priviledges on the problem if (!Authorization::CanEditProblem($r['current_user_id'], $r['problem'])) { throw new ForbiddenAccessException(); } try { // Array of GUIDs of pending runs $pendingRunsGuids = RunsDAO::GetPendingRunsOfProblem($r['problem']->getProblemId()); // Count of pending runs (int) $totalRunsCount = RunsDAO::CountTotalRunsOfProblem($r['problem']->getProblemId()); // List of verdicts $verdict_counts = array(); foreach (self::$verdicts as $verdict) { $verdict_counts[$verdict] = RunsDAO::CountTotalRunsOfProblemByVerdict($r['problem']->getProblemId(), $verdict); } // Array to count AC stats per case. // Let's try to get the last snapshot from cache. $problemStatsCache = new Cache(Cache::PROBLEM_STATS, $r['problem']->getAlias()); $cases_stats = $problemStatsCache->get(); if (is_null($cases_stats)) { // Initialize the array at counts = 0 $cases_stats = array(); $cases_stats['counts'] = array(); // We need to save the last_id that we processed, so next time we do not repeat this $cases_stats['last_id'] = 0; // Build problem dir $problem_dir = PROBLEMS_PATH . '/' . $r['problem']->getAlias() . '/cases/'; // Get list of cases $dir = opendir($problem_dir); if (is_dir($problem_dir)) { while (($file = readdir($dir)) !== false) { // If we have an input if (strstr($file, '.in')) { // Initialize it to 0 $cases_stats['counts'][str_replace('.in', '', $file)] = 0; } } closedir($dir); } } // Get all runs of this problem after the last id we had $runs = RunsDAO::searchRunIdGreaterThan(new Runs(array('problem_id' => $r['problem']->getProblemId())), $cases_stats['last_id'], 'run_id'); // For each run we got foreach ($runs as $run) { // Build grade dir $grade_dir = RunController::getGradePath($run); // Skip it if it failed to compile. if (file_exists("{$grade_dir}/compile_error.log")) { continue; } // Try to open the details file. if (file_exists("{$grade_dir}/details.json")) { $details = json_decode(file_get_contents("{$grade_dir}/details.json")); foreach ($details as $group) { foreach ($group->cases as $case) { if ($case->score > 0) { $cases_stats['counts'][$case->name]++; } } } } } } catch (Exception $e) { throw new InvalidDatabaseOperationException($e); } // Save the last id we saw in case we saw something if (!is_null($runs) && count($runs) > 0) { $cases_stats['last_id'] = $runs[count($runs) - 1]->getRunId(); } // Save in cache what we got $problemStatsCache->set($cases_stats, APC_USER_CACHE_PROBLEM_STATS_TIMEOUT); return array('total_runs' => $totalRunsCount, 'pending_runs' => $pendingRunsGuids, 'verdict_counts' => $verdict_counts, 'cases_stats' => $cases_stats['counts'], 'status' => 'ok'); }