PageRenderTime 62ms CodeModel.GetById 10ms app.highlight 46ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/galaxy/web/controllers/admin.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 635 lines | 633 code | 2 blank | 0 comment | 9 complexity | c85a25a9af4ee3daa2c99321c95daf71 MD5 | raw file
  1from galaxy.web.base.controller import *
  2from galaxy import model
  3from galaxy.model.orm import *
  4from galaxy.web.framework.helpers import time_ago, iff, grids
  5import logging
  6log = logging.getLogger( __name__ )
  7
  8from galaxy.actions.admin import AdminActions
  9from galaxy.web.params import QuotaParamParser
 10from galaxy.exceptions import *
 11
 12class UserListGrid( grids.Grid ):
 13    class EmailColumn( grids.TextColumn ):
 14        def get_value( self, trans, grid, user ):
 15            return user.email
 16    class UserNameColumn( grids.TextColumn ):
 17        def get_value( self, trans, grid, user ):
 18            if user.username:
 19                return user.username
 20            return 'not set'
 21    class StatusColumn( grids.GridColumn ):
 22        def get_value( self, trans, grid, user ):
 23            if user.purged:
 24                return "purged"
 25            elif user.deleted:
 26                return "deleted"
 27            return ""
 28    class GroupsColumn( grids.GridColumn ):
 29        def get_value( self, trans, grid, user ):
 30            if user.groups:
 31                return len( user.groups )
 32            return 0
 33    class RolesColumn( grids.GridColumn ):
 34        def get_value( self, trans, grid, user ):
 35            if user.roles:
 36                return len( user.roles )
 37            return 0
 38    class ExternalColumn( grids.GridColumn ):
 39        def get_value( self, trans, grid, user ):
 40            if user.external:
 41                return 'yes'
 42            return 'no'
 43    class LastLoginColumn( grids.GridColumn ):
 44        def get_value( self, trans, grid, user ):
 45            if user.galaxy_sessions:
 46                return self.format( user.galaxy_sessions[ 0 ].update_time )
 47            return 'never'
 48
 49    # Grid definition
 50    webapp = "galaxy"
 51    title = "Users"
 52    model_class = model.User
 53    template='/admin/user/grid.mako'
 54    default_sort_key = "email"
 55    columns = [
 56        EmailColumn( "Email",
 57                     key="email",
 58                     model_class=model.User,
 59                     link=( lambda item: dict( operation="information", id=item.id, webapp="galaxy" ) ),
 60                     attach_popup=True,
 61                     filterable="advanced" ),
 62        UserNameColumn( "User Name",
 63                        key="username",
 64                        model_class=model.User,
 65                        attach_popup=False,
 66                        filterable="advanced" ),
 67        GroupsColumn( "Groups", attach_popup=False ),
 68        RolesColumn( "Roles", attach_popup=False ),
 69        ExternalColumn( "External", attach_popup=False ),
 70        LastLoginColumn( "Last Login", format=time_ago, key="update_time" ),
 71        StatusColumn( "Status", attach_popup=False ),
 72        # Columns that are valid for filtering but are not visible.
 73        grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
 74    ]
 75    columns.append( grids.MulticolFilterColumn( "Search", 
 76                                                cols_to_filter=[ columns[0], columns[1] ], 
 77                                                key="free-text-search",
 78                                                visible=False,
 79                                                filterable="standard" ) )
 80    global_actions = [
 81        grids.GridAction( "Create new user", dict( controller='admin', action='users', operation='create', webapp="galaxy" ) )
 82    ]
 83    operations = [
 84        grids.GridOperation( "Manage Roles and Groups",
 85                             condition=( lambda item: not item.deleted ),
 86                             allow_multiple=False,
 87                             url_args=dict( webapp="galaxy", action="manage_roles_and_groups_for_user" ) ),
 88        grids.GridOperation( "Reset Password",
 89                             condition=( lambda item: not item.deleted ),
 90                             allow_multiple=True,
 91                             allow_popup=False,
 92                             url_args=dict( webapp="galaxy", action="reset_user_password" ) )
 93    ]
 94    #TODO: enhance to account for trans.app.config.allow_user_deletion here so that we can eliminate these operations if 
 95    # the setting is False
 96    operations.append( grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True ) )
 97    operations.append( grids.GridOperation( "Undelete", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) )
 98    operations.append( grids.GridOperation( "Purge", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) )
 99    standard_filters = [
100        grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
101        grids.GridColumnFilter( "Deleted", args=dict( deleted=True, purged=False ) ),
102        grids.GridColumnFilter( "Purged", args=dict( purged=True ) ),
103        grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
104    ]
105    num_rows_per_page = 50
106    preserve_state = False
107    use_paging = True
108    def get_current_item( self, trans, **kwargs ):
109        return trans.user
110
111class RoleListGrid( grids.Grid ):
112    class NameColumn( grids.TextColumn ):
113        def get_value( self, trans, grid, role ):
114            return role.name
115    class DescriptionColumn( grids.TextColumn ):
116        def get_value( self, trans, grid, role ):
117            if role.description:
118                return role.description
119            return ''
120    class TypeColumn( grids.TextColumn ):
121        def get_value( self, trans, grid, role ):
122            return role.type
123    class StatusColumn( grids.GridColumn ):
124        def get_value( self, trans, grid, role ):
125            if role.deleted:
126                return "deleted"
127            return ""
128    class GroupsColumn( grids.GridColumn ):
129        def get_value( self, trans, grid, role ):
130            if role.groups:
131                return len( role.groups )
132            return 0
133    class UsersColumn( grids.GridColumn ):
134        def get_value( self, trans, grid, role ):
135            if role.users:
136                return len( role.users )
137            return 0
138
139    # Grid definition
140    webapp = "galaxy"
141    title = "Roles"
142    model_class = model.Role
143    template='/admin/dataset_security/role/grid.mako'
144    default_sort_key = "name"
145    columns = [
146        NameColumn( "Name",
147                    key="name",
148                    link=( lambda item: dict( operation="Manage users and groups", id=item.id, webapp="galaxy" ) ),
149                    model_class=model.Role,
150                    attach_popup=True,
151                    filterable="advanced" ),
152        DescriptionColumn( "Description",
153                           key='description',
154                           model_class=model.Role,
155                           attach_popup=False,
156                           filterable="advanced" ),
157        TypeColumn( "Type",
158                    key='type',
159                    model_class=model.Role,
160                    attach_popup=False,
161                    filterable="advanced" ),
162        GroupsColumn( "Groups", attach_popup=False ),
163        UsersColumn( "Users", attach_popup=False ),
164        StatusColumn( "Status", attach_popup=False ),
165        # Columns that are valid for filtering but are not visible.
166        grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
167    ]
168    columns.append( grids.MulticolFilterColumn( "Search", 
169                                                cols_to_filter=[ columns[0], columns[1], columns[2] ], 
170                                                key="free-text-search",
171                                                visible=False,
172                                                filterable="standard" ) )
173    global_actions = [
174        grids.GridAction( "Add new role", dict( controller='admin', action='roles', operation='create' ) )
175    ]
176    operations = [ grids.GridOperation( "Edit",
177                                        condition=( lambda item: not item.deleted ),
178                                        allow_multiple=False,
179                                        url_args=dict( webapp="galaxy", action="rename_role" ) ),
180                   grids.GridOperation( "Delete",
181                                        condition=( lambda item: not item.deleted ),
182                                        allow_multiple=True,
183                                        url_args=dict( webapp="galaxy", action="mark_role_deleted" ) ),
184                   grids.GridOperation( "Undelete",
185                                        condition=( lambda item: item.deleted ),
186                                        allow_multiple=True,
187                                        url_args=dict( webapp="galaxy", action="undelete_role" ) ),
188                   grids.GridOperation( "Purge",
189                                        condition=( lambda item: item.deleted ),
190                                        allow_multiple=True,
191                                        url_args=dict( webapp="galaxy", action="purge_role" ) ) ]
192    standard_filters = [
193        grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
194        grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
195        grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
196    ]
197    num_rows_per_page = 50
198    preserve_state = False
199    use_paging = True
200    def apply_query_filter( self, trans, query, **kwargs ):
201        return query.filter( model.Role.type != model.Role.types.PRIVATE )
202
203class GroupListGrid( grids.Grid ):
204    class NameColumn( grids.TextColumn ):
205        def get_value( self, trans, grid, group ):
206            return group.name
207    class StatusColumn( grids.GridColumn ):
208        def get_value( self, trans, grid, group ):
209            if group.deleted:
210                return "deleted"
211            return ""
212    class RolesColumn( grids.GridColumn ):
213        def get_value( self, trans, grid, group ):
214            if group.roles:
215                return len( group.roles )
216            return 0
217    class UsersColumn( grids.GridColumn ):
218        def get_value( self, trans, grid, group ):
219            if group.members:
220                return len( group.members )
221            return 0
222
223    # Grid definition
224    webapp = "galaxy"
225    title = "Groups"
226    model_class = model.Group
227    template='/admin/dataset_security/group/grid.mako'
228    default_sort_key = "name"
229    columns = [
230        NameColumn( "Name",
231                    key="name",
232                    link=( lambda item: dict( operation="Manage users and roles", id=item.id, webapp="galaxy" ) ),
233                    model_class=model.Group,
234                    attach_popup=True,
235                    filterable="advanced" ),
236        UsersColumn( "Users", attach_popup=False ),
237        RolesColumn( "Roles", attach_popup=False ),
238        StatusColumn( "Status", attach_popup=False ),
239        # Columns that are valid for filtering but are not visible.
240        grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
241    ]
242    columns.append( grids.MulticolFilterColumn( "Search", 
243                                                cols_to_filter=[ columns[0], columns[1], columns[2] ], 
244                                                key="free-text-search",
245                                                visible=False,
246                                                filterable="standard" ) )
247    global_actions = [
248        grids.GridAction( "Add new group", dict( controller='admin', action='groups', operation='create', webapp="galaxy" ) )
249    ]
250    operations = [ grids.GridOperation( "Rename",
251                                        condition=( lambda item: not item.deleted ),
252                                        allow_multiple=False,
253                                        url_args=dict( webapp="galaxy", action="rename_group" ) ),
254                   grids.GridOperation( "Delete",
255                                        condition=( lambda item: not item.deleted ),
256                                        allow_multiple=True,
257                                        url_args=dict( webapp="galaxy", action="mark_group_deleted" ) ),
258                   grids.GridOperation( "Undelete",
259                                        condition=( lambda item: item.deleted ),
260                                        allow_multiple=True,
261                                        url_args=dict( webapp="galaxy", action="undelete_group" ) ),
262                   grids.GridOperation( "Purge",
263                                        condition=( lambda item: item.deleted ),
264                                        allow_multiple=True,
265                                        url_args=dict( webapp="galaxy", action="purge_group" ) ) ]
266    standard_filters = [
267        grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
268        grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
269        grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
270    ]
271    num_rows_per_page = 50
272    preserve_state = False
273    use_paging = True
274
275class QuotaListGrid( grids.Grid ):
276    class NameColumn( grids.TextColumn ):
277        def get_value( self, trans, grid, quota ):
278            return quota.name
279    class DescriptionColumn( grids.TextColumn ):
280        def get_value( self, trans, grid, quota ):
281            if quota.description:
282                return quota.description
283            return ''
284    class AmountColumn( grids.TextColumn ):
285        def get_value( self, trans, grid, quota ):
286            return quota.operation + quota.display_amount
287    class StatusColumn( grids.GridColumn ):
288        def get_value( self, trans, grid, quota ):
289            if quota.deleted:
290                return "deleted"
291            elif quota.default:
292                return "<strong>default for %s users</strong>" % quota.default[0].type
293            return ""
294    class UsersColumn( grids.GridColumn ):
295        def get_value( self, trans, grid, quota ):
296            if quota.users:
297                return len( quota.users )
298            return 0
299    class GroupsColumn( grids.GridColumn ):
300        def get_value( self, trans, grid, quota ):
301            if quota.groups:
302                return len( quota.groups )
303            return 0
304
305    # Grid definition
306    webapp = "galaxy"
307    title = "Quotas"
308    model_class = model.Quota
309    template='/admin/quota/grid.mako'
310    default_sort_key = "name"
311    columns = [
312        NameColumn( "Name",
313                    key="name",
314                    link=( lambda item: dict( operation="Manage users and groups", id=item.id, webapp="galaxy" ) if not item.default else dict( operation="Change amount", id=item.id, webapp="galaxy" ) ),
315                    model_class=model.Quota,
316                    attach_popup=True,
317                    filterable="advanced" ),
318        DescriptionColumn( "Description",
319                           key='description',
320                           model_class=model.Quota,
321                           attach_popup=False,
322                           filterable="advanced" ),
323        AmountColumn( "Amount",
324                    key='amount',
325                    model_class=model.Quota,
326                    attach_popup=False,
327                    filterable="advanced" ),
328        UsersColumn( "Users", attach_popup=False ),
329        GroupsColumn( "Groups", attach_popup=False ),
330        StatusColumn( "Status", attach_popup=False ),
331        # Columns that are valid for filtering but are not visible.
332        grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
333    ]
334    columns.append( grids.MulticolFilterColumn( "Search", 
335                                                cols_to_filter=[ columns[0], columns[1], columns[2] ], 
336                                                key="free-text-search",
337                                                visible=False,
338                                                filterable="standard" ) )
339    global_actions = [
340        grids.GridAction( "Add new quota", dict( controller='admin', action='quotas', operation='create' ) )
341    ]
342    operations = [ grids.GridOperation( "Rename",
343                                        condition=( lambda item: not item.deleted ),
344                                        allow_multiple=False,
345                                        url_args=dict( webapp="galaxy", action="rename_quota" ) ),
346                   grids.GridOperation( "Change amount",
347                                        condition=( lambda item: not item.deleted ),
348                                        allow_multiple=False,
349                                        url_args=dict( webapp="galaxy", action="edit_quota" ) ),
350                   grids.GridOperation( "Manage users and groups",
351                                        condition=( lambda item: not item.default and not item.deleted ),
352                                        allow_multiple=False,
353                                        url_args=dict( webapp="galaxy", action="manage_users_and_groups_for_quota" ) ),
354                   grids.GridOperation( "Set as different type of default",
355                                        condition=( lambda item: item.default ),
356                                        allow_multiple=False,
357                                        url_args=dict( webapp="galaxy", action="set_quota_default" ) ),
358                   grids.GridOperation( "Set as default",
359                                        condition=( lambda item: not item.default and not item.deleted ),
360                                        allow_multiple=False,
361                                        url_args=dict( webapp="galaxy", action="set_quota_default" ) ),
362                   grids.GridOperation( "Unset as default",
363                                        condition=( lambda item: item.default and not item.deleted ),
364                                        allow_multiple=False,
365                                        url_args=dict( webapp="galaxy", action="unset_quota_default" ) ),
366                   grids.GridOperation( "Delete",
367                                        condition=( lambda item: not item.deleted and not item.default ),
368                                        allow_multiple=True,
369                                        url_args=dict( webapp="galaxy", action="mark_quota_deleted" ) ),
370                   grids.GridOperation( "Undelete",
371                                        condition=( lambda item: item.deleted ),
372                                        allow_multiple=True,
373                                        url_args=dict( webapp="galaxy", action="undelete_quota" ) ),
374                   grids.GridOperation( "Purge",
375                                        condition=( lambda item: item.deleted ),
376                                        allow_multiple=True,
377                                        url_args=dict( webapp="galaxy", action="purge_quota" ) ) ]
378    standard_filters = [
379        grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
380        grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
381        grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
382    ]
383    num_rows_per_page = 50
384    preserve_state = False
385    use_paging = True
386
387class AdminGalaxy( BaseUIController, Admin, AdminActions, UsesQuota, QuotaParamParser ):
388    
389    user_list_grid = UserListGrid()
390    role_list_grid = RoleListGrid()
391    group_list_grid = GroupListGrid()
392    quota_list_grid = QuotaListGrid()
393
394    # Galaxy Quota Stuff
395    @web.expose
396    @web.require_admin
397    def quotas( self, trans, **kwargs ):
398        if 'operation' in kwargs:
399            operation = kwargs.pop('operation').lower()
400            if operation == "quotas":
401                return self.quota( trans, **kwargs )
402            if operation == "create":
403                return self.create_quota( trans, **kwargs )
404            if operation == "delete":
405                return self.mark_quota_deleted( trans, **kwargs )
406            if operation == "undelete":
407                return self.undelete_quota( trans, **kwargs )
408            if operation == "purge":
409                return self.purge_quota( trans, **kwargs )
410            if operation == "change amount":
411                return self.edit_quota( trans, **kwargs )
412            if operation == "manage users and groups":
413                return self.manage_users_and_groups_for_quota( trans, **kwargs )
414            if operation == "rename":
415                return self.rename_quota( trans, **kwargs )
416            if operation == "edit":
417                return self.edit_quota( trans, **kwargs )
418        # Render the list view
419        return self.quota_list_grid( trans, **kwargs )
420
421    @web.expose
422    @web.require_admin
423    def create_quota( self, trans, **kwd ):
424        params = self.get_quota_params( kwd )
425        if params.get( 'create_quota_button', False ):
426            try:
427                quota, message = self._create_quota( params )
428                return trans.response.send_redirect( web.url_for( controller='admin',
429                                                                  action='quotas',
430                                                                  webapp=params.webapp,
431                                                                  message=util.sanitize_text( message ),
432                                                                  status='done' ) )
433            except MessageException, e:
434                params.message = str( e )
435                params.status = 'error'
436        in_users = map( int, params.in_users )
437        in_groups = map( int, params.in_groups )
438        new_in_users = []
439        new_in_groups = []
440        for user in trans.sa_session.query( trans.app.model.User ) \
441                                    .filter( trans.app.model.User.table.c.deleted==False ) \
442                                    .order_by( trans.app.model.User.table.c.email ):
443            if user.id in in_users:
444                new_in_users.append( ( user.id, user.email ) )
445            else:
446                params.out_users.append( ( user.id, user.email ) )
447        for group in trans.sa_session.query( trans.app.model.Group ) \
448                                     .filter( trans.app.model.Group.table.c.deleted==False ) \
449                                     .order_by( trans.app.model.Group.table.c.name ):
450            if group.id in in_groups:
451                new_in_groups.append( ( group.id, group.name ) )
452            else:
453                params.out_groups.append( ( group.id, group.name ) )
454        return trans.fill_template( '/admin/quota/quota_create.mako',
455                                    webapp=params.webapp,
456                                    name=params.name,
457                                    description=params.description,
458                                    amount=params.amount,
459                                    operation=params.operation,
460                                    default=params.default,
461                                    in_users=new_in_users,
462                                    out_users=params.out_users,
463                                    in_groups=new_in_groups,
464                                    out_groups=params.out_groups,
465                                    message=params.message,
466                                    status=params.status )
467
468    @web.expose
469    @web.require_admin
470    def rename_quota( self, trans, **kwd ):
471        quota, params = self._quota_op( trans, 'rename_quota_button', self._rename_quota, kwd )
472        if not quota:
473            return
474        return trans.fill_template( '/admin/quota/quota_rename.mako',
475                                    id=params.id,
476                                    name=params.name or quota.name,
477                                    description=params.description or quota.description,
478                                    webapp=params.webapp,
479                                    message=params.message,
480                                    status=params.status )
481
482    @web.expose
483    @web.require_admin
484    def manage_users_and_groups_for_quota( self, trans, **kwd ):
485        quota, params = self._quota_op( trans, 'quota_members_edit_button', self._manage_users_and_groups_for_quota, kwd )
486        if not quota:
487            return
488        in_users = []
489        out_users = []
490        in_groups = []
491        out_groups = []
492        for user in trans.sa_session.query( trans.app.model.User ) \
493                                    .filter( trans.app.model.User.table.c.deleted==False ) \
494                                    .order_by( trans.app.model.User.table.c.email ):
495            if user in [ x.user for x in quota.users ]:
496                in_users.append( ( user.id, user.email ) )
497            else:
498                out_users.append( ( user.id, user.email ) )
499        for group in trans.sa_session.query( trans.app.model.Group ) \
500                                     .filter( trans.app.model.Group.table.c.deleted==False ) \
501                                     .order_by( trans.app.model.Group.table.c.name ):
502            if group in [ x.group for x in quota.groups ]:
503                in_groups.append( ( group.id, group.name ) )
504            else:
505                out_groups.append( ( group.id, group.name ) )
506        return trans.fill_template( '/admin/quota/quota.mako',
507                                    id=params.id,
508                                    name=quota.name,
509                                    in_users=in_users,
510                                    out_users=out_users,
511                                    in_groups=in_groups,
512                                    out_groups=out_groups,
513                                    webapp=params.webapp,
514                                    message=params.message,
515                                    status=params.status )
516
517    @web.expose
518    @web.require_admin
519    def edit_quota( self, trans, **kwd ):
520        quota, params = self._quota_op( trans, 'edit_quota_button', self._edit_quota, kwd )
521        if not quota:
522            return
523        return trans.fill_template( '/admin/quota/quota_edit.mako',
524                                    id=params.id,
525                                    operation=params.operation or quota.operation,
526                                    display_amount=params.amount or quota.display_amount,
527                                    webapp=params.webapp,
528                                    message=params.message,
529                                    status=params.status )
530
531    @web.expose
532    @web.require_admin
533    def set_quota_default( self, trans, **kwd ):
534        quota, params = self._quota_op( trans, 'set_default_quota_button', self._set_quota_default, kwd )
535        if not quota:
536            return
537        if params.default:
538            default = params.default
539        elif quota.default:
540            default = quota.default[0].type
541        else:
542            default = "no"
543        return trans.fill_template( '/admin/quota/quota_set_default.mako',
544                                    id=params.id,
545                                    default=default,
546                                    webapp=params.webapp,
547                                    message=params.message,
548                                    status=params.status )
549
550    @web.expose
551    @web.require_admin
552    def unset_quota_default( self, trans, **kwd ):
553        quota, params = self._quota_op( trans, True, self._unset_quota_default, kwd )
554        if not quota:
555            return
556        return trans.response.send_redirect( web.url_for( controller='admin',
557                                                          action='quotas',
558                                                          webapp=params.webapp,
559                                                          message=util.sanitize_text( params.message ),
560                                                          status='error' ) )
561                
562
563    @web.expose
564    @web.require_admin
565    def mark_quota_deleted( self, trans, **kwd ):
566        quota, params = self._quota_op( trans, True, self._mark_quota_deleted, kwd, listify=True )
567        if not quota:
568            return
569        return trans.response.send_redirect( web.url_for( controller='admin',
570                                                          action='quotas',
571                                                          webapp=params.webapp,
572                                                          message=util.sanitize_text( params.message ),
573                                                          status='error' ) )
574
575    @web.expose
576    @web.require_admin
577    def undelete_quota( self, trans, **kwd ):
578        quota, params = self._quota_op( trans, True, self._undelete_quota, kwd, listify=True )
579        if not quota:
580            return
581        return trans.response.send_redirect( web.url_for( controller='admin',
582                                                          action='quotas',
583                                                          webapp=params.webapp,
584                                                          message=util.sanitize_text( params.message ),
585                                                          status='error' ) )
586
587    @web.expose
588    @web.require_admin
589    def purge_quota( self, trans, **kwd ):
590        quota, params = self._quota_op( trans, True, self._purge_quota, kwd, listify=True )
591        if not quota:
592            return
593        return trans.response.send_redirect( web.url_for( controller='admin',
594                                                          action='quotas',
595                                                          webapp=params.webapp,
596                                                          message=util.sanitize_text( params.message ),
597                                                          status='error' ) )
598
599    def _quota_op( self, trans, do_op, op_method, kwd, listify=False ):
600        params = self.get_quota_params( kwd )
601        if listify:
602            quota = []
603            messages = []
604            for id in util.listify( params.id ):
605                try:
606                    quota.append( self.get_quota( trans, id ) )
607                except MessageException, e:
608                    messages.append( str( e ) )
609            if messages:
610                return None, trans.response.send_redirect( web.url_for( controller='admin',
611                                                                        action='quotas',
612                                                                        webapp=params.webapp,
613                                                                        message=util.sanitize_text( ', '.join( messages ) ),
614                                                                        status='error' ) )
615        else:
616            try:
617                quota = self.get_quota( trans, params.id, deleted=False )
618            except MessageException, e:
619                return None, trans.response.send_redirect( web.url_for( controller='admin',
620                                                                        action='quotas',
621                                                                        webapp=params.webapp,
622                                                                        message=util.sanitize_text( str( e ) ),
623                                                                        status='error' ) )
624        if do_op == True or ( do_op != False and params.get( do_op, False ) ):
625            try:
626                message = op_method( quota, params ) 
627                return None, trans.response.send_redirect( web.url_for( controller='admin',
628                                                                        action='quotas',
629                                                                        webapp=params.webapp,
630                                                                        message=util.sanitize_text( message ),
631                                                                        status='done' ) )
632            except MessageException, e:
633                params.message = e.err_msg
634                params.status = e.type
635        return quota, params