示例#1
0
    def patch_submission(submission):
        """
        Given a submission from a SQL query with some JOIN create a dict by
        splitting the keys using _
        :param submission: A dict with the submission
        :return: A dict with some properties nested
        """
        result = {}

        for k, v in submission.items():
            if "_" in k:
                a, b = k.split("_")
                if a not in result:
                    result[a] = {}
                result[a][b] = v
            else:
                result[k] = v

        feedback = json.loads(result["output"]["result"].decode())
        result["feedback"] = feedback["feedback"]
        temp = InfoHandler.patch_output(result["output"])

        del result["output"]
        result = BaseHandler.format_dates(result)
        result["output"] = temp

        return result
示例#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))
    def upload_source(self, input, file):
        """
        POST /upload_source
        """
        alerts = []
        if get_exeflags(file["content"]):
            alerts.append({
                "severity": "warning",
                "message": "You have submitted an executable! Please send the "
                           "source code."
            })
            Logger.info("UPLOAD",
                        "User %s has uploaded an executable" % input["token"])
        if not alerts:
            alerts.append({
                "severity": "success",
                "message": "Source file uploaded correctly."
            })

        source_id = Database.gen_id()
        try:
            path = StorageManager.new_source_file(source_id, file["name"])
        except ValueError:
            BaseHandler.raise_exc(BadRequest, "INVALID_FILENAME",
                                  "The provided file has an invalid name")

        StorageManager.save_file(path, file["content"])
        file_size = StorageManager.get_file_size(path)

        Database.add_source(source_id, input["id"], path, file_size)
        Logger.info("UPLOAD", "User %s has uploaded the source %s" % (
            input["token"], source_id))
        output = BaseHandler.format_dates(Database.get_source(source_id))
        output["validation"] = {"alerts": alerts}
        return output
示例#4
0
    def start(self):
        """
        POST /admin/start
        """
        if Database.get_meta("start_time", default=None, type=int) is not None:
            BaseHandler.raise_exc(Forbidden, "FORBIDDEN",
                                  "Contest has already been started!")

        start_time = int(time.time())
        Database.set_meta("start_time", start_time)
        Logger.info("CONTEST", "Contest started")
        return BaseHandler.format_dates({"start_time": start_time},
                                        fields=["start_time"])
示例#5
0
    def status(self):
        """
        POST /admin/status
        """
        start_time = Database.get_meta('start_time', type=int)
        extra_time = Database.get_meta('extra_time', type=int, default=0)
        end_time = BaseHandler.get_end_time(0)

        return BaseHandler.format_dates(
            {
                "start_time": start_time,
                "extra_time": extra_time,
                "end_time": end_time,
                "loaded": ContestManager.has_contest
            },
            fields=["start_time", "end_time"])
示例#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"])
示例#7
0
    def patch_output(output):
        """
        Given an output remove the private fields
        :param output: A dict from the outputs database table
        :return: The formatted and sanitized dict
        """
        result = {
            "id": output["id"],
            "date": output["date"],
            "path": output["path"],
            "size": output["size"],
            "validation": json.loads(output["result"].decode())["validation"],
        }

        if "input" in output:
            result["input"] = output["input"]

        return BaseHandler.format_dates(result)
示例#8
0
    def log(self,
            start_date: str,
            end_date: str,
            level: str,
            category: str = None):
        """
        POST /admin/log
        """
        if level not in Logger.HUMAN_MESSAGES:
            self.raise_exc(BadRequest, "INVALID_PARAMETER",
                           "The level provided is invalid")
        level = Logger.HUMAN_MESSAGES.index(level)

        try:
            start_date = dateutil.parser.parse(start_date).timestamp()
            end_date = dateutil.parser.parse(end_date).timestamp()
        except ValueError as e:
            BaseHandler.raise_exc(BadRequest, "INVALID_PARAMETER", str(e))
        return BaseHandler.format_dates(
            {"items": Logger.get_logs(level, category, start_date, end_date)})
示例#9
0
    def start(self, start_time: str):
        """
        POST /admin/start
        """
        previous_start = Database.get_meta("start_time", type=int)
        now = int(time.time())
        if previous_start and now > previous_start:
            BaseHandler.raise_exc(Forbidden, "FORBIDDEN",
                                  "Contest has already been started!")

        actual_start = None
        if start_time == "reset":
            Database.del_meta("start_time")
            return {"start_time": None}
        elif start_time == "now":
            actual_start = now
        else:
            actual_start = dateutil.parser.parse(start_time).timestamp()
        Database.set_meta("start_time", int(actual_start))
        Logger.info("CONTEST", "Contest starts at " + str(actual_start))
        return BaseHandler.format_dates({"start_time": actual_start},
                                        fields=["start_time"])
 def test_format_dates(self):
     dct = {
         "date": 12345678,
         "nondate": 12345678,
         "we": {
             "need": {
                 "to": {
                     "go": {
                         "deeper": 1010101010
                     }
                 }
             }
         }
     }
     formatted = BaseHandler.format_dates(dct, fields=["date", "deeper"])
     self.assertEqual(
         datetime.datetime.fromtimestamp(12345678).isoformat(),
         formatted["date"])
     self.assertEqual(12345678, formatted["nondate"])
     self.assertEqual(
         datetime.datetime.fromtimestamp(1010101010).isoformat(),
         formatted["we"]["need"]["to"]["go"]["deeper"])
示例#11
0
 def get_source(self, source):
     """
     GET /source/<source_id>
     """
     return BaseHandler.format_dates(source)
示例#12
0
 def get_input(self, input):
     """
     GET /input/<input_id>
     """
     return BaseHandler.format_dates(input)
示例#13
0
 def user_list(self):
     """
     POST /admin/user_list
     """
     return BaseHandler.format_dates({"items": Database.get_users()},
                                     fields=["first_date"])