commit/galaxy-central: james_taylor: biostar: support for asking questions with integrated authentication, still need support for landing page and search
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/a8caad109542/ changeset: a8caad109542 user: james_taylor date: 2013-03-12 20:14:25 summary: biostar: support for asking questions with integrated authentication, still need support for landing page and search affected #: 7 files diff -r a7475ad6ecfc0f1fcdab3cfacce586a107aa8057 -r a8caad109542661a7222c504a529ab5afbe303fb lib/galaxy/config.py --- a/lib/galaxy/config.py +++ b/lib/galaxy/config.py @@ -254,7 +254,9 @@ amqp_config = {} for k, v in amqp_config: self.amqp[k] = v - self.biostar = kwargs.get( 'biostar', None ) + self.biostar_url = kwargs.get( 'biostar_url', None ) + self.biostar_key_name = kwargs.get( 'biostar_key_name', None ) + self.biostar_key = kwargs.get( 'biostar_key', None ) self.running_functional_tests = string_as_bool( kwargs.get( 'running_functional_tests', False ) ) # Experimental: This will not be enabled by default and will hide # nonproduction code. diff -r a7475ad6ecfc0f1fcdab3cfacce586a107aa8057 -r a8caad109542661a7222c504a529ab5afbe303fb lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -402,6 +402,30 @@ self.app.model.ToolShedRepository.table.c.owner == owner, self.app.model.ToolShedRepository.table.c.installed_changeset_revision == installed_changeset_revision ) ) \ .first() + + def get_tool_components( self, tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=False ): + """ + Retrieve all loaded versions of a tool from the toolbox and return a select list enabling selection of a different version, the list of the tool's + loaded versions, and the specified tool. + """ + toolbox = self + tool_version_select_field = None + tools = [] + tool = None + # Backwards compatibility for datasource tools that have default tool_id configured, but which are now using only GALAXY_URL. + tool_ids = listify( tool_id ) + for tool_id in tool_ids: + if get_loaded_tools_by_lineage: + tools = toolbox.get_loaded_tools_by_lineage( tool_id ) + else: + tools = toolbox.get_tool( tool_id, tool_version=tool_version, get_all_versions=True ) + if tools: + tool = toolbox.get_tool( tool_id, tool_version=tool_version, get_all_versions=False ) + if len( tools ) > 1: + tool_version_select_field = self.build_tool_version_select_field( tools, tool.id, set_selected ) + break + return tool_version_select_field, tools, tool + def load_tool_tag_set( self, elem, panel_dict, integrated_panel_dict, tool_path, load_panel_dict, guid=None, index=None ): try: path = elem.get( "file" ) diff -r a7475ad6ecfc0f1fcdab3cfacce586a107aa8057 -r a8caad109542661a7222c504a529ab5afbe303fb lib/galaxy/webapps/galaxy/controllers/biostar.py --- /dev/null +++ b/lib/galaxy/webapps/galaxy/controllers/biostar.py @@ -0,0 +1,86 @@ +""" +Support for integration with the Biostar Q&A application +""" + +from galaxy.web.base.controller import BaseUIController, url_for, error, web + +import base64 +import json +import hmac + +# Biostar requires all keys to be present, so we start with a template +DEFAULT_PAYLOAD = { + 'email': "", + 'title': "Question about Galaxy", + 'tags': 'galaxy', + 'tool_name': '', + 'tool_version': '', + 'tool_id': '' +} + +def encode_data( key, data ): + """ + Encode data to send a question to Biostar + """ + text = json.dumps(data) + text = base64.urlsafe_b64encode(text) + digest = hmac.new(key, text).hexdigest() + return text, digest + + +class BiostarController( BaseUIController ): + """ + Provides integration with Biostar through external authentication, see: http://liondb.com/help/x/ + """ + + @web.expose + def biostar_redirect( self, trans, payload={}, biostar_action=None ): + """ + Generate a redirect to a Biostar site using external authentication to + pass Galaxy user information and information about a specific tool. + """ + # Ensure biostar integration is enabled + if not trans.app.config.biostar_url: + return error( "Biostar integration is not enabled" ) + # Start building up the payload + payload = dict( DEFAULT_PAYLOAD, **payload ) + # Do the best we can of providing user information for the payload + if trans.user: + payload['email'] = trans.user.email + if trans.user.username: + payload['username'] = trans.user.username + payload['display_name'] = trans.user.username + else: + payload['display_name'] = "Galaxy User" + else: + payload['username'] = payload['display_name'] = "Anonymous Galaxy User %d" % trans.galaxy_session.id + data, digest = encode_data( trans.app.config.biostar_key, payload ) + return trans.response.send_redirect( url_for( trans.app.config.biostar_url, data=data, digest=digest, name=trans.app.config.biostar_key_name, action=biostar_action ) ) + + @web.expose + def biostar_question_redirect( self, trans, payload={} ): + """ + Generate a redirect to a Biostar site using external authentication to + pass Galaxy user information and information about a specific tool. + """ + return self.biostar_redirect( trans, payload=payload, biostar_action='new' ) + + @web.expose + def biostar_tool_question_redirect( self, trans, tool_id=None ): + """ + Generate a redirect to a Biostar site using external authentication to + pass Galaxy user information and information about a specific tool. + """ + # tool_id is required + if tool_id is None: + return error( "No tool_id provided" ) + # Load the tool + tool_version_select_field, tools, tool = \ + self.app.toolbox.get_tool_components( tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=True ) + # No matching tool, unlikely + if not tool: + return error( "No tool found matching '%s'" % tool_id ) + # Tool specific information for payload + payload = { 'title': "Question about Galaxy tool '%s'" % tool.name, 'tool_name': tool.name, 'tool_version': tool.version, 'tool_id': tool.id } + # Pass on to regular question method + return self.biostar_question_redirect( trans, payload ) \ No newline at end of file diff -r a7475ad6ecfc0f1fcdab3cfacce586a107aa8057 -r a8caad109542661a7222c504a529ab5afbe303fb lib/galaxy/webapps/galaxy/controllers/root.py --- a/lib/galaxy/webapps/galaxy/controllers/root.py +++ b/lib/galaxy/webapps/galaxy/controllers/root.py @@ -26,28 +26,26 @@ params=kwd ) ## ---- Tool related ----------------------------------------------------- - + @web.expose def tool_menu( self, trans ): if trans.app.config.require_login and not trans.user: - return trans.fill_template( '/no_access.mako', message = 'Please log in to access Galaxy tools.' ) - else: - ## Get most recently used tools. - toolbox = self.get_toolbox() - recent_tools = [] - if trans.user: - for row in trans.sa_session.query( self.app.model.Job.tool_id ). \ - filter( self.app.model.Job.user==trans.user ). \ - order_by( self.app.model.Job.create_time.desc() ): - tool_id = row[0] - a_tool = toolbox.get_tool( tool_id ) - if a_tool and not a_tool.hidden and a_tool not in recent_tools: - recent_tools.append( a_tool ) - ## TODO: make number of recently used tools a user preference. - if len ( recent_tools ) == 5: - break - - return trans.fill_template('/root/tool_menu.mako', toolbox=toolbox, recent_tools=recent_tools ) + return trans.fill_template( '/no_access.mako', message='Please log in to access Galaxy tools.' ) + toolbox = self.get_toolbox() + ## Get most recently used tools. + # recent_tools = [] + # if trans.user: + # for row in trans.sa_session.query( self.app.model.Job.tool_id ) \ + # .filter( self.app.model.Job.user == trans.user ) \ + # .order_by( self.app.model.Job.create_time.desc() ): + # tool_id = row[0] + # a_tool = toolbox.get_tool( tool_id ) + # if a_tool and not a_tool.hidden and a_tool not in recent_tools: + # recent_tools.append( a_tool ) + # ## TODO: make number of recently used tools a user preference. + # if len( recent_tools ) == 5: + # break + return trans.fill_template( '/root/tool_menu.mako', toolbox=toolbox ) @web.json def tool_search( self, trans, **kwd ): @@ -215,7 +213,7 @@ "html": unicode( trans.fill_template( "root/history_item.mako", data=data, hid=data.hid ), 'utf-8' ), "force_history_refresh": force_history_refresh } - + return rval @web.json @@ -231,7 +229,7 @@ def __user_get_usage( self, trans ): usage = trans.app.quota_agent.get_usage( trans ) - percent = trans.app.quota_agent.get_percent( trans=trans, usage=usage ) + percent = trans.app.quota_agent.get_percent( trans=trans, usage=usage ) rval = {} if percent is None: rval['usage'] = util.nice_size( usage ) @@ -239,20 +237,19 @@ rval['percent'] = percent return rval - ## ---- Dataset display / editing ---------------------------------------- @web.expose def display( self, trans, id=None, hid=None, tofile=None, toext=".txt", **kwd ): """ - Returns data directly into the browser. + Returns data directly into the browser. Sets the mime-type according to the extension """ if hid is not None: try: hid = int( hid ) except: - return "hid '%s' is invalid" %str( hid ) + return "hid '%s' is invalid" % str( hid ) history = trans.get_history() for dataset in history.datasets: if dataset.hid == hid: @@ -264,7 +261,7 @@ try: data = self.app.model.HistoryDatasetAssociation.get( id ) except: - return "Dataset id '%s' is invalid" %str( id ) + return "Dataset id '%s' is invalid" % str( id ) if data: current_user_roles = trans.get_current_user_roles() if trans.app.security_agent.can_access_dataset( current_user_roles, data.dataset ): @@ -281,7 +278,7 @@ trans.log_event( "Display dataset id: %s" % str(id) ) try: return open( data.file_name ) - except: + except: return "This dataset contains no content" else: return "You are not allowed to access this dataset" @@ -322,7 +319,7 @@ return data.as_display_type( display_app, **kwd ) elif authz_method == 'display_at' and trans.app.host_security_agent.allow_action( trans.request.remote_addr, data.permitted_actions.DATASET_ACCESS, - dataset = data ): + dataset=data ): trans.response.set_content_type( data.get_mime() ) return data.as_display_type( display_app, **kwd ) else: @@ -349,12 +346,14 @@ return trans.fill_template( "/history/options.mako", user=trans.get_user(), history=trans.get_history( create=True ) ) + @web.expose def history_delete( self, trans, id ): """ Backward compatibility with check_galaxy script. """ return trans.webapp.controllers['history'].list( trans, id, operation='delete' ) + @web.expose def clear_history( self, trans ): """Clears the history for a user""" @@ -365,6 +364,7 @@ trans.sa_session.flush() trans.log_event( "History id %s cleared" % (str(history.id)) ) trans.response.send_redirect( url_for("/index" ) ) + @web.expose def history_import( self, trans, id=None, confirm=False, **kwd ): msg = "" @@ -379,7 +379,7 @@ if import_history.user_id == user.id: return trans.show_error_message( "You cannot import your own history.") new_history = import_history.copy( target_user=trans.user ) - new_history.name = "imported: "+new_history.name + new_history.name = "imported: " + new_history.name new_history.user_id = user.id galaxy_session = trans.get_galaxy_session() try: @@ -399,7 +399,7 @@ to begin.""" % ( new_history.name, web.url_for( '/' ) ) ) elif not user_history.datasets or confirm: new_history = import_history.copy() - new_history.name = "imported: "+new_history.name + new_history.name = "imported: " + new_history.name new_history.user_id = None galaxy_session = trans.get_galaxy_session() try: @@ -420,22 +420,24 @@ Warning! If you import this history, you will lose your current history. Click <a href="%s">here</a> to confirm. """ % web.url_for( controller='root', action='history_import', id=id, confirm=True ) ) + @web.expose def history_new( self, trans, name=None ): trans.new_history( name=name ) trans.log_event( "Created new History, id: %s." % str(trans.history.id) ) - return trans.show_message( "New history created", refresh_frames = ['history'] ) + return trans.show_message( "New history created", refresh_frames=['history'] ) + @web.expose - def history_add_to( self, trans, history_id=None, file_data=None, name="Data Added to History",info=None,ext="txt",dbkey="?",copy_access_from=None,**kwd ): + def history_add_to( self, trans, history_id=None, file_data=None, name="Data Added to History", info=None, ext="txt", dbkey="?", copy_access_from=None, **kwd ): """Adds a POSTed file to a History""" try: history = trans.sa_session.query( trans.app.model.History ).get( history_id ) - data = trans.app.model.HistoryDatasetAssociation( name = name, - info = info, - extension = ext, - dbkey = dbkey, - create_dataset = True, - sa_session = trans.sa_session ) + data = trans.app.model.HistoryDatasetAssociation( name=name, + info=info, + extension=ext, + dbkey=dbkey, + create_dataset=True, + sa_session=trans.sa_session ) if copy_access_from: copy_access_from = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( copy_access_from ) trans.app.security_agent.copy_dataset_permissions( copy_access_from.dataset, data.dataset ) @@ -457,11 +459,12 @@ trans.sa_session.flush() data.set_peek() trans.sa_session.flush() - trans.log_event("Added dataset %d to history %d" %(data.id, trans.history.id)) - return trans.show_ok_message("Dataset "+str(data.hid)+" added to history "+str(history_id)+".") + trans.log_event("Added dataset %d to history %d" % (data.id, trans.history.id)) + return trans.show_ok_message( "Dataset " + str(data.hid) + " added to history " + str(history_id) + "." ) except Exception, e: trans.log_event( "Failed to add dataset to history: %s" % ( e ) ) return trans.show_error_message("Adding File to History has Failed") + @web.expose def history_set_default_permissions( self, trans, id=None, **kwd ): """Sets the permissions on a history""" @@ -494,6 +497,7 @@ else: #user not logged in, history group must be only public return trans.show_error_message( "You must be logged in to change a history's default permissions." ) + @web.expose def dataset_make_primary( self, trans, id=None): """Copies a dataset and makes primary""" @@ -506,7 +510,7 @@ history.add_dataset(new_data) trans.sa_session.add( new_data ) trans.sa_session.flush() - return trans.show_message( "<p>Secondary dataset has been made primary.</p>", refresh_frames=['history'] ) + return trans.show_message( "<p>Secondary dataset has been made primary.</p>", refresh_frames=['history'] ) except: return trans.show_error_message( "<p>Failed to make secondary dataset primary.</p>" ) diff -r a7475ad6ecfc0f1fcdab3cfacce586a107aa8057 -r a8caad109542661a7222c504a529ab5afbe303fb lib/galaxy/webapps/galaxy/controllers/tool_runner.py --- a/lib/galaxy/webapps/galaxy/controllers/tool_runner.py +++ b/lib/galaxy/webapps/galaxy/controllers/tool_runner.py @@ -12,6 +12,7 @@ from galaxy.tools.parameters.basic import DataToolParameter, UnvalidatedValue from galaxy.util.bunch import Bunch from galaxy.util.hash_util import is_hashable +from galaxy.util import biostar from galaxy.web import error, url_for from galaxy.web.base.controller import BaseUIController from galaxy.web.form_builder import SelectField @@ -42,28 +43,10 @@ def default(self, trans, tool_id=None, **kwd): """Catches the tool id and redirects as needed""" return self.index(trans, tool_id=tool_id, **kwd) + def __get_tool_components( self, tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=False ): - """ - Retrieve all loaded versions of a tool from the toolbox and return a select list enabling selection of a different version, the list of the tool's - loaded versions, and the specified tool. - """ - toolbox = self.get_toolbox() - tool_version_select_field = None - tools = [] - tool = None - # Backwards compatibility for datasource tools that have default tool_id configured, but which are now using only GALAXY_URL. - tool_ids = galaxy.util.listify( tool_id ) - for tool_id in tool_ids: - if get_loaded_tools_by_lineage: - tools = toolbox.get_loaded_tools_by_lineage( tool_id ) - else: - tools = toolbox.get_tool( tool_id, tool_version=tool_version, get_all_versions=True ) - if tools: - tool = toolbox.get_tool( tool_id, tool_version=tool_version, get_all_versions=False ) - if len( tools ) > 1: - tool_version_select_field = self.build_tool_version_select_field( tools, tool.id, set_selected ) - break - return tool_version_select_field, tools, tool + return self.get_toolbox().get_tool_components( tool_id, tool_version, get_loaded_tools_by_lineage, set_selected ) + @web.expose def index(self, trans, tool_id=None, from_noframe=None, **kwd): # No tool id passed, redirect to main page diff -r a7475ad6ecfc0f1fcdab3cfacce586a107aa8057 -r a8caad109542661a7222c504a529ab5afbe303fb templates/webapps/galaxy/base_panels.mako --- a/templates/webapps/galaxy/base_panels.mako +++ b/templates/webapps/galaxy/base_panels.mako @@ -120,9 +120,9 @@ ## Help tab. <% menu_options = [] - qa_url = app.config.get( "qa_url", None ) - if qa_url: - menu_options = [ [_('Galaxy Q&A'), qa_url, "_blank" ] ] + if app.config.biostar_url: + menu_options = [ [_('Galaxy Q&A Site'), h.url_for( controller='biostar', action='biostar_redirect', biostar_action='show/tag/galaxy' ), "_blank" ], + [_('Ask a question'), h.url_for( controller='biostar', action='biostar_question_redirect' ), "_blank" ] ] menu_options.extend( [ [_('Support'), app.config.get( "support_url", "http://wiki.g2.bx.psu.edu/Support" ), "_blank" ], [_('Tool shed wiki'), app.config.get( "wiki_url", "http://wiki.g2.bx.psu.edu/Tool%20Shed" ), "_blank" ], diff -r a7475ad6ecfc0f1fcdab3cfacce586a107aa8057 -r a8caad109542661a7222c504a529ab5afbe303fb templates/webapps/galaxy/tool_form.mako --- a/templates/webapps/galaxy/tool_form.mako +++ b/templates/webapps/galaxy/tool_form.mako @@ -308,10 +308,10 @@ %else: <div class="toolFormTitle">${tool.name} ${tool_version_select_field.get_html()} %endif - %if trans.app.config.biostar: + + %if trans.app.config.biostar_url: <!-- BioStar links --> - <a href="${trans.app.config.biostar}/new/post/tagged/${low_tool_name}" target="galaxy_main" class="icon-button general-question tooltip close-side-panels" data-original-title="Ask a tool related question"></a> - <a href="${trans.app.config.biostar}/show/tag/${low_tool_name}/" target="galaxy_main" class="icon-button tag-question tooltip close-side-panels" data-original-title="See tool related posts" ></a> + <span class="pull-right"><a href="${h.url_for( controller='biostar', action='biostar_tool_question_redirect', tool_id=tool.id )}" target="galaxy_main" class="fa-icon-question-sign tooltip" data-original-title="Ask a question about this tool"></a></span><!-- End of BioStar links --> %endif </div> 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)
-
commits-noreply@bitbucket.org