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.py289
1 files changed, 0 insertions, 289 deletions
diff --git a/kpov_judge/web/kpov_judge/kpov_judge.py b/kpov_judge/web/kpov_judge/kpov_judge.py
deleted file mode 100755
index 47e413e..0000000
--- a/kpov_judge/web/kpov_judge/kpov_judge.py
+++ /dev/null
@@ -1,289 +0,0 @@
-#!/usr/bin/env python3
-
-import collections
-import datetime
-import json
-import random
-import settings
-import traceback
-import uuid
-
-from kpov_draw_setup import draw_setup
-import kpov_util
-
-import pymongo
-import flask
-from flask import Flask, g, session, redirect, url_for, abort, render_template, flash, app, request, Response
-from flask.ext.babel import Babel, gettext, ngettext, format_datetime, _
-import jinja2
-
-app = Flask(__name__)
-app.config.from_object(settings)
-babel = Babel(app)
-
-@babel.localeselector
-def get_locale():
- # terrible hack, should store as user preference in the DB
- if '/en/' in request.path:
- return 'en'
- if '/si/' in request.path:
- return 'sl'
- return request.accept_languages.best_match(['sl', 'en'])
-
-
-@app.before_request
-def before_request():
- g.db = pymongo.MongoClient(app.config['DB_URI']).get_default_database()
-
-
-@app.route('/')
-@app.route('/classes/')
-def index():
- student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody')
- classes = g.db.classes.find({}, {'class_id': 1, 'name': 1}).sort('class_id')
- return render_template('index.html', student_id=student_id, classes=classes)
-
-
-@app.route('/classes/<class_id>/')
-def class_tasks(class_id):
- student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody')
- clas = g.db.classes.find_one({'class_id': class_id})
- tasks = g.db.tasks.find({'class_id': class_id}, {'task_id': 1}).sort('task_id')
- if tasks is not None:
- task_list = [i['task_id'] for i in tasks]
- else:
- task_list = []
- return render_template('class_tasks.html', student_id=student_id, tasks=task_list, clas=clas)
-
-
-@app.route('/tasks/<class_id>/<task_id>/<lang>/setup.<ending>', methods=['GET'])
-def setup_svg(class_id, task_id, lang, ending):
- db = g.db
- fmt, mimetype = {
- 'svg':('svg', 'image/svg+xml'),
- 'png':('png', 'image/png'),
- }[ending]
- networks = list(db.networks.find({'class_id': class_id, 'task_id': task_id}))
- computers = list(db.computers_meta.find({'class_id': class_id, 'task_id': task_id}))
- return Response(draw_setup(computers, networks, format=fmt,
- icon_path=app.config['STATIC_DIR']),
- mimetype=mimetype)
-
-
-@app.route('/tasks/<class_id>/<task_id>/task.py')
-def task_source(class_id, task_id):
- db = g.db
- try:
- return db.tasks.find_one({'class_id': class_id, 'task_id': task_id})['source']
- except:
- return ''
-
-
-@app.route('/tasks/<class_id>/<task_id>/task.html')
-def task_html(class_id, task_id):
- return render_template('task.html', task=task_source(class_id, task_id))
-
-
-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']
- 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 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')
- d = {}
- exec(gen_params_code, globals(), d)
- params = d['gen_params'](student_id, meta)
- db.task_params.update({'class_id': class_id, 'task_id': task_id, 'student_id': student_id},
- {'$set': {'params': params}}, upsert=True)
- params = d['gen_params'](student_id, meta) # TODO this is repeated, is it necessary?
- for computer in db.computers_meta.find({'class_id': class_id, 'task_id': task_id}):
- try:
- name = computer.pop('name')
- del computer['_id']
- del computer['task_id']
- except Exception:
- pass
- db.student_computers.update({'class_id': class_id, 'task_id': task_id, 'student_id': student_id, 'name': name},
- {'$set': computer}, upsert=True)
- except Exception as e:
- meta = {'crash': {'public': True}}
- params = {'crash': "Parameter creator crashed or missing:\n{}".format(
- traceback.format_exc())}
- else:
- params = params['params']
- return params, meta
-
-
-@app.route('/tasks/<class_id>/<task_id>/')
-def task_lang_redirect(class_id, task_id):
- return redirect(url_for('task_greeting', class_id=class_id, task_id=task_id, lang=app.config['DEFAULT_LANG']))
-
-
-@app.route('/tasks/<class_id>/<task_id>/<lang>/howto/')
-def task_howto(class_id, task_id, lang):
- db = g.db
- return db.howtos.find_one({'class_id': class_id, 'task_id': task_id, 'lang': lang}).get('text', '')
-
-
-@app.route('/tasks/<class_id>/<task_id>/<lang>/images/<fname>')
-def task_image(class_id, task_id, lang, fname):
- db = g.db
- return db.howto_images.find_one({'class_id': class_id, 'task_id': task_id, 'fname': fname}).get('data', '')
-
-
-@app.route('/tasks/<class_id>/<task_id>/<lang>/')
-def task_greeting(class_id, task_id, lang):
- student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody')
- db = g.db
- # generate the parameters as soon as the student visits
- params, meta = get_params(class_id, task_id, student_id, db)
- instr_ok = True
- try:
- instructions = db.task_instructions.find_one({'class_id': class_id, 'task_id': task_id})
- instructions = instructions.get(lang, instructions[app.config['DEFAULT_LANG']])
- except Exception:
- try:
- instructions = list(instructions.values())[0]
- except Exception as e:
- instructions = str(e)
- instr_ok = False
- if instr_ok:
- try:
- public_params = []
- for k, v in meta.items():
- if v.get('public', False):
- public_params += [{
- 'name': k,
- 'value': params.get(k),
- 'description': v.get('descriptions', {}).get(lang)
- }]
- except Exception as e:
- instructions = str(e)
-
- computer_list = list(db.student_computers.find({'class_id': class_id, 'task_id': task_id, 'student_id': student_id}))
-
- backing_files = collections.defaultdict(set)
- for computer in computer_list:
- if 'disk_urls' not in computer:
- continue
- for name, disk in computer['disk_urls'].items():
- for fmt in disk['formats']:
- backing_files[fmt] |= set(disk[fmt][1:])
-
- if request.args.get('narediStack', 'false') == 'true':
- #db.student_tasks.update({'task_id': task_id, 'student_id': student_id}, {'$set': {'create_openstack': True}}, upsert = True)
- openstackCreated = False # Spremeni na True, ko odkomentiras zgornjo vrstico.
- else:
- if db.student_tasks.find({'class_id': class_id, 'task_id': task_id, 'student_id': student_id, 'openstack_created': True}).count() > 0:
- openstackCreated = True
- elif db.student_tasks.find({'class_id': class_id, 'task_id': task_id, 'student_id': student_id, 'create_openstack': True}).count() > 0:
- openstackCreated = True
- else:
- openstackCreated = False
-
- try:
- result = db.results.find_one(
- {'$query': {'class_id': class_id, 'task_id': task_id, 'student_id': student_id},
- '$orderby': collections.OrderedDict([('result', -1), ('time', 1)])},
- {'result': 1, 'status': 1, 'hints': 1, 'time': True, '_id': 0})
- result['time'] = format_datetime(result['time'])
- print(result)
- except Exception:
- result = None
-
- return render_template('task_greeting.html',
- disk_base_url='/'.join([app.config['STUDENT_DISK_URL'], student_id, class_id, task_id, '']),
- class_id=class_id,
- task_id=task_id,
- computers=sorted((c for c in computer_list if 'disk_urls' in c), key=lambda c: c['name']),
- backing_files={fmt: sorted(images) for fmt, images in backing_files.items()},
- lang='sl' if lang == 'si' else lang, # TODO s/si/sl in all tasks (and maybe elsewhere)
- openstack=openstackCreated,
- instructions=jinja2.Template(instructions),
- params=public_params,
- result=result,
- **{p['name']: p['value'] for p in public_params})
-
-
-@app.route('/tasks/<class_id>/<task_id>/token.json')
-def get_token(class_id, task_id):
- db = g.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']:
- shown_params[name] = param
- return json.dumps(shown_params)
-
-
-@app.route('/tasks/<class_id>/<task_id>/results.json', methods=['POST'])
-def results_json(class_id, task_id):
- db = g.db
- 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'})
-
- 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__':
- app.run(host='0.0.0.0')