1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/ec715604b476/ Changeset: ec715604b476 User: dan Date: 2014-03-24 21:19:35 Summary: Refactor tool error / bug reporting. Allow reporting errors via biostar in addition to existing email functionality. Affected #: 5 files diff -r 6e9354d1fbdfd92ff316c52302945c02bbf13a0c -r ec715604b476c47703b90385062a6ec482cfd302 lib/galaxy/tools/errors.py --- /dev/null +++ b/lib/galaxy/tools/errors.py @@ -0,0 +1,121 @@ +""" +Functionality for dealing with tool errors. +""" +import string +from galaxy import model, util, web + +error_report_template = """ +GALAXY TOOL ERROR REPORT +------------------------ + +This error report was sent from the Galaxy instance hosted on the server +"${host}" +----------------------------------------------------------------------------- +This is in reference to dataset id ${dataset_id} from history id ${history_id} +----------------------------------------------------------------------------- +You should be able to view the history containing the related history item + +${hid}: ${history_item_name} + +by logging in as a Galaxy admin user to the Galaxy instance referenced above +and pointing your browser to the following link. + +${history_view_link} +----------------------------------------------------------------------------- +The user '${email}' provided the following information: + +${message} +----------------------------------------------------------------------------- +job id: ${job_id} +tool id: ${job_tool_id} +job pid or drm id: ${job_runner_external_id} +----------------------------------------------------------------------------- +job command line: +${job_command_line} +----------------------------------------------------------------------------- +job stderr: +${job_stderr} +----------------------------------------------------------------------------- +job stdout: +${job_stdout} +----------------------------------------------------------------------------- +job info: +${job_info} +----------------------------------------------------------------------------- +job traceback: +${job_traceback} +----------------------------------------------------------------------------- +(This is an automated message). +""" + +class ErrorReporter( object ): + def __init__( self, hda, app ): + # Get the dataset + sa_session = app.model.context + if not isinstance( hda, model.HistoryDatasetAssociation ): + try: + hda = sa_session.query( model.HistoryDatasetAssociation ).get( hda ) + except: + hda = sa_session.query( model.HistoryDatasetAssociation ).get( app.security.decode_id( hda ) ) + assert isinstance( hda, model.HistoryDatasetAssociation ), ValueError( "Bad value provided for HDA (%s)." % ( hda ) ) + self.hda = hda + # Get the associated job + self.job = hda.creating_job + self.app = app + self.tool_id = self.job.tool_id + self.report = None + def _can_access_dataset( self, user ): + if user: + roles = user.all_roles() + else: + roles = [] + return self.app.security_agent.can_access_dataset( roles, self.hda.dataset ) + def create_report( self, email='', message='', **kwd ): + hda = self.hda + job = self.job + host = web.url_for( '/', qualified=True ) + history_view_link = web.url_for( controller="history", action="view", id=self.app.security.encode_id( hda.history_id ), qualified=True ) + # Build the email message + self.report = string.Template( error_report_template ) \ + .safe_substitute( host=host, + dataset_id=hda.dataset_id, + history_id=hda.history_id, + hid=hda.hid, + history_item_name=hda.get_display_name(), + history_view_link=history_view_link, + job_id=job.id, + job_tool_id=job.tool_id, + job_runner_external_id=job.job_runner_external_id, + job_command_line=job.command_line, + job_stderr=util.unicodify( job.stderr ), + job_stdout=util.unicodify( job.stdout ), + job_info=util.unicodify( job.info ), + job_traceback=util.unicodify( job.traceback ), + email=email, + message=util.unicodify( message ) ) + def _send_report( self, user, email=None, message=None, **kwd ): + return self.report + def send_report( self, user, email=None, message=None, **kwd ): + if self.report is None: + self.create_report( email=email, message=message, **kwd ) + return self._send_report( user, email=email, message=message, **kwd ) + +class EmailErrorReporter( ErrorReporter ): + def _send_report( self, user, email=None, message=None, **kwd ): + smtp_server = self.app.config.smtp_server + assert smtp_server, ValueError( "Mail is not configured for this galaxy instance" ) + to_address = self.app.config.error_email_to + assert to_address, ValueError( "Error reporting has been disabled for this galaxy instance" ) + + frm = to_address + # Check email a bit + email = email or '' + email = email.strip() + parts = email.split() + if len( parts ) == 1 and len( email ) > 0 and self._can_access_dataset( user ): + to = to_address + ", " + email + else: + to = to_address + subject = "Galaxy tool error report from %s" % email + # Send it + return util.send_mail( frm, to, subject, self.report, self.app.config ) diff -r 6e9354d1fbdfd92ff316c52302945c02bbf13a0c -r ec715604b476c47703b90385062a6ec482cfd302 lib/galaxy/util/biostar.py --- a/lib/galaxy/util/biostar.py +++ b/lib/galaxy/util/biostar.py @@ -7,6 +7,7 @@ import re from unicodedata import normalize from galaxy.web.base.controller import url_for +from galaxy.tools.errors import ErrorReporter _punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+') @@ -27,6 +28,8 @@ # Slugifying from Armin Ronacher (http://flask.pocoo.org/snippets/5/) def slugify(text, delim=u'-'): """Generates an slightly worse ASCII-only slug.""" + if not isinstance( text, unicode ): + text = unicode( text ) result = [] for word in _punct_re.split(text.lower()): word = normalize('NFKD', word).encode('ascii', 'ignore') @@ -63,7 +66,7 @@ Generate a reasonable biostar tag for a tool. """ #Biostar can now handle tags with spaces, do we want to generate tags differently now? - return slugify( unicode( tool.name ), delim='-' ) + return slugify( tool.name, delim='-' ) def populate_tag_payload( payload=None, tool=None ): if payload is None: @@ -119,3 +122,18 @@ delete_cookie( trans, trans.app.config.biostar_key_name ) return get_biostar_url( trans.app, biostar_action='log_out' ) return None + +class BiostarErrorReporter( ErrorReporter ): + def _send_report( self, user, email=None, message=None, **kwd ): + assert biostar_enabled( self.app ), ValueError( "Biostar is not configured for this galaxy instance" ) + assert self._can_access_dataset( user ), Exception( "You are not allowed to access this dataset." ) + tool_version_select_field, tools, tool = \ + self.app.toolbox.get_tool_components( self.tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=True ) + payload = { 'title': 'Bug report on "%s" tool' % ( tool.name ), 'content': self.report.replace( '\n', '<br />' ), 'tag_val':slugify( 'bug report' ) } + #Get footer for email from here + payload2 = populate_tool_payload( tool=tool ) + if 'content' in payload2: + payload[ 'content' ] = "%s<br />%s" % ( payload['content'], payload2['content'] ) + if 'tag_val' in payload2: + payload[ 'tag_val' ] = ','.join( [ payload2[ 'tag_val' ], payload[ 'tag_val' ] ] ) + return payload diff -r 6e9354d1fbdfd92ff316c52302945c02bbf13a0c -r ec715604b476c47703b90385062a6ec482cfd302 lib/galaxy/webapps/galaxy/controllers/biostar.py --- a/lib/galaxy/webapps/galaxy/controllers/biostar.py +++ b/lib/galaxy/webapps/galaxy/controllers/biostar.py @@ -75,6 +75,19 @@ return self.biostar_question_redirect( trans, payload ) @web.expose + def biostar_tool_bug_report( self, trans, hda=None, email=None, message=None ): + """ + Generate a redirect to a Biostar site using external authentication to + pass Galaxy user information and information about a specific tool error. + """ + try: + error_reporter = biostar.BiostarErrorReporter( hda, trans.app ) + payload = error_reporter.send_report( trans.user, email=email, message=message ) + except Exception, e: + return error( str( e ) ) + return self.biostar_question_redirect( trans, payload=payload ) + + @web.expose def biostar_logout( self, trans ): """ Log out of biostar diff -r 6e9354d1fbdfd92ff316c52302945c02bbf13a0c -r ec715604b476c47703b90385062a6ec482cfd302 lib/galaxy/webapps/galaxy/controllers/dataset.py --- a/lib/galaxy/webapps/galaxy/controllers/dataset.py +++ b/lib/galaxy/webapps/galaxy/controllers/dataset.py @@ -1,6 +1,5 @@ import logging import os -import string import tempfile import urllib import zipfile @@ -14,6 +13,7 @@ from galaxy.web.base.controller import BaseUIController, ERROR, SUCCESS, url_for, UsesHistoryDatasetAssociationMixin, UsesHistoryMixin, UsesExtendedMetadataMixin from galaxy.web.framework.helpers import grids, iff, time_ago from galaxy.web.framework.helpers import to_unicode +from galaxy.tools.errors import EmailErrorReporter eggs.require( "Paste" ) import paste.httpexceptions @@ -27,51 +27,6 @@ except ImportError: pass - -error_report_template = """ -GALAXY TOOL ERROR REPORT ------------------------- - -This error report was sent from the Galaxy instance hosted on the server -"${host}" ------------------------------------------------------------------------------ -This is in reference to dataset id ${dataset_id} from history id ${history_id} ------------------------------------------------------------------------------ -You should be able to view the history containing the related history item - -${hid}: ${history_item_name} - -by logging in as a Galaxy admin user to the Galaxy instance referenced above -and pointing your browser to the following link. - -${history_view_link} ------------------------------------------------------------------------------ -The user '${email}' provided the following information: - -${message} ------------------------------------------------------------------------------ -job id: ${job_id} -tool id: ${job_tool_id} -job pid or drm id: ${job_runner_external_id} ------------------------------------------------------------------------------ -job command line: -${job_command_line} ------------------------------------------------------------------------------ -job stderr: -${job_stderr} ------------------------------------------------------------------------------ -job stdout: -${job_stdout} ------------------------------------------------------------------------------ -job info: -${job_info} ------------------------------------------------------------------------------ -job traceback: -${job_traceback} ------------------------------------------------------------------------------ -(This is an automated message). -""" - class HistoryDatasetAssociationListGrid( grids.Grid ): # Custom columns for grid. class HistoryColumn( grids.GridColumn ): @@ -197,50 +152,15 @@ except: exit_code = "Invalid dataset ID or you are not allowed to access this dataset" return exit_code + @web.expose def report_error( self, trans, id, email='', message="", **kwd ): - smtp_server = trans.app.config.smtp_server - if smtp_server is None: - return trans.show_error_message( "Mail is not configured for this galaxy instance" ) - to_address = trans.app.config.error_email_to - if to_address is None: - return trans.show_error_message( "Error reporting has been disabled for this galaxy instance" ) - # Get the dataset and associated job - hda = trans.sa_session.query( model.HistoryDatasetAssociation ).get( id ) - job = hda.creating_job - # Get the name of the server hosting the Galaxy instance from which this report originated - host = trans.request.host - history_view_link = "%s/history/view?id=%s" % ( str( host ), trans.security.encode_id( hda.history_id ) ) - # Build the email message - body = string.Template( error_report_template ) \ - .safe_substitute( host=host, - dataset_id=hda.dataset_id, - history_id=hda.history_id, - hid=hda.hid, - history_item_name=hda.get_display_name(), - history_view_link=history_view_link, - job_id=job.id, - job_tool_id=job.tool_id, - job_runner_external_id=job.job_runner_external_id, - job_command_line=job.command_line, - job_stderr=util.unicodify( job.stderr ), - job_stdout=util.unicodify( job.stdout ), - job_info=util.unicodify( job.info ), - job_traceback=util.unicodify( job.traceback ), - email=email, - message=util.unicodify( message ) ) - frm = to_address - # Check email a bit - email = email.strip() - parts = email.split() - if len( parts ) == 1 and len( email ) > 0 and self._can_access_dataset( trans, hda ): - to = to_address + ", " + email - else: - to = to_address - subject = "Galaxy tool error report from %s" % email - # Send it + biostar_report = 'biostar' in str( kwd.get( 'submit_error_report') ).lower() + if biostar_report: + return trans.response.send_redirect( url_for( controller='biostar', action='biostar_tool_bug_report', hda=id, email=email, message=message ) ) try: - util.send_mail( frm, to, subject, body, trans.app.config ) + error_reporter = EmailErrorReporter( id, trans.app ) + error_reporter.send_report( user=trans.user, email=email, message=message ) return trans.show_ok_message( "Your error report has been sent" ) except Exception, e: return trans.show_error_message( "An error occurred sending the report by email: %s" % str( e ) ) diff -r 6e9354d1fbdfd92ff316c52302945c02bbf13a0c -r ec715604b476c47703b90385062a6ec482cfd302 templates/webapps/galaxy/dataset/errors.mako --- a/templates/webapps/galaxy/dataset/errors.mako +++ b/templates/webapps/galaxy/dataset/errors.mako @@ -71,7 +71,10 @@ <textarea name="message" rows="10" cols="40"></textarea></div><div class="form-row"> - <input type="submit" name="submit_error_report" value="Report"/> + <input type="submit" name="submit_error_report" value="Report" onclick="form.setAttribute('target', '_self');"/> + %if trans.app.config.biostar_url: + <input type="submit" name="submit_error_report" value="Post on Biostar" onclick="form.setAttribute('target', '_blank');"/> + %endif </div></form></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.