Source code for tool_shed.grids.repository_review_grids

import logging

from markupsafe import escape
from sqlalchemy import (
    and_,
    false,
    null,
    or_,
    true,
)

from galaxy.web.legacy_framework import grids
from tool_shed.grids.repository_grids import RepositoryGrid
from tool_shed.util import (
    hg_util,
    metadata_util,
)
from tool_shed.webapp import model

log = logging.getLogger(__name__)


[docs]class ComponentGrid(grids.Grid):
[docs] class NameColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, component): return escape(component.name)
[docs] class DescriptionColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, component): return escape(component.description)
title = "Repository review components" model_class = model.Component template = "/webapps/tool_shed/repository_review/grid.mako" default_sort_key = "name" use_hide_message = False columns = [ NameColumn( "Name", key="Component.name", link=(lambda item: dict(operation="edit", id=item.id)), attach_popup=False ), DescriptionColumn("Description", key="Component.description", attach_popup=False), ] global_actions = [ grids.GridAction( "Add new component", dict(controller="repository_review", action="manage_components", operation="create") ) ] num_rows_per_page = 50
[docs]class RepositoriesWithReviewsGrid(RepositoryGrid): # This grid filters out repositories that have been marked as either deprecated or deleted.
[docs] class WithReviewsRevisionColumn(grids.GridColumn):
[docs] def get_value(self, trans, grid, repository): # Restrict to revisions that have been reviewed. if repository.reviews: rval = "" repo = repository.hg_repo for review in repository.reviews: changeset_revision = review.changeset_revision rev, label = hg_util.get_rev_label_from_changeset_revision(repo, changeset_revision) rval += ( '<a href="manage_repository_reviews_of_revision?id=%s&changeset_revision=%s">%s</a><br/>' % (trans.security.encode_id(repository.id), changeset_revision, label) ) return rval return ""
[docs] class WithoutReviewsRevisionColumn(grids.GridColumn):
[docs] def get_value(self, trans, grid, repository): # Restrict the options to revisions that have not yet been reviewed. repository_metadata_revisions = metadata_util.get_repository_metadata_revisions_for_review( repository, reviewed=False ) if repository_metadata_revisions: rval = "" for repository_metadata in repository_metadata_revisions: rev, label, changeset_revision = hg_util.get_rev_label_changeset_revision_from_repository_metadata( trans.app, repository_metadata, repository=repository, include_date=True, include_hash=False ) rval += ( '<a href="manage_repository_reviews_of_revision?id=%s&changeset_revision=%s">%s</a><br/>' % (trans.security.encode_id(repository.id), changeset_revision, label) ) return rval return ""
[docs] class ReviewersColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, repository): rval = "" if repository.reviewers: for user in repository.reviewers: rval += f'<a class="view-info" href="repository_reviews_by_user?id={trans.security.encode_id(user.id)}">' rval += f"{user.username}</a> | " if rval[-3:] == " | ": rval = rval[:-3] return rval
[docs] class RatingColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, repository): rval = "" for review in repository.reviews: if review.rating: for index in range(1, 6): rval += "<input " rval += f'name="star1-{trans.security.encode_id(review.id)}" ' rval += 'type="radio" ' rval += 'class="community_rating_star star" ' rval += 'disabled="disabled" ' rval += f'value="{str(review.rating)}" ' if review.rating > (index - 0.5) and review.rating < (index + 0.5): rval += 'checked="checked" ' rval += "/>" rval += "<br/>" return rval
[docs] class ApprovedColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, repository): rval = "" for review in repository.reviews: if review.approved: rval += f"{review.approved}<br/>" return rval
title = "All reviewed repositories" model_class = model.Repository template = "/webapps/tool_shed/repository_review/grid.mako" default_sort_key = "Repository.name" columns = [ RepositoryGrid.NameColumn( "Repository name", key="name", link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)), attach_popup=True, ), RepositoryGrid.UserColumn("Owner", model_class=model.User, attach_popup=False, key="User.username"), WithReviewsRevisionColumn("Reviewed revisions"), ReviewersColumn("Reviewers", attach_popup=False), RatingColumn("Rating", attach_popup=False), ApprovedColumn("Approved", attach_popup=False), ] 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, ) ]
[docs] 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())) .join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id, ) ) .join((model.User.table, model.User.table.c.id == model.Repository.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) ) )
[docs]class RepositoriesWithoutReviewsGrid(RepositoriesWithReviewsGrid): # This grid filters out repositories that have been marked as either deprecated or deleted. 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", 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, ) ]
[docs] 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 == null(), ) ) .join(model.User.table) )
[docs]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, ) ]
[docs] 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 == null(), ) ) .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) )
[docs]class RepositoriesReviewedByMeGrid(RepositoriesWithReviewsGrid): # This grid filters out repositories that have been marked as either deprecated or deleted. columns = [ RepositoriesWithReviewsGrid.NameColumn( "Repository name", key="name", link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)), attach_popup=True, ), RepositoriesWithReviewsGrid.UserColumn("Owner", attach_popup=False), RepositoriesWithReviewsGrid.WithReviewsRevisionColumn("Reviewed revisions"), RepositoriesWithReviewsGrid.ReviewersColumn("Reviewers", attach_popup=False), RepositoriesWithReviewsGrid.RatingColumn("Rating", attach_popup=False), RepositoriesWithReviewsGrid.ApprovedColumn("Approved", attach_popup=False), ] columns.append( grids.MulticolFilterColumn( "Search repository name", cols_to_filter=[columns[0]], key="free-text-search", visible=False, filterable="standard", ) )
[docs] 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())) .join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id, ) ) .filter(model.RepositoryReview.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) ) )
[docs]class RepositoryReviewsByUserGrid(grids.Grid): # This grid filters out repositories that have been marked as deprecated.
[docs] class RepositoryNameColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, review): return escape(review.repository.name)
[docs] class RepositoryDescriptionColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, review): return escape(review.repository.description)
[docs] class RevisionColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, review): encoded_review_id = trans.security.encode_id(review.id) rval = '<a class="action-button" href="' if review.user == trans.user: rval += "edit_review" else: rval += "browse_review" revision_label = hg_util.get_revision_label( trans.app, review.repository, review.changeset_revision, include_date=True, include_hash=False ) rval += f'?id={encoded_review_id}">{revision_label}</a>' return rval
[docs] class RatingColumn(grids.TextColumn):
[docs] def get_value(self, trans, grid, review): if review.rating: for index in range(1, 6): rval = "<input " rval += f'name="star1-{trans.security.encode_id(review.id)}" ' rval += 'type="radio" ' rval += 'class="community_rating_star star" ' rval += 'disabled="disabled" ' rval += f'value="{str(review.rating)}" ' if review.rating > (index - 0.5) and review.rating < (index + 0.5): rval += 'checked="checked" ' rval += "/>" return rval return ""
title = "Reviews by user" model_class = model.RepositoryReview template = "/webapps/tool_shed/repository_review/grid.mako" default_sort_key = "repository_id" use_hide_message = False columns = [ RepositoryNameColumn( "Repository Name", model_class=model.Repository, key="Repository.name", link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)), attach_popup=True, ), RepositoryDescriptionColumn( "Description", model_class=model.Repository, key="Repository.description", attach_popup=False ), RevisionColumn("Revision", attach_popup=False), RatingColumn("Rating", attach_popup=False), ] operations = [ grids.GridOperation( "Inspect repository revisions", allow_multiple=False, condition=(lambda item: not item.deleted), async_compatible=False, ) ] num_rows_per_page = 50
[docs] def build_initial_query(self, trans, **kwd): user_id = trans.security.decode_id(kwd["id"]) return ( trans.sa_session.query(model.RepositoryReview) .filter( and_( model.RepositoryReview.table.c.deleted == false(), model.RepositoryReview.table.c.user_id == user_id ) ) .join((model.Repository.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id)) .filter(model.Repository.table.c.deprecated == false()) )
[docs]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, ) ]
[docs] 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) ) )
[docs]class RepositoriesWithNoToolTestsGrid(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 that contain tools with no tests or test data" 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, ) ]
[docs] 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())) .join(model.RepositoryMetadata.table) .filter( and_( model.RepositoryMetadata.table.c.downloadable == true(), model.RepositoryMetadata.table.c.includes_tools == true(), model.RepositoryMetadata.table.c.tools_functionally_correct == false(), ) ) .join(model.User.table) )