def generate_input(self, task, user): """ POST /generate_input """ token = user["token"] if Database.get_user_task(token, task["name"])["current_attempt"]: self.raise_exc(Forbidden, "FORBIDDEN", "You already have a ready input!") attempt = Database.get_next_attempt(token, task["name"]) id, path = ContestManager.get_input(task["name"], attempt) size = StorageManager.get_file_size(path) Database.begin() try: Database.add_input(id, token, task["name"], attempt, path, size, autocommit=False) Database.set_user_attempt(token, task["name"], attempt, autocommit=False) Database.commit() except: Database.rollback() raise Logger.info( "CONTEST", "Generated input %s for user %s on task %s" % (id, token, task["name"])) return BaseHandler.format_dates(Database.get_input(id=id))
def submit(self, output, source): """ POST /submit """ input = Database.get_input(output["input"]) if input is None: Logger.warning("DB_CONSISTENCY_ERROR", "Input %s not found in the db" % output["input"]) self.raise_exc(BadRequest, "WRONG_INPUT", "The provided input in invalid") if output["input"] != source["input"]: Logger.warning("POSSIBLE_CHEAT", "Trying to submit wrong pair source-output") self.raise_exc(Forbidden, "WRONG_OUTPUT_SOURCE", "The provided pair of source-output is invalid") score = ContestHandler.compute_score(input["task"], output["result"]) Database.begin() try: submission_id = Database.gen_id() if not Database.add_submission(submission_id, input["id"], output["id"], source["id"], score, autocommit=False): self.raise_exc(BadRequest, "INTERNAL_ERROR", "Error inserting the submission") ContestHandler.update_user_score(input["token"], input["task"], score) Database.set_user_attempt(input["token"], input["task"], None, autocommit=False) Database.commit() except sqlite3.IntegrityError as ex: Database.rollback() # provide a better error message if the input has already been # submitted if "UNIQUE constraint failed: submissions.input" in str(ex): self.raise_exc(Forbidden, "ALREADY_SUBMITTED", "This input has already been submitted") raise except: Database.rollback() raise Logger.info( "CONTEST", "User %s has submitted %s on %s" % (input["token"], submission_id, input["task"])) return InfoHandler.patch_submission( Database.get_submission(submission_id))
def test_get_user_windowed_partial_window(self): now = int(datetime.utcnow().timestamp()) Database.set_meta("start_time", now) Database.set_meta("contest_duration", 1000) Database.set_meta("window_duration", 100) Database.add_user("token", "", "") Database.set_start_delay("token", 990) Database.add_task("poldo", "", "", 42, 1) Database.add_user_task("token", "poldo") Database.add_input("inputid", "token", "poldo", 1, "/path", 42) Database.set_user_attempt("token", "poldo", 1) res = self.handler.get_user(token="token", _ip="1.1.1.1") end_time = datetime.fromtimestamp(now + 1000, timezone.utc).isoformat() self.assertEqual(end_time, res["end_time"])
def test_get_user_windowed_almost_finished(self): now = int(datetime.datetime.now().timestamp()) Database.set_meta("start_time", now - 90) Database.set_meta("contest_duration", 1000) Database.set_meta("window_duration", 100) Database.add_user("token", "", "") Database.set_start_delay("token", 10) Database.add_task("poldo", "", "", 42, 1) Database.add_user_task("token", "poldo") Database.add_input("inputid", "token", "poldo", 1, "/path", 42) Database.set_user_attempt("token", "poldo", 1) res = self.handler.get_user(token="token", _ip="1.1.1.1") end_time = datetime.datetime.fromtimestamp(now + 20).strftime( '%Y-%m-%dT%H:%M:%S') self.assertEqual(end_time, res["end_time"])
def test_get_user(self): now = int(datetime.utcnow().timestamp()) Database.set_meta("start_time", now) Database.set_meta("contest_duration", 1000) Database.set_meta("extra_time", 50) Database.add_user("token", "", "") Database.set_extra_time("token", 30) Database.add_task("poldo", "", "", 42, 1) Database.add_user_task("token", "poldo") Database.add_input("inputid", "token", "poldo", 1, "/path", 42) Database.set_user_attempt("token", "poldo", 1) res = self.handler.get_user(token="token", _ip="1.1.1.1") end_time = datetime.fromtimestamp(now + 1080, timezone.utc).isoformat() self.assertEqual(end_time, res["end_time"]) self.assertEqual("poldo", res["tasks"]["poldo"]["name"]) self.assertEqual("inputid", res["tasks"]["poldo"]["current_input"]["id"])