Exemple #1
0
class FormsGrid( grids.Grid ):
    # Custom column types
    class NameColumn( grids.TextColumn ):
        def get_value(self, trans, grid, form):
            return form.latest_form.name
    class DescriptionColumn( grids.TextColumn ):
        def get_value(self, trans, grid, form):
            return form.latest_form.desc
    class TypeColumn( grids.TextColumn ):
        def get_value(self, trans, grid, form):
            return form.latest_form.type
    class DeletedColumn( grids.GridColumn ):
       def get_accepted_filters( self ):
           """ Returns a list of accepted filters for this column. """
           accepted_filter_labels_and_vals = { "active" : "False", "deleted" : "True", "all": "All" }
           accepted_filters = []
           for label, val in accepted_filter_labels_and_vals.items():
               args = { self.key: val }
               accepted_filters.append( grids.GridColumnFilter( label, args) )
           return accepted_filters
    # Grid definition
    title = "Forms"
    template = "admin/forms/grid.mako"
    model_class = model.FormDefinitionCurrent
    default_sort_key = "-create_time"
    num_rows_per_page = 50
    preserve_state = True
    use_paging = True
    default_filter = dict( deleted="False" )
    columns = [
        NameColumn( "Name", 
                    key="name", 
                    model_class=model.FormDefinition,
                    link=( lambda item: iff( item.deleted, None, dict( operation="view", id=item.id ) ) ),
                    attach_popup=True, 
                    filterable="advanced" ),
        DescriptionColumn( "Description",
                           key='desc',
                           model_class=model.FormDefinition,
                           filterable="advanced" ),
        TypeColumn( "Type" ),
        DeletedColumn( "Deleted", 
                       key="deleted", 
                       visible=False, 
                       filterable="advanced" )
    ]
    columns.append( grids.MulticolFilterColumn( "Search", 
                                                cols_to_filter=[ columns[0], columns[1] ], 
                                                key="free-text-search",
                                                visible=False,
                                                filterable="standard" ) )
    operations = [
        grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted )  ),
        grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: not item.deleted )  ),
        grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ),    
    ]
    global_actions = [
        grids.GridAction( "Create new form", dict( controller='forms', 
                                                      action='new' ) )
    ]
Exemple #2
0
class UserRequestsGrid( RequestsGrid ):
    operations = [ operation for operation in RequestsGrid.operations ]
    operations.append( grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: item.is_unsubmitted and not item.deleted ) ) )
    operations.append( grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: item.is_new and not item.deleted ) ) )
    operations.append( grids.GridOperation( "Undelete", allow_multiple=True, condition=( lambda item: item.deleted ) ) )
    def apply_query_filter( self, trans, query, **kwd ):
        return query.filter_by( user=trans.user )
Exemple #3
0
class StoredWorkflowAllPublishedGrid(grids.Grid):
    title = "Published Workflows"
    model_class = model.StoredWorkflow
    default_sort_key = "update_time"
    default_filter = dict(public_url="All", username="******", tags="All")
    columns = [
        grids.PublicURLColumn("Name", key="name", filterable="advanced", attach_popup=True),
        grids.OwnerAnnotationColumn("Annotation",
                                    key="annotation",
                                    model_annotation_association_class=model.StoredWorkflowAnnotationAssociation,
                                    filterable="advanced"),
        grids.OwnerColumn("Owner", key="username", model_class=model.User, filterable="advanced"),
        grids.CommunityRatingColumn("Community Rating", key="rating"),
        grids.CommunityTagsColumn("Community Tags", key="tags",
                                  model_tag_association_class=model.StoredWorkflowTagAssociation,
                                  filterable="advanced", grid_name="PublicWorkflowListGrid"),
        grids.ReverseSortColumn("Last Updated", key="update_time", format=time_ago)
    ]
    columns.append(
        grids.MulticolFilterColumn(
            "Search name, annotation, owner, and tags",
            cols_to_filter=[columns[0], columns[1], columns[2], columns[4]],
            key="free-text-search", visible=False, filterable="standard"
        )
    )
    operations = [
        grids.GridOperation(
            'Run',
            condition=(lambda item: not item.deleted),
            allow_multiple=False,
            url_args=dict(controller='workflows', action="run")
        ),
        grids.GridOperation(
            "Import",
            condition=(lambda item: not item.deleted),
            allow_multiple=False,
            url_args=dict(action="imp")
        ),
        grids.GridOperation(
            "Save as File",
            condition=(lambda item: not item.deleted),
            allow_multiple=False,
            url_args=dict(action="export_to_file")
        ),
    ]
    num_rows_per_page = 50
    use_paging = True

    def build_initial_query(self, trans, **kwargs):
        # See optimization description comments and TODO for tags in matching public histories query.
        # In addition to that - be sure to lazyload the latest_workflow - it isn't needed and it causes all
        # of its steps to be eagerly loaded.
        return trans.sa_session.query(self.model_class).join("user").options(lazyload("latest_workflow"), eagerload("user").load_only("username"), eagerload("annotations"), undefer("average_rating"))

    def apply_query_filter(self, trans, query, **kwargs):
        # A public workflow is published, has a slug, and is not deleted.
        return query.filter(
            self.model_class.published == expression.true()).filter(
            self.model_class.slug.isnot(None)).filter(
            self.model_class.deleted == expression.false())
Exemple #4
0
class AdminRequestsGrid(RequestsGrid):
    class UserColumn(grids.TextColumn):
        def get_value(self, trans, grid, request):
            return escape(request.user.email)

    # Grid definition
    columns = [col for col in RequestsGrid.columns]
    columns.append(UserColumn("User", model_class=model.User, key='username'))
    operations = [operation for operation in RequestsGrid.operations]
    operations.append(
        grids.GridOperation("Edit",
                            allow_multiple=False,
                            condition=(lambda item: not item.deleted)))
    operations.append(
        grids.GridOperation(
            "Reject",
            allow_multiple=False,
            condition=(lambda item: not item.deleted and item.is_submitted)))
    operations.append(
        grids.GridOperation("Delete",
                            allow_multiple=True,
                            condition=(lambda item: not item.deleted)))
    operations.append(
        grids.GridOperation("Undelete", condition=(lambda item: item.deleted)))
    global_actions = [
        grids.GridAction(
            "Create new request",
            dict(controller='requests_common',
                 action='create_request',
                 cntrller='requests_admin'))
    ]
Exemple #5
0
class FormsGrid(grids.Grid):
    # Custom column types
    class NameColumn(grids.TextColumn):
        def get_value(self, trans, grid, form):
            return escape(form.latest_form.name)

    class DescriptionColumn(grids.TextColumn):
        def get_value(self, trans, grid, form):
            return escape(form.latest_form.desc)

    class TypeColumn(grids.TextColumn):
        def get_value(self, trans, grid, form):
            return form.latest_form.type
    # Grid definition
    title = "Forms"
    template = "admin/forms/grid.mako"
    model_class = model.FormDefinitionCurrent
    default_sort_key = "-create_time"
    num_rows_per_page = 50
    preserve_state = True
    use_paging = True
    default_filter = dict(deleted="False")
    columns = [
        NameColumn("Name",
                   key="name",
                   model_class=model.FormDefinition,
                   link=(lambda item: iff(item.deleted, None, dict(operation="view_latest_form_definition",
                                                                   id=item.id))),
                   attach_popup=True,
                   filterable="advanced"),
        DescriptionColumn("Description",
                          key='desc',
                          model_class=model.FormDefinition,
                          filterable="advanced"),
        TypeColumn("Type"),
        grids.DeletedColumn("Deleted",
                            key="deleted",
                            visible=False,
                            filterable="advanced")
    ]
    columns.append(grids.MulticolFilterColumn("Search",
                                              cols_to_filter=[columns[0], columns[1]],
                                              key="free-text-search",
                                              visible=False,
                                              filterable="standard"))
    operations = [
        grids.GridOperation("Edit", allow_multiple=False, condition=(lambda item: not item.deleted)),
        grids.GridOperation("Delete", allow_multiple=True, condition=(lambda item: not item.deleted)),
        grids.GridOperation("Undelete", condition=(lambda item: item.deleted)),
    ]
    global_actions = [
        grids.GridAction("Create new form", dict(controller='forms', action='create_form_definition'))
    ]

    def build_initial_query(self, trans, **kwargs):
        return trans.sa_session.query(self.model_class).join(model.FormDefinition, self.model_class.latest_form_id == model.FormDefinition.id)
class VisualizationListGrid(grids.Grid):
    def get_url_args(item):
        """
        Returns dictionary used to create item link.
        """
        url_kwargs = dict(controller='visualization', id=item.id)
        # TODO: hack to build link to saved visualization - need trans in this function instead in order to do
        # link_data = trans.app.visualizations_registry.get_visualizations( trans, item )
        if item.type in registry.VisualizationsRegistry.BUILT_IN_VISUALIZATIONS:
            url_kwargs['action'] = item.type
        else:
            url_kwargs['__route_name__'] = 'saved_visualization'
            url_kwargs['visualization_name'] = item.type
            url_kwargs['action'] = 'saved'
        return url_kwargs

    def get_display_name(self, trans, item):
        if trans.app.visualizations_registry and item.type in trans.app.visualizations_registry.plugins:
            plugin = trans.app.visualizations_registry.plugins[item.type]
            return plugin.config.get('name', item.type)
        return item.type

    # Grid definition
    title = "Saved Visualizations"
    model_class = model.Visualization
    default_sort_key = "-update_time"
    default_filter = dict(title="All", deleted="False", tags="All", sharing="All")
    columns = [
        grids.TextColumn("Title", key="title", attach_popup=True, link=get_url_args),
        grids.TextColumn("Type", method='get_display_name'),
        grids.TextColumn("Build", key="dbkey"),
        grids.IndividualTagsColumn("Tags", key="tags", model_tag_association_class=model.VisualizationTagAssociation, filterable="advanced", grid_name="VisualizationListGrid"),
        grids.SharingStatusColumn("Sharing", key="sharing", filterable="advanced", sortable=False),
        grids.GridColumn("Created", key="create_time", format=time_ago),
        grids.GridColumn("Last Updated", key="update_time", format=time_ago),
    ]
    columns.append(
        grids.MulticolFilterColumn(
            "Search",
            cols_to_filter=[columns[0], columns[2]],
            key="free-text-search", visible=False, filterable="standard")
    )
    operations = [
        grids.GridOperation("Open", allow_multiple=False, url_args=get_url_args),
        grids.GridOperation("Edit Attributes", allow_multiple=False, url_args=dict(controller="", action='visualizations/edit')),
        grids.GridOperation("Copy", allow_multiple=False, condition=(lambda item: not item.deleted)),
        grids.GridOperation("Share or Publish", allow_multiple=False, condition=(lambda item: not item.deleted), url_args=dict(action='sharing')),
        grids.GridOperation("Delete", condition=(lambda item: not item.deleted), confirm="Are you sure you want to delete this visualization?"),
    ]

    def apply_query_filter(self, trans, query, **kwargs):
        return query.filter_by(user=trans.user, deleted=False)
class AdminRepositoryListGrid(RepositoryListGrid):
    operations = [operation for operation in RepositoryListGrid.operations]
    operations.append(
        grids.GridOperation("Delete",
                            allow_multiple=False,
                            condition=(lambda item: not item.deleted),
                            async_compatible=False))
    operations.append(
        grids.GridOperation("Undelete",
                            allow_multiple=False,
                            condition=(lambda item: item.deleted),
                            async_compatible=False))
    standard_filters = []
Exemple #8
0
class AdminRepositoryGrid(RepositoryGrid):
    class DeletedColumn(grids.BooleanColumn):
        def get_value(self, trans, grid, repository):
            if repository.deleted:
                return 'yes'
            return ''

    columns = [
        RepositoryGrid.NameColumn(
            "Name",
            key="name",
            link=(lambda item: dict(operation="view_or_manage_repository",
                                    id=item.id)),
            attach_popup=True),
        RepositoryGrid.HeadsColumn("Heads"),
        RepositoryGrid.UserColumn(
            "Owner",
            model_class=model.User,
            link=(lambda item: dict(operation="repositories_by_user",
                                    id=item.id)),
            attach_popup=False,
            key="User.username"),
        RepositoryGrid.DeprecatedColumn("Deprecated",
                                        key="deprecated",
                                        attach_popup=False),
        # Columns that are valid for filtering but are not visible.
        DeletedColumn("Deleted", key="deleted", attach_popup=False)
    ]
    columns.append(
        grids.MulticolFilterColumn("Search repository name",
                                   cols_to_filter=[columns[0]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    operations = [operation for operation in RepositoryGrid.operations]
    operations.append(
        grids.GridOperation("Delete",
                            allow_multiple=False,
                            condition=(lambda item: not item.deleted),
                            async_compatible=False))
    operations.append(
        grids.GridOperation("Undelete",
                            allow_multiple=False,
                            condition=(lambda item: item.deleted),
                            async_compatible=False))
    standard_filters = []
    default_filter = {}

    def build_initial_query(self, trans, **kwd):
        return trans.sa_session.query(model.Repository) \
                               .join(model.User.table)
Exemple #9
0
class UserOpenIDGrid(grids.Grid):
    use_panels = False
    title = "OpenIDs linked to your account"
    model_class = model.UserOpenID
    template = '/user/openid_manage.mako'
    default_filter = {"openid": "All"}
    default_sort_key = "-create_time"
    columns = [
        grids.TextColumn("OpenID URL",
                         key="openid",
                         link=(lambda x: dict(action='openid_auth',
                                              login_button="Login",
                                              openid_url=x.openid
                                              if not x.provider else '',
                                              openid_provider=x.provider,
                                              auto_associate=True))),
        grids.GridColumn("Created", key="create_time", format=time_ago),
    ]
    operations = [
        grids.GridOperation("Delete", async_compatible=True),
    ]

    def build_initial_query(self, trans, **kwd):
        return trans.sa_session.query(
            self.model_class).filter(self.model_class.user_id == trans.user.id)
Exemple #10
0
class InteractiveToolEntryPointListGrid(grids.Grid):

    use_panels = True
    title = "Available InteractiveTools"
    model_class = model.InteractiveToolEntryPoint
    default_filter = {"name": "All"}
    default_sort_key = "-update_time"
    columns = [
        EntryPointLinkColumn("Name", filterable="advanced"),
        JobStatusColumn("Job Info", key="job_state", model_class=model.Job),
        grids.GridColumn("Created", key="created_time", format=time_ago),
        grids.GridColumn("Last Updated", key="modified_time", format=time_ago),
    ]
    columns.append(
        grids.MulticolFilterColumn(
            "Search",
            cols_to_filter=[columns[0]],
            key="free-text-search", visible=False, filterable="standard"
        )
    )
    operations = [
        grids.GridOperation("Stop", condition=(lambda item: item.active), async_compatible=False),
    ]

    def build_initial_query(self, trans, **kwargs):
        # Get list of user's active InteractiveTools
        return trans.app.interactivetool_manager.get_nonterminal_for_user_by_trans(trans)
class RepositoriesWithoutReviewsGrid(RepositoriesWithReviewsGrid):
    # This grid filters out repositories that have been marked as deprecated.
    title = "Repositories with no reviews"
    columns = [
        RepositoriesWithReviewsGrid.NameColumn(
            "Repository name",
            key="name",
            link=(lambda item: dict(operation="view_or_manage_repository",
                                    id=item.id)),
            attach_popup=True),
        RepositoriesWithReviewsGrid.DescriptionColumn("Synopsis",
                                                      key="description",
                                                      attach_popup=False),
        RepositoriesWithReviewsGrid.WithoutReviewsRevisionColumn(
            "Revisions for review"),
        RepositoriesWithReviewsGrid.UserColumn("Owner", attach_popup=False)
    ]
    columns.append(
        grids.MulticolFilterColumn("Search repository name, description",
                                   cols_to_filter=[columns[0], columns[1]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    operations = [
        grids.GridOperation("Inspect repository revisions",
                            allow_multiple=False,
                            condition=(lambda item: not item.deleted),
                            async_compatible=False)
    ]

    def build_initial_query(self, trans, **kwd):
        return trans.sa_session.query( model.Repository ) \
                               .filter( and_( model.Repository.table.c.deprecated == False,
                                              model.Repository.reviews == None ) ) \
                               .join( model.User.table )
Exemple #12
0
class PageListGrid( grids.Grid ):
    # Grid definition
    use_panels = True
    title = "Pages"
    model_class = model.Page
    default_filter = { "published" : "All"}
    default_sort_key = "-create_time"
    columns = [
        grids.TextColumn( "Title", key="title", model_class=model.Page, attach_popup=True, filterable="standard" ),
        PublicURLColumn( "Public URL" ),
        grids.GridColumn( "Published", key="published", format=format_bool, filterable="standard" ),
        grids.GridColumn( "Created", key="create_time", format=time_ago ),
        grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
    ]
    global_actions = [
        grids.GridAction( "Add new page", dict( action='create' ) )
    ]
    operations = [
        grids.GridOperation( "View", allow_multiple=False, url_args=dict( action='display') ),
        grids.GridOperation( "Edit name/id", allow_multiple=False, url_args=dict( action='edit') ),
        grids.GridOperation( "Edit content", allow_multiple=False, url_args=dict( action='edit_content') ),
        grids.GridOperation( "Delete" ),
        grids.GridOperation( "Publish", condition=( lambda item: not item.published ) ),
        grids.GridOperation( "Unpublish", condition=( lambda item: item.published ) ),
    ]
    def apply_default_filter( self, trans, query, **kwargs ):
        return query.filter_by( user=trans.user, deleted=False )
class PageListGrid( grids.Grid ):
    # Custom column.
    class URLColumn( grids.PublicURLColumn ):
        def get_value( self, trans, grid, item ):
            return url_for(controller='page', action='display_by_username_and_slug', username=item.user.username, slug=item.slug )

    # Grid definition
    use_panels = True
    title = "Pages"
    model_class = model.Page
    default_filter = { "published" : "All", "tags" : "All", "title" : "All", "sharing" : "All" }
    default_sort_key = "-update_time"
    columns = [
        grids.TextColumn( "Title", key="title", attach_popup=True, filterable="advanced" ),
        URLColumn( "Public URL" ),
        grids.OwnerAnnotationColumn( "Annotation", key="annotation", model_annotation_association_class=model.PageAnnotationAssociation, filterable="advanced" ),
        grids.IndividualTagsColumn( "Tags", key="tags", model_tag_association_class=model.PageTagAssociation, filterable="advanced", grid_name="PageListGrid" ),
        grids.SharingStatusColumn( "Sharing", key="sharing", filterable="advanced", sortable=False ),
        grids.GridColumn( "Created", key="create_time", format=time_ago ),
        grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
    ]
    columns.append(
        grids.MulticolFilterColumn(
        "Search",
        cols_to_filter=[ columns[0], columns[2] ],
        key="free-text-search", visible=False, filterable="standard" )
                )
    global_actions = [
        grids.GridAction( "Add new page", dict( action='create' ) )
    ]
    operations = [
        grids.DisplayByUsernameAndSlugGridOperation( "View", allow_multiple=False ),
        grids.GridOperation( "Edit content", allow_multiple=False, url_args=dict( action='edit_content') ),
        grids.GridOperation( "Edit attributes", allow_multiple=False, url_args=dict( action='edit') ),
        grids.GridOperation( "Share or Publish", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=False ),
        grids.GridOperation( "Delete", confirm="Are you sure you want to delete this page?" ),
    ]
    def apply_query_filter( self, trans, query, **kwargs ):
        return query.filter_by( user=trans.user, deleted=False )
Exemple #14
0
class SharedHistoryListGrid(grids.Grid):

    # Custom column types
    class DatasetsByStateColumn(grids.GridColumn):
        def get_value(self, trans, grid, history):
            rval = ''
            for state in ('ok', 'running', 'queued', 'error'):
                total = sum(1 for d in history.active_datasets if d.state == state)
                if total:
                    rval += f'<div class="count-box state-color-{state}">{total}</div>'
            return rval

    class SharedByColumn(grids.GridColumn):
        def get_value(self, trans, grid, history):
            return escape(history.user.email)

    # Grid definition
    title = "Histories shared with you by others"
    model_class = model.History
    default_sort_key = "-update_time"
    columns = [
        grids.GridColumn("Name", key="name", attach_popup=True),
        DatasetsByStateColumn("Datasets", sortable=False),
        grids.GridColumn("Created", key="create_time", format=time_ago),
        grids.GridColumn("Last Updated", key="update_time", format=time_ago),
        SharedByColumn("Shared by", key="user_id")
    ]
    operations = [
        grids.GridOperation("View", allow_multiple=False, url_args=dict(controller="", action="histories/view")),
        grids.GridOperation("Copy", allow_multiple=False),
        grids.GridOperation("Unshare", allow_multiple=False)
    ]

    def build_initial_query(self, trans, **kwargs):
        return trans.sa_session.query(self.model_class).join('users_shared_with')

    def apply_query_filter(self, trans, query, **kwargs):
        return query.filter(model.HistoryUserShareAssociation.user == trans.user)
Exemple #15
0
class StoredWorkflowListGrid(grids.Grid):
    class StepsColumn(grids.GridColumn):
        def get_value(self, trans, grid, workflow):
            return len(workflow.latest_workflow.steps)

    # Grid definition
    use_panels = True
    title = "Saved Workflows"
    model_class = model.StoredWorkflow
    default_filter = {"name": "All", "tags": "All"}
    default_sort_key = "-update_time"
    columns = [
        grids.TextColumn("Name",
                         key="name",
                         attach_popup=True,
                         filterable="advanced"),
        grids.IndividualTagsColumn(
            "Tags",
            "tags",
            model_tag_association_class=model.StoredWorkflowTagAssociation,
            filterable="advanced",
            grid_name="StoredWorkflowListGrid"),
        StepsColumn("Steps"),
        grids.GridColumn("Created", key="create_time", format=time_ago),
        grids.GridColumn("Last Updated", key="update_time", format=time_ago),
    ]
    columns.append(
        grids.MulticolFilterColumn("Search",
                                   cols_to_filter=[columns[0], columns[1]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    operations = [
        grids.GridOperation("Edit",
                            allow_multiple=False,
                            condition=(lambda item: not item.deleted),
                            async_compatible=False),
        grids.GridOperation("Run",
                            condition=(lambda item: not item.deleted),
                            async_compatible=False),
        grids.GridOperation("Copy",
                            condition=(lambda item: not item.deleted),
                            async_compatible=False),
        grids.GridOperation("Rename",
                            condition=(lambda item: not item.deleted),
                            async_compatible=False),
        grids.GridOperation("Sharing",
                            condition=(lambda item: not item.deleted),
                            async_compatible=False),
        grids.GridOperation("Delete",
                            condition=(lambda item: item.deleted),
                            async_compatible=True),
    ]

    def apply_query_filter(self, trans, query, **kwargs):
        return query.filter_by(user=trans.user, deleted=False)
class RepositoriesReadyForReviewGrid(RepositoriesWithoutReviewsGrid):
    # Repositories that are ready for human review are those that either:
    # 1) Have no tools
    # 2) Have tools that have been proven to be functionally correct within Galaxy.
    # This grid filters out repositories that have been marked as either deprecated or deleted.
    title = "Repositories ready for review"
    columns = [
        RepositoriesWithoutReviewsGrid.NameColumn(
            "Repository name",
            key="name",
            link=(lambda item: dict(operation="view_or_manage_repository",
                                    id=item.id)),
            attach_popup=True),
        RepositoriesWithoutReviewsGrid.DescriptionColumn("Synopsis",
                                                         key="description",
                                                         attach_popup=False),
        RepositoriesWithoutReviewsGrid.WithoutReviewsRevisionColumn(
            "Revisions for review"),
        RepositoriesWithoutReviewsGrid.UserColumn("Owner",
                                                  model_class=model.User,
                                                  attach_popup=False,
                                                  key="User.username")
    ]
    columns.append(
        grids.MulticolFilterColumn("Search repository name, description",
                                   cols_to_filter=[columns[0], columns[1]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    operations = [
        grids.GridOperation("Inspect repository revisions",
                            allow_multiple=False,
                            condition=(lambda item: not item.deleted),
                            async_compatible=False)
    ]

    def build_initial_query(self, trans, **kwd):
        return trans.sa_session.query( model.Repository ) \
                               .filter( and_( model.Repository.table.c.deleted == False,
                                              model.Repository.table.c.deprecated == False,
                                              model.Repository.reviews == None ) ) \
                               .join( model.RepositoryMetadata.table ) \
                               .filter( and_( model.RepositoryMetadata.table.c.downloadable == True,
                                              or_( model.RepositoryMetadata.table.c.includes_tools == False,
                                                   and_( model.RepositoryMetadata.table.c.includes_tools == True,
                                                         model.RepositoryMetadata.table.c.tools_functionally_correct == True ) ) ) ) \
                               .join( model.User.table )
Exemple #17
0
class VisualizationListGrid( grids.Grid ):
    def get_url_args( item ):
        """
        Returns dictionary used to create item link.
        """
        controller = "visualization"
        action = item.type
        if item.type == "phyloviz":
            controller = "phyloviz"
            action = "visualization"
        return dict( controller=controller, action=action, id=item.id )

    # Grid definition
    title = "Saved Visualizations"
    model_class = model.Visualization
    default_sort_key = "-update_time"
    default_filter = dict( title="All", deleted="False", tags="All", sharing="All" )
    columns = [
        grids.TextColumn( "Title", key="title", attach_popup=True, link=get_url_args ),
        grids.TextColumn( "Type", key="type" ),
        grids.TextColumn( "Dbkey", key="dbkey" ),
        grids.IndividualTagsColumn( "Tags", key="tags", model_tag_association_class=model.VisualizationTagAssociation, filterable="advanced", grid_name="VisualizationListGrid" ),
        grids.SharingStatusColumn( "Sharing", key="sharing", filterable="advanced", sortable=False ),
        grids.GridColumn( "Created", key="create_time", format=time_ago ),
        grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
    ]    
    columns.append( 
        grids.MulticolFilterColumn(  
        "Search", 
        cols_to_filter=[ columns[0], columns[2] ], 
        key="free-text-search", visible=False, filterable="standard" )
                )
    global_actions = [
        grids.GridAction( "Create new visualization", dict( action='create' ) )
    ]
    operations = [
        grids.GridOperation( "Open", allow_multiple=False, url_args=get_url_args ),
        grids.GridOperation( "Open in Circster", allow_multiple=False, condition=( lambda item: item.type == 'trackster' ), url_args=dict( action='circster' ) ),
        grids.GridOperation( "Edit Attributes", allow_multiple=False, url_args=dict( action='edit') ),
        grids.GridOperation( "Copy", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=False, url_args=dict( action='copy') ),
        grids.GridOperation( "Share or Publish", allow_multiple=False, condition=( lambda item: not item.deleted ), async_compatible=False ),
        grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), async_compatible=True, confirm="Are you sure you want to delete this visualization?" ),
    ]
    def apply_query_filter( self, trans, query, **kwargs ):
        return query.filter_by( user=trans.user, deleted=False )
class ReviewedRepositoriesIOwnGrid(RepositoriesWithReviewsGrid):
    title = "Reviewed repositories I own"
    columns = [
        RepositoriesWithReviewsGrid.NameColumn(
            "Repository name",
            key="name",
            link=(lambda item: dict(operation="view_or_manage_repository",
                                    id=item.id)),
            attach_popup=True),
        RepositoriesWithReviewsGrid.WithReviewsRevisionColumn(
            "Reviewed revisions"),
        RepositoriesWithReviewsGrid.WithoutReviewsRevisionColumn(
            "Revisions for review"),
        RepositoriesWithReviewsGrid.ReviewersColumn("Reviewers",
                                                    attach_popup=False),
        RepositoryGrid.DeprecatedColumn("Deprecated")
    ]
    columns.append(
        grids.MulticolFilterColumn("Search repository name",
                                   cols_to_filter=[columns[0]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    operations = [
        grids.GridOperation("Inspect repository revisions",
                            allow_multiple=False,
                            condition=(lambda item: not item.deleted),
                            async_compatible=False)
    ]

    def build_initial_query(self, trans, **kwd):
        return trans.sa_session.query( model.Repository ) \
                               .join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
                               .filter( model.Repository.table.c.user_id == trans.user.id ) \
                               .join( ( model.User.table, model.User.table.c.id == model.RepositoryReview.table.c.user_id ) ) \
                               .outerjoin( ( model.ComponentReview.table, model.ComponentReview.table.c.repository_review_id == model.RepositoryReview.table.c.id ) ) \
                               .outerjoin( ( model.Component.table, model.Component.table.c.id == model.ComponentReview.table.c.component_id ) )
Exemple #19
0
class DataTransferGrid(grids.Grid):
    # Custom column types
    class NameColumn(grids.TextColumn):
        def get_value(self, trans, grid, sample_dataset):
            return escape(sample_dataset.name)

    class SizeColumn(grids.TextColumn):
        def get_value(self, trans, grid, sample_dataset):
            return sample_dataset.size

    class StatusColumn(grids.TextColumn):
        def get_value(self, trans, grid, sample_dataset):
            return sample_dataset.status

    class ExternalServiceColumn(grids.TextColumn):
        def get_value(self, trans, grid, sample_dataset):
            try:
                return escape(sample_dataset.external_service.name)
            except:
                return 'None'

    # Grid definition
    title = "Sample Datasets"
    template = "admin/requests/sample_datasets_grid.mako"
    model_class = model.SampleDataset
    default_sort_key = "-create_time"
    num_rows_per_page = 50
    preserve_state = True
    use_paging = False
    columns = [
        NameColumn("Name",
                   link=(lambda item: dict(operation="view", id=item.id)),
                   attach_popup=True,
                   filterable="advanced"),
        SizeColumn("Size", filterable="advanced"),
        grids.GridColumn("Last Updated", key="update_time", format=time_ago),
        ExternalServiceColumn(
            'External service',
            link=(lambda item: dict(operation="view_external_service",
                                    id=item.external_service.id)),
        ),
        StatusColumn("Transfer Status",
                     filterable="advanced",
                     label_id_prefix='datasetTransferStatus-'),
    ]
    columns.append(
        grids.MulticolFilterColumn("Search",
                                   cols_to_filter=[columns[0]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    operations = [
        grids.GridOperation(
            "Transfer",
            allow_multiple=True,
            condition=(lambda item: item.status in
                       [model.SampleDataset.transfer_status.NOT_STARTED])),
        grids.GridOperation(
            "Rename",
            allow_multiple=True,
            allow_popup=False,
            condition=(lambda item: item.status in
                       [model.SampleDataset.transfer_status.NOT_STARTED])),
        grids.GridOperation(
            "Delete",
            allow_multiple=True,
            condition=(lambda item: item.status in
                       [model.SampleDataset.transfer_status.NOT_STARTED]))
    ]

    def apply_query_filter(self, trans, query, **kwd):
        sample_id = kwd.get('sample_id', None)
        if not sample_id:
            return query
        return query.filter_by(sample_id=trans.security.decode_id(sample_id))
class InstalledRepositoryGrid(grids.Grid):
    class ToolShedStatusColumn(grids.TextColumn):
        def get_value(self, trans, grid, tool_shed_repository):
            if tool_shed_repository.tool_shed_status:
                tool_shed_status_str = ''
                if tool_shed_repository.is_deprecated_in_tool_shed:
                    tool_shed_status_str += generate_deprecated_repository_img_str(
                        include_mouse_over=True)
                if tool_shed_repository.is_latest_installable_revision:
                    tool_shed_status_str += generate_latest_revision_img_str(
                        include_mouse_over=True)
                if tool_shed_repository.revision_update_available:
                    tool_shed_status_str += generate_revision_updates_img_str(
                        include_mouse_over=True)
                if tool_shed_repository.upgrade_available:
                    tool_shed_status_str += generate_revision_upgrades_img_str(
                        include_mouse_over=True)
                if tool_shed_repository.includes_workflows:
                    tool_shed_status_str += generate_includes_workflows_img_str(
                        include_mouse_over=True)
            else:
                tool_shed_status_str = generate_unknown_img_str(
                    include_mouse_over=True)
            return tool_shed_status_str

    class NameColumn(grids.TextColumn):
        def get_value(self, trans, grid, tool_shed_repository):
            return str(tool_shed_repository.name)

    class DescriptionColumn(grids.TextColumn):
        def get_value(self, trans, grid, tool_shed_repository):
            return util.unicodify(tool_shed_repository.description)

    class OwnerColumn(grids.TextColumn):
        def get_value(self, trans, grid, tool_shed_repository):
            return str(tool_shed_repository.owner)

    class RevisionColumn(grids.TextColumn):
        def get_value(self, trans, grid, tool_shed_repository):
            return str(tool_shed_repository.changeset_revision)

    class StatusColumn(grids.TextColumn):
        def get_value(self, trans, grid, tool_shed_repository):
            return suc.get_tool_shed_repository_status_label(
                trans.app, tool_shed_repository)

    class ToolShedColumn(grids.TextColumn):
        def get_value(self, trans, grid, tool_shed_repository):
            return tool_shed_repository.tool_shed

    class DeletedColumn(grids.DeletedColumn):
        def get_accepted_filters(self):
            """ Returns a list of accepted filters for this column. """
            accepted_filter_labels_and_vals = {
                "Active": "False",
                "Deactivated or uninstalled": "True",
                "All": "All"
            }
            accepted_filters = []
            for label, val in accepted_filter_labels_and_vals.items():
                args = {self.key: val}
                accepted_filters.append(grids.GridColumnFilter(label, args))
            return accepted_filters

    # Grid definition
    title = "Installed tool shed repositories"
    model_class = tool_shed_install.ToolShedRepository
    template = '/admin/tool_shed_repository/grid.mako'
    default_sort_key = "name"
    columns = [
        ToolShedStatusColumn(label=""),
        NameColumn(
            label="Name",
            key="name",
            link=(lambda item: iff(
                item.status in [
                    tool_shed_install.ToolShedRepository.installation_status.
                    CLONING
                ], None, dict(operation="manage_repository", id=item.id))),
            attach_popup=True),
        DescriptionColumn(label="Description"),
        OwnerColumn(label="Owner"),
        RevisionColumn(label="Revision"),
        StatusColumn(label="Installation Status", filterable="advanced"),
        ToolShedColumn(label="Tool shed"),
        # Columns that are valid for filtering but are not visible.
        DeletedColumn(label="Status",
                      key="deleted",
                      visible=False,
                      filterable="advanced")
    ]
    columns.append(
        grids.MulticolFilterColumn("Search repository name",
                                   cols_to_filter=[columns[1]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    global_actions = [
        grids.GridAction(
            label="Update tool shed status",
            url_args=dict(
                controller='admin_toolshed',
                action='update_tool_shed_status_for_installed_repository',
                all_installed_repositories=True),
            inbound=False)
    ]
    operations = [ grids.GridOperation( label="Update tool shed status",
                                        condition=( lambda item: not item.deleted ),
                                        allow_multiple=False,
                                        url_args=dict( controller='admin_toolshed',
                                                       action='browse_repositories',
                                                       operation='update tool shed status' ) ),
                   grids.GridOperation( label="Get updates",
                                        condition=( lambda item: \
                                                        not item.deleted and \
                                                        item.revision_update_available and \
                                                        item.status not in \
                                                            [ tool_shed_install.ToolShedRepository.installation_status.ERROR,
                                                              tool_shed_install.ToolShedRepository.installation_status.NEW ] ),
                                        allow_multiple=False,
                                        url_args=dict( controller='admin_toolshed',
                                                       action='browse_repositories',
                                                       operation='get updates' ) ),
                   grids.GridOperation( label="Install latest revision",
                                        condition=( lambda item: item.upgrade_available ),
                                        allow_multiple=False,
                                        url_args=dict( controller='admin_toolshed',
                                                       action='browse_repositories',
                                                       operation='install latest revision' ) ),
                   grids.GridOperation( label="Install",
                                        condition=( lambda item: \
                                                    not item.deleted and \
                                                    item.status == tool_shed_install.ToolShedRepository.installation_status.NEW ),
                                        allow_multiple=False,
                                        url_args=dict( controller='admin_toolshed',
                                                       action='manage_repository',
                                                       operation='install' ) ),
                   grids.GridOperation( label="Deactivate or uninstall",
                                        condition=( lambda item: \
                                                    not item.deleted and \
                                                    item.status != tool_shed_install.ToolShedRepository.installation_status.NEW ),
                                        allow_multiple=False,
                                        url_args=dict( controller='admin_toolshed',
                                                       action='browse_repositories',
                                                       operation='deactivate or uninstall' ) ),
                   grids.GridOperation( label="Reset to install",
                                        condition=( lambda item: \
                                                        ( item.status == tool_shed_install.ToolShedRepository.installation_status.ERROR ) ),
                                        allow_multiple=False,
                                        url_args=dict( controller='admin_toolshed',
                                                       action='browse_repositories',
                                                       operation='reset to install' ) ),
                   grids.GridOperation( label="Activate or reinstall",
                                        condition=( lambda item: item.deleted ),
                                        allow_multiple=False,
                                        target=None,
                                        url_args=dict( controller='admin_toolshed',
                                                       action='browse_repositories',
                                                       operation='activate or reinstall' ) ),
                   grids.GridOperation( label="Purge",
                                        condition=( lambda item: item.is_new ),
                                        allow_multiple=False,
                                        target=None,
                                        url_args=dict( controller='admin_toolshed',
                                                       action='browse_repositories',
                                                       operation='purge' ) ) ]
    standard_filters = []
    default_filter = dict(deleted="False")
    num_rows_per_page = 50
    preserve_state = False
    use_paging = False

    def build_initial_query(self, trans, **kwd):
        return trans.install_model.context.query( self.model_class ) \
                               .order_by( self.model_class.table.c.tool_shed,
                                          self.model_class.table.c.name,
                                          self.model_class.table.c.owner,
                                          self.model_class.table.c.ctx_rev )

    @property
    def legend(self):
        legend_str = '%s&nbsp;&nbsp;Updates are available in the Tool Shed for this revision<br/>' % generate_revision_updates_img_str(
        )
        legend_str += '%s&nbsp;&nbsp;A newer installable revision is available for this repository<br/>' % generate_revision_upgrades_img_str(
        )
        legend_str += '%s&nbsp;&nbsp;This is the latest installable revision of this repository<br/>' % generate_latest_revision_img_str(
        )
        legend_str += '%s&nbsp;&nbsp;This repository is deprecated in the Tool Shed<br/>' % generate_deprecated_repository_img_str(
        )
        legend_str += '%s&nbsp;&nbsp;This repository contains exported workflows<br/>' % generate_includes_workflows_img_str(
        )
        legend_str += '%s&nbsp;&nbsp;Unable to get information from the Tool Shed<br/>' % generate_unknown_img_str(
        )
        return legend_str
 def browse_libraries(self, trans, **kwd):
     if 'operation' in kwd:
         operation = kwd['operation'].lower()
         if operation == "browse":
             return trans.response.send_redirect(
                 web.url_for(controller='library_common',
                             action='browse_library',
                             cntrller='library_admin',
                             **kwd))
         elif operation == "delete":
             return self.delete_library(trans, **kwd)
         elif operation == "undelete":
             return self.undelete_library(trans, **kwd)
     self.library_list_grid.operations = []
     if 'f-deleted' in kwd:
         if kwd['f-deleted'] != 'All':
             if galaxy.util.string_as_bool(kwd['f-deleted']):
                 # We're viewing deleted data libraries, so add a GridOperation
                 # enabling one or more of them to be undeleted.
                 self.library_list_grid.operations = [
                     grids.GridOperation(
                         "Undelete",
                         condition=(lambda item: item.deleted),
                         allow_multiple=True,
                         allow_popup=False,
                         url_args=dict(webapp="galaxy"))
                 ]
             else:
                 # We're viewing active data libraries, so add a GridOperation
                 # enabling one or more of them to be deleted.
                 self.library_list_grid.operations = [
                     grids.GridOperation(
                         "Delete",
                         condition=(lambda item: not item.deleted),
                         allow_multiple=True,
                         allow_popup=False,
                         url_args=dict(webapp="galaxy"))
                 ]
     else:
         # We're viewing active data libraries, so add a GridOperation
         # enabling one or more of them to be deleted.
         self.library_list_grid.operations = [
             grids.GridOperation("Delete",
                                 condition=(lambda item: not item.deleted),
                                 allow_multiple=True,
                                 allow_popup=False,
                                 url_args=dict(webapp="galaxy"))
         ]
     if 'f-free-text-search' in kwd:
         search_term = kwd["f-free-text-search"]
         if trans.app.config.enable_lucene_library_search:
             indexed_search_enabled = True
             search_url = trans.app.config.config_dict.get(
                 "fulltext_find_url", "")
             if search_url:
                 status, message, lddas = lucene_search(
                     trans, 'library_admin', search_term, search_url, **kwd)
         elif trans.app.config.enable_whoosh_library_search:
             indexed_search_enabled = True
             status, message, lddas = whoosh_search(trans, 'library_admin',
                                                    search_term, **kwd)
         else:
             indexed_search_enabled = False
         if indexed_search_enabled:
             comptypes = get_comptypes(trans)
             show_deleted = galaxy.util.string_as_bool(
                 kwd.get('show_deleted', False))
             use_panels = galaxy.util.string_as_bool(
                 kwd.get('use_panels', False))
             return trans.fill_template(
                 '/library/common/library_dataset_search_results.mako',
                 cntrller='library_admin',
                 search_term=search_term,
                 comptypes=comptypes,
                 lddas=lddas,
                 show_deleted=show_deleted,
                 use_panels=use_panels,
                 message=escape(message),
                 status=escape(status))
     # Render the list view
     return self.library_list_grid(trans, **kwd)
Exemple #22
0
class AdminGalaxy( BaseUIController, Admin, AdminActions, UsesQuotaMixin, QuotaParamParser ):

    user_list_grid = UserListGrid()
    role_list_grid = RoleListGrid()
    group_list_grid = GroupListGrid()
    quota_list_grid = QuotaListGrid()
    tool_version_list_grid = ToolVersionListGrid()
    delete_operation = grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True )
    undelete_operation = grids.GridOperation( "Undelete", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True )
    purge_operation = grids.GridOperation( "Purge", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True )

    @web.expose
    @web.require_admin
    def quotas( self, trans, **kwargs ):
        if 'operation' in kwargs:
            operation = kwargs.pop('operation').lower()
            if operation == "quotas":
                return self.quota( trans, **kwargs )
            if operation == "create":
                return self.create_quota( trans, **kwargs )
            if operation == "delete":
                return self.mark_quota_deleted( trans, **kwargs )
            if operation == "undelete":
                return self.undelete_quota( trans, **kwargs )
            if operation == "purge":
                return self.purge_quota( trans, **kwargs )
            if operation == "change amount":
                return self.edit_quota( trans, **kwargs )
            if operation == "manage users and groups":
                return self.manage_users_and_groups_for_quota( trans, **kwargs )
            if operation == "rename":
                return self.rename_quota( trans, **kwargs )
            if operation == "edit":
                return self.edit_quota( trans, **kwargs )
        # Render the list view
        return self.quota_list_grid( trans, **kwargs )

    @web.expose
    @web.require_admin
    def create_quota( self, trans, **kwd ):
        params = self.get_quota_params( kwd )
        if params.get( 'create_quota_button', False ):
            try:
                quota, message = self._create_quota( params )
                return trans.response.send_redirect( web.url_for( controller='admin',
                                                                  action='quotas',
                                                                  webapp=params.webapp,
                                                                  message=sanitize_text( message ),
                                                                  status='done' ) )
            except MessageException as e:
                params.message = str( e )
                params.status = 'error'
        in_users = map( int, params.in_users )
        in_groups = map( int, params.in_groups )
        new_in_users = []
        new_in_groups = []
        for user in trans.sa_session.query( trans.app.model.User ) \
                                    .filter( trans.app.model.User.table.c.deleted == expression.false() ) \
                                    .order_by( trans.app.model.User.table.c.email ):
            if user.id in in_users:
                new_in_users.append( ( user.id, user.email ) )
            else:
                params.out_users.append( ( user.id, user.email ) )
        for group in trans.sa_session.query( trans.app.model.Group ) \
                                     .filter( trans.app.model.Group.table.c.deleted == expression.false() ) \
                                     .order_by( trans.app.model.Group.table.c.name ):
            if group.id in in_groups:
                new_in_groups.append( ( group.id, group.name ) )
            else:
                params.out_groups.append( ( group.id, group.name ) )
        return trans.fill_template( '/admin/quota/quota_create.mako',
                                    webapp=params.webapp,
                                    name=params.name,
                                    description=params.description,
                                    amount=params.amount,
                                    operation=params.operation,
                                    default=params.default,
                                    in_users=new_in_users,
                                    out_users=params.out_users,
                                    in_groups=new_in_groups,
                                    out_groups=params.out_groups,
                                    message=params.message,
                                    status=params.status )

    @web.expose
    @web.require_admin
    def rename_quota( self, trans, **kwd ):
        quota, params = self._quota_op( trans, 'rename_quota_button', self._rename_quota, kwd )
        if not quota:
            return
        return trans.fill_template( '/admin/quota/quota_rename.mako',
                                    id=params.id,
                                    name=params.name or quota.name,
                                    description=params.description or quota.description,
                                    webapp=params.webapp,
                                    message=params.message,
                                    status=params.status )

    @web.expose
    @web.require_admin
    def manage_users_and_groups_for_quota( self, trans, **kwd ):
        quota, params = self._quota_op( trans, 'quota_members_edit_button', self._manage_users_and_groups_for_quota, kwd )
        if not quota:
            return
        in_users = []
        out_users = []
        in_groups = []
        out_groups = []
        for user in trans.sa_session.query( trans.app.model.User ) \
                                    .filter( trans.app.model.User.table.c.deleted == expression.false() ) \
                                    .order_by( trans.app.model.User.table.c.email ):
            if user in [ x.user for x in quota.users ]:
                in_users.append( ( user.id, user.email ) )
            else:
                out_users.append( ( user.id, user.email ) )
        for group in trans.sa_session.query( trans.app.model.Group ) \
                                     .filter( trans.app.model.Group.table.c.deleted == expression.false()) \
                                     .order_by( trans.app.model.Group.table.c.name ):
            if group in [ x.group for x in quota.groups ]:
                in_groups.append( ( group.id, group.name ) )
            else:
                out_groups.append( ( group.id, group.name ) )
        return trans.fill_template( '/admin/quota/quota.mako',
                                    id=params.id,
                                    name=quota.name,
                                    in_users=in_users,
                                    out_users=out_users,
                                    in_groups=in_groups,
                                    out_groups=out_groups,
                                    webapp=params.webapp,
                                    message=params.message,
                                    status=params.status )

    @web.expose
    @web.require_admin
    def edit_quota( self, trans, **kwd ):
        quota, params = self._quota_op( trans, 'edit_quota_button', self._edit_quota, kwd )
        if not quota:
            return
        return trans.fill_template( '/admin/quota/quota_edit.mako',
                                    id=params.id,
                                    operation=params.operation or quota.operation,
                                    display_amount=params.amount or quota.display_amount,
                                    webapp=params.webapp,
                                    message=params.message,
                                    status=params.status )

    @web.expose
    @web.require_admin
    def set_quota_default( self, trans, **kwd ):
        quota, params = self._quota_op( trans, 'set_default_quota_button', self._set_quota_default, kwd )
        if not quota:
            return
        if params.default:
            default = params.default
        elif quota.default:
            default = quota.default[0].type
        else:
            default = "no"
        return trans.fill_template( '/admin/quota/quota_set_default.mako',
                                    id=params.id,
                                    default=default,
                                    webapp=params.webapp,
                                    message=params.message,
                                    status=params.status )

    @web.expose
    @web.require_admin
    def unset_quota_default( self, trans, **kwd ):
        quota, params = self._quota_op( trans, True, self._unset_quota_default, kwd )
        if not quota:
            return
        return trans.response.send_redirect( web.url_for( controller='admin',
                                                          action='quotas',
                                                          webapp=params.webapp,
                                                          message=sanitize_text( params.message ),
                                                          status='error' ) )

    @web.expose
    @web.require_admin
    def mark_quota_deleted( self, trans, **kwd ):
        quota, params = self._quota_op( trans, True, self._mark_quota_deleted, kwd, listify=True )
        if not quota:
            return
        return trans.response.send_redirect( web.url_for( controller='admin',
                                                          action='quotas',
                                                          webapp=params.webapp,
                                                          message=sanitize_text( params.message ),
                                                          status='error' ) )

    @web.expose
    @web.require_admin
    def undelete_quota( self, trans, **kwd ):
        quota, params = self._quota_op( trans, True, self._undelete_quota, kwd, listify=True )
        if not quota:
            return
        return trans.response.send_redirect( web.url_for( controller='admin',
                                                          action='quotas',
                                                          webapp=params.webapp,
                                                          message=sanitize_text( params.message ),
                                                          status='error' ) )

    @web.expose
    @web.require_admin
    def purge_quota( self, trans, **kwd ):
        quota, params = self._quota_op( trans, True, self._purge_quota, kwd, listify=True )
        if not quota:
            return
        return trans.response.send_redirect( web.url_for( controller='admin',
                                                          action='quotas',
                                                          webapp=params.webapp,
                                                          message=sanitize_text( params.message ),
                                                          status='error' ) )

    def _quota_op( self, trans, do_op, op_method, kwd, listify=False ):
        params = self.get_quota_params( kwd )
        if listify:
            quota = []
            messages = []
            for id in galaxy.util.listify( params.id ):
                try:
                    quota.append( self.get_quota( trans, id ) )
                except MessageException as e:
                    messages.append( str( e ) )
            if messages:
                return None, trans.response.send_redirect( web.url_for( controller='admin',
                                                                        action='quotas',
                                                                        webapp=params.webapp,
                                                                        message=sanitize_text( ', '.join( messages ) ),
                                                                        status='error' ) )
        else:
            try:
                quota = self.get_quota( trans, params.id, deleted=False )
            except MessageException as e:
                return None, trans.response.send_redirect( web.url_for( controller='admin',
                                                                        action='quotas',
                                                                        webapp=params.webapp,
                                                                        message=sanitize_text( str( e ) ),
                                                                        status='error' ) )
        if do_op is True or ( do_op is not False and params.get( do_op, False ) ):
            try:
                message = op_method( quota, params )
                return None, trans.response.send_redirect( web.url_for( controller='admin',
                                                                        action='quotas',
                                                                        webapp=params.webapp,
                                                                        message=sanitize_text( message ),
                                                                        status='done' ) )
            except MessageException as e:
                params.message = e.err_msg
                params.status = e.type
        return quota, params

    @web.expose
    @web.require_admin
    def impersonate( self, trans, email=None, **kwd ):
        if not trans.app.config.allow_user_impersonation:
            return trans.show_error_message( "User impersonation is not enabled in this instance of Galaxy." )
        message = ''
        status = 'done'
        emails = None
        if email is not None:
            user = trans.sa_session.query( trans.app.model.User ).filter_by( email=email ).first()
            if user:
                trans.handle_user_logout()
                trans.handle_user_login(user)
                message = 'You are now logged in as %s, <a target="_top" href="%s">return to the home page</a>' % ( email, url_for( controller='root' ) )
                emails = []
            else:
                message = 'Invalid user selected'
                status = 'error'
        if emails is None:
            emails = [ u.email for u in trans.sa_session.query( trans.app.model.User ).enable_eagerloads( False ).all() ]
        return trans.fill_template( 'admin/impersonate.mako', emails=emails, message=message, status=status )

    def check_for_tool_dependencies( self, trans, migration_stage ):
        # Get the 000x_tools.xml file associated with migration_stage.
        tools_xml_file_path = os.path.abspath( os.path.join( trans.app.config.root, 'scripts', 'migrate_tools', '%04d_tools.xml' % migration_stage ) )
        tree = galaxy.util.parse_xml( tools_xml_file_path )
        root = tree.getroot()
        tool_shed = root.get( 'name' )
        shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed )
        repo_name_dependency_tups = []
        if shed_url:
            for elem in root:
                if elem.tag == 'repository':
                    tool_dependencies = []
                    tool_dependencies_dict = {}
                    repository_name = elem.get( 'name' )
                    changeset_revision = elem.get( 'changeset_revision' )
                    params = dict( name=repository_name, owner='devteam', changeset_revision=changeset_revision )
                    pathspec = [ 'repository', 'get_tool_dependencies' ]
                    text = url_get( shed_url, password_mgr=self.app.tool_shed_registry.url_auth( shed_url ), pathspec=pathspec, params=params )
                    if text:
                        tool_dependencies_dict = encoding_util.tool_shed_decode( text )
                        for dependency_key, requirements_dict in tool_dependencies_dict.items():
                            tool_dependency_name = requirements_dict[ 'name' ]
                            tool_dependency_version = requirements_dict[ 'version' ]
                            tool_dependency_type = requirements_dict[ 'type' ]
                            tool_dependency_readme = requirements_dict.get( 'readme', '' )
                            tool_dependencies.append( ( tool_dependency_name, tool_dependency_version, tool_dependency_type, tool_dependency_readme ) )
                    repo_name_dependency_tups.append( ( repository_name, tool_dependencies ) )
        return repo_name_dependency_tups

    @web.expose
    @web.require_admin
    def review_tool_migration_stages( self, trans, **kwd ):
        message = escape( galaxy.util.restore_text( kwd.get( 'message', '' ) ) )
        status = galaxy.util.restore_text( kwd.get( 'status', 'done' ) )
        migration_stages_dict = odict()
        migration_modules = []
        migration_scripts_dir = os.path.abspath( os.path.join( trans.app.config.root, 'lib', 'tool_shed', 'galaxy_install', 'migrate', 'versions' ) )
        migration_scripts_dir_contents = os.listdir( migration_scripts_dir )
        for item in migration_scripts_dir_contents:
            if os.path.isfile( os.path.join( migration_scripts_dir, item ) ) and item.endswith( '.py' ):
                module = item.replace( '.py', '' )
                migration_modules.append( module )
        if migration_modules:
            migration_modules.sort()
            # Remove the 0001_tools.py script since it is the seed.
            migration_modules = migration_modules[ 1: ]
            # Reverse the list so viewing will be newest to oldest.
            migration_modules.reverse()
        for migration_module in migration_modules:
            migration_stage = int( migration_module.replace( '_tools', '' ) )
            repo_name_dependency_tups = self.check_for_tool_dependencies( trans, migration_stage )
            open_file_obj, file_name, description = imp.find_module( migration_module, [ migration_scripts_dir ] )
            imported_module = imp.load_module( 'upgrade', open_file_obj, file_name, description )
            migration_info = imported_module.__doc__
            open_file_obj.close()
            migration_stages_dict[ migration_stage ] = ( migration_info, repo_name_dependency_tups )
        return trans.fill_template( 'admin/review_tool_migration_stages.mako',
                                    migration_stages_dict=migration_stages_dict,
                                    message=message,
                                    status=status )

    @web.expose
    @web.require_admin
    def tool_errors( self, trans, **kwd ):
        return trans.fill_template('admin/tool_errors.mako', tool_errors=global_tool_errors.error_stack)

    @web.expose
    @web.require_admin
    def view_datatypes_registry( self, trans, **kwd ):
        message = escape( galaxy.util.restore_text( kwd.get( 'message', '' ) ) )
        status = galaxy.util.restore_text( kwd.get( 'status', 'done' ) )
        return trans.fill_template( 'admin/view_datatypes_registry.mako', message=message, status=status )

    @web.expose
    @web.require_admin
    def view_tool_data_tables( self, trans, **kwd ):
        message = escape( galaxy.util.restore_text( kwd.get( 'message', '' ) ) )
        status = galaxy.util.restore_text( kwd.get( 'status', 'done' ) )
        return trans.fill_template( 'admin/view_data_tables_registry.mako', message=message, status=status )

    @web.expose
    @web.require_admin
    def display_applications( self, trans, **kwd ):
        return trans.fill_template( 'admin/view_display_applications.mako', display_applications=trans.app.datatypes_registry.display_applications )

    @web.expose
    @web.require_admin
    def reload_display_application( self, trans, **kwd ):
        galaxy.queue_worker.send_control_task(trans.app,
                                              'reload_display_application',
                                              noop_self=True,
                                              kwargs={'display_application_ids': kwd.get( 'id' )} )
        reloaded, failed = trans.app.datatypes_registry.reload_display_applications( kwd.get( 'id' ) )
        if not reloaded and failed:
            return trans.show_error_message( 'Unable to reload any of the %i requested display applications ("%s").'
                                             % ( len( failed ), '", "'.join( failed ) ) )
        if failed:
            return trans.show_warn_message( 'Reloaded %i display applications ("%s"), but failed to reload %i display applications ("%s").'
                                            % ( len( reloaded ), '", "'.join( reloaded ), len( failed ), '", "'.join( failed ) ) )
        if not reloaded:
            return trans.show_warn_message( 'You need to request at least one display application to reload.' )
        return trans.show_ok_message( 'Reloaded %i requested display applications ("%s").' % ( len( reloaded ), '", "'.join( reloaded ) ) )

    @web.expose
    @web.require_admin
    def recalculate_user_disk_usage( self, trans, **kwd ):
        user_id = kwd.get( 'id', None )
        user = trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( user_id ) )
        if not user:
            return trans.show_error_message( "User not found for id (%s)" % sanitize_text( str( user_id ) ) )
        current = user.get_disk_usage()
        user.calculate_and_set_disk_usage()
        new = user.get_disk_usage()
        if new in ( current, None ):
            message = 'Usage is unchanged at %s.' % nice_size( current )
        else:
            message = 'Usage has changed by %s to %s.' % ( nice_size( new - current ), nice_size( new )  )
        return trans.response.send_redirect( web.url_for( controller='admin',
                                                          action='users',
                                                          message=sanitize_text( message ),
                                                          status='info' ) )
Exemple #23
0
class QuotaListGrid( grids.Grid ):

    class NameColumn( grids.TextColumn ):
        def get_value( self, trans, grid, quota ):
            return escape(quota.name)

    class DescriptionColumn( grids.TextColumn ):
        def get_value( self, trans, grid, quota ):
            if quota.description:
                return escape(quota.description)
            return ''

    class AmountColumn( grids.TextColumn ):
        def get_value( self, trans, grid, quota ):
            return quota.operation + quota.display_amount

    class StatusColumn( grids.GridColumn ):
        def get_value( self, trans, grid, quota ):
            if quota.deleted:
                return "deleted"
            elif quota.default:
                return "<strong>default for %s users</strong>" % quota.default[0].type
            return ""

    class UsersColumn( grids.GridColumn ):
        def get_value( self, trans, grid, quota ):
            if quota.users:
                return len( quota.users )
            return 0

    class GroupsColumn( grids.GridColumn ):
        def get_value( self, trans, grid, quota ):
            if quota.groups:
                return len( quota.groups )
            return 0

    # Grid definition
    title = "Quotas"
    model_class = model.Quota
    template = '/admin/quota/grid.mako'
    default_sort_key = "name"
    columns = [
        NameColumn( "Name",
                    key="name",
                    link=( lambda item: dict( operation="Change amount", id=item.id, webapp="galaxy" ) ),
                    model_class=model.Quota,
                    attach_popup=True,
                    filterable="advanced" ),
        DescriptionColumn( "Description",
                           key='description',
                           model_class=model.Quota,
                           attach_popup=False,
                           filterable="advanced" ),
        AmountColumn( "Amount",
                      key='amount',
                      model_class=model.Quota,
                      attach_popup=False,
                      filterable="advanced" ),
        UsersColumn( "Users", attach_popup=False ),
        GroupsColumn( "Groups", attach_popup=False ),
        StatusColumn( "Status", attach_popup=False ),
        # Columns that are valid for filtering but are not visible.
        grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
    ]
    columns.append( grids.MulticolFilterColumn( "Search",
                                                cols_to_filter=[ columns[0], columns[1], columns[2] ],
                                                key="free-text-search",
                                                visible=False,
                                                filterable="standard" ) )
    global_actions = [
        grids.GridAction( "Add new quota", dict( controller='admin', action='quotas', operation='create' ) )
    ]
    operations = [ grids.GridOperation( "Rename",
                                        condition=( lambda item: not item.deleted ),
                                        allow_multiple=False,
                                        url_args=dict( webapp="galaxy", action="rename_quota" ) ),
                   grids.GridOperation( "Change amount",
                                        condition=( lambda item: not item.deleted ),
                                        allow_multiple=False,
                                        url_args=dict( webapp="galaxy", action="edit_quota" ) ),
                   grids.GridOperation( "Manage users and groups",
                                        condition=( lambda item: not item.default and not item.deleted ),
                                        allow_multiple=False,
                                        url_args=dict( webapp="galaxy", action="manage_users_and_groups_for_quota" ) ),
                   grids.GridOperation( "Set as different type of default",
                                        condition=( lambda item: item.default ),
                                        allow_multiple=False,
                                        url_args=dict( webapp="galaxy", action="set_quota_default" ) ),
                   grids.GridOperation( "Set as default",
                                        condition=( lambda item: not item.default and not item.deleted ),
                                        allow_multiple=False,
                                        url_args=dict( webapp="galaxy", action="set_quota_default" ) ),
                   grids.GridOperation( "Unset as default",
                                        condition=( lambda item: item.default and not item.deleted ),
                                        allow_multiple=False,
                                        url_args=dict( webapp="galaxy", action="unset_quota_default" ) ),
                   grids.GridOperation( "Delete",
                                        condition=( lambda item: not item.deleted and not item.default ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="mark_quota_deleted" ) ),
                   grids.GridOperation( "Undelete",
                                        condition=( lambda item: item.deleted ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="undelete_quota" ) ),
                   grids.GridOperation( "Purge",
                                        condition=( lambda item: item.deleted ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="purge_quota" ) ) ]
    standard_filters = [
        grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
        grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
        grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
    ]
    num_rows_per_page = 50
    preserve_state = False
    use_paging = True
Exemple #24
0
class UserListGrid( grids.Grid ):

    class EmailColumn( grids.TextColumn ):
        def get_value( self, trans, grid, user ):
            return escape(user.email)

    class UserNameColumn( grids.TextColumn ):
        def get_value( self, trans, grid, user ):
            if user.username:
                return escape(user.username)
            return 'not set'

    class StatusColumn( grids.GridColumn ):
        def get_value( self, trans, grid, user ):
            if user.purged:
                return "purged"
            elif user.deleted:
                return "deleted"
            return ""

    class GroupsColumn( grids.GridColumn ):
        def get_value( self, trans, grid, user ):
            if user.groups:
                return len( user.groups )
            return 0

    class RolesColumn( grids.GridColumn ):
        def get_value( self, trans, grid, user ):
            if user.roles:
                return len( user.roles )
            return 0

    class ExternalColumn( grids.GridColumn ):
        def get_value( self, trans, grid, user ):
            if user.external:
                return 'yes'
            return 'no'

    class LastLoginColumn( grids.GridColumn ):
        def get_value( self, trans, grid, user ):
            if user.galaxy_sessions:
                return self.format( user.galaxy_sessions[ 0 ].update_time )
            return 'never'

    class TimeCreatedColumn( grids.GridColumn ):
        def get_value( self, trans, grid, user ):
            return user.create_time.strftime('%x')

    class ActivatedColumn( grids.GridColumn ):
        def get_value( self, trans, grid, user ):
            if user.active:
                return 'Y'
            else:
                return 'N'

    # Grid definition
    title = "Users"
    model_class = model.User
    template = '/admin/user/grid.mako'
    default_sort_key = "email"
    columns = [
        EmailColumn( "Email",
                     key="email",
                     model_class=model.User,
                     link=( lambda item: dict( operation="information", id=item.id, webapp="galaxy" ) ),
                     attach_popup=True,
                     filterable="advanced",
                     target="top" ),
        UserNameColumn( "User Name",
                        key="username",
                        model_class=model.User,
                        attach_popup=False,
                        filterable="advanced" ),
        GroupsColumn( "Groups", attach_popup=False ),
        RolesColumn( "Roles", attach_popup=False ),
        ExternalColumn( "External", attach_popup=False ),
        LastLoginColumn( "Last Login", format=time_ago ),
        StatusColumn( "Status", attach_popup=False ),
        TimeCreatedColumn( "Created", attach_popup=False ),
        ActivatedColumn( "Activated", attach_popup=False ),
        # Columns that are valid for filtering but are not visible.
        grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
    ]
    columns.append( grids.MulticolFilterColumn( "Search",
                                                cols_to_filter=[ columns[0], columns[1] ],
                                                key="free-text-search",
                                                visible=False,
                                                filterable="standard" ) )
    global_actions = [
        grids.GridAction( "Create new user", dict( controller='admin', action='users', operation='create', webapp="galaxy" ) )
    ]
    operations = [
        grids.GridOperation( "Manage Roles and Groups",
                             condition=( lambda item: not item.deleted ),
                             allow_multiple=False,
                             url_args=dict( webapp="galaxy", action="manage_roles_and_groups_for_user" ) ),
        grids.GridOperation( "Reset Password",
                             condition=( lambda item: not item.deleted ),
                             allow_multiple=True,
                             allow_popup=False,
                             url_args=dict( webapp="galaxy", action="reset_user_password" ) ),
        grids.GridOperation( "Recalculate Disk Usage",
                             condition=( lambda item: not item.deleted ),
                             allow_multiple=False,
                             url_args=dict( webapp="galaxy", action="recalculate_user_disk_usage" ) )
    ]
    standard_filters = [
        grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
        grids.GridColumnFilter( "Deleted", args=dict( deleted=True, purged=False ) ),
        grids.GridColumnFilter( "Purged", args=dict( purged=True ) ),
        grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
    ]
    num_rows_per_page = 50
    preserve_state = False
    use_paging = True

    def get_current_item( self, trans, **kwargs ):
        return trans.user
Exemple #25
0
class GroupListGrid( grids.Grid ):

    class NameColumn( grids.TextColumn ):
        def get_value( self, trans, grid, group ):
            return escape(group.name)

    class StatusColumn( grids.GridColumn ):
        def get_value( self, trans, grid, group ):
            if group.deleted:
                return "deleted"
            return ""

    class RolesColumn( grids.GridColumn ):
        def get_value( self, trans, grid, group ):
            if group.roles:
                return len( group.roles )
            return 0

    class UsersColumn( grids.GridColumn ):
        def get_value( self, trans, grid, group ):
            if group.members:
                return len( group.members )
            return 0

    # Grid definition
    title = "Groups"
    model_class = model.Group
    template = '/admin/dataset_security/group/grid.mako'
    default_sort_key = "name"
    columns = [
        NameColumn( "Name",
                    key="name",
                    link=( lambda item: dict( operation="Manage users and roles", id=item.id, webapp="galaxy" ) ),
                    model_class=model.Group,
                    attach_popup=True,
                    filterable="advanced" ),
        UsersColumn( "Users", attach_popup=False ),
        RolesColumn( "Roles", attach_popup=False ),
        StatusColumn( "Status", attach_popup=False ),
        # Columns that are valid for filtering but are not visible.
        grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
    ]
    columns.append( grids.MulticolFilterColumn( "Search",
                                                cols_to_filter=[ columns[0], columns[1], columns[2] ],
                                                key="free-text-search",
                                                visible=False,
                                                filterable="standard" ) )
    global_actions = [
        grids.GridAction( "Add new group", dict( controller='admin', action='groups', operation='create', webapp="galaxy" ) )
    ]
    operations = [ grids.GridOperation( "Rename",
                                        condition=( lambda item: not item.deleted ),
                                        allow_multiple=False,
                                        url_args=dict( webapp="galaxy", action="rename_group" ) ),
                   grids.GridOperation( "Delete",
                                        condition=( lambda item: not item.deleted ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="mark_group_deleted" ) ),
                   grids.GridOperation( "Undelete",
                                        condition=( lambda item: item.deleted ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="undelete_group" ) ),
                   grids.GridOperation( "Purge",
                                        condition=( lambda item: item.deleted ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="purge_group" ) ) ]
    standard_filters = [
        grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
        grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
        grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
    ]
    num_rows_per_page = 50
    preserve_state = False
    use_paging = True
Exemple #26
0
class RoleListGrid( grids.Grid ):

    class NameColumn( grids.TextColumn ):
        def get_value( self, trans, grid, role ):
            return escape(role.name)

    class DescriptionColumn( grids.TextColumn ):
        def get_value( self, trans, grid, role ):
            if role.description:
                return escape(role.description)
            return ''

    class TypeColumn( grids.TextColumn ):
        def get_value( self, trans, grid, role ):
            return role.type

    class StatusColumn( grids.GridColumn ):
        def get_value( self, trans, grid, role ):
            if role.deleted:
                return "deleted"
            return ""

    class GroupsColumn( grids.GridColumn ):
        def get_value( self, trans, grid, role ):
            if role.groups:
                return len( role.groups )
            return 0

    class UsersColumn( grids.GridColumn ):
        def get_value( self, trans, grid, role ):
            if role.users:
                return len( role.users )
            return 0

    # Grid definition
    title = "Roles"
    model_class = model.Role
    template = '/admin/dataset_security/role/grid.mako'
    default_sort_key = "name"
    columns = [
        NameColumn( "Name",
                    key="name",
                    link=( lambda item: dict( operation="Manage users and groups", id=item.id, webapp="galaxy" ) ),
                    model_class=model.Role,
                    attach_popup=True,
                    filterable="advanced" ),
        DescriptionColumn( "Description",
                           key='description',
                           model_class=model.Role,
                           attach_popup=False,
                           filterable="advanced" ),
        TypeColumn( "Type",
                    key='type',
                    model_class=model.Role,
                    attach_popup=False,
                    filterable="advanced" ),
        GroupsColumn( "Groups", attach_popup=False ),
        UsersColumn( "Users", attach_popup=False ),
        StatusColumn( "Status", attach_popup=False ),
        # Columns that are valid for filtering but are not visible.
        grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
    ]
    columns.append( grids.MulticolFilterColumn( "Search",
                                                cols_to_filter=[ columns[0], columns[1], columns[2] ],
                                                key="free-text-search",
                                                visible=False,
                                                filterable="standard" ) )
    global_actions = [
        grids.GridAction( "Add new role", dict( controller='admin', action='roles', operation='create' ) )
    ]
    operations = [ grids.GridOperation( "Edit",
                                        condition=( lambda item: not item.deleted ),
                                        allow_multiple=False,
                                        url_args=dict( webapp="galaxy", action="rename_role" ) ),
                   grids.GridOperation( "Delete",
                                        condition=( lambda item: not item.deleted ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="mark_role_deleted" ) ),
                   grids.GridOperation( "Undelete",
                                        condition=( lambda item: item.deleted ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="undelete_role" ) ),
                   grids.GridOperation( "Purge",
                                        condition=( lambda item: item.deleted ),
                                        allow_multiple=True,
                                        url_args=dict( webapp="galaxy", action="purge_role" ) ) ]
    standard_filters = [
        grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
        grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
        grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
    ]
    num_rows_per_page = 50
    preserve_state = False
    use_paging = True

    def apply_query_filter( self, trans, query, **kwargs ):
        return query.filter( model.Role.type != model.Role.types.PRIVATE )
Exemple #27
0
class AdminController(BaseUIController, Admin):

    user_list_grid = admin_grids.UserGrid()
    role_list_grid = admin_grids.RoleGrid()
    group_list_grid = admin_grids.GroupGrid()
    manage_category_grid = admin_grids.ManageCategoryGrid()
    repository_grid = admin_grids.AdminRepositoryGrid()
    repository_metadata_grid = admin_grids.RepositoryMetadataGrid()

    delete_operation = grids.GridOperation(
        "Delete",
        condition=(lambda item: not item.deleted),
        allow_multiple=True)
    undelete_operation = grids.GridOperation(
        "Undelete",
        condition=(lambda item: item.deleted and not item.purged),
        allow_multiple=True)
    purge_operation = grids.GridOperation(
        "Purge",
        condition=(lambda item: item.deleted and not item.purged),
        allow_multiple=True)

    @web.expose
    @web.require_admin
    def browse_repositories(self, trans, **kwd):
        # We add parameters to the keyword dict in this method in order to rename the param
        # with an "f-" prefix, simulating filtering by clicking a search link.  We have
        # to take this approach because the "-" character is illegal in HTTP requests.
        if 'operation' in kwd:
            operation = kwd['operation'].lower()
            if operation == "view_or_manage_repository":
                return trans.response.send_redirect(
                    web.url_for(controller='repository',
                                action='browse_repositories',
                                **kwd))
            elif operation == "edit_repository":
                return trans.response.send_redirect(
                    web.url_for(controller='repository',
                                action='edit_repository',
                                **kwd))
            elif operation == "repositories_by_user":
                # Eliminate the current filters if any exist.
                for k, v in list(kwd.items()):
                    if k.startswith('f-'):
                        del kwd[k]
                if 'user_id' in kwd:
                    user = suc.get_user(trans.app, kwd['user_id'])
                    kwd['f-email'] = user.email
                    del kwd['user_id']
                else:
                    # The received id is the repository id, so we need to get the id of the user
                    # that uploaded the repository.
                    repository_id = kwd.get('id', None)
                    repository = repository_util.get_repository_in_tool_shed(
                        trans.app, repository_id)
                    kwd['f-email'] = repository.user.email
            elif operation == "repositories_by_category":
                # Eliminate the current filters if any exist.
                for k, v in list(kwd.items()):
                    if k.startswith('f-'):
                        del kwd[k]
                category_id = kwd.get('id', None)
                category = suc.get_category(trans.app, category_id)
                kwd['f-Category.name'] = category.name
            elif operation == "receive email alerts":
                if kwd['id']:
                    kwd['caller'] = 'browse_repositories'
                    return trans.response.send_redirect(
                        web.url_for(controller='repository',
                                    action='set_email_alerts',
                                    **kwd))
                else:
                    del kwd['operation']
            elif operation == 'delete':
                return self.delete_repository(trans, **kwd)
            elif operation == "undelete":
                return self.undelete_repository(trans, **kwd)
        # The changeset_revision_select_field in the RepositoryGrid performs a refresh_on_change
        # which sends in request parameters like changeset_revison_1, changeset_revision_2, etc.  One
        # of the many select fields on the grid performed the refresh_on_change, so we loop through
        # all of the received values to see which value is not the repository tip.  If we find it, we
        # know the refresh_on_change occurred, and we have the necessary repository id and change set
        # revision to pass on.
        for k, v in kwd.items():
            changeset_revision_str = 'changeset_revision_'
            if k.startswith(changeset_revision_str):
                repository_id = trans.security.encode_id(
                    int(k.lstrip(changeset_revision_str)))
                repository = repository_util.get_repository_in_tool_shed(
                    trans.app, repository_id)
                if repository.tip(trans.app) != v:
                    return trans.response.send_redirect(
                        web.url_for(controller='repository',
                                    action='browse_repositories',
                                    operation='view_or_manage_repository',
                                    id=trans.security.encode_id(repository.id),
                                    changeset_revision=v))
        # Render the list view
        return self.repository_grid(trans, **kwd)

    @web.expose
    @web.require_admin
    def browse_repository_metadata(self, trans, **kwd):
        if 'operation' in kwd:
            operation = kwd['operation'].lower()
            if operation == "delete":
                return self.delete_repository_metadata(trans, **kwd)
            if operation == "view_or_manage_repository_revision":
                # The received id is a RepositoryMetadata object id, so we need to get the
                # associated Repository and redirect to view_or_manage_repository with the
                # changeset_revision.
                repository_metadata = metadata_util.get_repository_metadata_by_id(
                    trans.app, kwd['id'])
                repository = repository_metadata.repository
                kwd['id'] = trans.security.encode_id(repository.id)
                kwd['changeset_revision'] = repository_metadata.changeset_revision
                kwd['operation'] = 'view_or_manage_repository'
                return trans.response.send_redirect(
                    web.url_for(controller='repository',
                                action='browse_repositories',
                                **kwd))
        return self.repository_metadata_grid(trans, **kwd)

    @web.expose
    @web.require_admin
    def create_category(self, trans, **kwd):
        message = escape(kwd.get('message', ''))
        status = kwd.get('status', 'done')
        name = kwd.get('name', '').strip()
        description = kwd.get('description', '').strip()
        if kwd.get('create_category_button', False):
            if not name or not description:
                message = 'Enter a valid name and a description'
                status = 'error'
            elif suc.get_category_by_name(trans.app, name):
                message = 'A category with that name already exists'
                status = 'error'
            else:
                # Create the category
                category = trans.app.model.Category(name=name,
                                                    description=description)
                trans.sa_session.add(category)
                trans.sa_session.flush()
                # Update the Tool Shed's repository registry.
                trans.app.repository_registry.add_category_entry(category)
                message = "Category '%s' has been created" % escape(
                    category.name)
                status = 'done'
                trans.response.send_redirect(
                    web.url_for(controller='admin',
                                action='manage_categories',
                                message=message,
                                status=status))
        return trans.fill_template(
            '/webapps/tool_shed/category/create_category.mako',
            name=name,
            description=description,
            message=message,
            status=status)

    @web.expose
    @web.require_admin
    def delete_repository(self, trans, **kwd):
        message = escape(kwd.get('message', ''))
        status = kwd.get('status', 'done')
        id = kwd.get('id', None)
        if id:
            # Deleting multiple items is currently not allowed (allow_multiple=False), so there will only be 1 id.
            ids = util.listify(id)
            count = 0
            deleted_repositories = ""
            for repository_id in ids:
                repository = repository_util.get_repository_in_tool_shed(
                    trans.app, repository_id)
                if repository:
                    if not repository.deleted:
                        # Mark all installable repository_metadata records as not installable.
                        for repository_metadata in repository.downloadable_revisions:
                            repository_metadata.downloadable = False
                            trans.sa_session.add(repository_metadata)
                        # Mark the repository admin role as deleted.
                        repository_admin_role = repository.admin_role
                        if repository_admin_role is not None:
                            repository_admin_role.deleted = True
                            trans.sa_session.add(repository_admin_role)
                        repository.deleted = True
                        trans.sa_session.add(repository)
                        trans.sa_session.flush()
                        # Update the repository registry.
                        trans.app.repository_registry.remove_entry(repository)
                        count += 1
                        deleted_repositories += " %s " % repository.name
            if count:
                message = "Deleted %d %s: %s" % (
                    count, inflector.cond_plural(
                        len(ids), "repository"), escape(deleted_repositories))
            else:
                message = "All selected repositories were already marked deleted."
        else:
            message = "No repository ids received for deleting."
            status = 'error'
        trans.response.send_redirect(
            web.url_for(controller='admin',
                        action='browse_repositories',
                        message=util.sanitize_text(message),
                        status=status))

    @web.expose
    @web.require_admin
    def delete_repository_metadata(self, trans, **kwd):
        message = escape(kwd.get('message', ''))
        status = kwd.get('status', 'done')
        id = kwd.get('id', None)
        if id:
            ids = util.listify(id)
            count = 0
            for repository_metadata_id in ids:
                repository_metadata = metadata_util.get_repository_metadata_by_id(
                    trans.app, repository_metadata_id)
                trans.sa_session.delete(repository_metadata)
                trans.sa_session.flush()
                count += 1
            if count:
                message = "Deleted %d repository metadata %s" % (
                    count, inflector.cond_plural(len(ids), "record"))
        else:
            message = "No repository metadata ids received for deleting."
            status = 'error'
        trans.response.send_redirect(
            web.url_for(controller='admin',
                        action='browse_repository_metadata',
                        message=util.sanitize_text(message),
                        status=status))

    @web.expose
    @web.require_admin
    def edit_category(self, trans, **kwd):
        '''Handle requests to edit TS category name or description'''
        message = escape(kwd.get('message', ''))
        status = kwd.get('status', 'done')
        id = kwd.get('id', None)
        if not id:
            message = "No category ids received for editing"
            trans.response.send_redirect(
                web.url_for(controller='admin',
                            action='manage_categories',
                            message=message,
                            status='error'))
        category = suc.get_category(trans.app, id)
        original_category_name = str(category.name)
        original_category_description = str(category.description)
        if kwd.get('edit_category_button', False):
            flush_needed = False
            new_name = kwd.get('name', '').strip()
            new_description = kwd.get('description', '').strip()
            if original_category_name != new_name:
                if not new_name:
                    message = 'Enter a valid name'
                    status = 'error'
                elif original_category_name != new_name and suc.get_category_by_name(
                        trans.app, new_name):
                    message = 'A category with that name already exists'
                    status = 'error'
                else:
                    category.name = new_name
                    flush_needed = True
            if original_category_description != new_description:
                category.description = new_description
                if not flush_needed:
                    flush_needed = True
            if flush_needed:
                trans.sa_session.add(category)
                trans.sa_session.flush()
                if original_category_name != new_name:
                    # Update the Tool Shed's repository registry.
                    trans.app.repository_registry.edit_category_entry(
                        original_category_name, new_name)
                message = "The information has been saved for category '%s'" % escape(
                    category.name)
                status = 'done'
                return trans.response.send_redirect(
                    web.url_for(controller='admin',
                                action='manage_categories',
                                message=message,
                                status=status))
        return trans.fill_template(
            '/webapps/tool_shed/category/edit_category.mako',
            category=category,
            message=message,
            status=status)

    @web.expose
    @web.require_admin
    def manage_categories(self, trans, **kwd):
        if 'f-free-text-search' in kwd:
            # Trick to enable searching repository name, description from the CategoryGrid.
            # What we've done is rendered the search box for the RepositoryGrid on the grid.mako
            # template for the CategoryGrid.  See ~/templates/webapps/tool_shed/category/grid.mako.
            # Since we are searching repositories and not categories, redirect to browse_repositories().
            return trans.response.send_redirect(
                web.url_for(controller='admin',
                            action='browse_repositories',
                            **kwd))
        if 'operation' in kwd:
            operation = kwd['operation'].lower()
            if operation == "create":
                return trans.response.send_redirect(
                    web.url_for(controller='admin',
                                action='create_category',
                                **kwd))
            elif operation == "delete":
                return trans.response.send_redirect(
                    web.url_for(controller='admin',
                                action='mark_category_deleted',
                                **kwd))
            elif operation == "undelete":
                return trans.response.send_redirect(
                    web.url_for(controller='admin',
                                action='undelete_category',
                                **kwd))
            elif operation == "purge":
                return trans.response.send_redirect(
                    web.url_for(controller='admin',
                                action='purge_category',
                                **kwd))
            elif operation == "edit":
                return trans.response.send_redirect(
                    web.url_for(controller='admin',
                                action='edit_category',
                                **kwd))
        return self.manage_category_grid(trans, **kwd)

    @web.expose
    @web.require_admin
    def regenerate_statistics(self, trans, **kwd):
        message = escape(kwd.get('message', ''))
        status = kwd.get('status', 'done')
        if 'regenerate_statistics_button' in kwd:
            trans.app.shed_counter.generate_statistics()
            message = "Successfully regenerated statistics"
        return trans.fill_template('/webapps/tool_shed/admin/statistics.mako',
                                   message=message,
                                   status=status)

    @web.expose
    @web.require_admin
    def manage_role_associations(self, trans, **kwd):
        """Manage users, groups and repositories associated with a role."""
        role_id = kwd.get('id', None)
        role = repository_util.get_role_by_id(trans.app, role_id)
        # We currently only have a single role associated with a repository, the repository admin role.
        repository_role_association = role.repositories[0]
        repository = repository_role_association.repository
        associations_dict = repository_util.handle_role_associations(
            trans.app, role, repository, **kwd)
        in_users = associations_dict.get('in_users', [])
        out_users = associations_dict.get('out_users', [])
        in_groups = associations_dict.get('in_groups', [])
        out_groups = associations_dict.get('out_groups', [])
        message = associations_dict.get('message', '')
        status = associations_dict.get('status', 'done')
        return trans.fill_template('/webapps/tool_shed/role/role.mako',
                                   in_admin_controller=True,
                                   repository=repository,
                                   role=role,
                                   in_users=in_users,
                                   out_users=out_users,
                                   in_groups=in_groups,
                                   out_groups=out_groups,
                                   message=message,
                                   status=status)

    @web.expose
    @web.require_admin
    def reset_metadata_on_selected_repositories_in_tool_shed(
            self, trans, **kwd):
        rmm = repository_metadata_manager.RepositoryMetadataManager(
            trans.app, trans.user)
        if 'reset_metadata_on_selected_repositories_button' in kwd:
            message, status = rmm.reset_metadata_on_selected_repositories(
                **kwd)
        else:
            message = escape(util.restore_text(kwd.get('message', '')))
            status = kwd.get('status', 'done')
        repositories_select_field = rmm.build_repository_ids_select_field(
            name='repository_ids',
            multiple=True,
            display='checkboxes',
            my_writable=False)
        return trans.fill_template(
            '/webapps/tool_shed/common/reset_metadata_on_selected_repositories.mako',
            repositories_select_field=repositories_select_field,
            message=message,
            status=status)

    @web.expose
    @web.require_admin
    def undelete_repository(self, trans, **kwd):
        message = escape(kwd.get('message', ''))
        id = kwd.get('id', None)
        if id:
            # Undeleting multiple items is currently not allowed (allow_multiple=False), so there will only be 1 id.
            ids = util.listify(id)
            count = 0
            undeleted_repositories = ""
            for repository_id in ids:
                repository = repository_util.get_repository_in_tool_shed(
                    trans.app, repository_id)
                if repository:
                    if repository.deleted:
                        # Inspect all repository_metadata records to determine those that are installable, and mark
                        # them accordingly.
                        for repository_metadata in repository.metadata_revisions:
                            metadata = repository_metadata.metadata
                            if metadata:
                                if metadata_util.is_downloadable(metadata):
                                    repository_metadata.downloadable = True
                                    trans.sa_session.add(repository_metadata)
                        # Mark the repository admin role as not deleted.
                        repository_admin_role = repository.admin_role
                        if repository_admin_role is not None:
                            repository_admin_role.deleted = False
                            trans.sa_session.add(repository_admin_role)
                        repository.deleted = False
                        trans.sa_session.add(repository)
                        trans.sa_session.flush()
                        if not repository.deprecated:
                            # Update the repository registry.
                            trans.app.repository_registry.add_entry(repository)
                        count += 1
                        undeleted_repositories += " %s" % repository.name
            if count:
                message = "Undeleted %d %s: %s" % (
                    count, inflector.cond_plural(
                        count, "repository"), undeleted_repositories)
            else:
                message = "No selected repositories were marked deleted, so they could not be undeleted."
        else:
            message = "No repository ids received for undeleting."
        trans.response.send_redirect(
            web.url_for(controller='admin',
                        action='browse_repositories',
                        message=util.sanitize_text(message),
                        status='done'))

    @web.expose
    @web.require_admin
    def mark_category_deleted(self, trans, **kwd):
        # TODO: We should probably eliminate the Category.deleted column since it really makes no
        # sense to mark a category as deleted (category names and descriptions can be changed instead).
        # If we do this, and the following 2 methods can be eliminated.
        message = escape(kwd.get('message', ''))
        id = kwd.get('id', None)
        if id:
            ids = util.listify(id)
            message = "Deleted %d categories: " % len(ids)
            for category_id in ids:
                category = suc.get_category(trans.app, category_id)
                category.deleted = True
                trans.sa_session.add(category)
                trans.sa_session.flush()
                # Update the Tool Shed's repository registry.
                trans.app.repository_registry.remove_category_entry(category)
                message += " %s " % escape(category.name)
        else:
            message = "No category ids received for deleting."
        trans.response.send_redirect(
            web.url_for(controller='admin',
                        action='manage_categories',
                        message=util.sanitize_text(message),
                        status='done'))

    @web.expose
    @web.require_admin
    def purge_category(self, trans, **kwd):
        # This method should only be called for a Category that has previously been deleted.
        # Purging a deleted Category deletes all of the following from the database:
        # - RepoitoryCategoryAssociations where category_id == Category.id
        message = escape(kwd.get('message', ''))
        id = kwd.get('id', None)
        if id:
            ids = util.listify(id)
            count = 0
            purged_categories = ""
            message = "Purged %d categories: " % len(ids)
            for category_id in ids:
                category = suc.get_category(trans.app, category_id)
                if category.deleted:
                    # Delete RepositoryCategoryAssociations
                    for rca in category.repositories:
                        trans.sa_session.delete(rca)
                    trans.sa_session.flush()
                    purged_categories += " %s " % category.name
            message = "Purged %d categories: %s" % (count,
                                                    escape(purged_categories))
        else:
            message = "No category ids received for purging."
        trans.response.send_redirect(
            web.url_for(controller='admin',
                        action='manage_categories',
                        message=util.sanitize_text(message),
                        status='done'))

    @web.expose
    @web.require_admin
    def undelete_category(self, trans, **kwd):
        message = escape(kwd.get('message', ''))
        id = kwd.get('id', None)
        if id:
            ids = util.listify(id)
            count = 0
            undeleted_categories = ""
            for category_id in ids:
                category = suc.get_category(trans.app, category_id)
                if category.deleted:
                    category.deleted = False
                    trans.sa_session.add(category)
                    trans.sa_session.flush()
                    # Update the Tool Shed's repository registry.
                    trans.app.repository_registry.add_category_entry(category)
                    count += 1
                    undeleted_categories += " %s" % category.name
            message = "Undeleted %d categories: %s" % (
                count, escape(undeleted_categories))
        else:
            message = "No category ids received for undeleting."
        trans.response.send_redirect(
            web.url_for(controller='admin',
                        action='manage_categories',
                        message=util.sanitize_text(message),
                        status='done'))
Exemple #28
0
class RepositoryMetadataGrid(grids.Grid):
    class IdColumn(grids.IntegerColumn):
        def get_value(self, trans, grid, repository_metadata):
            return repository_metadata.id

    class NameColumn(grids.TextColumn):
        def get_value(self, trans, grid, repository_metadata):
            return escape(repository_metadata.repository.name)

    class OwnerColumn(grids.TextColumn):
        def get_value(self, trans, grid, repository_metadata):
            return escape(repository_metadata.repository.user.username)

    class RevisionColumn(grids.TextColumn):
        def get_value(self, trans, grid, repository_metadata):
            repository = repository_metadata.repository
            return hg_util.get_revision_label(
                trans.app,
                repository,
                repository_metadata.changeset_revision,
                include_date=True,
                include_hash=True)

    class ToolsColumn(grids.TextColumn):
        def get_value(self, trans, grid, repository_metadata):
            tools_str = '0'
            if repository_metadata:
                metadata = repository_metadata.metadata
                if metadata:
                    if 'tools' in metadata:
                        # We used to display the following, but grid was too cluttered.
                        # for tool_metadata_dict in metadata[ 'tools' ]:
                        #    tools_str += '%s <b>%s</b><br/>' % ( tool_metadata_dict[ 'id' ], tool_metadata_dict[ 'version' ] )
                        return '%d' % len(metadata['tools'])
            return tools_str

    class DatatypesColumn(grids.TextColumn):
        def get_value(self, trans, grid, repository_metadata):
            datatypes_str = '0'
            if repository_metadata:
                metadata = repository_metadata.metadata
                if metadata:
                    if 'datatypes' in metadata:
                        # We used to display the following, but grid was too cluttered.
                        # for datatype_metadata_dict in metadata[ 'datatypes' ]:
                        #    datatypes_str += '%s<br/>' % datatype_metadata_dict[ 'extension' ]
                        return '%d' % len(metadata['datatypes'])
            return datatypes_str

    class WorkflowsColumn(grids.TextColumn):
        def get_value(self, trans, grid, repository_metadata):
            workflows_str = '0'
            if repository_metadata:
                metadata = repository_metadata.metadata
                if metadata:
                    if 'workflows' in metadata:
                        # We used to display the following, but grid was too cluttered.
                        # workflows_str += '<b>Workflows:</b><br/>'
                        # metadata[ 'workflows' ] is a list of tuples where each contained tuple is
                        # [ <relative path to the .ga file in the repository>, <exported workflow dict> ]
                        # workflow_tups = metadata[ 'workflows' ]
                        # workflow_metadata_dicts = [ workflow_tup[1] for workflow_tup in workflow_tups ]
                        # for workflow_metadata_dict in workflow_metadata_dicts:
                        #    workflows_str += '%s<br/>' % workflow_metadata_dict[ 'name' ]
                        return '%d' % len(metadata['workflows'])
            return workflows_str

    class DeletedColumn(grids.BooleanColumn):
        def get_value(self, trans, grid, repository_metadata):
            if repository_metadata.repository.deleted:
                return 'yes'
            return ''

    class DeprecatedColumn(grids.BooleanColumn):
        def get_value(self, trans, grid, repository_metadata):
            if repository_metadata.repository.deprecated:
                return 'yes'
            return ''

    class MaliciousColumn(grids.BooleanColumn):
        def get_value(self, trans, grid, repository_metadata):
            if repository_metadata.malicious:
                return 'yes'
            return ''

    # Grid definition
    title = "Repository Metadata"
    model_class = model.RepositoryMetadata
    default_sort_key = "name"
    use_hide_message = False
    columns = [
        IdColumn("Id", visible=False, attach_popup=False),
        NameColumn(
            "Name",
            key="name",
            model_class=model.Repository,
            link=(lambda item: dict(
                operation="view_or_manage_repository_revision", id=item.id)),
            attach_popup=True),
        OwnerColumn("Owner", attach_popup=False),
        RevisionColumn("Revision", attach_popup=False),
        ToolsColumn("Tools", attach_popup=False),
        DatatypesColumn("Datatypes", attach_popup=False),
        WorkflowsColumn("Workflows", attach_popup=False),
        DeletedColumn("Deleted", attach_popup=False),
        DeprecatedColumn("Deprecated", attach_popup=False),
        MaliciousColumn("Malicious", attach_popup=False)
    ]
    columns.append(
        grids.MulticolFilterColumn("Search repository name",
                                   cols_to_filter=[columns[1]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    operations = [
        grids.GridOperation(
            "Delete",
            allow_multiple=False,
            allow_popup=True,
            async_compatible=False,
            confirm=
            "Repository metadata records cannot be recovered after they are deleted. Click OK to delete the selected items."
        )
    ]
    standard_filters = []
    default_filter = {}
    use_paging = False

    def build_initial_query(self, trans, **kwd):
        return trans.sa_session.query(model.RepositoryMetadata) \
                               .join(model.Repository.table)
Exemple #29
0
class UserGrid(grids.Grid):
    class UserLoginColumn(grids.TextColumn):
        def get_value(self, trans, grid, user):
            return escape(user.email)

    class UserNameColumn(grids.TextColumn):
        def get_value(self, trans, grid, user):
            if user.username:
                return escape(user.username)
            return 'not set'

    class GroupsColumn(grids.GridColumn):
        def get_value(self, trans, grid, user):
            if user.groups:
                return len(user.groups)
            return 0

    class RolesColumn(grids.GridColumn):
        def get_value(self, trans, grid, user):
            if user.roles:
                return len(user.roles)
            return 0

    class ExternalColumn(grids.GridColumn):
        def get_value(self, trans, grid, user):
            if user.external:
                return 'yes'
            return 'no'

    class LastLoginColumn(grids.GridColumn):
        def get_value(self, trans, grid, user):
            if user.galaxy_sessions:
                return self.format(user.galaxy_sessions[0].update_time)
            return 'never'

    class StatusColumn(grids.GridColumn):
        def get_value(self, trans, grid, user):
            if user.purged:
                return "purged"
            elif user.deleted:
                return "deleted"
            return ""

    class EmailColumn(grids.GridColumn):
        def filter(self, trans, user, query, column_filter):
            if column_filter == 'All':
                return query
            return query.filter(
                and_(model.Tool.table.c.user_id == model.User.table.c.id,
                     model.User.table.c.email == column_filter))

    title = "Users"
    model_class = model.User
    default_sort_key = "email"
    columns = [
        UserLoginColumn(
            "Email",
            key="email",
            link=(lambda item: dict(operation="information", id=item.id)),
            attach_popup=True,
            filterable="advanced"),
        UserNameColumn("User Name",
                       key="username",
                       attach_popup=False,
                       filterable="advanced"),
        GroupsColumn("Groups", attach_popup=False),
        RolesColumn("Roles", attach_popup=False),
        ExternalColumn("External", attach_popup=False),
        LastLoginColumn("Last Login", format=time_ago),
        StatusColumn("Status", attach_popup=False),
        # Columns that are valid for filtering but are not visible.
        EmailColumn("Email", key="email", visible=False)
    ]
    columns.append(
        grids.MulticolFilterColumn("Search",
                                   cols_to_filter=[columns[0], columns[1]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    global_actions = [
        grids.GridAction(
            "Create new user",
            dict(controller='admin', action='users', operation='create'))
    ]
    operations = [
        grids.GridOperation(
            "Manage Roles and Groups",
            condition=(lambda item: not item.deleted),
            allow_multiple=False,
            url_args=dict(action="manage_roles_and_groups_for_user")),
        grids.GridOperation("Reset Password",
                            condition=(lambda item: not item.deleted),
                            allow_multiple=True,
                            allow_popup=False,
                            url_args=dict(action="reset_user_password"))
    ]
    standard_filters = [
        grids.GridColumnFilter("Active", args=dict(deleted=False)),
        grids.GridColumnFilter("Deleted",
                               args=dict(deleted=True, purged=False)),
        grids.GridColumnFilter("Purged", args=dict(purged=True)),
        grids.GridColumnFilter("All", args=dict(deleted='All'))
    ]

    use_paging = False

    def get_current_item(self, trans, **kwargs):
        return trans.user
Exemple #30
0
class RoleGrid(grids.Grid):
    class NameColumn(grids.TextColumn):
        def get_value(self, trans, grid, role):
            return escape(str(role.name))

    class DescriptionColumn(grids.TextColumn):
        def get_value(self, trans, grid, role):
            if role.description:
                return str(role.description)
            return ''

    class TypeColumn(grids.TextColumn):
        def get_value(self, trans, grid, role):
            return str(role.type)

    class StatusColumn(grids.GridColumn):
        def get_value(self, trans, grid, role):
            if role.deleted:
                return "deleted"
            return ""

    class GroupsColumn(grids.GridColumn):
        def get_value(self, trans, grid, role):
            if role.groups:
                return len(role.groups)
            return 0

    class RepositoriesColumn(grids.GridColumn):
        def get_value(self, trans, grid, role):
            if role.repositories:
                return len(role.repositories)
            return 0

    class UsersColumn(grids.GridColumn):
        def get_value(self, trans, grid, role):
            if role.users:
                return len(role.users)
            return 0

    title = "Roles"
    model_class = model.Role
    default_sort_key = "name"
    columns = [
        NameColumn("Name",
                   key="name",
                   link=(lambda item: dict(
                       operation="Manage role associations", id=item.id)),
                   attach_popup=True,
                   filterable="advanced"),
        DescriptionColumn("Description",
                          key='description',
                          attach_popup=False,
                          filterable="advanced"),
        GroupsColumn("Groups", attach_popup=False),
        RepositoriesColumn("Repositories", attach_popup=False),
        UsersColumn("Users", attach_popup=False),
        # Columns that are valid for filtering but are not visible.
        grids.DeletedColumn("Deleted",
                            key="deleted",
                            visible=False,
                            filterable="advanced")
    ]
    columns.append(
        grids.MulticolFilterColumn("Search",
                                   cols_to_filter=[columns[0]],
                                   key="free-text-search",
                                   visible=False,
                                   filterable="standard"))
    global_actions = [
        grids.GridAction(
            "Add new role",
            dict(controller='admin', action='roles', operation='create'))
    ]
    # Repository admin roles currently do not have any operations since they are managed automatically based
    # on other events.  For example, if a repository is renamed, its associated admin role is automatically
    # renamed accordingly and if a repository is deleted its associated admin role is automatically deleted.
    operations = [
        grids.GridOperation("Rename",
                            condition=(lambda item: not item.deleted and
                                       not item.is_repository_admin_role),
                            allow_multiple=False,
                            url_args=dict(action="rename_role")),
        grids.GridOperation("Delete",
                            condition=(lambda item: not item.deleted and
                                       not item.is_repository_admin_role),
                            allow_multiple=True,
                            url_args=dict(action="mark_role_deleted")),
        grids.GridOperation("Undelete",
                            condition=(lambda item: item.deleted and not item.
                                       is_repository_admin_role),
                            allow_multiple=True,
                            url_args=dict(action="undelete_role")),
        grids.GridOperation("Purge",
                            condition=(lambda item: item.deleted and not item.
                                       is_repository_admin_role),
                            allow_multiple=True,
                            url_args=dict(action="purge_role"))
    ]
    standard_filters = [
        grids.GridColumnFilter("Active", args=dict(deleted=False)),
        grids.GridColumnFilter("Deleted", args=dict(deleted=True)),
        grids.GridColumnFilter("All", args=dict(deleted='All'))
    ]

    use_paging = False

    def apply_query_filter(self, trans, query, **kwd):
        return query.filter(model.Role.type != model.Role.types.PRIVATE)