Commit 1e53d0f7b15c754a5b3e3c15996a8ecdb72bb9c2
1 parent
6c831b0d
Exists in
master
and in
1 other branch
- replaced loggedin by tags 'online' and 'finished'. Tags are shown in
/students.
Showing
5 changed files
with
49 additions
and
34 deletions
Show diff stats
BUGS.md
1 | - | 1 | + |
2 | 2 | ||
3 | # BUGS | 3 | # BUGS |
4 | 4 | ||
5 | +!!! - questions type script, necessário dar um caminho exacto relativamete ao directorio do server em vez da pergunta. deveria ser possivel mover as perguntas de directorio sem rebentar os caminhos. | ||
5 | - se database for mal configurada, é criada uma base de dados vazia e rebenta na autenticacao. | 6 | - se database for mal configurada, é criada uma base de dados vazia e rebenta na autenticacao. |
6 | -- hash das passwords obtidas da concatenacao do numero de aluno com password (evita que passwords repetidas sejam detectadas). | ||
7 | - mostrar erro quando nao consegue importar questions files | 7 | - mostrar erro quando nao consegue importar questions files |
8 | -- numeros das perguntas não fazem sentido quando há caixas de informação (numerar informacao tb?) | ||
9 | - testar regex na definicao das perguntas. como se faz rawstring em yaml? singlequote? problemas de backslash??? sim... necessário fazer \\ em varios casos, mas não é claro! e.g. \n é convertido em espaço mas \w é convertido em \\ e w. | 8 | - testar regex na definicao das perguntas. como se faz rawstring em yaml? singlequote? problemas de backslash??? sim... necessário fazer \\ em varios casos, mas não é claro! e.g. \n é convertido em espaço mas \w é convertido em \\ e w. |
10 | 9 | ||
11 | 10 | ||
12 | # TODO | 11 | # TODO |
13 | 12 | ||
14 | -- Quando apresenta o teste, preencher com os valores definidos em answer (permite que professor dê informação à partida, e no modo practice fiquem com o preenchido anteriormente) | ||
15 | -- testar envio de parametros para stdin para perguntas tipo generator | 13 | +- Criar botão para o docente fazer enable/disable do aluno explicitamente (exames presenciais). |
14 | +- testar envio de parametros para stdin para perguntas tipo generator. | ||
15 | +- hash das passwords obtidas da concatenacao do numero de aluno com password (evita que passwords repetidas sejam detectadas). | ||
16 | - permitir enviar varios testes, aluno escolhe qual o teste que quer fazer. | 16 | - permitir enviar varios testes, aluno escolhe qual o teste que quer fazer. |
17 | - criar script json2md.py ou outra forma de gerar um teste ja realizado | 17 | - criar script json2md.py ou outra forma de gerar um teste ja realizado |
18 | - Menu para professor com link para /results e /students | 18 | - Menu para professor com link para /results e /students |
19 | - implementar singlepage/multipage. Fazer uma class para single page que trate de andar gerir o avanco e correcao das perguntas | 19 | - implementar singlepage/multipage. Fazer uma class para single page que trate de andar gerir o avanco e correcao das perguntas |
20 | - permitir adicionar imagens nas perguntas | 20 | - permitir adicionar imagens nas perguntas |
21 | - criar perguntas de outros tipos, e.g. associação, ordenação, varios textinput | 21 | - criar perguntas de outros tipos, e.g. associação, ordenação, varios textinput |
22 | +- perguntas para professor corrigir mais tarde. | ||
23 | +- testar com microsoft surface. | ||
22 | 24 | ||
23 | 25 | ||
24 | # FIXED | 26 | # FIXED |
25 | 27 | ||
28 | +- numeros das perguntas não fazem sentido quando há caixas de informação (numerar informacao tb?) | ||
29 | +- Quando apresenta o teste, preencher com os valores definidos em answer (permite que professor dê informação à partida, e no modo practice fiquem com o preenchido anteriormente) | ||
26 | - information points é definido onde? test.y ou questions.py? | 30 | - information points é definido onde? test.y ou questions.py? |
27 | - textarea monospace | 31 | - textarea monospace |
28 | - disable tab behavior in textarea. | 32 | - disable tab behavior in textarea. |
questions.py
@@ -95,7 +95,12 @@ def create_question(q): | @@ -95,7 +95,12 @@ def create_question(q): | ||
95 | questiontype = Question | 95 | questiontype = Question |
96 | 96 | ||
97 | # create question instance and return | 97 | # create question instance and return |
98 | - return questiontype(q) | 98 | + try: |
99 | + qinstance = questiontype(q) | ||
100 | + except: | ||
101 | + print(' * Error creating question "{0}" from file "{1}".'.format(q['ref'], q['filename'])) | ||
102 | + | ||
103 | + return qinstance | ||
99 | 104 | ||
100 | 105 | ||
101 | # --------------------------------------------------------------------------- | 106 | # --------------------------------------------------------------------------- |
serve.py
@@ -23,7 +23,8 @@ class Root(object): | @@ -23,7 +23,8 @@ class Root(object): | ||
23 | self.database = database.Database(testconf['database']) | 23 | self.database = database.Database(testconf['database']) |
24 | self.auth = AuthController(database=testconf['database']) | 24 | self.auth = AuthController(database=testconf['database']) |
25 | self.templates = TemplateLookup(directories=['templates'], input_encoding='utf-8') | 25 | self.templates = TemplateLookup(directories=['templates'], input_encoding='utf-8') |
26 | - self.loggedin = set() # students currently logged in | 26 | + self.tags = {'online': set(), 'finished': set()} |
27 | + # self.loggedin = set() # students currently logged in | ||
27 | 28 | ||
28 | # --- DEFAULT ------------------------------------------------------------ | 29 | # --- DEFAULT ------------------------------------------------------------ |
29 | # any path, e.g. /xpto/aargh is redirected to the test | 30 | # any path, e.g. /xpto/aargh is redirected to the test |
@@ -37,7 +38,7 @@ class Root(object): | @@ -37,7 +38,7 @@ class Root(object): | ||
37 | @require() | 38 | @require() |
38 | def logout(self): | 39 | def logout(self): |
39 | uid = cherrypy.session.get('userid') | 40 | uid = cherrypy.session.get('userid') |
40 | - self.loggedin.discard(uid) | 41 | + self.tags['online'].discard(uid) |
41 | cherrypy.lib.sessions.expire() # session coockie expires client side | 42 | cherrypy.lib.sessions.expire() # session coockie expires client side |
42 | cherrypy.session['userid'] = cherrypy.request.login = None | 43 | cherrypy.session['userid'] = cherrypy.request.login = None |
43 | cherrypy.log.error('Student {0} logged out.'.format(uid), 'APPLICATION') | 44 | cherrypy.log.error('Student {0} logged out.'.format(uid), 'APPLICATION') |
@@ -58,7 +59,7 @@ class Root(object): | @@ -58,7 +59,7 @@ class Root(object): | ||
58 | 59 | ||
59 | students = self.database.get_students() | 60 | students = self.database.get_students() |
60 | template = self.templates.get_template('students.html') | 61 | template = self.templates.get_template('students.html') |
61 | - return template.render(students=students, loggedin=self.loggedin) | 62 | + return template.render(students=students, tags=self.tags) |
62 | 63 | ||
63 | # --- RESULTS ------------------------------------------------------------ | 64 | # --- RESULTS ------------------------------------------------------------ |
64 | @cherrypy.expose | 65 | @cherrypy.expose |
@@ -82,7 +83,7 @@ class Root(object): | @@ -82,7 +83,7 @@ class Root(object): | ||
82 | cherrypy.session['test'] = t = test.Test(self.testconf) | 83 | cherrypy.session['test'] = t = test.Test(self.testconf) |
83 | t['number'] = uid | 84 | t['number'] = uid |
84 | t['name'] = name | 85 | t['name'] = name |
85 | - self.loggedin.add(uid) # track logged in students | 86 | + self.tags['online'].add(uid) # track logged in students |
86 | 87 | ||
87 | # Generate question | 88 | # Generate question |
88 | template = self.templates.get_template('test.html') | 89 | template = self.templates.get_template('test.html') |
@@ -126,7 +127,8 @@ class Root(object): | @@ -126,7 +127,8 @@ class Root(object): | ||
126 | 127 | ||
127 | else: | 128 | else: |
128 | # ---- Expire session ---- | 129 | # ---- Expire session ---- |
129 | - self.loggedin.discard(t['number']) | 130 | + self.tags['online'].discard(t['number']) |
131 | + self.tags['finished'].add(t['number']) | ||
130 | cherrypy.lib.sessions.expire() # session coockie expires client side | 132 | cherrypy.lib.sessions.expire() # session coockie expires client side |
131 | cherrypy.session['userid'] = cherrypy.request.login = None | 133 | cherrypy.session['userid'] = cherrypy.request.login = None |
132 | cherrypy.log.error('Student %s terminated with grade = %.2f points.' % | 134 | cherrypy.log.error('Student %s terminated with grade = %.2f points.' % |
templates/students.html
@@ -33,12 +33,13 @@ | @@ -33,12 +33,13 @@ | ||
33 | <div class="container"> | 33 | <div class="container"> |
34 | <div class="panel panel-default drop-shadow"> | 34 | <div class="panel panel-default drop-shadow"> |
35 | <div class="panel-heading"> | 35 | <div class="panel-heading"> |
36 | - List of students (${len(loggedin)} online) | 36 | + <span class="badge">${len(tags['online'])} online</span> <span class="badge">${len(tags['finished'])} finished</span> |
37 | </div> | 37 | </div> |
38 | <!-- <div class="panel-body"> --> | 38 | <!-- <div class="panel-body"> --> |
39 | <table class="table"> | 39 | <table class="table"> |
40 | <thead> | 40 | <thead> |
41 | <tr> | 41 | <tr> |
42 | + <th>Tags</th> | ||
42 | <th>Número</th> | 43 | <th>Número</th> |
43 | <th>Nome</th> | 44 | <th>Nome</th> |
44 | <th>Password</th> | 45 | <th>Password</th> |
@@ -46,27 +47,31 @@ | @@ -46,27 +47,31 @@ | ||
46 | </thead> | 47 | </thead> |
47 | <tbody> | 48 | <tbody> |
48 | % for r in students: | 49 | % for r in students: |
49 | - % if r[0] in loggedin: | ||
50 | - <tr class="danger"> | ||
51 | - % else: | ||
52 | - <tr> | ||
53 | - % endif | ||
54 | - <td>${r[0]}</td> <!-- numero --> | ||
55 | - <td>${r[1]}</td> <!-- nome --> | ||
56 | - <td class="col-sm-6"> | ||
57 | - <form action="/students/" method="post" id="${r[0]}"> | ||
58 | - <div class="input-group"> | ||
59 | - <span class="input-group-btn"> | ||
60 | - <!-- <button class="btn btn-danger" type="submit">reset</button> --> | ||
61 | - <button form="${r[0]}" type="submit" value="submit" class="btn btn-danger">reset</button> | 50 | + <tr> |
51 | + <td> | ||
52 | + % if r[0] in tags['online']: | ||
53 | + <span class="label label-primary">online</span> | ||
54 | + % endif | ||
55 | + % if r[0] in tags['finished']: | ||
56 | + <span class="label label-success">finished</span> | ||
57 | + % endif | ||
58 | + </td> | ||
59 | + <td>${r[0]}</td> <!-- numero --> | ||
60 | + <td>${r[1]}</td> <!-- nome --> | ||
61 | + <td class="col-sm-3"> | ||
62 | + <form action="/students/" method="post" id="${r[0]}"> | ||
63 | + <div class="input-group"> | ||
64 | + <input type="password" class="form-control" placeholder="${r[2][:8]}" name="${r[0]}"> | ||
65 | + <span class="input-group-btn"> | ||
66 | + <!-- <button class="btn btn-danger" type="submit">reset</button> --> | ||
67 | + <button form="${r[0]}" type="submit" value="submit" class="btn btn-danger">reset</button> | ||
62 | 68 | ||
63 | - </span> | ||
64 | - <input type="password" class="form-control" placeholder="${r[2]}" name="${r[0]}"> | ||
65 | - </div><!-- /input-group --> | ||
66 | - </form> | ||
67 | - </td> <!-- password --> | ||
68 | - </tr> | ||
69 | - % endfor | 69 | + </span> |
70 | + </div><!-- /input-group --> | ||
71 | + </form> | ||
72 | + </td> <!-- password --> | ||
73 | + </tr> | ||
74 | + % endfor | ||
70 | </tbody> | 75 | </tbody> |
71 | </table> | 76 | </table> |
72 | </div> <!-- panel --> | 77 | </div> <!-- panel --> |
templates/test.html
@@ -88,7 +88,7 @@ | @@ -88,7 +88,7 @@ | ||
88 | ${t['name']} (${t['number']}) <span class="caret"></span> | 88 | ${t['name']} (${t['number']}) <span class="caret"></span> |
89 | </a> | 89 | </a> |
90 | <ul class="dropdown-menu"> | 90 | <ul class="dropdown-menu"> |
91 | - <li><a href="/logout"><span class="glyphicon glyphicon-log-out" aria-hidden="true"></span> Logout</a></li> | 91 | + <li><a href="/logout"><span class="glyphicon glyphicon-log-out" aria-hidden="true"></span> Sair</a></li> |
92 | <!-- <li><a href="#">Change password</a></li> --> | 92 | <!-- <li><a href="#">Change password</a></li> --> |
93 | </ul> | 93 | </ul> |
94 | </li> | 94 | </li> |
@@ -101,7 +101,6 @@ | @@ -101,7 +101,6 @@ | ||
101 | <div class="container"> | 101 | <div class="container"> |
102 | <div class="row"> | 102 | <div class="row"> |
103 | <form action="/correct/" method="post" id="test"> | 103 | <form action="/correct/" method="post" id="test"> |
104 | - | ||
105 | <%! | 104 | <%! |
106 | import markdown as md | 105 | import markdown as md |
107 | import yaml | 106 | import yaml |