Commit 1e53d0f7b15c754a5b3e3c15996a8ecdb72bb9c2

Authored by Miguel Barao
1 parent 6c831b0d
Exists in master and in 1 other branch dev

- replaced loggedin by tags 'online' and 'finished'. Tags are shown in

/students.
BUGS.md
1   -
  1 +
2 2  
3 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 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 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 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 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 16 - permitir enviar varios testes, aluno escolhe qual o teste que quer fazer.
17 17 - criar script json2md.py ou outra forma de gerar um teste ja realizado
18 18 - Menu para professor com link para /results e /students
19 19 - implementar singlepage/multipage. Fazer uma class para single page que trate de andar gerir o avanco e correcao das perguntas
20 20 - permitir adicionar imagens nas perguntas
21 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 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 30 - information points é definido onde? test.y ou questions.py?
27 31 - textarea monospace
28 32 - disable tab behavior in textarea.
... ...
questions.py
... ... @@ -95,7 +95,12 @@ def create_question(q):
95 95 questiontype = Question
96 96  
97 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 23 self.database = database.Database(testconf['database'])
24 24 self.auth = AuthController(database=testconf['database'])
25 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 29 # --- DEFAULT ------------------------------------------------------------
29 30 # any path, e.g. /xpto/aargh is redirected to the test
... ... @@ -37,7 +38,7 @@ class Root(object):
37 38 @require()
38 39 def logout(self):
39 40 uid = cherrypy.session.get('userid')
40   - self.loggedin.discard(uid)
  41 + self.tags['online'].discard(uid)
41 42 cherrypy.lib.sessions.expire() # session coockie expires client side
42 43 cherrypy.session['userid'] = cherrypy.request.login = None
43 44 cherrypy.log.error('Student {0} logged out.'.format(uid), 'APPLICATION')
... ... @@ -58,7 +59,7 @@ class Root(object):
58 59  
59 60 students = self.database.get_students()
60 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 64 # --- RESULTS ------------------------------------------------------------
64 65 @cherrypy.expose
... ... @@ -82,7 +83,7 @@ class Root(object):
82 83 cherrypy.session['test'] = t = test.Test(self.testconf)
83 84 t['number'] = uid
84 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 88 # Generate question
88 89 template = self.templates.get_template('test.html')
... ... @@ -126,7 +127,8 @@ class Root(object):
126 127  
127 128 else:
128 129 # ---- Expire session ----
129   - self.loggedin.discard(t['number'])
  130 + self.tags['online'].discard(t['number'])
  131 + self.tags['finished'].add(t['number'])
130 132 cherrypy.lib.sessions.expire() # session coockie expires client side
131 133 cherrypy.session['userid'] = cherrypy.request.login = None
132 134 cherrypy.log.error('Student %s terminated with grade = %.2f points.' %
... ...
templates/students.html
... ... @@ -33,12 +33,13 @@
33 33 <div class="container">
34 34 <div class="panel panel-default drop-shadow">
35 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 37 </div>
38 38 <!-- <div class="panel-body"> -->
39 39 <table class="table">
40 40 <thead>
41 41 <tr>
  42 + <th>Tags</th>
42 43 <th>Número</th>
43 44 <th>Nome</th>
44 45 <th>Password</th>
... ... @@ -46,27 +47,31 @@
46 47 </thead>
47 48 <tbody>
48 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 75 </tbody>
71 76 </table>
72 77 </div> <!-- panel -->
... ...
templates/test.html
... ... @@ -88,7 +88,7 @@
88 88 ${t['name']} (${t['number']}) <span class="caret"></span>
89 89 </a>
90 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 92 <!-- <li><a href="#">Change password</a></li> -->
93 93 </ul>
94 94 </li>
... ... @@ -101,7 +101,6 @@
101 101 <div class="container">
102 102 <div class="row">
103 103 <form action="/correct/" method="post" id="test">
104   -
105 104 <%!
106 105 import markdown as md
107 106 import yaml
... ...