/** * Gets the user that solved more problems during last month * * @global type $conn * @param string (date) $firstDay * @return null|Users */ public static function calculateCoderOfTheMonth($firstDay) { $endTime = $firstDay; $startTime = null; $lastMonth = intval(date('m')) - 1; if ($lastMonth === 0) { // First month of the year, we need to check into last month of last year. $lastYear = intval(date('Y')) - 1; $startTime = date($lastYear . '-12-01'); } else { $startTime = date('Y-' . $lastMonth . '-01'); } $sql = "\n\t\t\tSELECT\n\t\t\t\tusername, name, up.user_id, COUNT(ps.problem_id) ProblemsSolved, SUM(ROUND(100 / LOG(2, ps.accepted+1) , 0)) score\n\t\t\tFROM\n\t\t\t\t(\n\t\t\t\t\tSELECT DISTINCT\n\t\t\t\t\t\tr.user_id, r.problem_id\n\t\t\t\t\tFROM\n\t\t\t\t\t\tRuns r\n\t\t\t\t\tWHERE\n\t\t\t\t\t\tr.verdict = 'AC' AND r.test = 0 AND \n\t\t\t\t\t\tr.time >= ? AND \n\t\t\t\t\t\tr.time <= ?\n\t\t\t\t) AS up\n\t\t\tINNER JOIN\n\t\t\t\tProblems ps ON ps.problem_id = up.problem_id and ps.public = 1\n\t\t\tINNER JOIN\n\t\t\t\tUsers u ON u.user_id = up.user_id \n\t\t\tGROUP BY\n\t\t\t\tuser_id\n\t\t\tORDER BY\n\t\t\t\tscore DESC\n\t\t\tLIMIT 1\n\t\t"; $val = array($startTime, $endTime); global $conn; $rs = $conn->GetRow($sql, $val); if (count($rs) == 0) { return NULL; } $totalCount = $rs['ProblemsSolved']; $user = UsersDAO::getByPK($rs['user_id']); $score = $rs['score']; return array("totalCount" => $totalCount, "user" => $user, "score" => $score); }
/** * Test that we are able to submit a problem without testplan */ public function testValidProblemNoTestplan() { // Get the problem data $problemData = ProblemsFactory::getRequest(OMEGAUP_RESOURCES_ROOT . 'triangulos.zip'); $r = $problemData['request']; $problemAuthor = $problemData['author']; // Login user $r['auth_token'] = $this->login($problemAuthor); // Get File Uploader Mock and tell Omegaup API to use it FileHandler::SetFileUploader($this->createFileUploaderMock()); // Call the API $response = ProblemController::apiCreate($r); // Validate // Verify response $this->assertEquals('ok', $response['status']); $this->assertEquals('cases/1.in', $response['uploaded_files'][0]); // Verify data in DB $problem_mask = new Problems(); $problem_mask->setTitle($r['title']); $problems = ProblemsDAO::search($problem_mask); // Check that we only retreived 1 element $this->assertEquals(1, count($problems)); $problem = $problems[0]; // Verify contest was found $this->assertNotNull($problem); $this->assertNotNull($problem->getProblemId()); // Verify DB data $this->assertEquals($r['title'], $problem->getTitle()); $this->assertEquals(substr($r['title'], 0, 32), $problem->getAlias()); $this->assertEquals($r['validator'], $problem->getValidator()); $this->assertEquals($r['time_limit'], $problem->getTimeLimit()); $this->assertEquals($r['memory_limit'], $problem->getMemoryLimit()); $this->assertEquals($r['order'], $problem->getOrder()); $this->assertEquals($r['source'], $problem->getSource()); // Verify author username -> author id conversion $user = UsersDAO::getByPK($problem->getAuthorId()); $this->assertEquals($user->getUsername(), $r['author_username']); // Verify problem contents were copied $targetpath = PROBLEMS_PATH . DIRECTORY_SEPARATOR . $problem->getAlias() . DIRECTORY_SEPARATOR; $this->assertFileExists($targetpath . 'cases'); $this->assertFileExists($targetpath . 'statements' . DIRECTORY_SEPARATOR . 'es.html'); // Default data $this->assertEquals(0, $problem->getVisits()); $this->assertEquals(0, $problem->getSubmissions()); $this->assertEquals(0, $problem->getAccepted()); $this->assertEquals(0, $problem->getDifficulty()); }
/** * Returns the list of coders of the month * * @param Request $r */ public static function apiCoderOfTheMonthList(Request $r) { $response = array(); $response['coders'] = array(); try { $coders = CoderOfTheMonthDAO::getAll(null, null, 'time', 'DESC'); foreach ($coders as $c) { $user = UsersDAO::getByPK($c->user_id); $email = EmailsDAO::getByPK($user->getMainEmailId()); $response['coders'][] = array('username' => $user->getUsername(), 'gravatar_32' => 'https://secure.gravatar.com/avatar/' . md5($email->getEmail()) . '?s=32', 'date' => $c->getTime()); } } catch (Exception $ex) { 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; }
public function LoginViaFacebook() { //ok, the user does not have any auth token //if he wants to test facebook login //Facebook must send me the state=something //query, so i dont have to be testing //facebook sessions on every single petition //made from the front-end if (!isset($_GET['state'])) { return false; } //if that is not true, may still be logged with //facebook, lets test that $facebook = self::getFacebookInstance(); // Get User ID $fb_user = $facebook->getUser(); if ($fb_user == 0) { self::$log->info('FB session unavailable.'); return false; } // We may or may not have this data based on whether the user is logged in. // If we have a $fb_user id here, it means we know the user is logged into // Facebook, but we don't know if the access token is valid. An access // token is invalid if the user logged out of Facebook. try { // Proceed knowing you have a logged in user who's authenticated. $fb_user_profile = $facebook->api('/me'); } catch (FacebookApiException $e) { $fb_user = null; self::$log->error('FacebookException:' . $e); return false; } //ok we know the user is logged in, //lets look for his information on the database //if there is none, it means that its the first //time the user has been here, lets register his info self::$log->info('User is logged in via facebook !!'); $results = UsersDAO::FindByEmail($fb_user_profile['email']); if (!is_null($results)) { //user has been here before with facebook! $vo_User = $results; self::$log->info('user has been here before with facebook!'); } else { // The user has never been here before, let's register him // I have a problem with this: $username = self::getUniqueUsernameFromEmail($fb_user_profile['email']); // Even if the user gave us his/her email, we should not // just go ahead and assume its ok to share with the world // maybe we could do: // $username = str_replace(" ", "_", $fb_user_profile["name"] ), UserController::$permissionKey = uniqid(); $r = new Request(array('name' => $fb_user_profile['name'], 'username' => $username, 'email' => $fb_user_profile['email'], 'facebook_user_id' => $fb_user_profile['id'], 'password' => null, 'permission_key' => UserController::$permissionKey, 'ignore_password' => true)); try { $res = UserController::apiCreate($r); } catch (ApiException $e) { self::$log->error('Unable to login via Facebook ' . $e); return false; } $vo_User = UsersDAO::getByPK($res['user_id']); } //since we got here, this user does not have //any auth token, lets give him one //so we dont have to call facebook to see //if he is still logged in, and he can call //the api $this->RegisterSession($vo_User); }
/** * Returns ALL users participating in a contest * * @param Request $r * @return array * @throws InvalidDatabaseOperationException */ public static function apiUsers(Request $r) { // Authenticate request self::authenticateRequest($r); Validators::isStringNonEmpty($r["contest_alias"], "contest_alias"); try { $contest = ContestsDAO::getByAlias($r["contest_alias"]); } catch (Exception $e) { throw new InvalidDatabaseOperationException($e); } if (!Authorization::IsContestAdmin($r["current_user_id"], $contest)) { throw new ForbiddenAccessException(); } // Get users from DB $contest_user_key = new ContestsUsers(); $contest_user_key->setContestId($contest->getContestId()); try { $db_results = ContestsUsersDAO::search($contest_user_key); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } $users = array(); // Add all users to an array foreach ($db_results as $result) { $user_id = $result->getUserId(); $user = UsersDAO::getByPK($user_id); $users[] = array("user_id" => $user_id, "username" => $user->getUsername(), 'access_time' => $result->access_time, 'country' => $user->getCountryId()); } $response = array(); $response["users"] = $users; $response["status"] = "ok"; return $response; }
/** * Entry point for Problem Details API * * @param Request $r * @throws InvalidFilesystemOperationException * @throws InvalidDatabaseOperationException */ public static function apiDetails(Request $r) { // Get user. // Allow unauthenticated requests if we are not openning a problem // inside a contest. try { self::authenticateRequest($r); } catch (UnauthorizedException $e) { if (!is_null($r['contest_alias'])) { throw $e; } } // Validate request self::validateDetails($r); $response = array(); // Create array of relevant columns $relevant_columns = array('title', 'alias', 'validator', 'time_limit', 'validator_time_limit', 'overall_wall_time_limit', 'extra_wall_time', 'memory_limit', 'output_limit', 'visits', 'submissions', 'accepted', 'difficulty', 'creation_date', 'source', 'order', 'points', 'public', 'languages', 'slow', 'stack_limit', 'email_clarifications'); // Read the file that contains the source if (!ProblemController::isLanguageSupportedForProblem($r)) { // If there is no language file for the problem, return the spanish version. $r['lang'] = 'es'; } $statement_type = ProblemController::getStatementType($r); Cache::getFromCacheOrSet(Cache::PROBLEM_STATEMENT, $r['problem']->getAlias() . '-' . $r['lang'] . '-' . $statement_type, $r, 'ProblemController::getProblemStatement', $file_content, APC_USER_CACHE_PROBLEM_STATEMENT_TIMEOUT); // Add problem statement to source $response['problem_statement'] = $file_content; $response['problem_statement_language'] = $r['lang']; // Add the example input. $sample_input = null; Cache::getFromCacheOrSet(Cache::PROBLEM_SAMPLE, $r['problem']->getAlias() . '-sample.in', $r, 'ProblemController::getSampleInput', $sample_input, APC_USER_CACHE_PROBLEM_STATEMENT_TIMEOUT); if (!empty($sample_input)) { $response['sample_input'] = $sample_input; } // Add the problem the response $response = array_merge($response, $r['problem']->asFilteredArray($relevant_columns)); // If the problem is public or if the user has admin privileges, show the // problem source and alias of owner. if ($r['problem']->public || Authorization::IsProblemAdmin($r['current_user_id'], $r['problem'])) { $problemsetter = UsersDAO::getByPK($r['problem']->author_id); if (!is_null($problemsetter)) { $response['problemsetter'] = array('username' => $problemsetter->username, 'name' => is_null($problemsetter->name) ? $problemsetter->username : $problemsetter->name); } } else { unset($response['source']); } if (!is_null($r['current_user_id'])) { // Create array of relevant columns for list of runs $relevant_columns = array('guid', 'language', 'status', 'verdict', 'runtime', 'penalty', 'memory', 'score', 'contest_score', 'time', 'submit_delay'); // Search the relevant runs from the DB $contest = ContestsDAO::getByAlias($r['contest_alias']); $keyrun = new Runs(array('user_id' => $r['current_user_id'], 'problem_id' => $r['problem']->getProblemId(), 'contest_id' => is_null($r['contest']) ? null : $r['contest']->getContestId())); // Get all the available runs done by the current_user try { $runs_array = RunsDAO::search($keyrun); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } // Add each filtered run to an array if (count($runs_array) >= 0) { $runs_filtered_array = array(); foreach ($runs_array as $run) { $filtered = $run->asFilteredArray($relevant_columns); $filtered['alias'] = $r['problem']->alias; $filtered['username'] = $r['current_user']->username; $filtered['time'] = strtotime($filtered['time']); array_push($runs_filtered_array, $filtered); } } $response['runs'] = $runs_filtered_array; } if (!is_null($r['contest'])) { // At this point, contestant_user relationship should be established. try { ContestsUsersDAO::CheckAndSaveFirstTimeAccess($r['current_user_id'], $r['contest']->contest_id); } catch (ApiException $e) { throw $e; } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } // As last step, register the problem as opened if (!ContestProblemOpenedDAO::getByPK($r['contest']->getContestId(), $r['problem']->getProblemId(), $r['current_user_id'])) { //Create temp object $keyContestProblemOpened = new ContestProblemOpened(array('contest_id' => $r['contest']->getContestId(), 'problem_id' => $r['problem']->getProblemId(), 'user_id' => $r['current_user_id'])); try { // Save object in the DB ContestProblemOpenedDAO::save($keyContestProblemOpened); } catch (Exception $e) { // Operation failed in the data layer throw new InvalidDatabaseOperationException($e); } } } elseif (isset($r['show_solvers']) && $r['show_solvers']) { $response['solvers'] = RunsDAO::GetBestSolvingRunsForProblem($r['problem']->problem_id); } if (!is_null($r['current_user_id'])) { ProblemViewedDAO::MarkProblemViewed($r['current_user_id'], $r['problem']->problem_id); } $response['score'] = self::bestScore($r); $response['status'] = 'ok'; return $response; }
/** * Details of a group (users in a group) * * @param Request $r */ public static function apiDetails(Request $r) { self::validateGroupAndOwner($r); $response = array(); $response["group"] = array(); $response["users"] = array(); $response["scoreboards"] = array(); try { $response["group"] = $r["group"]->asArray(); $userGroups = GroupsUsersDAO::search(new GroupsUsers(array("group_id" => $r["group"]->group_id))); foreach ($userGroups as $userGroup) { $r["user"] = UsersDAO::getByPK($userGroup->user_id); $userProfile = UserController::getProfile($r); $response["users"][] = $userProfile; } $scoreboards = GroupsScoreboardsDAO::search(new GroupsScoreboards(array("group_id" => $r["group"]->group_id))); foreach ($scoreboards as $scoreboard) { $response["scoreboards"][] = $scoreboard->asArray(); } } catch (Exception $ex) { throw new InvalidDatabaseOperationException($ex); } $response["status"] = "ok"; return $response; }
/** * Returns the list of coders of the month * * @param Request $r */ public static function apiCoderOfTheMonthList(Request $r) { $response = array(); $response["coders"] = array(); try { $coders = CoderOfTheMonthDAO::getAll(null, null, "time", "DESC"); foreach ($coders as $c) { $user = UsersDAO::getByPK($c->user_id); $email = EmailsDAO::getByPK($user->getMainEmailId()); $response["coders"][] = array("username" => $user->getUsername(), "gravatar_32" => "https://secure.gravatar.com/avatar/" . md5($email->getEmail()) . "?s=32", "date" => $c->getTime()); } } catch (Exception $ex) { 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; }