예제 #1
0
    def test_input_invalid_params(self):
        Database.connected = False
        Database.connect_to_database()

        with self.assertRaises(ValueError) as ex:
            Database.get_input()

        self.assertEqual("Invalid parameters to get_input",
                         ex.exception.args[0])
예제 #2
0
    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))
예제 #3
0
 def _guess_token(**kwargs):
     if "token" in kwargs:
         return kwargs["token"]
     elif "input_id" in kwargs:
         input = Database.get_input(kwargs["input_id"])
         if input: return input["token"]
     elif "output_id" in kwargs:
         output = Database.get_output(kwargs["output_id"])
         if output:
             input = Database.get_input(output["input"])
             if input: return input["token"]
     elif "source_id" in kwargs:
         source = Database.get_source(kwargs["source_id"])
         if source:
             input = Database.get_input(source["input"])
             if input: return input["token"]
     elif "submission_id" in kwargs:
         submission = Database.get_submission(kwargs["submission_id"])
         if submission: return submission["token"]
     return None
예제 #4
0
 def test_generate_input_transaction_broken(self, register_mock,
                                            get_file_size_mock,
                                            get_input_mock):
     Utils.start_contest()
     self._insert_data()
     with self.assertRaises(Exception) as ex:
         with patch("terry.database.Database.commit",
                    side_effect=Exception("ops...")):
             self.handler.generate_input(token='token',
                                         task='poldo',
                                         _ip='1.1.1.1')
     self.assertIn("ops...", ex.exception.args[0])
     self.assertIsNone(Database.get_input("inputid"))
예제 #5
0
    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))
예제 #6
0
    def get_user(self, user):
        """
        GET /user/<token>
        """
        token = user["token"]

        user["contest"] = self.get_contest()

        if not user["contest"]["has_started"]:
            del user["extra_time"]
            return user

        end_time = InfoHandler.get_end_time(user["extra_time"])
        if user["contest_start_delay"] is not None:
            end_time = min(
                end_time,
                InfoHandler.get_window_end_time(user["extra_time"],
                                                user["contest_start_delay"]),
            )

        user["end_time"] = end_time
        del user["extra_time"]
        user["tasks"] = {}

        tasks = Database.get_user_task(token)
        for task in tasks:
            task_name = task["task"]

            if task["current_attempt"] is not None:
                current_input = Database.get_input(
                    token=token,
                    task=task_name,
                    attempt=task["current_attempt"])
            else:
                current_input = None

            user["tasks"][task_name] = {
                "name": task_name,
                "score": task["score"],
                "current_input": current_input,
            }

        user["total_score"] = sum(task["score"] for task in tasks)

        return BaseHandler.format_dates(user, fields=["end_time"])