Skip to content
Snippets Groups Projects
Commit b7137b52 authored by Martin Mareš's avatar Martin Mareš
Browse files

org_contest_solutions využívá ke kontrole práv get_soulutions_context

Takže by již měl k tabulce řešení mít přístup i dozor.
parent a09b8eab
No related branches found
No related tags found
1 merge request!9WIP: Zárodek uživatelské části webu a submitování
......@@ -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
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,
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment