diff --git a/BUGS.md b/BUGS.md index b898992..a13ed05 100644 --- a/BUGS.md +++ b/BUGS.md @@ -22,6 +22,7 @@ # FIXED +- server nao esta a receber eventos focus/blur dos utilizadores diferentes de '0', estranho... - permitir adicionar imagens nas perguntas. - detect_unfocus.js so funciona se estiver inline no html. porquê??? - inserir novo aluno /admin não fecha. diff --git a/app.py b/app.py index 33f4198..6cc5a43 100644 --- a/app.py +++ b/app.py @@ -218,7 +218,8 @@ class App(object): 'password_defined': pw != '', 'grades': self.get_student_grades_from_test(uid, self.testfactory['ref']), 'ip_address': self.online.get(uid, {}).get('student', {}).get('ip_address',''), - 'user_agent': self.online.get(uid, {}).get('student', {}).get('user_agent','') + 'user_agent': self.online.get(uid, {}).get('student', {}).get('user_agent',''), + 'focus': self.online.get(uid, {}).get('student', {}).get('focus', True), }) return l @@ -263,3 +264,6 @@ class App(object): logger.error('Insert failed: student {} already exists.'.format(uid)) else: logger.info('New student inserted into database: {}, {}'.format(uid, name)) + + def set_student_focus(self, uid, value): + self.online[uid]['student']['focus'] = value diff --git a/serve.py b/serve.py index 40c6feb..03a8a8f 100755 --- a/serve.py +++ b/serve.py @@ -63,7 +63,8 @@ def secureheaders(): headers = cherrypy.response.headers headers['X-Frame-Options'] = 'DENY' headers['X-XSS-Protection'] = '1; mode=block' - headers['Content-Security-Policy'] = "default-src='self'" + # FIXME disabled because MathJax requires unsafe javascript eval: + # headers['Content-Security-Policy'] = "default-src 'self'" if (cherrypy.server.ssl_certificate != None and cherrypy.server.ssl_private_key != None): headers['Strict-Transport-Security'] = 'max-age=31536000' # one year @@ -88,6 +89,7 @@ class AdminWebService(object): } return json.dumps(data, default=str) + @cherrypy.tools.accept(media='application/json') # FIXME def POST(self, **args): # print('POST', args) # FIXME if args['cmd'] == 'allow': @@ -106,6 +108,25 @@ class AdminWebService(object): print(args) # ============================================================================ +# Student webservice +# ============================================================================ +class StudentWebService(object): + exposed = True + _cp_config = { + 'auth.require': [] + } + + def __init__(self, app): + self.app = app + + @cherrypy.tools.accept(media='application/json') # FIXME + def POST(self, **args): + uid = cherrypy.session.get(SESSION_KEY) + if args['cmd'] == 'focus': + v = json.loads(args['value']) + self.app.set_student_focus(uid=args['number'], value=v) + +# ============================================================================ # Webserver root # ============================================================================ class Root(object): @@ -287,6 +308,7 @@ if __name__ == '__main__': # --- create webserver webapp = Root(app) webapp.adminwebservice = AdminWebService(app) + webapp.studentwebservice = StudentWebService(app) # --- site wide configuration (valid for all apps) cherrypy.tools.secureheaders = cherrypy.Tool('before_finalize', secureheaders, priority=60) @@ -312,6 +334,11 @@ if __name__ == '__main__': 'tools.response_headers.on': True, 'tools.response_headers.headers': [('Content-Type', 'text/plain')], }, + '/studentwebservice': { + 'request.dispatch': cherrypy.dispatch.MethodDispatcher(), + 'tools.response_headers.on': True, + 'tools.response_headers.headers': [('Content-Type', 'text/plain')], + }, '/static': { 'tools.auth.on': False, # everything in /static is public 'tools.staticdir.on': True, diff --git a/static/css/test.css b/static/css/test.css new file mode 100644 index 0000000..4175d70 --- /dev/null +++ b/static/css/test.css @@ -0,0 +1,18 @@ +/* Fixes navigation panel overlaying content */ +body { + padding-top: 80px; + background: #aaa; +} +/* Hack to avoid name clash between pygments and mathjax */ +.MathJax .mo, +.MathJax .mi { + color: inherit; +} +.drop-shadow { + -webkit-box-shadow: 0 0 5px 2px rgba(0, 0, 0, .5); + box-shadow: 0px 2px 10px 3px rgba(0, 0, 0, .2); + border-radius:5px; +} +textarea { + font-family: monospace !important; +} diff --git a/static/js/admin.js b/static/js/admin.js index 1a7fd37..d66ac4d 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -57,23 +57,24 @@ $(document).ready(function() { var active = []; $.each(students, function(i, r) { if (r['start_time'] != '') { - active.push([r['uid'], r['name'], r['start_time'], r['ip_address'], r['user_agent']]); + active.push([r['uid'], r['name'], r['start_time'], r['ip_address'], r['user_agent'], r['focus']]); } }); // sort by start time active.sort(function(a,b){return a[2] < b[2] ? -1 : (a[2] == b[2] ? 0 : 1);}); n = active.length; for(var i = 0; i < n; i++) { - rows += "\ - " + active[i][0] + "\ - " + active[i][1] + "\ - " + active[i][2].slice(0,10) + "\ - " + active[i][2].slice(11,19) + '\ -
' + active[i][3] + '
\ + rows += '\ + ' + active[i][0] + '\ + ' + active[i][1] + '\ + ' + active[i][2].slice(11,19) + '\ +
' + active[i][3] + '
\ + ' + (active[i][5]? '' : 'unfocus') + '\ '; } $("#online_students").html(rows); $("#online-header").html(n + " Activo(s)"); + } // ---------------------------------------------------------------------- @@ -111,14 +112,12 @@ $(document).ready(function() { rows += ''; rows += '\ - \ - ' + uid + '\ - ' + d['name'] + (d['password_defined'] ? ' pw' : '') +'\ - ' + - + ' + + (d['start_time']=='' ? '' : ' teste') + // (d['online'] ? 'online' : '') + - (d['start_time']==''?'':'teste') + '\ + ' + uid + '\ + ' + d['name'] + (d['password_defined'] ? ' pw' : '') +'\ '; var g = d['grades']; var glength = g.length; diff --git a/static/js/detect_unfocus.js b/static/js/detect_unfocus.js index 483487f..b4798e1 100644 --- a/static/js/detect_unfocus.js +++ b/static/js/detect_unfocus.js @@ -2,10 +2,11 @@ $(document).ready(function() { $(window).focus(function(){ $.ajax({ type: "POST", - url: "/adminwebservice", + url: "/studentwebservice", data: { "cmd": "focus", - "name": $("#number").text() + "number": $("#number").text(), + "value": true } }); }); @@ -13,10 +14,11 @@ $(document).ready(function() { $(window).blur(function(e){ $.ajax({ type: "POST", - url: "/adminwebservice", + url: "/studentwebservice", data: { - "cmd": "blur", - "name": $("#number").text() + "cmd": "focus", + "number": $("#number").text(), + "value": false } }); }); diff --git a/templates/admin.html b/templates/admin.html index bc76fe0..05cda14 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -90,9 +90,10 @@ Número Nome - Data de início + Hora de início IP + Estado @@ -113,7 +114,7 @@ Perm. Número Nome - Estado + Nota diff --git a/templates/test.html b/templates/test.html index e3546c7..8209402 100644 --- a/templates/test.html +++ b/templates/test.html @@ -10,18 +10,19 @@ - - + + @@ -32,26 +33,6 @@ - @@ -59,7 +40,6 @@