return out
+def derive_group_code_from_section(site, section):
+ """
+ This function is used to simplify common-case permission setting
+ on course sites. It takes a site and a section number/code, and
+ returns the most likely external group code. (This function will
+ probably check the site's term and course codes, and merge those
+ with the section code, to derive the group code.) Return None if a
+ valid, unambiguous group code cannot be generated.
+ """
+ try:
+ section = int(section)
+ except:
+ return None
+
+ return '%s-%s-%s' % (site.course.code.replace('-', ''),
+ section,
+ site.start_term.code)
+
#--------------------------------------------------
# proxy server integration
choose_access = django.forms.RadioSelect(choices=choices)
+ show_add_section_panel = gethook('derive_group_code_from_section')
+
if request.method != 'POST':
return g.render('edit_site_permissions.xhtml', **locals())
else:
POST = request.POST
- access = POST.get('access')
- site.access = access
+ message = 'Changes saved.' # default
+
+ if 'action_access_level' in POST:
+ access = POST.get('access')
+ site.access = access
+
+ elif 'action_add_group' in POST:
+ section = POST.get('section', '').strip()
+ groupcode = None
+ if section:
+ groupcode = callhook('derive_group_code_from_section',
+ site, section)
+ if not groupcode:
+ groupcode = POST.get('groupcode','').strip()
+
+ if not groupcode:
+ message = 'No group code or section number provided.'
+ else:
+ group, created = models.Group.objects.get_or_create(
+ site=site, external_id=groupcode)
+
site.save()
-
- return HttpResponseRedirect('../../')
+ return g.render('edit_site_permissions.xhtml', **locals())
@instructors_only
def delete_site(request, site_id):
<?python
+from django.db.models import Count
title = _('Site permissions')
instructors = site.get_instructors()
members = models.Membership.objects.select_related().filter(group__site=site).order_by('user__last_name', 'user__first_name')
-extgroups = site.group_set.filter(external_id__isnull=False)
+extgroups = site.group_set.filter(external_id__isnull=False).annotate(Count('membership')).order_by('external_id')
?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xi="http://www.w3.org/2001/XInclude"
<script type="text/javascript" src="${ROOT}/static/edit_site_permissions.js"/>
<style type="text/css">
#access_level li { list-style-type: none; }
+ .popup { background-color: #ddd; padding: 24; margin: 0 24; }
+ #message { background-color: #fdd; padding: 12; display: inline-block; }
</style>
</head>
<body>
${site_banner(site)}
<h1>${title}</h1>
+ <div py:if="defined('message')" id="message">${message}</div>
<form action="." method="POST">
- <p>Who has permission to view resources in this site?</p>
- <div id="access_level" style="margin-left: 12;">${Markup(choose_access.render('access', site.access, {'id':'id_access'}, []))}</div>
- <p><input type="submit" name="action_access_level" value="Change access level"/>
- ${go_back_link()}</p>
+ <div>
+ <h2>Security level</h2>
+ <div>Who has permission to view resources in this site?</div>
+ <div id="access_level" style="margin: 8;">${Markup(choose_access.render('access', site.access, {'id':'id_access'}, []))}</div>
+ <p><input type="submit" name="action_access_level" value="Change security level"/>
+ ${go_back_link()}</p>
+ </div>
- <h2>Current Membership</h2>
+ <div>
+ <h2>Class lists and groups</h2>
+ <div py:if="not extgroups">No external lists are currently associated.</div>
+
+ <table class="pagetable" py:if="extgroups">
+ <thead>
+ <tr><th>Class/group code</th><th>Known members</th></tr>
+ </thead>
+ <tbody>
+ <tr py:for="eg in extgroups">
+ <td>${eg.external_id}</td>
+ <td>${eg.membership__count}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div>
+ <p><input type="button" value="Add external group" onclick="$('#addExternalGroupPopup').fadeIn();"/></p>
+ <div class="popup" id="addExternalGroupPopup" style="display: none;">
+ <li py:if="show_add_section_panel">
+ Add the class list for ${site.course.code}, section <input name="section" style="width: 2em;"/>, ${site.start_term.name}
+ </li>
+ <li>
+ Add a class list or group by its group code: <input name="groupcode" style="width: 15em;"/>
+ </li>
+ <p><input type="submit" name="action_add_group" value="Add class list or group"/></p>
+ </div>
+ </div>
+
+ </div>
+ <div>
+ <h2>Current membership</h2>
<table class="pagetable" style="width: 100%;">
<thead>
<tr><th>Name</th><th>Role</th><th>User ID</th><th>Group</th></tr>
<td>${member.group.external_id or '(internal)'}</td>
</tr>
</table>
- <div py:if="extgroups">
- <h2>External Groups</h2>
- <p py:for="eg in extgroups">${eg.external_id}</p>
- </div>
-
- <!-- <h2>Instructor Access</h2> -->
- <!-- <div py:if="defined('instructor_error')" class="errors">${instructor_error}</div> -->
- <!-- <table class="pagetable"> -->
- <!-- <thead> -->
- <!-- <tr><th>Person</th><th>Role</th><th>Remove?</th></tr> -->
- <!-- </thead> -->
- <!-- <tbody> -->
- <!-- <select py:def="select_role(mbr)" -->
- <!-- py:replace="Markup(django.forms.Select(choices= -->
- <!-- [(u'INSTR',_('Instructor')), (u'PROXY', _('Proxy instructor'))]) -->
- <!-- .render('instructor_role_%d' % mbr.id, mbr.role))"/> -->
- <!-- <tr py:for="mbr in instructors"> -->
- <!-- <td>${mbr.user.get_full_name() or ''} <code>(${mbr.user.username})</code></td> -->
- <!-- <td>${select_role(mbr)}</td> -->
- <!-- <td><input type="checkbox" name="instructor_remove_${mbr.id}"/></td> -->
- <!-- </tr> -->
- <!-- <tr style="vertical-align: bottom;"> -->
- <!-- <td><p>Username of the new instructor.</p><input type="text" name="new_instructor_name"/></td> -->
- <!-- <td><select name="new_instructor_role"> -->
- <!-- <option value="INSTR">Instructor</option> -->
- <!-- <option value="PROXY">Proxy instructor</option> -->
- <!-- </select> -->
- <!-- </td> -->
- <!-- <td/> -->
- <!-- </tr> -->
- <!-- </tbody> -->
- <!-- </table> -->
- <!-- <p> <input type="submit" name="action_save_instructor" value="Save changes to instructors"/></p> -->
+ </div>
</form>
<div class="gap"/>
</body>