Skip to content
Snippets Groups Projects

Praktické úlohy a propojení s CMS

Merged Martin Mareš requested to merge mj/prakticke-ulohy into devel
1 file
+ 4
1
Compare changes
  • Side-by-side
  • Inline
+ 82
36
from dataclasses import dataclass
from flask import render_template, jsonify, g, redirect, url_for, flash, request
from flask_wtf import FlaskForm
import flask_wtf.file
import hashlib
import hmac
from sqlalchemy import and_
from sqlalchemy.orm import joinedload
from typing import List, Tuple
from typing import List, Tuple, Optional
import werkzeug.exceptions
import wtforms
from wtforms.validators import Required
@@ -342,13 +345,44 @@ class SubmitForm(FlaskForm):
submit = wtforms.SubmitField('Odevzdat')
@dataclass
class CMSParams:
url: str
username: str
first_name: str
last_name: str
timestamp: str
signature: str = ""
back_url: str = ""
def get_cms_params() -> Optional[CMSParams]:
if not (hasattr(config, 'CMS_ROOT') and hasattr(config, 'CMS_SSO_SECRET')):
return None
p = CMSParams(
url=config.CMS_ROOT + 'sso-login',
username=f'osmo{g.user.user_id}',
first_name=g.user.first_name,
last_name=g.user.last_name,
timestamp=str(int(mo.now.timestamp())),
)
msg = ":".join((p.username, p.first_name, p.last_name, p.timestamp)).encode('utf-8')
key = config.CMS_SSO_SECRET.encode('us-ascii')
p.signature = hmac.HMAC(key, msg, digestmod=hashlib.sha256).hexdigest()
return p
@app.route('/user/contest/<int:contest_id>/task/<int:task_id>/', methods=('GET', 'POST'))
def user_contest_task(contest_id: int, task_id: int):
contest = get_contest(contest_id)
task = get_task(contest, task_id)
sess = db.get_session()
if contest.round.has_messages:
messages = sess.query(db.Message).filter_by(round_id=contest.round_id).order_by(db.Message.created_at).all()
else:
messages = None
state = contest.ct_state()
if state == db.RoundState.preparing:
@@ -356,8 +390,13 @@ def user_contest_task(contest_id: int, task_id: int):
# stránku, abychom něco neprozradili jménem úlohy
raise werkzeug.exceptions.Forbidden()
form: Optional[SubmitForm] = None
if task.type == db.TaskType.regular:
form = SubmitForm()
if contest.ct_can_submit() and form.validate_on_submit():
if task.type != db.TaskType.regular:
raise werkzeug.exceptions.Forbidden()
file = form.file.data.stream
paper = db.Paper(task=task, for_user_obj=g.user, uploaded_by_obj=g.user, type=db.PaperType.solution, note=form.note.data)
submitter = mo.submit.Submitter()
@@ -391,6 +430,12 @@ def user_contest_task(contest_id: int, task_id: int):
flash('Řešení odevzdáno', 'success')
return redirect(url_for('user_contest', id=contest_id))
cms_params: Optional[CMSParams] = None
if task.type == db.TaskType.cms:
cms_params = get_cms_params()
if cms_params:
cms_params.back_url = url_for('user_contest_task', contest_id=contest_id, task_id=task_id)
sol = sess.query(db.Solution).filter_by(task=task, user=g.user).one_or_none()
papers = (sess.query(db.Paper)
@@ -406,6 +451,7 @@ def user_contest_task(contest_id: int, task_id: int):
sol=sol,
papers=papers,
form=form,
cms_params=cms_params,
messages=messages,
)
Loading