Beispiel #1
0
def create_problem(db: Session, Problem: schemas.ProblemBase):
    temp = Problem.dict()
    db_obj = models.Problem(**temp)
    db.add(db_obj)
    db.commit()
    db.refresh(db_obj)
    return db_obj
Beispiel #2
0
def add_problem():
	problem = request.form.get('problem')
	newProblem = models.Problem()
	newProblem.name = problem
	newProblem.save()
	json = '{"' + str(newProblem.id) + '":"' + str(newProblem.name) + '"}'
	resp = flask.Response(response=json, status=200, headers=None, mimetype='application/json', content_type=None, direct_passthrough=False)
	return resp
Beispiel #3
0
    def test_work_through_prob2(self):
        # 54 * 199 = 10746
        prob = models.Problem(54, 199)
        expected_width = 2
        actual_width = prob.working_grid.width
        self.assertEqual(expected_width, actual_width)

        expected_ans_array = [6, 4, 7, 0, 1]
        actual_ans_array = prob.final_answer.answer_arr
        self.assertEqual(expected_ans_array, actual_ans_array)
Beispiel #4
0
    def test_work_through_prob1(self):
        # 386 * 27 = 9126
        prob = models.Problem(386, 27)
        expected_width = 3
        actual_width = prob.working_grid.width
        self.assertEqual(expected_width, actual_width)

        expected_ans_array = [2, 2, 4, 0, 1]
        actual_ans_array = prob.final_answer.answer_arr
        self.assertEqual(expected_ans_array, actual_ans_array)
Beispiel #5
0
    async def add(self, info):
        if not await has_perm(info['bot'], info['channel'], info['user'],
                              "add problems"):
            return
        content = info['content']
        if len(content) == 1 and content[0].lower() == "help":
            em = Embed(title="Problem Adding Help",
                       description="Details on how to add a problem.",
                       color=BOT_COLOUR)
            for x in Problem.command_help["add"]:
                em.add_field(name=x[0], value=x[1])
            await info['bot'].send_message(info['channel'], embed=em)
            return

        try:
            if len(info['message'].attachments) != 1:
                await info['bot'].send_message(
                    info['channel'],
                    "Please upload one file for the problem statement.")
                return
            elif len(content) < 5:
                raise IndexError
            problem_code = content[0].lower()
            name = " ".join(content[1:-3])
            point_value, time_limit, memory_limit = map(int, content[-3:])
        except (KeyError, ValueError, IndexError, requests.HTTPError):
            await info['bot'].send_message(
                info['channel'],
                "Failed to parse the message content to create a new problem. Please try again."
            )

        with await database.locks["problem"][problem_code]:
            if problem_code in database.problem_list.keys():
                await info['bot'].send_message(
                    info['channel'],
                    "A problem with problem code `{}` already exists. Please try again."
                    .format(problem_code))
                return
            id = database.add_problem(
                models.Problem(None, name, problem_code, info['user'].id,
                               time_limit, memory_limit, point_value))
            with open("problems/{0}.pdf".format(id), "wb") as f:
                f.write(
                    requests.get(
                        info['message'].attachments[0]['url']).content)
        await info['bot'].delete_message(info['message'])
        await info['bot'].send_message(
            info['channel'],
            "Problem `{}` successfully created!".format(problem_code))
Beispiel #6
0
def create_test_db():
    t = models.Notice("Game Start!")
    db_session.add(t)

    t = models.User("admin", "admin", "admin", 2)
    t.is_admin = True
    db_session.add(t)

    for i in xrange(5):
        t = models.User("guest%d" % i, "guest", "guest", 1)
        db_session.add(t)

    r = config.category
    for i in xrange(16):
        cate = r[0] if i < 4 else (r[1] if i < 8 else
                                   (r[2] if i < 12 else
                                    (r[3] if i < 15 else r[4])))
        t = models.Problem("prob" + str(i), "AAAA", cate, "flag%d" % i)
        db_session.add(t)

    db_session.commit()
Beispiel #7
0
class Problem(BaseHandler):
    command_help = {}
    command_help["add"] = [
        [
            "Command", "`" + COMMAND_PREFIX +
            "problem add (problem code) (problem name) (point value) (time limit) (memory limit)`"
        ],
        [
            "Details",
            "Please include a file when adding the problem as the problem statement."
        ],
        [
            "problem code",
            "The problem code that the problem should have. This should be unique with all problems."
        ],
        ["problem name", "The user readable problem name."],
        [
            "point value",
            "An integer value for the point value of the problem."
        ],
        [
            "time limit",
            "An integer value for the time limit (in seconds) of the problem."
        ],
        [
            "memory limit",
            "An integer value for the memory limit (in kilobytes) of the problem."
        ],
    ]
    command_help["change"] = [
        [
            "Command", "`" + COMMAND_PREFIX +
            "problem change (problem code) (field to change) (new value)`"
        ],
        ["problem code", "The problem code for the problem to change."],
        [
            "field to change",
            "The field in the problem to change. Possible fields are: [`" +
            "`, `".join(
                set(models.Problem().__dict__.keys()) -
                unchangeable_problem_fields) + "`]"
        ],
        ["new value", "The new value for the field specified."],
    ]

    async def list(self, info):
        current_list, page_num = await get_current_list(
            info, list(database.problem_list.values()), 35)
        current_list.sort(key=lambda x: x.name)
        if current_list is None:
            return
        em = Embed(title="Problems",
                   description="Problem page {}".format(page_num),
                   color=BOT_COLOUR)
        em.add_field(name="Problem Name",
                     value='\n'.join(x.name for x in current_list))
        em.add_field(name="Problem Code",
                     value='\n'.join(x.code for x in current_list))
        em.add_field(name="Is Public",
                     value='\n'.join("Y" if x.is_public else "N"
                                     for x in current_list))
        await info['bot'].send_message(info['channel'], embed=em)

    async def view(self, info, in_contest=False):
        try:
            problem_code = info['content'][0].lower()
            problem = database.problem_list[problem_code]
        except KeyError:
            await info['bot'].send_message(
                info['channel'], "Please enter a valid problem code.")
            return
        except IndexError:
            await info['bot'].send_message(info['channel'],
                                           "Please enter a problem code.")
            return
        with await database.locks["problem"][problem_code]:
            if not await has_perm(info['bot'], info['channel'], info['user'],
                                  "view this problem", not problem.is_public
                                  and not in_contest):
                return
            description = "Details on problem `{}`".format(
                problem.code) if not in_contest else info['description']
            em = Embed(title="Problem Info",
                       description=description,
                       color=BOT_COLOUR)
            em.add_field(name="Problem Name", value=problem.name)
            em.add_field(name="Problem Code", value=problem.code)
            em.add_field(name="Point Value",
                         value="{}p".format(
                             problem.point_value if not in_contest else 100))
            em.add_field(name="Time Limit",
                         value="{}s".format(problem.time_limit))
            em.add_field(name="Memory Limit",
                         value=to_memory(problem.memory_limit))
            if not in_contest and info['user'].is_admin:
                em.add_field(name="Is Public",
                             value="Y" if problem.is_public else "N")

        await info['bot'].send_message(info['user'].discord_user, embed=em)
        await info['bot'].send_file(info['user'].discord_user, problem.file)
        await info['bot'].send_message(
            info['channel'],
            "{}, problem statement has been sent to your private messages.".
            format(info['user'].discord_user.mention))

    async def add(self, info):
        if not await has_perm(info['bot'], info['channel'], info['user'],
                              "add problems"):
            return
        content = info['content']
        if len(content) == 1 and content[0].lower() == "help":
            em = Embed(title="Problem Adding Help",
                       description="Details on how to add a problem.",
                       color=BOT_COLOUR)
            for x in Problem.command_help["add"]:
                em.add_field(name=x[0], value=x[1])
            await info['bot'].send_message(info['channel'], embed=em)
            return

        try:
            if len(info['message'].attachments) != 1:
                await info['bot'].send_message(
                    info['channel'],
                    "Please upload one file for the problem statement.")
                return
            elif len(content) < 5:
                raise IndexError
            problem_code = content[0].lower()
            name = " ".join(content[1:-3])
            point_value, time_limit, memory_limit = map(int, content[-3:])
        except (KeyError, ValueError, IndexError, requests.HTTPError):
            await info['bot'].send_message(
                info['channel'],
                "Failed to parse the message content to create a new problem. Please try again."
            )

        with await database.locks["problem"][problem_code]:
            if problem_code in database.problem_list.keys():
                await info['bot'].send_message(
                    info['channel'],
                    "A problem with problem code `{}` already exists. Please try again."
                    .format(problem_code))
                return
            id = database.add_problem(
                models.Problem(None, name, problem_code, info['user'].id,
                               time_limit, memory_limit, point_value))
            with open("problems/{0}.pdf".format(id), "wb") as f:
                f.write(
                    requests.get(
                        info['message'].attachments[0]['url']).content)
        await info['bot'].delete_message(info['message'])
        await info['bot'].send_message(
            info['channel'],
            "Problem `{}` successfully created!".format(problem_code))

    async def change(self, info):
        if not await has_perm(info['bot'], info['channel'], info['user'],
                              "change problems"):
            return
        content = info['content']
        if len(content) == 1 and content[0].lower() == "help":
            em = Embed(title="Problem Changing Help",
                       description="Details on how to change a problem.",
                       color=BOT_COLOUR)
            for x in self.command_help["change"]:
                em.add_field(name=x[0], value=x[1])
            await info['bot'].send_message(info['channel'], embed=em)
            return

        exceptions = {
            KeyError: "The problem that you entered does not exist.",
            IndexError:
            "Failed to parse the message content to change the problem. Please try again.",
            ValueError:
            "The specified new value is invalid. Please try again.",
            TypeError:
            "Cannot change the field you entered. Please try again.",
        }
        try:
            problem_code = content[0].lower()
            field = content[1].lower()
            value = content[2]
            if field != "name":
                value = int(value)
            problem = database.problem_list[problem_code]
            if field in unchangeable_problem_fields or field not in problem.__dict__.keys(
            ):
                raise TypeError
        except (*exceptions, ) as e:
            await info['bot'].send_message(info['channel'],
                                           exceptions[type(e)])
            return
        with await database.locks["problem"][problem_code]:
            database.change_problem(problem, field, value)
        await info['bot'].send_message(
            info['channel'],
            "Successfully changed problem `{}`.".format(problem_code))

    async def make(self, info):
        if not await has_perm(info['bot'], info['channel'], info['user'],
                              "change a problem's visibility"):
            return

        exceptions = {
            KeyError:
            "The problem that you entered does not exist.",
            IndexError:
            "Failed to parse the message content to change the problem. Please try again.",
            ValueError:
            "The specified new value is invalid. Please enter `public` or `private` try again.",
        }
        try:
            value = info['content'][0].lower()
            problem_code = info['content'][1].lower()
            problem = database.problem_list[problem_code]
            if value not in ["public", "private"]:
                raise ValueError
        except (*exceptions, ) as e:
            await info['bot'].send_message(info['channel'],
                                           exceptions[type(e)])
            return

        with await database.locks["problem"][problem_code]:
            database.change_problem(problem, "is_public", (value == "public"))
        await info['bot'].send_message(
            info['channel'],
            "Successfully made problem `{0}` {1}.".format(problem_code, value))

    async def delete(self, info):
        if not await has_perm(info['bot'], info['channel'], info['user'],
                              "delete problems"):
            return
        try:
            problem_code = info['content'][0].lower()
            if problem_code not in database.problem_list.keys():
                raise ValueError
        except (KeyError, IndexError):
            await info['bot'].send_message(
                info['channel'],
                "Failed to parse the message content to delete the problem. Please try again."
            )
        except ValueError:
            await info['bot'].send_message(
                info['channel'],
                "Problem `{}` does not exist.".format(problem_code))

        with await database.locks["problem"][problem_code]:
            database.delete_problem(database.problem_list[problem_code])
        await info['bot'].send_message(
            info['channel'],
            "Successfully deleted problem `{}`.".format(problem_code))

    async def submit(self, info, contest=None):
        if len(info['message'].attachments) < 1:
            await info['bot'].send_message(
                info['channel'],
                "Please upload one file for judging in the message.")
            return
        url = info['message'].attachments[0]["url"]
        submission_time = datetime.datetime.now()

        exceptions = {
            IndexError: "Please select a problem to submit the code to.",
            KeyError: "Invalid problem code.",
            UnicodeDecodeError: "Please upload a valid code file.",
            ValueError: "Please upload a file less than 65536 characters.",
        }
        try:
            problem_code = info['content'][0]
            problem = database.problem_list[problem_code]
            if contest is not None and get_element(contest.contest.problems,
                                                   problem) is None:
                raise KeyError
            code = requests.get(url).content.decode("utf-8")
            if len(code) > 65536:
                raise ValueError
        except (*exceptions, ) as e:
            await info['bot'].send_message(info['channel'],
                                           exceptions[type(e)])
            return
        finally:
            try:
                await info['bot'].delete_message(info['message'])
            except errors.Forbidden:
                pass
        if not await has_perm(info['bot'], info['channel'], info['user'],
                              "submit to private problems",
                              not problem.is_public and contest is None):
            return
        id = database.create_submission(
            models.Submission(None,
                              result="QU",
                              user=info['user'].id,
                              problem=problem_code,
                              submission_time=submission_time,
                              source=code,
                              contest=contest))
        database.judgeserver.judges.judge(id, problem,
                                          judge_lang[info['user'].language],
                                          code)
        await info['bot'].send_message(
            info['channel'],
            "{0}, Submitting code to `{1}`. Please wait.".format(
                info['user'].discord_user.mention, problem_code))
        await info['bot'].loop.create_task(
            wait_submission_finish(info['bot'], info['channel'], id,
                                   info['user'], contest))
Beispiel #8
0
def main():
    conn = pymysql.connect(host=migrate_config.OLD_HOST,
                           port=migrate_config.OLD_PORT,
                           user=migrate_config.OLD_USER,
                           password=migrate_config.OLD_PASSWORD,
                           db=migrate_config.OLD_DATABASE)
    joined_teams: Dict[int, List[int]] = {}
    user_admin_teams: Dict[int, List[int]] = {}
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute("SELECT * FROM users")
    print("loading user...")
    for item in cursor.fetchall():
        joined_teams[item["id"]] = json.loads(item["joined_teams"])
        print(item["username"])
        user = models.User(id=item["id"],
                           banned=item["banned"],
                           username=item["username"],
                           password=item["password"],
                           description=item["description"],
                           email=item["email"],
                           register_time=item["register_time"],
                           rating_history=json.loads(item["rating_history"]),
                           rating=item["rating"],
                           permission_group=item["permission_group"],
                           permissions=json.loads(item["permissions"]),
                           force_logout_before=item["force_logout_before"],
                           phone_number=None,
                           phone_verified=False)
        db.session.add(user)
    db.session.commit()
    print("loading problems...")
    cursor.execute("SELECT * FROM problems")
    for item in cursor.fetchall():
        print(item["id"], item["title"])
        prob = models.Problem(id=item["id"],
                              uploader_id=item["uploader_id"],
                              title=item["title"],
                              background=item["background"],
                              content=item["content"],
                              input_format=item["input_format"],
                              output_format=item["output_format"],
                              hint=item["hint"],
                              example=json.loads(item["example"]),
                              files=json.loads(item["files"]),
                              downloads=json.loads(item["downloads"]),
                              provides=json.loads(item["provides"]),
                              subtasks=json.loads(item["subtasks"]),
                              public=item["public"],
                              spj_filename=item["spj_filename"],
                              using_file_io=item["using_file_io"],
                              input_file_name=item["input_file_name"],
                              output_file_name=item["output_file_name"],
                              problem_type=item["problem_type"],
                              can_see_results=item["can_see_results"],
                              create_time=item["create_time"],
                              extra_parameter=json.loads(
                                  item["extra_parameter"]),
                              remote_judge_oj=item["remote_judge_oj"],
                              remote_problem_id=item["remote_problem_id"],
                              cached_submit_count=0,
                              cached_accepted_count=0,
                              team_id=None,
                              invite_code=str(uuid.uuid1()),
                              submission_visible=True)
        db.session.add(prob)
    db.session.commit()
    print("loading submissions...")
    cursor.execute("SELECT * FROM submissions")
    for item in cursor.fetchall():
        print(item["id"])
        item.update(
            dict(judge_result=json.loads(item["judge_result"]),
                 selected_compile_parameters=json.loads(
                     item["selected_compile_parameters"])))
        submission = models.Submission(**item)
        db.session.add(submission)
    db.session.commit()
    print("loading contests..")
    cursor.execute("SELECT * FROM contest")
    for item in cursor.fetchall():
        print(item["id"])
        item.update(dict(closed=False, problems=json.loads(item["problems"])))
        contest = models.Contest(**item)
        db.session.add(contest)
    db.session.commit()
    print("loading teams..")
    cursor.execute("SELECT * FROM team")
    for item in cursor.fetchall():
        team = models.Team(id=item["id"],
                           name=item["name"],
                           description=item["description"],
                           owner_id=item["owner_id"],
                           tasks=json.loads(item["tasks"]),
                           create_time=item["create_time"],
                           invite_code=str(uuid.uuid1()),
                           private=False,
                           team_contests=[],
                           team_problems=[],
                           team_problemsets=[])
        for uid in item["admins"]:
            if uid not in user_admin_teams:
                user_admin_teams[uid] = []
            user_admin_teams[uid].append(item["id"])
        db.session.add(team)
    db.session.commit()
    for user, teams in joined_teams.items():
        admin_teams = user_admin_teams.get(user, set())
        for x in teams:
            db.session.add(
                models.TeamMember(uid=user,
                                  team_id=x,
                                  is_admin=x in admin_teams))
    db.session.commit()
    print("loading permission groups..")
    db.session.query(models.PermissionGroup).delete()
    db.session.commit()
    cursor.execute("SELECT * FROM permission_groups")
    for item in cursor.fetchall():
        item.update(dict(permissions=json.loads(item["permissions"])))
        db.session.add(models.PermissionGroup(**item))
    db.session.commit()
    print("loading problemsets...")
    cursor.execute("SELECT * FROM problem_set")
    for item in cursor.fetchall():
        item.update(dict(problems=json.loads(item["problems"])))
        db.session.add(models.ProblemSet(**item))
    db.session.commit()
    print("loading remote accounts...")
    cursor.execute("SELECT * FROM remote_accounts")
    for item in cursor.fetchall():
        item.update(dict(session=item["session"]))
        db.session.add(models.RemoteAccount(**item))
    db.session.commit()
    print("loading discussions..")
    cursor.execute("SELECT * FROM discussions")
    for item in cursor.fetchall():
        db.session.add(models.Discussion(**item, private=False))
    db.session.commit()
    print("loading comments..")
    cursor.execute("SELECT * FROM comments")
    for item in cursor.fetchall():
        if not db.session.query(
                models.Discussion).filter_by(id=item["discussion_id"]).count():
            continue
        db.session.add(models.Comment(**item))
    db.session.commit()
    print("Done!")