From 1017b68c1f70d832409aa4bac6605982ff04e8ba Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Mon, 26 Mar 2012 16:07:49 -0500 Subject: [PATCH] manage_students and bulk_regsiter --- VERSION | 2 +- applications/admin/controllers/default.py | 29 ++- applications/admin/models/0.py | 2 +- applications/admin/static/css/styles.css | 168 ++++++++++++++++++ .../admin/views/default/bulk_register.html | 5 + .../admin/views/default/manage_students.html | 5 + applications/admin/views/default/site.html | 7 +- 7 files changed, 214 insertions(+), 4 deletions(-) create mode 100644 applications/admin/views/default/bulk_register.html create mode 100644 applications/admin/views/default/manage_students.html diff --git a/VERSION b/VERSION index 1da0e49c..411210d2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 1.99.7 (2012-03-26 11:17:03) dev +Version 1.99.7 (2012-03-26 16:07:16) dev diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py index 430aee47..bb995b16 100644 --- a/applications/admin/controllers/default.py +++ b/applications/admin/controllers/default.py @@ -49,7 +49,8 @@ def safe_write(a, value, b='w'): def get_app(name=None): app = name or request.args(0) - if app and (not MULTI_USER_MODE or db(db.app.name==app)(db.app.owner==auth.user.id).count()): + if app and (not MULTI_USER_MODE or is_manager() or \ + db(db.app.name==app)(db.app.owner==auth.user.id).count()): return app session.flash = 'App does not exist or your are not authorized' redirect(URL('site')) @@ -158,6 +159,7 @@ def site(): if app_create(appname, request): if MULTI_USER_MODE: db.app.insert(name=appname,owner=auth.user.id) + # LOG_PROGRESS session.flash = T('new application "%s" created', appname) redirect(URL('design',args=appname)) else: @@ -190,6 +192,7 @@ def site(): overwrite=request.vars.overwrite_check) if f and installed: msg = 'application %(appname)s installed with md5sum: %(digest)s' + # LOG_PROGRESS session.flash = T(msg, dict(appname=appname, digest=md5_hash(installed))) elif f and request.vars.overwrite_check: @@ -329,6 +332,7 @@ def delete(): elif 'delete' in request.vars: try: os.unlink(apath(filename, r=request)) + # LOG_PROGRESS session.flash = T('file "%(filename)s" deleted', dict(filename=filename)) except Exception: @@ -461,6 +465,7 @@ def edit(): safe_write(path + '.bak', data) data = request.vars.data.replace('\r\n', '\n').strip() + '\n' safe_write(path, data) + # LOG_PROGRESS file_hash = md5_hash(data) saved_on = time.ctime(os.stat(path)[stat.ST_MTIME]) response.flash = T('file saved on %s', saved_on) @@ -996,6 +1001,7 @@ def create_file(): raise SyntaxError safe_write(full_filename, text) + # LOG_PROGRESS session.flash = T('file "%(filename)s" created', dict(filename=full_filename[len(path):])) redirect(URL('edit', @@ -1042,6 +1048,7 @@ def upload_file(): os.makedirs(dirpath) safe_write(filename, request.vars.file.file.read(), 'wb') + # LOG_PROGRESS session.flash = T('file "%(filename)s" uploaded', dict(filename=filename[len(path):])) except Exception: @@ -1351,3 +1358,23 @@ def reload_routes(): redirect(URL('site')) +def manage_students(): + if not (MULTI_USER_MODE and is_manager()): + raise HTTP(401) + db.auth_user.registration_key.writable = True + grid = SQLFORM.grid(db.auth_user) + return locals() + +def bulk_register(): + if not (MULTI_USER_MODE and is_manager()): + raise HTTP(401) + form = SQLFORM.factory(Field('emails','text')) + if form.process().accepted: + emails = [x.strip() for x in form.vars.emails.split('\n') if x.strip()] + n = 0 + for email in emails: + if not db.auth_user(email=email): + n += db.auth_user.insert(email = email) and 1 or 0 + session.flash = T('%s students registered',n) + redirect(URL('site')) + return locals() diff --git a/applications/admin/models/0.py b/applications/admin/models/0.py index c2db7649..ab900b66 100644 --- a/applications/admin/models/0.py +++ b/applications/admin/models/0.py @@ -56,7 +56,7 @@ import os GAE_APPCFG = os.path.abspath(os.path.join('/usr/local/bin/appcfg.py')) # To use web2py as a teaching tool, set MULTI_USER_MODE to True -MULTI_USER_MODE = False +MULTI_USER_MODE = True # configurable twitterbox, set to None/False to suppress TWITTER_HASH = "web2py" diff --git a/applications/admin/static/css/styles.css b/applications/admin/static/css/styles.css index 7fc8b0ff..08a82d72 100644 --- a/applications/admin/static/css/styles.css +++ b/applications/admin/static/css/styles.css @@ -1077,3 +1077,171 @@ ul#snapshot > li { .ui-multiselect { border: 1px solid #ccc; width:400px;} #editor_area textarea { height: 400px; width: 100% } + +/* +*Grid +* +* The default style for SQLFORM.grid even using jquery-iu or another ui framework +* will look better with the declarations below +* if needed to remove base.css consider keeping these following lines in some css file. +*/ +.web2py_table { border: 1px solid #ccc; } +.web2py_paginator { border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 1px solid #ccc; } +.web2py_grid a { text-decoration:none;} +.web2py_grid table { width: 100% } +.web2py_grid td { white-space:normal; } +.web2py_grid tbody td { + padding: 2px 5px 2px 5px; + line-height: 13.5px; + vertical-align: middle; +} +.web2py_grid input:focus, +.web2py_grid textarea:focus, +.web2py_grid select:focus { + border: 1px solid #ffffff; + -webkit-box-shadow: 0px 0px 6px #007eff; + -moz-box-shadow: 0px 0px 5px #007eff; + box-shadow: 0px 0px 5px #007eff; + } + +.web2py_grid thead th { + background-color:#EAEAEA; + padding: 10px 5px 10px 5px; + line-height: 13.5px; + vertical-align: middle; + font-weight: bold; + border-bottom: 1px solid #DDD; + border-right: 1px solid #DDD; +} +.web2py_grid tr.odd {background-color: #F9F9F9;} +.web2py_grid tr:hover {background-color: #F5F5F5; } + +/* +.web2py_breadcrumbs a { + line-height: 20px; margin-right: 5px; display: inline-block; + padding: 3px 5px 3px 5px; + font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; + color: #3C3C3D; + text-shadow: 1px 1px 0 #FFFFFF; + white-space: nowrap; overflow: visible; cursor: pointer; + background:#ECECEC; + text-decoration: none; border: 1px solid #CACACA; + -webkit-border-radius: 2px; -moz-border-radius: 2px; + -webkit-background-clip: padding-box; border-radius: 2px; + outline: none; position: relative; zoom: 1; *display: inline; +} +*/ + +.web2py_console { + min-height: 60px; + text-align: left; +} + + +.web2py_search_actions{ + width:40%; + float:left; + text-align:left; +} + +.web2py_grid .row_buttons { + min-height:25px; + vertical-align: middle; +} + +.web2py_grid .row_buttons a { + margin: 3px; +} + +.web2py_grid .row_buttons a, +.web2py_paginator ul li a, +.web2py_search_actions a, +.web2py_console input[type=submit], +.web2py_console input[type=button], +.web2py_console button { + line-height: 20px; + margin-right: 5px; display: inline-block; + padding: 3px 5px 3px 5px; + font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; + font-size: 1em; + color: #3C3C3D; + text-shadow: 1px 1px 0 #FFFFFF; + background:#ECECEC; + white-space: nowrap; overflow: visible; + cursor: pointer; text-decoration: none; + border: 1px solid #CACACA; + -webkit-border-radius: 2px; -moz-border-radius: 2px; + -webkit-background-clip: padding-box; border-radius: 2px; + outline: none; position: relative; zoom: 1; *display: inline; +} + +.web2py_grid .row_buttons a:hover, +.web2py_search_actions a:hover, +.web2py_console input[type=submit]:hover, +.web2py_console input[type=button]:hover, +.web2py_paginator ul li a:hover { +color: #222; + background: #ddd; /* Old browsers */ + background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */ + background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,\ +0,.3))); /* Chrome,Safari4+ */ + background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */ + background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */ + background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */ + background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */ + border: 1px solid #888; + border-top: 1px solid #aaa; + border-left: 1px solid #aaa; +/* + color: #FFFFFF; border-color: #388AD4; text-decoration: none; + text-shadow: -1px -1px 0 rgba(0,0,0,0.3); + background-position: 0 -40px; background-color: #2D7DC5; +*/ +} + +.web2py_counter { + margin-top: 5px; + margin-right:5px; + width:35%; + float:right; + text-align:right; +} + +/*Fix firefox problem*/ +.web2py_table {clear: both; display: block;} + +.web2py_paginator { + padding: 5px; + color: #333; + text-align:right; + background-color: #f2f2f2; padding: 5px; border-bottom: 1px solid #DDD; + +} +.web2py_paginator ul { + list-style-type: none; + margin: 0px; + padding: 0px; +} +.web2py_paginator ul li { + display: inline; +} +.web2py_paginator .current { + font-weight: bold; +} +#w2p_query_trigger { + margin-left: 0; +} +#w2p_query_panel { + // float:left; + background:#e0e0e0; + border:1px solid #CFCFCF; + // bottom:3px; + // left:187px; + // margin-top: 30px; + min-width:550px; + min-height:16px; + padding: 3px 3px; + border-radius:2px; +} +.ie9 #query_panel {padding-bottom:2px;} + diff --git a/applications/admin/views/default/bulk_register.html b/applications/admin/views/default/bulk_register.html new file mode 100644 index 00000000..4f3a10d3 --- /dev/null +++ b/applications/admin/views/default/bulk_register.html @@ -0,0 +1,5 @@ +{{extend 'layout.html'}} + +

{{=T('Bulk Student Registration')}}

+ +{{=form}} diff --git a/applications/admin/views/default/manage_students.html b/applications/admin/views/default/manage_students.html new file mode 100644 index 00000000..0bfe7c1f --- /dev/null +++ b/applications/admin/views/default/manage_students.html @@ -0,0 +1,5 @@ +{{extend 'layout.html'}} + +

{{=T('Manage Admin Users/Students')}}

+ +{{=grid}} diff --git a/applications/admin/views/default/site.html b/applications/admin/views/default/site.html index e7c51d60..520f3780 100644 --- a/applications/admin/views/default/site.html +++ b/applications/admin/views/default/site.html @@ -38,6 +38,10 @@ {{=button(URL('uninstall',args=a), T("Uninstall"))}} {{=button_enable(URL('enable',args=a), a)}} {{pass}} + {{if a=='admin' and MULTI_USER_MODE and is_manager():}} + {{=button(URL('default','manage_students'), T('Manage Students'))}} + {{=button(URL('default','bulk_register'), T('Bulk Register'))}} + {{pass}}

{{pass}} @@ -63,11 +67,12 @@

{{=T('Checking for upgrades...')}} {{session.check_version=False}} +

{{else:}}

{{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}} - {{pass}}

+ {{pass}}
Running on {{=request.env.server_software}}