From b7137b520984a387493fe259ebc5be58b475e388 Mon Sep 17 00:00:00 2001 From: Martin Mares <mj@ucw.cz> Date: Mon, 11 Jan 2021 17:38:30 +0100 Subject: [PATCH] =?UTF-8?q?org=5Fcontest=5Fsolutions=20vyu=C5=BE=C3=ADv?= =?UTF-8?q?=C3=A1=20ke=20kontrole=20pr=C3=A1v=20get=5Fsoulutions=5Fcontext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Takže by již měl k tabulce řešení mít přístup i dozor. --- mo/web/org_contest.py | 128 ++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 62 deletions(-) diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index ee3b1b12..6ed8b346 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -427,77 +427,20 @@ def make_contestant_table(query: Query, add_checkbox: bool = False, add_contest_ ) -@app.route('/org/contest/c/<int:id>/reseni', methods=('GET', 'POST')) -@app.route('/org/contest/c/<int:id>/site/<int:site_id>/reseni', methods=('GET', 'POST')) -def org_contest_solutions(id: int, site_id: Optional[int] = None): - contest, site, rr = get_contest_site_rr(id, site_id, Right.manage_contest) - - sess = db.get_session() - - pions_subq = sess.query(db.Participation.user_id).filter_by(contest=contest) - if site: - pions_subq = pions_subq.filter_by(place=site) - pions_subq = pions_subq.subquery() - pions = (sess.query(db.Participation) - .filter(db.Participation.user_id.in_(pions_subq)) - .options(joinedload(db.Participation.user)) - .all()) - - tasks_subq = sess.query(db.Task.task_id).filter_by(round=contest.round).subquery() - tasks = (sess.query(db.Task) - .filter_by(round=contest.round) - .order_by(db.Task.code) - .all()) - - sols = sess.query(db.Solution).filter( - db.Solution.user_id.in_(pions_subq), - db.Solution.task_id.in_(tasks_subq) - ).options( - joinedload(db.Solution.final_submit_obj), - joinedload(db.Solution.final_feedback_obj) - ).all() - - if request.method == 'POST' and 'download' in request.form: - paper_ids = [sol.final_submit for sol in sols if sol.final_submit is not None] - mo.jobs.submit.schedule_download_submits(paper_ids, 'Odevzdaná řešení', g.user) - flash('Příprava řešení ke stažení zahájena.', 'success') - return redirect(url_for('org_jobs')) - - task_sols: Dict[int, Dict[int, db.Solution]] = {} - for t in tasks: - task_sols[t.task_id] = {} - for s in sols: - task_sols[s.task_id][s.user_id] = s - - def paper_link(paper: db.Paper) -> str: - return url_for('org_submit_paper', - contest_id=contest.contest_id, - paper_id=paper.paper_id, - site_id=site_id, - filename=mo.web.util.task_paper_filename(paper)) - - return render_template( - 'org_contest_solutions.html', - contest=contest, site=site, - pions=pions, tasks=tasks, tasks_sols=task_sols, - paper_link=paper_link, - ) - - @dataclass class SolutionContext: contest: db.Contest round: db.Round pion: db.Participation user: Optional[db.User] - task: db.Task + task: Optional[db.Task] site: Optional[db.Place] allow_view: bool allow_upload_solutions: bool allow_upload_feedback: bool -def get_solution_context(contest_id: int, user_id: Optional[int], task_id: int, site_id: Optional[int]) -> SolutionContext: +def get_solution_context(contest_id: int, user_id: Optional[int], task_id: Optional[int], site_id: Optional[int]) -> SolutionContext: sess = db.get_session() # Nejprve zjistíme, zda existuje soutěž @@ -505,9 +448,12 @@ def get_solution_context(contest_id: int, user_id: Optional[int], task_id: int, round = contest.round # Najdeme úlohu a ověříme, že je součástí soutěže - task = sess.query(db.Task).get(task_id) - if not task or task.round != round: - raise werkzeug.exceptions.NotFound() + if task_id is not None: + task = sess.query(db.Task).get(task_id) + if not task or task.round != round: + raise werkzeug.exceptions.NotFound() + else: + task = None site = None user = None @@ -598,6 +544,7 @@ def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Option else: raise werkzeug.exceptions.Forbidden() + assert sc.task is not None and sc.user is not None paper = db.Paper(task=sc.task, for_user_obj=sc.user, uploaded_by_obj=g.user, type=type, note=form.note.data) submitter = mo.submit.Submitter(instance_path=app.instance_path) self_url = url_for('org_submit_list', contest_id=contest_id, user_id=user_id, task_id=task_id, site_id=site_id) @@ -746,6 +693,7 @@ def get_solutions_query( def org_contest_task_submits(contest_id: int, task_id: int, site_id: Optional[int] = None): sc = get_solution_context(contest_id, None, task_id, site_id) + assert sc.task is not None q = get_solutions_query(sc.task, for_contest=sc.contest, for_site=sc.site) solutions: List[db.Solution] = q.all() @@ -761,3 +709,59 @@ def org_contest_task_submits(contest_id: int, task_id: int, site_id: Optional[in sc=sc, solutions=solutions, paper_link=paper_link, ) + + +@app.route('/org/contest/c/<int:id>/reseni', methods=('GET', 'POST')) +@app.route('/org/contest/c/<int:id>/site/<int:site_id>/reseni', methods=('GET', 'POST')) +def org_contest_solutions(id: int, site_id: Optional[int] = None): + sc = get_solution_context(id, None, None, site_id) + sess = db.get_session() + + pions_subq = sess.query(db.Participation.user_id).filter_by(contest=sc.contest) + if sc.site: + pions_subq = pions_subq.filter_by(place=sc.site) + pions_subq = pions_subq.subquery() + pions = (sess.query(db.Participation) + .filter(db.Participation.user_id.in_(pions_subq)) + .options(joinedload(db.Participation.user)) + .all()) + + tasks_subq = sess.query(db.Task.task_id).filter_by(round=sc.round).subquery() + tasks = (sess.query(db.Task) + .filter_by(round=sc.round) + .order_by(db.Task.code) + .all()) + + sols = sess.query(db.Solution).filter( + db.Solution.user_id.in_(pions_subq), + db.Solution.task_id.in_(tasks_subq) + ).options( + joinedload(db.Solution.final_submit_obj), + joinedload(db.Solution.final_feedback_obj) + ).all() + + if request.method == 'POST' and 'download' in request.form: + paper_ids = [sol.final_submit for sol in sols if sol.final_submit is not None] + mo.jobs.submit.schedule_download_submits(paper_ids, 'Odevzdaná řešení', g.user) + flash('Příprava řešení ke stažení zahájena.', 'success') + return redirect(url_for('org_jobs')) + + task_sols: Dict[int, Dict[int, db.Solution]] = {} + for t in tasks: + task_sols[t.task_id] = {} + for s in sols: + task_sols[s.task_id][s.user_id] = s + + def paper_link(paper: db.Paper) -> str: + return url_for('org_submit_paper', + contest_id=sc.contest.contest_id, + paper_id=paper.paper_id, + site_id=site_id, + filename=mo.web.util.task_paper_filename(paper)) + + return render_template( + 'org_contest_solutions.html', + contest=sc.contest, site=sc.site, + pions=pions, tasks=tasks, tasks_sols=task_sols, + paper_link=paper_link, + ) -- GitLab