Commit deb94ec762808cf5714ac8b014930211d1741675
1 parent
fb7a9089
Exists in
master
and in
1 other branch
- show browser/screen area and focus state on admin page.
- minor cosmetic changes.
Showing
3 changed files
with
41 additions
and
13 deletions
Show diff stats
perguntations/app.py
@@ -86,6 +86,8 @@ class App(): | @@ -86,6 +86,8 @@ class App(): | ||
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 | + self.unfocus = set() # set of students that have no browser focus | ||
90 | + self.area = dict() # {uid: percent_area} | ||
89 | 91 | ||
90 | logger.info('Loading test configuration "%s".', conf["testfile"]) | 92 | logger.info('Loading test configuration "%s".', conf["testfile"]) |
91 | try: | 93 | try: |
@@ -268,12 +270,12 @@ class App(): | @@ -268,12 +270,12 @@ class App(): | ||
268 | def event_test(self, uid, cmd, value): | 270 | def event_test(self, uid, cmd, value): |
269 | '''handles browser events the occur during the test''' | 271 | '''handles browser events the occur during the test''' |
270 | if cmd == 'focus': | 272 | if cmd == 'focus': |
271 | - logger.info('"%s": focus %s', uid, value) | 273 | + if value: |
274 | + self.focus_student(uid) | ||
275 | + else: | ||
276 | + self.unfocus_student(uid) | ||
272 | elif cmd == 'size': | 277 | elif cmd == 'size': |
273 | - scr_y, scr_x, win_y, win_x = value | ||
274 | - area = win_x * win_y / (scr_x * scr_y) * 100 | ||
275 | - logger.info('"%s": area=%g%%, window=%dx%d, screen=%dx%d', | ||
276 | - uid, area, win_x, win_y, scr_x, scr_y) | 278 | + self.set_screen_area(uid, value) |
277 | 279 | ||
278 | # ------------------------------------------------------------------------ | 280 | # ------------------------------------------------------------------------ |
279 | # --- GETTERS | 281 | # --- GETTERS |
@@ -374,6 +376,8 @@ class App(): | @@ -374,6 +376,8 @@ class App(): | ||
374 | 'start_time': self.online.get(uid, {}).get('test', {}) | 376 | 'start_time': self.online.get(uid, {}).get('test', {}) |
375 | .get('start_time', ''), | 377 | .get('start_time', ''), |
376 | 'password_defined': pw != '', | 378 | 'password_defined': pw != '', |
379 | + 'unfocus': uid in self.unfocus, | ||
380 | + 'area': self.area.get(uid, None), | ||
377 | 'grades': self.get_student_grades_from_test( | 381 | 'grades': self.get_student_grades_from_test( |
378 | uid, self.testfactory['ref']) | 382 | uid, self.testfactory['ref']) |
379 | } for uid, name, pw in self.get_all_students()] | 383 | } for uid, name, pw in self.get_all_students()] |
@@ -406,12 +410,30 @@ class App(): | @@ -406,12 +410,30 @@ class App(): | ||
406 | def allow_all_students(self): | 410 | def allow_all_students(self): |
407 | '''allow all students to login''' | 411 | '''allow all students to login''' |
408 | logger.info('Allowing all students...') | 412 | logger.info('Allowing all students...') |
409 | - self.allowed = set(s[0] for s in self.get_all_students()) | 413 | + self.allowed.update(s[0] for s in self.get_all_students()) |
410 | 414 | ||
411 | def deny_all_students(self): | 415 | def deny_all_students(self): |
412 | '''deny all students to login''' | 416 | '''deny all students to login''' |
413 | logger.info('Denying all students...') | 417 | logger.info('Denying all students...') |
414 | - self.allowed = set() | 418 | + self.allowed.clear() |
419 | + | ||
420 | + def focus_student(self, uid): | ||
421 | + '''set student in focus state''' | ||
422 | + self.unfocus.discard(uid) | ||
423 | + logger.info('"%s" focus', uid) | ||
424 | + | ||
425 | + def unfocus_student(self, uid): | ||
426 | + '''set student in unfocus state''' | ||
427 | + self.unfocus.add(uid) | ||
428 | + logger.info('"%s" unfocus', uid) | ||
429 | + | ||
430 | + def set_screen_area(self, uid, sizes): | ||
431 | + '''set current browser area as detected in resize event''' | ||
432 | + scr_y, scr_x, win_y, win_x = sizes | ||
433 | + area = win_x * win_y / (scr_x * scr_y) * 100 | ||
434 | + self.area[uid] = area | ||
435 | + logger.info('"%s": area=%g%%, window=%dx%d, screen=%dx%d', | ||
436 | + uid, area, win_x, win_y, scr_x, scr_y) | ||
415 | 437 | ||
416 | async def update_student_password(self, uid, password=''): | 438 | async def update_student_password(self, uid, password=''): |
417 | '''change password on the database''' | 439 | '''change password on the database''' |
perguntations/static/js/admin.js
@@ -16,11 +16,9 @@ $(document).ready(function() { | @@ -16,11 +16,9 @@ $(document).ready(function() { | ||
16 | // button handlers (runs once) | 16 | // button handlers (runs once) |
17 | $("#allow_all").click(function() { | 17 | $("#allow_all").click(function() { |
18 | $.postJSON("/admin", {"cmd": "allow_all"}); | 18 | $.postJSON("/admin", {"cmd": "allow_all"}); |
19 | - // $(":checkbox").prop("checked", true).trigger('change'); | ||
20 | }); | 19 | }); |
21 | $("#deny_all").click(function() { | 20 | $("#deny_all").click(function() { |
22 | $.postJSON("/admin", {"cmd": "deny_all"}); | 21 | $.postJSON("/admin", {"cmd": "deny_all"}); |
23 | - // $(":checkbox").prop("checked", false).trigger('change'); | ||
24 | }); | 22 | }); |
25 | $("#reset_password").click(function () { | 23 | $("#reset_password").click(function () { |
26 | $.postJSON("/admin", { | 24 | $.postJSON("/admin", { |
@@ -120,7 +118,15 @@ $(document).ready(function() { | @@ -120,7 +118,15 @@ $(document).ready(function() { | ||
120 | var uid = d['uid']; | 118 | var uid = d['uid']; |
121 | var checked = d['allowed'] ? 'checked' : ''; | 119 | var checked = d['allowed'] ? 'checked' : ''; |
122 | var password_defined = d['password_defined'] ? ' <span class="badge badge-secondary"><i class="fa fa-key" aria-hidden="true"></i></span>' : ''; | 120 | var password_defined = d['password_defined'] ? ' <span class="badge badge-secondary"><i class="fa fa-key" aria-hidden="true"></i></span>' : ''; |
123 | - var hora_inicio = d['start_time'] ? ' <span class="badge badge-success">' + d['start_time'].slice(11,19) + '</span>': ''; | 121 | + var hora_inicio = d['start_time'] ? ' <span class="badge badge-success"><i class="fas fa-hourglass-start"></i> ' + d['start_time'].slice(11,16) + '</span>': ''; |
122 | + var unfocus = d['unfocus']? ' <span class="badge badge-danger">unfocus</span>' : ''; | ||
123 | + var area = ''; | ||
124 | + if (d['start_time'] ) { | ||
125 | + if (d['area'] > 75) | ||
126 | + area = ' <span class="badge badge-success"><i class="fas fa-desktop"></i> ' + Math.round(d['area']) + '%</span>'; | ||
127 | + else | ||
128 | + area = ' <span class="badge badge-danger"><i class="fas fa-desktop"></i> ' + Math.round(d['area']) + '%</span>'; | ||
129 | + }; | ||
124 | var g = d['grades']; | 130 | var g = d['grades']; |
125 | 131 | ||
126 | t[i] = []; | 132 | t[i] = []; |
@@ -128,7 +134,7 @@ $(document).ready(function() { | @@ -128,7 +134,7 @@ $(document).ready(function() { | ||
128 | t[i][1] = '<input type="checkbox" name="' + uid + '" value="true"' + checked + '> '; | 134 | t[i][1] = '<input type="checkbox" name="' + uid + '" value="true"' + checked + '> '; |
129 | t[i][2] = uid; | 135 | t[i][2] = uid; |
130 | t[i][3] = d['name']; | 136 | t[i][3] = d['name']; |
131 | - t[i][4] = password_defined + hora_inicio; | 137 | + t[i][4] = password_defined + hora_inicio + area + unfocus; |
132 | 138 | ||
133 | var gbar = ''; | 139 | var gbar = ''; |
134 | for (var j=0; j < g.length; j++) | 140 | for (var j=0; j < g.length; j++) |
perguntations/templates/review.html
@@ -74,9 +74,9 @@ | @@ -74,9 +74,9 @@ | ||
74 | <h1 class="display-5">{{ t['title'] }}</h1> | 74 | <h1 class="display-5">{{ t['title'] }}</h1> |
75 | <h5> | 75 | <h5> |
76 | <div class="row"> | 76 | <div class="row"> |
77 | - <label for="duracao" class="col-sm-2">Duração (minutos):</label> | 77 | + <label for="duracao" class="col-sm-2">Duração:</label> |
78 | <div class="col-sm-10" id="duracao"> | 78 | <div class="col-sm-10" id="duracao"> |
79 | - {{ t.get('duration', 0) if t.get('duration', 0) > 0 else '+'+chr(8734) }} | 79 | + {{ str(t.get('duration', 0)) + ' minutos' if t.get('duration', 0) > 0 else '+'+chr(8734) }} |
80 | </div> | 80 | </div> |
81 | </div> | 81 | </div> |
82 | </h5> | 82 | </h5> |