summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicky Zhou <ricky@fedoraproject.org>2008-07-11 22:09:52 (GMT)
committerRicky Zhou <ricky@fedoraproject.org>2008-07-11 22:09:52 (GMT)
commit711954a719fad9ce6434e203a8df3204c7df5bd8 (patch)
treef26fe789502c6667bde14e3dcdd8e060ffcb7ef8
parentd006a23d1cab54af66082265e803ec182aefae90 (diff)
downloadfas-711954a719fad9ce6434e203a8df3204c7df5bd8.zip
fas-711954a719fad9ce6434e203a8df3204c7df5bd8.tar.gz
fas-711954a719fad9ce6434e203a8df3204c7df5bd8.tar.xz
Half of group member sorting...
-rw-r--r--fas.cfg6
-rw-r--r--fas.wsgi31
-rw-r--r--fas/controllers.py3
-rw-r--r--fas/group.py26
-rw-r--r--fas/templates/group/member-list.html14
-rw-r--r--fas/user.py4
-rw-r--r--fas/validators.py12
7 files changed, 75 insertions, 21 deletions
diff --git a/fas.cfg b/fas.cfg
index 09c10b3..67ad726 100644
--- a/fas.cfg
+++ b/fas.cfg
@@ -109,9 +109,9 @@ level='DEBUG'
qualname='fas'
handlers=['debug_out']
-[[[allinfo]]]
-level='INFO'
-handlers=['debug_out']
+#[[[allinfo]]]
+#level='INFO'
+#handlers=['debug_out']
[[[access]]]
level='INFO'
diff --git a/fas.wsgi b/fas.wsgi
index bfe11a4..d59bd67 100644
--- a/fas.wsgi
+++ b/fas.wsgi
@@ -27,7 +27,9 @@ turbogears.startup.NestedVariablesFilter = MyNestedVariablesFilter
turbogears.update_config(configfile="/home/ricky/work/fedora/fas/fas.cfg", modulename="fas.config")
turbogears.config.update({'global': {'server.environment': 'development'}})
+turbogears.config.update({'global': {'debug': 'on'}})
turbogears.config.update({'global': {'autoreload.on': False}})
+turbogears.config.update({'global': {'server.throw_errors': True}})
turbogears.config.update({'global': {'server.log_to_screen': False}})
turbogears.config.update({'global': {'server.webpath': '/accounts'}})
turbogears.config.update({'global': {'base_url_filter.on': True}})
@@ -37,10 +39,39 @@ import fas.controllers
cherrypy.root = fas.controllers.Root()
+from weberror.evalexception import EvalException
+
if cherrypy.server.state == 0:
atexit.register(cherrypy.server.stop)
cherrypy.server.start(init_only=True, server_class=None)
+from webob import Request
+
def application(environ, start_response):
environ['SCRIPT_NAME'] = ''
return cherrypy._cpwsgi.wsgiApp(environ, start_response)
+
+def fake_call(self, environ, start_response):
+ ## FIXME: print better error message (maybe fall back on
+ ## normal middleware, plus an error message)
+ assert not environ['wsgi.multiprocess'], (
+ "The EvalException middleware is not usable in a "
+ "multi-process environment")
+ # XXX: Legacy support for Paste restorer
+ environ['weberror.evalexception'] = environ['paste.evalexception'] = \
+ self
+ # UGH, this is hideous:
+ environ['PATH_INFO_OLD'] = environ['PATH_INFO']
+ environ['SCRIPT_NAME'] = '/accounts'
+ environ['PATH_INFO'] = environ['PATH_INFO'].split('/', 2)[-1]
+ req = Request(environ)
+ if req.path_info_peek() == '_debug':
+ return self.debug(req)(environ, start_response)
+ else:
+ environ['PATH_INFO'] = environ['PATH_INFO_OLD']
+ return self.respond(environ, start_response)
+
+setattr(EvalException, '__call__', fake_call)
+
+application = EvalException(application, global_conf={'debug': True})
+
diff --git a/fas/controllers.py b/fas/controllers.py
index dc582f6..ead07dc 100644
--- a/fas/controllers.py
+++ b/fas/controllers.py
@@ -46,9 +46,6 @@ from fas.util import available_languages
import plugin
import os
-import sys
-reload(sys)
-sys.setdefaultencoding('utf-8')
import datetime
diff --git a/fas/group.py b/fas/group.py
index d2bbd81..efe7f5f 100644
--- a/fas/group.py
+++ b/fas/group.py
@@ -36,11 +36,15 @@ from fas.auth import *
import re
import turbomail
-from fas.validators import UnknownGroup, KnownGroup, ValidGroupType, KnownUser
+from fas.validators import UnknownGroup, KnownGroup, ValidGroupType, ValidRoleSort, KnownUser
class GroupView(validators.Schema):
groupname = KnownGroup
+class GroupMembers(validators.Schema):
+ groupname = KnownGroup
+ order_by = ValidRoleSort
+
class GroupCreate(validators.Schema):
name = validators.All(
@@ -122,7 +126,7 @@ class Group(controllers.Controller):
return dict(tg_errors=tg_errors)
@identity.require(turbogears.identity.not_anonymous())
- @validate(validators=GroupView())
+ @validate(validators=GroupMembers())
@error_handler(error)
@expose(template="fas.templates.group.view", allow_json=True)
def view(self, groupname):
@@ -146,8 +150,15 @@ class Group(controllers.Controller):
@validate(validators=GroupView())
@error_handler(error)
@expose(template="fas.templates.group.members", allow_json=True)
- def members(self, groupname, search=u'a*'):
+ def members(self, groupname, search=u'a*', order_by='username'):
'''View group'''
+ sort_map = { 'username': 'username',
+ 'sponsor': None,
+ 'creation': PersonRoles.c.creation,
+ 'approval': PersonRoles.c.approval,
+ 'role_status': PersonRoles.c.role_status,
+ 'role_type': PersonRoles.c.role_type,
+ }
if not isinstance(search, unicode) and isinstance(search, basestring):
search = unicode(search, 'utf-8', 'replace')
@@ -163,10 +174,11 @@ class Group(controllers.Controller):
return dict()
# return all members of this group that fit the search criteria
- members = PersonRoles.query.join('group').join('member').filter(and_(
- Groups.name==groupname,
- People.username.like(re_search)
- ))
+ #members = PersonRoles.query.join('group').join('member').filter(and_(
+ #Groups.name==groupname,
+ #People.username.like(re_search)
+ #)).order_by(order_by)
+ members = PersonRoles.query.filter_by(group=group).filter(PersonRoles.member.has(People.username.like(re_search))).order_by(sort_map[order_by]).all()
group.jsonProps = {'PersonRoles': ['member']}
return dict(group=group, members=members, search=search)
diff --git a/fas/templates/group/member-list.html b/fas/templates/group/member-list.html
index c95fb72..64e40c6 100644
--- a/fas/templates/group/member-list.html
+++ b/fas/templates/group/member-list.html
@@ -11,16 +11,16 @@
?>
<thead>
<tr>
- <th>${_('Username')}</th>
- <th>${_('Sponsor')}</th>
- <th>${_('Date Added')}</th>
- <th>${_('Date Approved')}</th>
- <th>${_('Approval')}</th>
- <th>${_('Role Type')}</th>
+ <th><a href="?order_by=username">${_('Username')}</a></th>
+ <th><a href="?order_by=sponsor">${_('Sponsor')}</a></th>
+ <th><a href="?order_by=creation">${_('Date Added')}</a></th>
+ <th><a href="?order_by=approval">${_('Date Approved')}</a></th>
+ <th><a href="?order_by=role_status">${_('Approval')}</a></th>
+ <th><a href="?order_by=role_type">${_('Role Type')}</a></th>
<th py:if="can_sponsor">${_('Action')}</th>
</tr>
</thead>
- <tr py:for="role in sorted(members, lambda x,y: cmp(x.member.username, y.member.username))">
+ <tr py:for="role in members">
<td><a href="${tg.url('/user/view/%s' % role.member.username)}">${role.member.username}</a></td>
<td py:if='role.sponsor'><a href="${tg.url('/user/view/%s' % role.sponsor.username)}">${role.sponsor.username}</a></td>
<td py:if='not role.sponsor'>${_('None')}</td>
diff --git a/fas/user.py b/fas/user.py
index a4b2bac..c800596 100644
--- a/fas/user.py
+++ b/fas/user.py
@@ -319,6 +319,8 @@ https://admin.fedoraproject.org/accounts/user/verifyemail/%s
list of usernames with information about whether the user is
approved in cla_done
+ supybot-fedora uses the email attribute
+
The json information is useful so we probably want to create a new
method for it at some point. One which returns the list of users with
more complete information about themselves. Then this method can
@@ -339,7 +341,7 @@ https://admin.fedoraproject.org/accounts/user/verifyemail/%s
PersonRolesTable, PersonRoles.person_id==People.id).join(
GroupsTable, PersonRoles.group_id==Groups.id)
- columns = [People.username, People.id, People.human_name, People.ssh_key]
+ columns = [People.username, People.id, People.human_name, People.ssh_key, People.email]
if identity.in_group('fas-system'):
columns.append(People.password)
approved = select(columns, from_obj=PeopleGroupsTable
diff --git a/fas/validators.py b/fas/validators.py
index 94ca9f4..c7b0d08 100644
--- a/fas/validators.py
+++ b/fas/validators.py
@@ -89,6 +89,18 @@ class ValidGroupType(validators.FancyValidator):
raise validators.Invalid(_("Invalid group type.") % value,
value, state)
+class ValidRoleSort(validators.FancyValidator):
+ '''Make sure that a role sort key is valid'''
+ def _to_python(self, value, state):
+ # pylint: disable-msg=C0111,W0613
+ return value.strip()
+ def validate_python(self, value, state):
+ # pylint: disable-msg=C0111
+ if value not in ('username', 'role_type', 'role_status', \
+ 'creation', 'approval'):
+ raise validators.Invalid(_("Invalid sort key.") % value,
+ value, state)
+
class KnownUser(validators.FancyValidator):
'''Make sure that a user already exists'''
def _to_python(self, value, state):