summaryrefslogtreecommitdiff
path: root/kpov_judge/web/kpov_judge/kpov_judge.py
diff options
context:
space:
mode:
Diffstat (limited to 'kpov_judge/web/kpov_judge/kpov_judge.py')
-rwxr-xr-xkpov_judge/web/kpov_judge/kpov_judge.py161
1 files changed, 64 insertions, 97 deletions
diff --git a/kpov_judge/web/kpov_judge/kpov_judge.py b/kpov_judge/web/kpov_judge/kpov_judge.py
index ddef16d..7415724 100755
--- a/kpov_judge/web/kpov_judge/kpov_judge.py
+++ b/kpov_judge/web/kpov_judge/kpov_judge.py
@@ -71,74 +71,6 @@ def class_tasks(class_id):
return render_template('class_tasks.html', student_id=student_id, tasks=task_list, clas=clas)
-def results_post(class_id, task_id, token, results):
- student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody')
- db = g.db
- #params = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'student_id': student_id})['params']
- print(class_id, task_id, token)
- params = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'params.token': token})['params']
- if not params:
- raise Exception('Invalid token.')
-
- if params is None:
- # params = {}
- #else:
- # params = params['params']
- return {'result': 0, 'hints': ['task not found'], status: 'NOT OK'} # no such task
- user_params = json.loads(flask.app.request.form['params'])
- meta = db.task_params_meta.find_one({'task_id': task_id})
- if meta is None:
- meta = {}
- else:
- meta = meta['params']
- for param_name, param_meta in meta.items():
- if param_meta.get('w', False) and param_name in user_params:
- params[param_name] = user_params[param_name]
- try:
- task_check_source = db.task_checkers.find_one({'class_id': class_id, 'task_id': task_id})['source']
- d = {}
- exec(compile(task_check_source, 'checker.py', 'exec'), globals(), d)
- res, hints = d['task_check'](collections.defaultdict(str, results), params)
- except Exception as e:
- hints = ["Checker died: " + str(e)]
- res = 0
- if (isinstance(res, int) or isinstance(res, float)) and res > 0:
- res_status = 'OK'
- else:
- res_status = 'NOT OK'
- db.results.insert({'class_id': class_id, 'task_id': task_id, 'result': res, 'hints': hints, 'status': res_status,'student_id': student_id, 'response': results, 'time': datetime.datetime.now()})
- return {'result': res, 'hints': hints, 'status': res_status}
-
-
-def results_dict(class_id, task_id, token):
- db = g.db
- try:
- task_params = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'token': token})
- if not task_params:
- raise Exception('Invalid token.')
- #student_id = flask.app.request.environ.get('REMOTE_USER')
- student_id = task_params['student_id']
- entry = db.results.find_one(
- {'$query': {'class_id': class_id, 'task_id': task_id, 'student_id': student_id}, # vsi uporabniki brez nastavljenega REMOTE_USER (i.e. Apache basic auth) imajo skupne rezultate, napaka?
- '$orderby': {'time': -1}},
- {'result': 1, 'status': 1, 'hints': 1, '_id': 0})
- if entry is None:
- return {'result': 'Naloga ni bila nikdar ocenjena', 'status': 'NOT OK'}
- return entry
- except Exception as e:
- return {'Error': str(e)}
-
-
-@app.route('/tasks/<class_id>/<task_id>/results.json', methods=['GET', 'POST'])
-def results_json(class_id, task_id):
- if flask.app.request.method == 'POST':
- return json.dumps(
- results_post(class_id, task_id,
- json.loads(flask.app.request.form['params']).get('token'),
- json.loads(flask.app.request.form['results'])))
- return json.dumps(results_dict(class_id, task_id, request.args.get('token')))
-
-
@app.route('/tasks/<class_id>/<task_id>/<lang>/setup.<ending>', methods=['GET'])
def setup_svg(class_id, task_id, lang, ending):
db = g.db
@@ -168,22 +100,14 @@ def task_html(class_id, task_id):
return render_template('task.html', task=task_source(class_id, task_id))
-def make_token(student_id):
- # TODO need nginx support, in version 1.11.3, not yet in debian stable
- #import jwt
- #message = {'student_id': student_id}
- #return jwt.encode(message, app.config['JWT_SECRET'], algorithm='HS512').decode('utf-8')
- return str(uuid.uuid4())
-
def get_params(class_id, task_id, student_id, db):
try:
meta = db.task_params_meta.find_one({'class_id': class_id, 'task_id': task_id})['params']
- meta['token'] = {'public': True, 'generated': True, 'type': 'password', 'w': False}
except Exception:
return {'mama': 'ZAKVAJ?'}, {'mama': {'public': True}}
params = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'student_id': student_id})
- if params is None:
+ if params is None or 'params' not in params: # TODO try with $exists: params or smth.
try:
gen_params_source = db.gen_params.find_one({'class_id': class_id, 'task_id': task_id})['source']
gen_params_code = compile(gen_params_source, 'generator.py', 'exec')
@@ -302,12 +226,24 @@ def task_greeting(class_id, task_id, lang):
**{p['name']: p['value'] for p in public_params})
-@app.route('/tasks/<class_id>/<task_id>/params.json')
-def params_json(class_id, task_id, student_id=None):
- if not student_id:
- student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody')
+@app.route('/tasks/<class_id>/<task_id>/token.json')
+def get_token(class_id, task_id):
db = g.db
- params, meta = get_params(class_id, task_id, student_id, db)
+ student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody')
+ token = str(uuid.uuid4())
+ db.task_params.update({'class_id': class_id, 'task_id': task_id, 'student_id': student_id},
+ {'$set': {'token': token}}, upsert=True)
+ return json.dumps({'token': token})
+
+
+@app.route('/tasks/<class_id>/<task_id>/params.json', methods=['POST'])
+def params_json(class_id, task_id):
+ db = g.db
+ token = flask.app.request.form['token']
+ record = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'token': token})
+ if not record:
+ return json.dumps({})
+ params, meta = get_params(record['class_id'], record['task_id'], record['student_id'], db)
shown_params = {}
for name, param in params.items():
if meta.get(name, {'public': False})['public']:
@@ -315,23 +251,54 @@ def params_json(class_id, task_id, student_id=None):
return json.dumps(shown_params)
-@app.route('/tasks/<class_id>/<task_id>/params-token.json', methods=['POST'])
-def params_token_json(class_id, task_id):
+@app.route('/tasks/<class_id>/<task_id>/results.json', methods=['POST'])
+def results_json(class_id, task_id):
db = g.db
- token = json.loads(flask.app.request.form['params']).get('token', '')
- record = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'params.token': token})
- if not record:
- return json.dumps({})
- return params_json(record['class_id'], record['task_id'], record['student_id'])
+ token = flask.app.request.form.get('token', '')
+ task = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'token': token})
+ if not task:
+ return json.dumps({'result': 0, 'hints': ['invalid token'], 'status': 'NOT OK'})
-@app.route('/tasks/<class_id>/<task_id>/results-token.json', methods=['GET', 'POST'])
-def results_token_json(class_id, task_id):
- db = g.db
- token = json.loads(flask.app.request.form['params']).get('token', '')
- record = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'params.token': token})
- if not record:
- return json.dumps({})
- return results_json(class_id, task_id)
+ params = task['params']
+ if params is None:
+ return json.dumps({'result': 0, 'hints': ['no parameters found for task'], 'status': 'NOT OK'}) # no such task
+
+ results = json.loads(flask.app.request.form['results'])
+ user_params = json.loads(flask.app.request.form['params'])
+
+ meta = db.task_params_meta.find_one({'task_id': task_id})
+ if meta is None:
+ meta = {}
+ else:
+ meta = meta['params']
+ for param_name, param_meta in meta.items():
+ if param_meta.get('w', False) and param_name in user_params:
+ params[param_name] = user_params[param_name]
+
+ # hack to get token into task_check function
+ # TODO rethink the API
+ params['token'] = token
+ try:
+ task_check_source = db.task_checkers.find_one({'class_id': class_id, 'task_id': task_id})['source']
+ d = {}
+ exec(compile(task_check_source, 'checker.py', 'exec'), globals(), d)
+ res, hints = d['task_check'](collections.defaultdict(str, results), params)
+ except Exception as e:
+ hints = ["Checker died: " + str(e)]
+ res = 0
+ if (isinstance(res, int) or isinstance(res, float)) and res > 0:
+ res_status = 'OK'
+ else:
+ res_status = 'NOT OK'
+
+ db.results.insert({
+ 'class_id': class_id, 'task_id': task_id,
+ 'result': res, 'hints': hints, 'status': res_status,
+ 'student_id': task['student_id'],
+ 'response': results,
+ 'time': datetime.datetime.now()
+ })
+ return json.dumps({'result': res, 'hints': hints, 'status': res_status})
if __name__ == '__main__':