commit/galaxy-central: jgoecks: Infrastructure for managing visualizations: (a) support for creating multiple types of visualizations; (b) a placeholder visualization API controller; (c) abstract visualization creation so that it can be reused in multiple controllers.
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/62bdb265d300/ changeset: 62bdb265d300 user: jgoecks date: 2012-05-26 00:23:43 summary: Infrastructure for managing visualizations: (a) support for creating multiple types of visualizations; (b) a placeholder visualization API controller; (c) abstract visualization creation so that it can be reused in multiple controllers. affected #: 6 files diff -r 4288ffb1bd16d8f014dc06759c8073919e7347c8 -r 62bdb265d3007d4f761a1defa82a44d888c30bfd lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -2445,12 +2445,13 @@ self.user = None class Visualization( object ): - def __init__( self, user=None, type=None, title=None, dbkey=None, latest_revision=None ): + def __init__( self, user=None, type=None, title=None, dbkey=None, slug=None, latest_revision=None ): self.id = None self.user = user self.type = type self.title = title self.dbkey = dbkey + self.slug = slug self.latest_revision = latest_revision self.revisions = [] if self.latest_revision: diff -r 4288ffb1bd16d8f014dc06759c8073919e7347c8 -r 62bdb265d3007d4f761a1defa82a44d888c30bfd lib/galaxy/visualization/__init__.py --- a/lib/galaxy/visualization/__init__.py +++ b/lib/galaxy/visualization/__init__.py @@ -1,3 +1,3 @@ """ Package for Galaxy visualization plugins. -""" \ No newline at end of file +""" diff -r 4288ffb1bd16d8f014dc06759c8073919e7347c8 -r 62bdb265d3007d4f761a1defa82a44d888c30bfd lib/galaxy/web/api/visualizations.py --- /dev/null +++ b/lib/galaxy/web/api/visualizations.py @@ -0,0 +1,28 @@ +from galaxy import web +from galaxy.web.base.controller import BaseController, BaseAPIController + +class VisualizationsController( BaseAPIController ): + """ + RESTful controller for interactions with visualizations. + """ + + @web.expose_api + def index( self, trans, **kwds ): + """ + GET /api/visualizations: + """ + pass + + @web.json + def show( self, trans, id, **kwd ): + """ + GET /api/visualizations/{viz_id} + """ + pass + + @web.expose_api + def create( self, trans, payload, **kwd ): + """ + POST /api/visualizations + """ + pass \ No newline at end of file diff -r 4288ffb1bd16d8f014dc06759c8073919e7347c8 -r 62bdb265d3007d4f761a1defa82a44d888c30bfd lib/galaxy/web/base/controller.py --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -7,6 +7,7 @@ from galaxy import config, tools, web, util from galaxy.util import inflector from galaxy.util.hash_util import * +from galaxy.util.sanitize_html import sanitize_html from galaxy.web import error, form, url_for from galaxy.model.orm import * from galaxy.workflow.modules import * @@ -275,8 +276,45 @@ class UsesVisualization( SharableItemSecurity ): """ Mixin for controllers that use Visualization objects. """ + + viz_types = [ "trackster", "circos" ] len_files = None + + def create_visualization( self, trans, title, slug, type, dbkey, annotation=None, config={} ): + user = trans.get_user() + + # Error checking. + title_err = slug_err = "" + if not title: + title_err = "visualization name is required" + elif not slug: + slug_err = "visualization id is required" + elif not VALID_SLUG_RE.match( slug ): + slug_err = "visualization identifier must consist of only lowercase letters, numbers, and the '-' character" + elif trans.sa_session.query( trans.model.Visualization ).filter_by( user=user, slug=slug, deleted=False ).first(): + slug_err = "visualization id must be unique" + + if title_err or slug_err: + return { 'title_err': title_err, 'slug_err': slug_err } + + # Create visualization + visualization = trans.model.Visualization( user=user, title=title, slug=slug, dbkey=dbkey, type=type ) + if annotation: + annotation = sanitize_html( annotation, 'utf-8', 'text/html' ) + self.add_item_annotation( trans.sa_session, trans.user, visualization, annotation ) + + # And the first visualization revision + revision = trans.model.VisualizationRevision( visualization=visualization, title=title, config={}, dbkey=dbkey ) + visualization.latest_revision = revision + + # Persist + session = trans.sa_session + session.add(visualization) + session.add(revision) + session.flush() + + return visualization def _get_dbkeys( self, trans ): """ Returns all valid dbkeys that a user can use in a visualization. """ diff -r 4288ffb1bd16d8f014dc06759c8073919e7347c8 -r 62bdb265d3007d4f761a1defa82a44d888c30bfd lib/galaxy/web/buildapp.py --- a/lib/galaxy/web/buildapp.py +++ b/lib/galaxy/web/buildapp.py @@ -132,6 +132,7 @@ webapp.api_mapper.resource_with_deleted( 'quota', 'quotas', path_prefix='/api' ) webapp.api_mapper.resource( 'tool', 'tools', path_prefix='/api' ) webapp.api_mapper.resource_with_deleted( 'user', 'users', path_prefix='/api' ) + webapp.api_mapper.resource( 'visualization', 'visualizations', path_prefix='/api' ) webapp.api_mapper.resource( 'workflow', 'workflows', path_prefix='/api' ) webapp.api_mapper.resource_with_deleted( 'history', 'histories', path_prefix='/api' ) #webapp.api_mapper.connect( 'run_workflow', '/api/workflow/{workflow_id}/library/{library_id}', controller='workflows', action='run', workflow_id=None, library_id=None, conditions=dict(method=["GET"]) ) diff -r 4288ffb1bd16d8f014dc06759c8073919e7347c8 -r 62bdb265d3007d4f761a1defa82a44d888c30bfd lib/galaxy/web/controllers/visualization.py --- a/lib/galaxy/web/controllers/visualization.py +++ b/lib/galaxy/web/controllers/visualization.py @@ -4,7 +4,6 @@ from galaxy.web.framework.helpers import time_ago, grids, iff from galaxy.util.sanitize_html import sanitize_html - class VisualizationListGrid( grids.Grid ): # Grid definition title = "Saved Visualizations" @@ -14,6 +13,7 @@ columns = [ grids.TextColumn( "Title", key="title", attach_popup=True, link=( lambda item: dict( controller="tracks", action="browser", id=item.id ) ) ), + 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 ), @@ -346,51 +346,31 @@ @web.expose @web.require_login( "create visualizations" ) - def create( self, trans, visualization_title="", visualization_slug="", visualization_annotation="", visualization_dbkey="" ): + def create( self, trans, visualization_title="", visualization_slug="", visualization_annotation="", visualization_dbkey="", + visualization_type="" ): """ Create a new visualization """ - user = trans.get_user() visualization_title_err = visualization_slug_err = visualization_annotation_err = "" if trans.request.method == "POST": - if not visualization_title: - visualization_title_err = "visualization name is required" - elif not visualization_slug: - visualization_slug_err = "visualization id is required" - elif not VALID_SLUG_RE.match( visualization_slug ): - visualization_slug_err = "visualization identifier must consist of only lowercase letters, numbers, and the '-' character" - elif trans.sa_session.query( model.Visualization ).filter_by( user=user, slug=visualization_slug, deleted=False ).first(): - visualization_slug_err = "visualization id must be unique" + rval = self.create_visualization( trans, title=visualization_title, + slug=visualization_slug, + annotation=visualization_annotation, + dbkey=visualization_dbkey, + type=visualization_type ) + if isinstance( rval, dict ): + # Found error creating viz. + visualization_title_err = rval[ 'title_err' ] + visualization_slug_err = rval[ 'slug_err' ] else: - # Create the new stored visualization - visualization = model.Visualization() - visualization.title = visualization_title - visualization.slug = visualization_slug - visualization.dbkey = visualization_dbkey - visualization.type = 'trackster' # HACK: set visualization type to trackster since it's the only viz - visualization_annotation = sanitize_html( visualization_annotation, 'utf-8', 'text/html' ) - self.add_item_annotation( trans.sa_session, trans.get_user(), visualization, visualization_annotation ) - visualization.user = user - - # And the first (empty) visualization revision - visualization_revision = model.VisualizationRevision() - visualization_revision.title = visualization_title - visualization_revision.config = {} - visualization_revision.dbkey = visualization_dbkey - visualization_revision.visualization = visualization - visualization.latest_revision = visualization_revision - - # Persist - session = trans.sa_session - session.add(visualization) - session.add(visualization_revision) - session.flush() - + # Successfully created viz. return trans.response.send_redirect( web.url_for( action='list' ) ) - + + viz_type_options = [ ( t, t ) for t in self.viz_types ] return trans.show_form( web.FormBuilder( web.url_for(), "Create new visualization", submit_text="Submit" ) .add_text( "visualization_title", "Visualization title", value=visualization_title, error=visualization_title_err ) + .add_select( "visualization_type", "Type", options=viz_type_options, error=None ) .add_text( "visualization_slug", "Visualization identifier", value=visualization_slug, error=visualization_slug_err, help="""A unique identifier that will be used for public links to this visualization. A default is generated Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.
participants (1)
-
Bitbucket