diff --git a/BUGS.md b/BUGS.md index b1d9135..b898992 100644 --- a/BUGS.md +++ b/BUGS.md @@ -1,13 +1,11 @@ # BUGS +- implementar practice mode. - usar thread.Lock para aceder a variaveis de estado? # TODO -- lidar com focus. aviso em /admin -- implementar practice mode. -- permitir adicionar imagens nas perguntas. - abrir o teste numa janela maximizada e que nao permite que o aluno a redimensione/mova. - detectar scroll e enviar posição para servidor (analise de scroll para detectar copianço? ou simplesmente para analisar como os alunos percorrem o teste) - detectar se janela perde focus e alertar o prof (http://stackoverflow.com/questions/1060008/is-there-a-way-to-detect-if-a-browser-window-is-not-currently-active) @@ -24,6 +22,7 @@ # FIXED +- permitir adicionar imagens nas perguntas. - detect_unfocus.js so funciona se estiver inline no html. porquê??? - inserir novo aluno /admin não fecha. - se aluno desistir, ainda fica marcado como online diff --git a/app.py b/app.py index 1c68a4a..33f4198 100644 --- a/app.py +++ b/app.py @@ -6,7 +6,7 @@ import bcrypt from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, scoped_session from models import Base, Student, Test, Question -from contextlib import contextmanager # to create `with` statement for db sessions +from contextlib import contextmanager # to use `with` statement for db sessions import test import threading @@ -28,7 +28,7 @@ class App(object): # } logger.info('============= Running perguntations =============') self.lock = threading.Lock() - self.online = dict() # {uid: {'student':{}}} + self.online = dict() # {uid: {'student':{}}} self.allowed = set([]) # '0' is hardcoded to allowed elsewhere self.testfactory = test.TestFactory(filename, conf=conf) @@ -226,6 +226,13 @@ class App(object): # set of 'uid' allowed to login return self.allowed + def get_file(self, uid, ref, key): + # return filename corresponding to (uid, ref, name) if declared in the question + t = self.get_test(uid) + for q in t['questions']: + if q['ref'] == ref and key in q['files']: + return path.abspath(path.join(q['path'], q['files'][key])) + # --- helpers (change state) def allow_student(self, uid): self.allowed.add(uid) diff --git a/questions.py b/questions.py index b86d033..946393e 100644 --- a/questions.py +++ b/questions.py @@ -38,6 +38,7 @@ logger = logging.getLogger(__name__) try: import yaml + # import markdown except ImportError: logger.critical('Python package missing. See README.md for instructions.') sys.exit(1) @@ -46,7 +47,7 @@ else: # correct: !regex '[aA]zul' yaml.add_constructor('!regex', lambda l, n: re.compile(l.construct_scalar(n))) -from tools import load_yaml, run_script +from tools import load_yaml, run_script, md_to_html # =========================================================================== @@ -179,6 +180,7 @@ class Question(dict): self.set_defaults({ 'title': '', 'answer': None, + 'files': {}, }) def correct(self): diff --git a/serve.py b/serve.py index 0dd25c5..40c6feb 100755 --- a/serve.py +++ b/serve.py @@ -231,6 +231,14 @@ class Root(object): allgrades=self.app.get_student_grades_from_all_tests(uid) ) + # --- FILE --------------------------------------------------------------- + @cherrypy.expose + @require() + def file(self, ref, name): + # serve a static file: userid, question ref, file name + uid = cherrypy.session.get(SESSION_KEY) + filename = self.app.get_file(uid, ref, name) + return cherrypy.lib.static.serve_file(filename) # --- ADMIN -------------------------------------------------------------- @cherrypy.expose diff --git a/templates/test.html b/templates/test.html index d366ab9..e3546c7 100644 --- a/templates/test.html +++ b/templates/test.html @@ -99,17 +99,9 @@
<%! - import markdown as md import yaml - import random + from tools import md_to_html %> - <%def name="pretty(text)"> - ${md.markdown(str(text), extensions=['markdown.extensions.tables', - 'markdown.extensions.fenced_code', - 'markdown.extensions.codehilite', - 'markdown.extensions.def_list', - 'markdown.extensions.sane_lists'])} - <% total_points = sum(q['points'] for q in t['questions']) %> @@ -135,7 +127,7 @@ ${q['title']}

- ${pretty(q['text'])} + ${md_to_html(q['text'], q['ref'], q['files'])}

% elif q['type'] == 'warning': @@ -144,7 +136,7 @@ ${q['title']}

- ${pretty(q['text'])} + ${md_to_html(q['text'], q['ref'], q['files'])}

% elif q['type'] == 'alert': @@ -153,7 +145,7 @@ ${q['title']}

- ${pretty(q['text'])} + ${md_to_html(q['text'], q['ref'], q['files'])}

@@ -170,7 +162,7 @@
- ${pretty(q['text'])} + ${md_to_html(q['text'], q['ref'], q['files'])}
@@ -179,7 +171,7 @@
% endfor @@ -189,7 +181,7 @@
% endfor @@ -207,7 +199,7 @@
- ${pretty(q['hint'])} + ${md_to_html(q['hint'], q['ref'], q['files'])}
% endif # hint @@ -223,7 +215,7 @@