diff options
Diffstat (limited to 'kpov_judge')
-rwxr-xr-x | kpov_judge/add_task.py | 52 | ||||
-rwxr-xr-x | kpov_judge/create_disk_images.py | 42 | ||||
-rw-r--r-- | kpov_judge/tasks/rename_grep_network/task.py | 46 | ||||
-rwxr-xr-x | kpov_judge/web/kpov_judge/kpov_judge.py | 158 | ||||
-rw-r--r-- | kpov_judge/web/kpov_judge/templates/index.html | 6 |
5 files changed, 181 insertions, 123 deletions
diff --git a/kpov_judge/add_task.py b/kpov_judge/add_task.py index f95f44d..6bb3a2c 100755 --- a/kpov_judge/add_task.py +++ b/kpov_judge/add_task.py @@ -38,9 +38,12 @@ if __name__ == '__main__': dirname = sys.argv[1] fname = os.path.join(dirname, 'task.py') try: - task_id = sys.argv[2] + class_id, task_id = sys.argv[2].split('/') except: - task_id = os.path.basename(os.path.normpath(dirname)) + normpath = os.path.normpath(dirname) + class_id = os.path.split(os.path.dirname(normpath))[-1] + task_id = os.path.basename(normpath) + print(class_id, task_id) db = pymongo.MongoClient(settings.DB_HOST).kpov try: db.authenticate(settings.USERNAME, settings.PASSWORD) @@ -65,38 +68,57 @@ if __name__ == '__main__': gen_params_source = inspect.getsource(gen_params) prepare_disks_source = inspect.getsource(prepare_disks) x = params_meta.keys() # check for existence - db.computers_meta.remove({'task_id': task_id}) + db.computers_meta.remove({'task_id': task_id, 'class_id': class_id}) auto_networks = set([None]) for k, v in computers.iteritems(): for n in v.get('networks_interfaces', []): auto_networks.add(n.get('network', None)) - db.computers_meta.update({'task_id': task_id, 'name': k}, {'$set': v}, upsert=True) + db.computers_meta.update({ + 'task_id': task_id, + 'class_id': class_id, + 'name': k + }, {'$set': v}, upsert=True) auto_networks.remove(None) - db.networks.remove({'task_id': task_id}) + db.networks.remove({'task_id': task_id, 'class_id': class_id}) try: net_list = networks.iteritems() except: net_list = [(k, {'public': False}) for k in auto_networks] for k, v in net_list: - db.networks.update({'task_id': task_id, 'name': k}, {'$set': v}, upsert=True) - db.task_checkers.update({'task_id': task_id}, {'$set': {'source': task_check_source}}, upsert=True) - db.tasks.update({'task_id': task_id},{'$set': {'source': task_source}}, upsert=True) - db.prepare_disks.update({'task_id': task_id}, {'$set': {'source': prepare_disks_source}}, upsert=True) - db.gen_params.update({'task_id': task_id}, {'$set': {'source': gen_params_source}}, upsert=True) - db.task_params_meta.update({'task_id': task_id}, {'$set': {'params': params_meta}}, upsert=True) + db.networks.update({'task_id': task_id, 'class_id': class_id, 'name': k}, {'$set': v}, upsert=True) + db.task_checkers.update({ + 'task_id': task_id, 'class_id': class_id + }, {'$set': {'source': task_check_source}}, upsert=True) + db.tasks.update({ + 'task_id': task_id, 'class_id': class_id + },{'$set': {'source': task_source}}, upsert=True) + db.prepare_disks.update({ + 'task_id': task_id, 'class_id': class_id + }, {'$set': {'source': prepare_disks_source}}, upsert=True) + db.gen_params.update({'task_id': task_id, 'class_id': class_id}, + {'$set': {'source': gen_params_source}}, upsert=True) + db.task_params_meta.update({'task_id': task_id, 'class_id': class_id}, + {'$set': {'params': params_meta}}, upsert=True) #instructions = dict([(k, v.encode('utf8')) for k, v in instructions.iteritems()]) #print instructions - db.task_instructions.update({'task_id': task_id}, {'$set': instructions - }, upsert=True) + db.task_instructions.update({'task_id': task_id, 'class_id': class_id}, + {'$set': instructions}, upsert=True) for howto_dir in glob.glob(os.path.join(dirname, 'howtos/*')): howto_lang = os.path.basename(os.path.normpath(howto_dir)) if howto_lang not in {'images'}: with open(os.path.join(howto_dir, 'index.html')) as f: - db.howtos.update({'task_id': task_id, 'lang': howto_lang}, + db.howtos.update({ + 'task_id': task_id, + 'class_id': class_id, + 'lang': howto_lang}, {'$set': {'text': f.read()}}, upsert=True) else: for img in glob.glob(os.path.join(howto_dir, '*')): fname = os.path.basename(img) with open(img) as f: - db.howto_images.update({'task_id': task_id, 'fname': fname}, + db.howto_images.update({ + 'task_id': task_id, + 'class_id': class_id, + 'fname': fname, + }, {'$set': {'data': Binary(f.read())}}, upsert=True) diff --git a/kpov_judge/create_disk_images.py b/kpov_judge/create_disk_images.py index d28ef1d..c9d433f 100755 --- a/kpov_judge/create_disk_images.py +++ b/kpov_judge/create_disk_images.py @@ -13,13 +13,13 @@ import subprocess import fcntl from util import write_default_config -def get_prepare_disks(db, task_id): - prepare_disks_source = db.prepare_disks.find_one({'task_id':task_id})['source'] +def get_prepare_disks(db, class_id, task_id): + prepare_disks_source = db.prepare_disks.find_one({'class_id': class_id, 'task_id':task_id})['source'] prepare_disks_code = compile(prepare_disks_source, 'prepare_disks.py', 'exec') exec(prepare_disks_code) return prepare_disks -def create_snapshot(task_id, student_id, disk_name, overwrite = True, cow = False): +def create_snapshot(class_id, task_id, student_id, disk_name, overwrite = True, cow = False): print(os.path.join(settings.DISK_TEMPLATE_PATH, disk_name) + '.*') template_paths = glob.glob(os.path.join(settings.DISK_TEMPLATE_PATH, disk_name) + '.*') filtered_paths = filter((lambda x: os.path.splitext(x)[1] == '.' + settings.STUDENT_DISK_FORMAT), template_paths) @@ -28,11 +28,11 @@ def create_snapshot(task_id, student_id, disk_name, overwrite = True, cow = Fals else: template_path = template_paths[0] if cow: - d = os.path.join(student_id, task_id, disk_name) + os.path.splitext(template_path)[1] + d = os.path.join(student_id, class_id, task_id, disk_name) + os.path.splitext(template_path)[1] else: - d = os.path.join(student_id, task_id, disk_name) + '.qcow2' + d = os.path.join(student_id, class_id, task_id, disk_name) + '.qcow2' try: - os.makedirs(os.path.join(settings.STUDENT_DISK_PATH, student_id, task_id)) + os.makedirs(os.path.join(settings.STUDENT_DISK_PATH, student_id, class_id, task_id)) except: pass disk_file = os.path.join(settings.STUDENT_DISK_PATH, d) @@ -61,7 +61,7 @@ def publish_snapshot(d): if __name__ == '__main__': if len(sys.argv) != 1: print "Usage: {0}" - print "Create the neccessarry disk images" + print "Create the pending disk images" db = pymongo.MongoClient(settings.DB_HOST).kpov try: db.authenticate(settings.USERNAME, settings.PASSWORD) @@ -69,26 +69,26 @@ if __name__ == '__main__': print str(e) dev_prefix = settings.GUESTFS_DEV_PREFIX l = db.student_computers.find({"disk_urls": {"$exists": False}}) - computers_by_task_student = dict() + computers_by_class_task_student = dict() for computer in l: - student_id, task_id = computer['student_id'], computer['task_id'] - if (task_id, student_id) not in computers_by_task_student: - computers_by_task_student[(task_id, student_id)] = list() - computers_by_task_student[(task_id, student_id)].append(computer) - for (task_id, student_id), computers in computers_by_task_student.iteritems(): - print "Creating", task_id, " for ", student_id - l = db.student_computers.find_one({'task_id': task_id, 'student_id':student_id, "disk_urls": {"$exists": False}}) + student_id, task_id, class_id = computer['student_id'], computer['task_id'], computer['class_id'] + if (class_id, task_id, student_id) not in computers_by_class_task_student: + computers_by_class_task_student[(class_id, task_id, student_id)] = list() + computers_by_class_task_student[(class_id, task_id, student_id)].append(computer) + for (class_id, task_id, student_id), computers in computers_by_class_task_student.items(): + print "Creating {}/{} for {}".format(class_id, task_id, student_id) + l = db.student_computers.find_one({'class_id': class_id, 'task_id': task_id, 'student_id':student_id, "disk_urls": {"$exists": False}}) if l is None: continue lock_file = os.path.join(settings.STUDENT_LOCKFILE_PATH, - '{0}-{1}.lock'.format(student_id, task_id)) + '{0}-{1}-{2}.lock'.format(student_id, class_id, task_id)) lock_fp = open(lock_file, 'w') try: fcntl.lockf(lock_fp, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: continue - task_params = db.task_params.find_one({'task_id': task_id, 'student_id': student_id})['params'] - prepare_disks = get_prepare_disks(db, task_id) + task_params = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'student_id': student_id})['params'] + prepare_disks = get_prepare_disks(db, class_id, task_id) # tule odpri, ustvari snapshote za vajo templates = dict() all_disks = dict() @@ -104,7 +104,7 @@ if __name__ == '__main__': g = guestfs.GuestFS() for disk in computer['disks']: lock_fp.write("register " + disk['name'] + '\n') - snap = create_snapshot(task_id, student_id, disk['name'], + snap = create_snapshot(class_id, task_id, student_id, disk['name'], cow = settings.STUDENT_DISK_COW) snap_file = os.path.join(settings.STUDENT_DISK_PATH, snap) if 'options' in disk: @@ -149,9 +149,10 @@ if __name__ == '__main__': lock_fp.write("preparing disks\n") global_params = { 'task_name': task_id, + 'class_id': class_id, 'username': student_id} if 'TASK_URL' in vars(settings): - global_params['task_url'] = settings.TASK_URL + global_params['task_url'] = settings.TASK_URL + '/' + class_id + '/' prepare_disks(templates, task_params, global_params) # pospravi za seboj. lock_fp.write("unmounting\n") @@ -171,6 +172,7 @@ if __name__ == '__main__': "disk_urls": {"$exists": False}, 'student_id': student_id, 'task_id': task_id, + 'class_id': class_id, 'name': comp_name}, {'$set': { 'disk_urls': disk_urls }}) # print "done for ", student_id, task_id diff --git a/kpov_judge/tasks/rename_grep_network/task.py b/kpov_judge/tasks/rename_grep_network/task.py index ce761db..91ace1a 100644 --- a/kpov_judge/tasks/rename_grep_network/task.py +++ b/kpov_judge/tasks/rename_grep_network/task.py @@ -12,7 +12,7 @@ instructions = { 'si': u""" Ustvari dva navidezna računalnika s slikama diskov - SimpleArbiterExam s sliko diska simpleArbiterDhcp in -SmallStudent s slikama diska student-entrance3 +SmallStudent s slikama diska student-entrance4 in smallstudent-personal. Drugi razdelek na sliki smallstudent-personal priklopi na imenik {mntdir} @@ -26,11 +26,12 @@ Na SmallStudent ustvari uporabnika {testuser} z geslom {passwd}. Na smallstudent-personal je nekje skrita datoteka, ki vsebuje niz {magicstr}. -Skopiraj jo v domači imenik {testuser} in preimenuj tako, da vse znake 'O' v imenu zamenjaš z 'I'. -Pazi, da nobena druga datoteka v domačem imeniku v svojem imenu ne bo vsebovala "I". +Skopiraj jo v domači imenik {testuser} in preimenuj tako, da vse znake 'O' v imenu zamenjaš s 'K'. +V kopiji zamenjaj vse pojavitve številke "12" z "dvanajst". +Pazi, da nobena druga datoteka v domačem imeniku v svojem imenu ne bo vsebovala "K". Poskrbi, da bo lastnik {testuser}, skupina pa naj ostane nespremenjena. -Brati naj jo ima pravico samo lastnik, pisati lastnik in skupina, poganjati nihče. +Brati naj jo ima pravico samo lastnik, pisati lastnik in ostali, poganjati le skupina. """, 'en': u''' ''', @@ -60,11 +61,11 @@ computers = { 'disks': [ { 'name': 'student-entrance3', - 'parts': [{'dev': 'a1', 'path': '/'}], + # 'parts': [{'dev': 'sda1', 'path': '/'}], }, { 'name': 'smallstudent-personal', - 'parts': [{'dev': 'b1', 'path': '/media'}, {'dev': 'b2', 'path': '/mnt'}] + 'parts': [{'dev': 'sdb1', 'path': '/media'}, {'dev': 'sdb2', 'path': '/mnt'}] } ], 'network_interfaces': [ @@ -222,23 +223,22 @@ def task_check(results, params): score = 0 hidden_contents = params['magicstr'] r = random.Random(params['rndseed']) - dstfile = "".join([r.choice("qQoOp") for i in range(64)]) + "I.txt" - dstfile = dstfile.replace('O', 'I') + dstfile = "".join([r.choice("qQoOp") for i in range(64)]) + "K.txt" + dstfile = dstfile.replace('O', 'K') for i in range(1000): start = "".join([r.choice(["po", "p0", "no", "ko", "fo", "qo"]) for i in range(20)]) - mid = "".join([r.choice("uiasdfghjkyxcvbnm1234567890ASDFGHJKYZXCVBNM") for i in range(60)]) - end = r.choice(["lz", "1z", "Iz", "iz", "l2", "I2", "12"]) + mid = "".join([r.choice("1lIi") + r.choice("zZ2") for i in range(60)]) #if start[:2] == "po" and end == "lz": # start = "po" # mid = "kaka" - x = start + mid + end + x = start + mid hidden_contents += x + "\r\n" - expected_contents = hidden_contents - #expected_contents = re.sub(r"^po.*lz\r$", - # r"pokakalz\r", - # hidden_contents, - # re.MULTILINE) - expected_contents = "cat ~/*I*.txt\r\n".format(dstfile) + expected_contents + #expected_contents = hidden_contents + expected_contents = re.sub(r"12", + r"dvanajst", + hidden_contents, + re.MULTILINE) + expected_contents = "cat ~/*K*.txt\r\n".format(dstfile) + expected_contents if results["dst_file_contents"] == expected_contents: score += 3 else: @@ -252,7 +252,7 @@ def task_check(results, params): hints += ["wrong file contents\n" + str(diff_pos[1])] #hints += ["wrong file contents"] params['dstfile'] = dstfile - expected_dst_ls = u"ls -l ~/\\*I\\*.txt\r\n-rw--w---- 1 {testuser} bilbo .*{dstfile}\r\n".format(**params) + expected_dst_ls = u"ls -l ~/\\*K\\*.txt\r\n-rw---x-w- 1 {testuser} bilbo .*{dstfile}\r\n".format(**params) if re.match(expected_dst_ls, results["dst_ls"]): score += 2 else: @@ -263,7 +263,7 @@ def task_check(results, params): "/dev/sdb2 on {mntdir} type ext4".format(**params), "sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)", "proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)", - "udev on /dev type devtmpfs (rw,nosuid,relatime,size=500680k,nr_inodes=125170,mode=755)", + "udev on /dev type devtmpfs (rw,nosuid,relatime", "/dev/sda1 on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)",] if all([results["mnt"].find(expected_mnt) > -1 for expected_mnt in expected_mnts]): score += 3 @@ -284,10 +284,10 @@ def prepare_disks(templates, task_params, global_params): r = random.Random(task_params['rndseed']) dstfile = "".join([r.choice("qQoOp") for i in range(64)]) + "I.txt" for i in range(1000): - x = "".join([r.choice(["po", "p0", "no", "ko", "fo", "qo"]) for i in range(20)]) - x += "".join([r.choice("uiasdfghjkyxcvbnm1234567890ASDFGHJKYZXCVBNM") for i in range(60)]) - x += r.choice(["lz", "1z", "Iz", "iz", "l2", "I2", "12"]) - hidden_contents += x + "\n" + + start = "".join([r.choice(["po", "p0", "no", "ko", "fo", "qo"]) for i in range(20)]) + mid = "".join([r.choice("1lIi") + r.choice("zZ2") for i in range(60)]) + hidden_contents += start + mid + "\n" # create hidden file dir_list = ['Qlipper', 'Thunar', 'blender', 'autostart', 'kazam', 'mc', 'netsurf', 'pulse', 'qupzilla', 'radare2', 'teamviewer', 'texstudio', 'vlc'] ending_list = ['rc', '.conf', '', '.txt'] diff --git a/kpov_judge/web/kpov_judge/kpov_judge.py b/kpov_judge/web/kpov_judge/kpov_judge.py index 1bd42c5..2b1d3c6 100755 --- a/kpov_judge/web/kpov_judge/kpov_judge.py +++ b/kpov_judge/web/kpov_judge/kpov_judge.py @@ -29,6 +29,7 @@ def gen_params(user_id, meta): params_meta = {'neznano_ime_naloge': {'opis':'NEZNANA NALOGA', 'w': False}} """ + @app.before_request def before_request(): g.db = pymongo.MongoClient(app.config['DB_HOST']).kpov @@ -39,21 +40,40 @@ def before_request(): except Exception as e: raise e #no auth or auth config? + @app.route('/') def root(): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') # env = flask.app.request.environ - tasks = g.db.tasks.find({}, {'task_id': 1}).sort('task_id') + 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') + # env = flask.app.request.environ + 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('index.html', student_id=student_id, tasks=task_list) + return render_template('class_tasks.html', student_id=student_id, tasks=task_list, clas=clas) + -def results_post(task_id, results): +@app.route('/classes/') +def class_list(): + student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') + # env = flask.app.request.environ + classes = g.db.classes.find({}, {'class_id': 1, 'name': 1,}).sort('name') + return render_template('class_list.html', student_id=student_id, classes=classes) + + +def results_post(class_id, task_id, results): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') db = g.db - params = db.task_params.find_one({'task_id': task_id, 'student_id': student_id})['params'] + params = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'student_id': student_id})['params'] if params is None: # params = {} #else: @@ -69,7 +89,7 @@ def results_post(task_id, results): 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({'task_id': task_id})['source'] + task_check_source = db.task_checkers.find_one({'class_id': class_id, 'task_id': task_id})['source'] task_check_code = compile(task_check_source, 'checker.py', 'exec') exec(task_check_code) # raise Exception(str(params)) @@ -81,15 +101,16 @@ def results_post(task_id, results): res_status = 'OK' else: res_status = 'NOT OK' - db.results.insert({'task_id': task_id, 'result': res, 'hints': hints, 'status': res_status,'student_id': student_id, 'response': results, 'time': datetime.datetime.now()}) + 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(task_id): + +def results_dict(class_id, task_id): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') db = g.db try: entry = db.results.find_one( - {'$query': {'task_id': task_id, 'student_id': student_id}, # vsi uporabniki brez nastavljenega REMOTE_USER (i.e. Apache basic auth) imajo skupne rezultate, napaka? + {'$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: @@ -98,34 +119,38 @@ def results_dict(task_id): except Exception as e: return {'Error': str(e)} -@app.route('/tasks/<task_id>/results.json', methods=['GET', 'POST']) -def results_json(task_id): + +@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(task_id, + return json.dumps(results_post(class_id, task_id, json.loads(flask.app.request.form['results']))) - return json.dumps(results_dict(task_id)) + return json.dumps(results_dict(class_id, task_id)) -@app.route('/tasks/<task_id>/<lang>/setup.<ending>', methods=['GET']) -def setup_svg(task_id, lang, ending): + +@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({'task_id': task_id})) - computers = list(db.computers_meta.find({'task_id': task_id})) + 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/<task_id>/<lang>/results.html') -def results_html(task_id, lang): - return render_template('results.html', results=results_dict(task_id)) -def public_meta(db, task_id): +@app.route('/tasks/<class_id>/<task_id>/<lang>/results.html') +def results_html(class_id, task_id, lang): + return render_template('results.html', results=results_dict(class_id, task_id)) + + +def public_meta(db, class_id, task_id): shown = {} try: - meta = db.task_params_meta.find_one({'task_id': task_id})['params'] + meta = db.task_params_meta.find_one({'class_id': class_id, 'task_id': task_id})['params'] for k, v in meta.iteritems(): try: if v['public']: @@ -137,42 +162,44 @@ def public_meta(db, task_id): return shown -@app.route('/tasks/<task_id>/task.py') -def task_source(task_id): +@app.route('/tasks/<class_id>/<task_id>/task.py') +def task_source(class_id, task_id): db = g.db try: - task_str = db.tasks.find_one({'task_id': task_id})['source'] + task_str = db.tasks.find_one({'class_id': class_id, 'task_id': task_id})['source'] except Exception: return dummy_task return task_str -@app.route('/tasks/<task_id>/task.html') -def task_html(task_id): - return render_template('task.html', task=task_source(task_id)) -def get_params(task_id, student_id, db): +@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({'task_id': task_id})['params'] + 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({'task_id': task_id, 'student_id': student_id}) + params = db.task_params.find_one({'class_id': class_id, 'task_id': task_id, 'student_id': student_id}) if params is None: try: - gen_params_source = db.gen_params.find_one({'task_id': task_id})['source'] + 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') exec(gen_params_code) params = gen_params(student_id, meta) - db.task_params.update({'task_id': task_id, 'student_id': student_id}, + db.task_params.update({'class_id': class_id, '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}): + 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({'task_id': task_id, 'student_id': student_id, 'name': name}, + 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}} @@ -182,29 +209,33 @@ def get_params(task_id, student_id, db): params = params['params'] return params, meta -@app.route('/tasks/<task_id>/') -def task_lang_redirect(task_id): - return redirect(url_for('task_greeting', task_id=task_id, lang=app.config['DEFAULT_LANG'])) -@app.route('/tasks/<task_id>/<lang>/howto/') -def task_howto(task_id, lang): +@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({'task_id': task_id, 'lang': lang})[0].get('text', '') + return db.howtos.find_one({'class_id': class_id, 'task_id': task_id, 'lang': lang}).get('text', '') -@app.route('/tasks/<task_id>/<lang>/images/<fname>') -def task_image(task_id, lang, fname): + +@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({'task_id': task_id, 'fname': fname})[0].get('data', '') + return db.howto_images.find_one({'class_id': class_id, 'task_id': task_id, 'fname': fname}).get('data', '') + -@app.route('/tasks/<task_id>/<lang>/') -def task_greeting(task_id, lang): +@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(task_id, student_id, db) + params, meta = get_params(class_id, task_id, student_id, db) instr_ok = True try: - instructions = db.task_instructions.find({'task_id': task_id})[0] + 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: @@ -212,7 +243,6 @@ def task_greeting(task_id, lang): except Exception as e: instructions = str(e) instr_ok = False - instructions = instructions if instr_ok: try: public_params = {} @@ -225,24 +255,25 @@ def task_greeting(task_id, lang): # instructions = instructions.format(**public_params).encode('utf8') except Exception as e: instructions = str(e) - computer_list = db.student_computers.find({'task_id': task_id, 'student_id': student_id}) + computer_list = db.student_computers.find({'class_id': class_id, '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: + 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({'task_id': task_id, 'student_id': student_id, 'create_openstack': True}).count() > 0: + 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 return render_template('task_greeting.html', computers=computer_list, lang=lang, openstack=openstackCreated, instructions=instructions) -@app.route('/tasks/<task_id>/params.json', methods=['GET', 'POST']) -def params_json(task_id): + +@app.route('/tasks/<class_id>/<task_id>/params.json', methods=['GET', 'POST']) +def params_json(class_id, task_id): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') db = g.db - params, meta = get_params(task_id, student_id, db) + params, meta = get_params(class_id, task_id, student_id, db) shown_params = {} if flask.app.request.method == 'POST': try: @@ -254,18 +285,19 @@ def params_json(task_id): 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}}) + db.task_params.update({'class_id': class_id, 'task_id': task_id, 'student_id': student_id}, {'$set': {'params': params}}) else: for name, param in params.iteritems(): if meta.get(name, {'public': False})['public']: shown_params[name] = param return json.dumps(shown_params) -@app.route('/tasks/<task_id>/<lang>/params.html', methods=['GET', 'POST']) -def params_html(task_id, lang): + +@app.route('/tasks/<class_id>/<task_id>/<lang>/params.html', methods=['GET', 'POST']) +def params_html(class_id, task_id, lang): student_id = flask.app.request.environ.get('REMOTE_USER', 'Nobody') db = g.db - params, meta = get_params(task_id, student_id, db) + params, meta = get_params(class_id, task_id, student_id, db) shown_params = {} for name, meta_param in meta.iteritems(): if meta_param.get('public', False): @@ -278,18 +310,20 @@ def params_html(task_id, lang): params[k] = flask.app.request.form[k] if v.get('public', False): shown_params[name] = params.get(name, '') - db.task_params.update({'task_id': task_id, 'student_id': student_id}, {'$set': {'params': params}}) + db.task_params.update({'class_id': class_id, 'task_id': task_id, 'student_id': student_id}, {'$set': {'params': params}}) return render_template('params.html', params=shown_params, params_meta=meta) -@app.route('/tasks/<task_id>/params_meta.json') -def params_meta(task_id): +@app.route('/tasks/<class_id>/<task_id>/params_meta.json') +def params_meta(class_id, task_id): db = g.db - return json.dumps(public_meta(db, task_id)) + return json.dumps(public_meta(db, class_id, task_id)) + @app.route('/static/<path:filename>') def send_foo(filename): return send_from_directory(app.config.STATIC_FILES, filename) + if __name__ == '__main__': app.run(host='0.0.0.0') diff --git a/kpov_judge/web/kpov_judge/templates/index.html b/kpov_judge/web/kpov_judge/templates/index.html index 193f419..b5149ab 100644 --- a/kpov_judge/web/kpov_judge/templates/index.html +++ b/kpov_judge/web/kpov_judge/templates/index.html @@ -7,10 +7,10 @@ Zdravo, {{student_id}} {{env}} </p> <p> -Trenutno so na voljo naloge: +Trenutno so na voljo predmeti: <ul> -{% for t in tasks %} -<li><a href="tasks/{{t}}">{{t}}</a></li> +{% for c in classes %} +<li><a href="{{url_for('class_tasks', class_id=c.class_id)}}">{{c.name}}</a></li> {% endfor %} </ul> </li> |