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}}