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 |