Commit a81c224118174dd8bd9d44e82e2a108c5f45b36c

Authored by Miguel Barão
1 parent fda752eb
Exists in master and in 1 other branch dev

- fix regression with allow_all button

- simplified log messages
perguntations/__init__.py
@@ -32,7 +32,7 @@ proof of submission and for review. @@ -32,7 +32,7 @@ proof of submission and for review.
32 ''' 32 '''
33 33
34 APP_NAME = 'perguntations' 34 APP_NAME = 'perguntations'
35 -APP_VERSION = '2020.05.dev4' 35 +APP_VERSION = '2020.05.dev5'
36 APP_DESCRIPTION = __doc__ 36 APP_DESCRIPTION = __doc__
37 37
38 __author__ = 'Miguel Barão' 38 __author__ = 'Miguel Barão'
perguntations/app.py
@@ -85,7 +85,7 @@ class App(): @@ -85,7 +85,7 @@ class App():
85 # ------------------------------------------------------------------------ 85 # ------------------------------------------------------------------------
86 def __init__(self, conf): 86 def __init__(self, conf):
87 self.online = dict() # {uid: {'student':{...}, 'test': {...}}, ...} 87 self.online = dict() # {uid: {'student':{...}, 'test': {...}}, ...}
88 - self.allowed = set([]) # '0' is hardcoded to allowed elsewhere 88 + self.allowed = set() # '0' is hardcoded to allowed elsewhere
89 89
90 logger.info('Loading test configuration "%s".', conf["testfile"]) 90 logger.info('Loading test configuration "%s".', conf["testfile"])
91 try: 91 try:
@@ -138,7 +138,7 @@ class App(): @@ -138,7 +138,7 @@ class App():
138 async def login(self, uid, try_pw): 138 async def login(self, uid, try_pw):
139 '''login authentication''' 139 '''login authentication'''
140 if uid not in self.allowed and uid != '0': # not allowed 140 if uid not in self.allowed and uid != '0': # not allowed
141 - logger.warning('Student %s: not allowed to login.', uid) 141 + logger.warning('"%s" not allowed to login.', uid)
142 return False 142 return False
143 143
144 # get name+password from db 144 # get name+password from db
@@ -157,34 +157,34 @@ class App(): @@ -157,34 +157,34 @@ class App():
157 if pw_ok: # success 157 if pw_ok: # success
158 self.allowed.discard(uid) # remove from set of allowed students 158 self.allowed.discard(uid) # remove from set of allowed students
159 if uid in self.online: 159 if uid in self.online:
160 - logger.warning('Student %s: already logged in.', uid) 160 + logger.warning('"%s" already logged in.', uid)
161 else: # make student online 161 else: # make student online
162 self.online[uid] = {'student': {'name': name, 'number': uid}} 162 self.online[uid] = {'student': {'name': name, 'number': uid}}
163 - logger.info('Student %s: logged in.', uid) 163 + logger.info('"%s" logged in.', uid)
164 return True 164 return True
165 # wrong password 165 # wrong password
166 - logger.info('Student %s: wrong password.', uid) 166 + logger.info('"%s" wrong password.', uid)
167 return False 167 return False
168 168
169 # ------------------------------------------------------------------------ 169 # ------------------------------------------------------------------------
170 def logout(self, uid): 170 def logout(self, uid):
171 '''student logout''' 171 '''student logout'''
172 self.online.pop(uid, None) # remove from dict if exists 172 self.online.pop(uid, None) # remove from dict if exists
173 - logger.info('Student %s: logged out.', uid) 173 + logger.info('"%s" logged out.', uid)
174 174
175 # ------------------------------------------------------------------------ 175 # ------------------------------------------------------------------------
176 async def generate_test(self, uid): 176 async def generate_test(self, uid):
177 '''generate a test for a given student''' 177 '''generate a test for a given student'''
178 if uid in self.online: 178 if uid in self.online:
179 - logger.info('Student %s: generating new test.', uid) 179 + logger.info('"%s" generating new test.', uid)
180 student_id = self.online[uid]['student'] # {number, name} 180 student_id = self.online[uid]['student'] # {number, name}
181 test = await self.testfactory.generate(student_id) 181 test = await self.testfactory.generate(student_id)
182 self.online[uid]['test'] = test 182 self.online[uid]['test'] = test
183 - logger.info('Student %s: test is ready.', uid) 183 + logger.info('"%s" test is ready.', uid)
184 return self.online[uid]['test'] 184 return self.online[uid]['test']
185 185
186 # this implies an error in the code. should never be here! 186 # this implies an error in the code. should never be here!
187 - logger.critical('Student %s: offline, cant generate test', uid) 187 + logger.critical('"%s" offline, cant generate test', uid)
188 188
189 # ------------------------------------------------------------------------ 189 # ------------------------------------------------------------------------
190 async def correct_test(self, uid, ans): 190 async def correct_test(self, uid, ans):
@@ -198,10 +198,10 @@ class App(): @@ -198,10 +198,10 @@ class App():
198 198
199 # --- submit answers and correct test 199 # --- submit answers and correct test
200 test.update_answers(ans) 200 test.update_answers(ans)
201 - logger.info('Student %s: %d answers submitted.', uid, len(ans)) 201 + logger.info('"%s" submitted %d answers.', uid, len(ans))
202 202
203 grade = await test.correct() 203 grade = await test.correct()
204 - logger.info('Student %s: grade = %g points.', uid, grade) 204 + logger.info('"%s" grade = %g points.', uid, grade)
205 205
206 # --- save test in JSON format 206 # --- save test in JSON format
207 fields = (uid, test['ref'], str(test['finish_time'])) 207 fields = (uid, test['ref'], str(test['finish_time']))
@@ -210,7 +210,7 @@ class App(): @@ -210,7 +210,7 @@ class App():
210 with open(path.expanduser(fpath), 'w') as file: 210 with open(path.expanduser(fpath), 'w') as file:
211 # default=str required for datetime objects 211 # default=str required for datetime objects
212 json.dump(test, file, indent=2, default=str) 212 json.dump(test, file, indent=2, default=str)
213 - logger.info('Student %s: saved JSON.', uid) 213 + logger.info('"%s" saved JSON.', uid)
214 214
215 # --- insert test and questions into database 215 # --- insert test and questions into database
216 with self.db_session() as sess: 216 with self.db_session() as sess:
@@ -233,7 +233,7 @@ class App(): @@ -233,7 +233,7 @@ class App():
233 test_id=test['ref']) 233 test_id=test['ref'])
234 for q in test['questions'] if 'grade' in q]) 234 for q in test['questions'] if 'grade' in q])
235 235
236 - logger.info('Student %s: database updated.', uid) 236 + logger.info('"%s" database updated.', uid)
237 return grade 237 return grade
238 238
239 # ------------------------------------------------------------------------ 239 # ------------------------------------------------------------------------
@@ -261,18 +261,18 @@ class App(): @@ -261,18 +261,18 @@ class App():
261 state=test['state'], 261 state=test['state'],
262 comment='')) 262 comment=''))
263 263
264 - logger.info('Student %s: gave up.', uid) 264 + logger.info('"%s" gave up.', uid)
265 return test 265 return test
266 266
267 # ------------------------------------------------------------------------ 267 # ------------------------------------------------------------------------
268 def event_test(self, uid, cmd, value): 268 def event_test(self, uid, cmd, value):
269 '''handles browser events the occur during the test''' 269 '''handles browser events the occur during the test'''
270 if cmd == 'focus': 270 if cmd == 'focus':
271 - logger.info('Student %s: focus %s', uid, value) 271 + logger.info('"%s": focus %s', uid, value)
272 elif cmd == 'size': 272 elif cmd == 'size':
273 scr_y, scr_x, win_y, win_x = value 273 scr_y, scr_x, win_y, win_x = value
274 area = win_x * win_y / (scr_x * scr_y) * 100 274 area = win_x * win_y / (scr_x * scr_y) * 100
275 - logger.info('Student %s: area=%g%%, window=%dx%d, screen=%dx%d', 275 + logger.info('"%s": area=%g%%, window=%dx%d, screen=%dx%d',
276 uid, area, win_x, win_y, scr_x, scr_y) 276 uid, area, win_x, win_y, scr_x, scr_y)
277 277
278 # ------------------------------------------------------------------------ 278 # ------------------------------------------------------------------------
@@ -396,12 +396,22 @@ class App(): @@ -396,12 +396,22 @@ class App():
396 def allow_student(self, uid): 396 def allow_student(self, uid):
397 '''allow a single student to login''' 397 '''allow a single student to login'''
398 self.allowed.add(uid) 398 self.allowed.add(uid)
399 - logger.info('Student %s: allowed to login.', uid) 399 + logger.info('"%s" allowed to login.', uid)
400 400
401 def deny_student(self, uid): 401 def deny_student(self, uid):
402 '''deny a single student to login''' 402 '''deny a single student to login'''
403 self.allowed.discard(uid) 403 self.allowed.discard(uid)
404 - logger.info('Student %s: denied to login', uid) 404 + logger.info('"%s" denied to login', uid)
  405 +
  406 + def allow_all_students(self):
  407 + '''allow all students to login'''
  408 + logger.info('Allowing all students...')
  409 + self.allowed = set(s[0] for s in self.get_all_students())
  410 +
  411 + def deny_all_students(self):
  412 + '''deny all students to login'''
  413 + logger.info('Denying all students...')
  414 + self.allowed = set()
405 415
406 async def update_student_password(self, uid, password=''): 416 async def update_student_password(self, uid, password=''):
407 '''change password on the database''' 417 '''change password on the database'''
@@ -410,7 +420,7 @@ class App(): @@ -410,7 +420,7 @@ class App():
410 with self.db_session() as sess: 420 with self.db_session() as sess:
411 student = sess.query(Student).filter_by(id=uid).one() 421 student = sess.query(Student).filter_by(id=uid).one()
412 student.password = password 422 student.password = password
413 - logger.info('Student %s: password updated.', uid) 423 + logger.info('"%s" password updated.', uid)
414 424
415 def insert_new_student(self, uid, name): 425 def insert_new_student(self, uid, name):
416 '''insert new student into the database''' 426 '''insert new student into the database'''
@@ -420,4 +430,4 @@ class App(): @@ -420,4 +430,4 @@ class App():
420 except exc.SQLAlchemyError: 430 except exc.SQLAlchemyError:
421 logger.error('Insert failed: student %s already exists?', uid) 431 logger.error('Insert failed: student %s already exists?', uid)
422 else: 432 else:
423 - logger.info('New student inserted: %s, %s', uid, name) 433 + logger.info('New student: "%s", "%s"', uid, name)
perguntations/serve.py
@@ -241,10 +241,12 @@ class AdminHandler(BaseHandler): @@ -241,10 +241,12 @@ class AdminHandler(BaseHandler):
241 241
242 if cmd == 'allow': 242 if cmd == 'allow':
243 self.testapp.allow_student(value) 243 self.testapp.allow_student(value)
244 -  
245 elif cmd == 'deny': 244 elif cmd == 'deny':
246 self.testapp.deny_student(value) 245 self.testapp.deny_student(value)
247 - 246 + elif cmd == 'allow_all':
  247 + self.testapp.allow_all_students()
  248 + elif cmd == 'deny_all':
  249 + self.testapp.deny_all_students()
248 elif cmd == 'reset_password': 250 elif cmd == 'reset_password':
249 await self.testapp.update_student_password(uid=value, password='') 251 await self.testapp.update_student_password(uid=value, password='')
250 252
perguntations/static/js/admin.js
@@ -15,10 +15,12 @@ $(document).ready(function() { @@ -15,10 +15,12 @@ $(document).ready(function() {
15 function button_handlers() { 15 function button_handlers() {
16 // button handlers (runs once) 16 // button handlers (runs once)
17 $("#allow_all").click(function() { 17 $("#allow_all").click(function() {
18 - $(":checkbox").prop("checked", true).trigger('change'); 18 + $.postJSON("/admin", {"cmd": "allow_all"});
  19 + // $(":checkbox").prop("checked", true).trigger('change');
19 }); 20 });
20 $("#deny_all").click(function() { 21 $("#deny_all").click(function() {
21 - $(":checkbox").prop("checked", false).trigger('change'); 22 + $.postJSON("/admin", {"cmd": "deny_all"});
  23 + // $(":checkbox").prop("checked", false).trigger('change');
22 }); 24 });
23 $("#reset_password").click(function () { 25 $("#reset_password").click(function () {
24 $.postJSON("/admin", { 26 $.postJSON("/admin", {