#!/usr/bin/env python import flask from flask import Flask, g, session, redirect, url_for, abort, render_template, flash, app, request import pymongo import json import random import settings import datetime import kpov_random_helpers app = Flask(__name__) app.config.from_object(settings) dummy_task = """ def task(neznano_ime_naloge): print "Ta naloga ne obstaja!" return {'odgovor': 'neznana naloga'} """ dummy_checker = """ def task_check(results, params): raise Exception("neznana naloga?") return "Manjka preverjalnik naloge (neznana naloga?)" """ dummy_meta = {'neznano_ime_naloge': {'opis':'NEZNANA NALOGA', 'w': False}} @app.before_request def before_request(): g.db = pymongo.MongoClient(app.config['DB_HOST']).kpov try: user = app.config['USERNAME'] password = app.config['PASSWORD'] g.db.authenticate(user, password) except: #no auth or auth config? pass @app.route('/') def root(): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') tasks = g.db.tasks.find(dict(), {'task_id':1}) if tasks is not None: task_list = [i['task_id'] for i in tasks] else: task_list = [] return render_template('index.html', student_id=student_id, tasks=task_list) @app.route('/kpov_judge/') def auth_greeting(): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') return "To je past!" + str(flask.app.request.__dict__) @app.route('//results.json', methods=['GET', 'POST']) def results(task_id): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') db = g.db if flask.app.request.method == 'POST': results = json.loads(flask.app.request.form['results']) params = db.task_params.find_one({'task_id': task_id, 'student_id': student_id}) if params is None: params = dict() else: params = params['params'] 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 = dict() else: meta = meta['params'] for param_name, param_meta in meta.iteritems(): if param_meta.get('w', False) and param_name in user_params: params[param_name] = user_params[param_name] task_check_source = db.task_checkers.find_one({'task_id':task_id}) if task_check_source is None: task_check_source = dummy_checker else: task_check_source = task_check_source['source'] try: task_check_code = compile(task_check_source, 'checker.py', 'exec') exec(task_check_code) res = task_check(results, params) except Exception, e: res = "Checker crashed: " + str(e) # flask.app.logger.error(str(e)) if (type(res) is int and res > 0): res_status = 'OK' else: res_status = 'NOT OK' db.results.insert({'task_id': task_id, 'result': res, 'status': res_status,'student_id': student_id, 'response': results, 'time': datetime.datetime.now()}) return json.dumps({'result': res, 'status': res_status}) else: try: entry = db.results.find_one({'$query': {'task_id': task_id, 'student_id': student_id}, '$orderby': {'status': -1}}, {'result': 1, 'status': 1, '_id': 0}) if entry is None: return json.dumps({'result': 'Naloga ni bila nikdar ocenjena', 'status': 'NOT OK'}) return json.dumps(entry) except Exception, e: return json.dumps({'Error': str(e)}) # flask.app.logger.error(str(e)) return json.dumps({'result':"Mama! Zakaj si me zapustila? Sedaj se bom razstrelil."}) def public_meta(db, task_id): shown = dict() try: meta = db.task_params_meta.find_one({'task_id': task_id})['params'] for k, v in meta.iteritems(): try: if v['public']: shown[k] = v except: pass except: shown = dummy_meta return shown @app.route('//task.py', methods=['GET']) def task_source(task_id): db = g.db try: task_str = db.tasks.find_one({'task_id': task_id})['source'] meta_str = '\nparam_meta = ' + str(public_meta(db, task_id)) except: return dummy_task + '\nparam_meta = ' + str(dummy_meta) return task_str + meta_str def get_params(task_id, student_id, db): try: meta = db.task_params_meta.find_one({'task_id': task_id})['params'] except: return {'mama': 'ZAKVAJ?'}, {'mama':{'public': True}} params = db.task_params.find_one({'task_id': task_id, 'student_id': student_id}) s = "" if params is None: try: gen_params_source = db.gen_params.find_one({'task_id':task_id})['source'] gen_params_code = compile(gen_params_source, 'generator.py', 'exec') exec(gen_params_code) params = gen_params(student_id, meta) db.task_params.update({'task_id':task_id, 'student_id':student_id}, {'$set': {'params': params}}, upsert=True) params = gen_params(student_id, meta) for computer in db.computers_meta.find({'task_id': task_id}): try: name = computer.pop('name') del computer['_id'] del computer['task_id'] except: pass db.student_computers.update({'task_id': task_id, 'student_id': student_id, 'name': name}, {'$set': computer}, upsert=True) except Exception, e: meta = {'crash':{'public': True}} params = {'crash': "Parameter creator crashed or missing:" + str(e)} else: params = params['params'] return params, meta @app.route('//', methods = ['GET']) def task_greeting(task_id): 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(task_id, student_id, db) computer_list = db.student_computers.find({'task_id':task_id, 'student_id': student_id}) 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({'task_id':task_id, 'student_id': student_id, 'openstack_created': True}).count() > 0: openstackCreated = True elif db.student_tasks.find({'task_id':task_id, 'student_id': student_id, 'create_openstack': True}).count() > 0: openstackCreated = True else: openstackCreated = False return render_template('task.html', computers = computer_list, openstack = openstackCreated) @app.route('//params.json', methods=['GET', 'POST']) def params(task_id): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') db = g.db params, meta = get_params(task_id, student_id, db) shown_params = dict() for name, param in params.iteritems(): if meta.get(name, {'public': False})['public']: shown_params[name] = param if flask.app.request.method == 'POST': shown_params = dict() try: new_params = json.loads(flask.app.request.form['params']) except: new_params = dict() for name in params.iteritems(): if meta.get(name, {'w': False})['w'] and k in new_params: params[name] = new_params[name] if meta.get(name, {'public': False})['public']: shown_params[name] = params[name] db.task_params.update({'task_id':task_id, 'student_id':student_id}, {'$set': {'params': params}}, upsert=True) return json.dumps(shown_params) @app.route('//params_meta.json', methods=['GET']) def params_meta(task_id): db = g.db return json.dumps(public_meta(db, task_id)) if __name__ == '__main__': app.run()