diff --git a/lib/galaxy/jobs/runners/drmaa.py b/lib/galaxy/jobs/runners/drmaa.py index 425108b4e85..70878a76849 100644 --- a/lib/galaxy/jobs/runners/drmaa.py +++ b/lib/galaxy/jobs/runners/drmaa.py @@ -212,9 +212,16 @@ class DRMAAJobRunner( AsynchronousJobRunner ): try: assert external_job_id not in ( None, 'None' ), '(%s/%s) Invalid job id' % ( galaxy_id_tag, external_job_id ) state = self.ds.jobStatus( external_job_id ) - # TODO: probably need to keep track of InvalidJobException count and remove after it exceeds some configurable - except ( drmaa.DrmCommunicationException, drmaa.InternalException, drmaa.InvalidJobException ), e: - log.warning( "(%s/%s) job check resulted in %s: %s", galaxy_id_tag, external_job_id, e.__class__.__name__, e ) + # InternalException was reported to be necessary on some DRMs, but + # this could cause failures to be detected as completion! Please + # report if you experience problems with this. + except ( drmaa.InvalidJobException, drmaa.InternalException ), e: + # we should only get here if an orphaned job was put into the queue at app startup + log.info( "(%s/%s) job left DRM queue with following message: %s" % ( galaxy_id_tag, external_job_id, e ) ) + self.work_queue.put( ( self.finish_job, ajs ) ) + continue + except drmaa.DrmCommunicationException, e: + log.warning( "(%s/%s) unable to communicate with DRM: %s" % ( galaxy_id_tag, external_job_id, e )) new_watched.append( ajs ) continue except Exception, e: diff --git a/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py b/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py index eb22124631e..d3dc4b6d737 100755 --- a/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py +++ b/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py @@ -9,7 +9,6 @@ import urllib2 import zipfile import tool_shed.util.shed_util_common as suc from galaxy.datatypes import checkers -from urllib2 import HTTPError log = logging.getLogger( __name__ ) diff --git a/lib/tool_shed/util/shed_util_common.py b/lib/tool_shed/util/shed_util_common.py index fde3d7cbdf4..f084643df00 100644 --- a/lib/tool_shed/util/shed_util_common.py +++ b/lib/tool_shed/util/shed_util_common.py @@ -21,6 +21,7 @@ from tool_shed.util import common_util from tool_shed.util import encoding_util from tool_shed.util import xml_util from xml.etree import ElementTree as XmlET +from urllib2 import HTTPError from galaxy import eggs eggs.require( 'mercurial' ) @@ -1232,10 +1233,25 @@ def get_tool_shed_status_for_installed_repository( app, repository ): try: encoded_tool_shed_status_dict = common_util.tool_shed_get( app, tool_shed_url, url ) tool_shed_status_dict = encoding_util.tool_shed_decode( encoded_tool_shed_status_dict ) + return tool_shed_status_dict + except HTTPError, e: + # This should handle backward compatility to the Galaxy 12/20/12 release. We used to only handle updates for an installed revision + # using a boolean value. + log.debug( "Error attempting to get tool shed status for installed repository %s: %s\nAttempting older 'check_for_updates' method.\n" % \ + ( str( repository.name ), str( e ) ) ) + url = url_join( tool_shed_url, + 'repository/check_for_updates?name=%s&owner=%s&changeset_revision=%s&from_update_manager=True' % \ + ( repository.name, repository.owner, repository.changeset_revision ) ) + try: + # The value of text will be 'true' or 'false', depending upon whether there is an update available for the installed revision. + text = common_util.tool_shed_get( app, tool_shed_url, url ) + return dict( revision_update=text ) + except Exception, e: + # The required tool shed may be unavailable, so default the revision_update value to 'false'. + return dict( revision_update='false' ) except Exception, e: log.exception( "Error attempting to get tool shed status for installed repository %s: %s" % ( str( repository.name ), str( e ) ) ) return {} - return tool_shed_status_dict def get_updated_changeset_revisions( trans, name, owner, changeset_revision ): """ diff --git a/static/scripts/galaxy.upload.js b/static/scripts/galaxy.upload.js index d0e13e7d059..340dac9dffe 100644 --- a/static/scripts/galaxy.upload.js +++ b/static/scripts/galaxy.upload.js @@ -57,6 +57,10 @@ var GalaxyUpload = Backbone.View.extend( return; } + // check if logged in + if (!Galaxy.currUser.get('id')) + return; + // add activate icon var self = this; this.button_show = new mod_master.GalaxyMasterIcon ( diff --git a/static/scripts/utils/galaxy.uploadbox.js b/static/scripts/utils/galaxy.uploadbox.js index 002c7c4122a..cc75da213cb 100755 --- a/static/scripts/utils/galaxy.uploadbox.js +++ b/static/scripts/utils/galaxy.uploadbox.js @@ -24,7 +24,8 @@ error_filesize : "File exceeds 2GB. Please use an FTP client.", error_default : "Please make sure the file is available.", error_server : "The server is unavailable.", - error_toomany : "You can only queue <20 files per upload session." + error_toomany : "You can only queue <20 files per upload session.", + error_login : "Uploads require you to log in." } // options @@ -158,6 +159,9 @@ // process an upload, recursive function process() { + // log + //console.log("Processing queue..." + queue_length + " (" + queue_running + " / " + queue_pause + ")"); + // validate if (queue_length == 0 || queue_pause) { @@ -167,6 +171,9 @@ return; } else queue_running = true; + + // log + //console.log("Looking for file..."); // get an identifier from the queue var index = -1; @@ -181,52 +188,23 @@ // remove from queue remove(index) + + // log + //console.log("Initializing ('" + file.name + "')."); - // start - var data = opts.initialize(index, file); + // identify maximum file size + var filesize = file.size; + var maxfilesize = 1048576 * opts.maxfilesize; - // add file to queue - try + // check file size + if (filesize < maxfilesize) { - // load file read - var reader = new FileReader(); - - // identify maximum file size - var filesize = file.size; - var maxfilesize = 1048576 * opts.maxfilesize; - - // set index - reader.index = index; - if (filesize < maxfilesize) - { - // link load - reader.onload = function(e) - { - send(index, file, data) - }; - - // link error - reader.onerror = function(e) - { - error(index, file, opts.error_default); - }; - - // link abort - reader.onabort = function(e) - { - error(index, file, opts.error_default); - }; - - // read data - reader.readAsDataURL(file); - } else { - // skip file - error(index, file, opts.error_filesize); - } - } catch (err) - { - // parse error - error(index, file, err); + // send data + var data = opts.initialize(index, file); + send(index, file, data) + } else { + // skip file + error(index, file, opts.error_filesize); } } @@ -241,10 +219,17 @@ // prepare request xhr = new XMLHttpRequest(); - + xhr.open('POST', opts.url, true); + xhr.setRequestHeader('Accept', 'application/json'); + xhr.setRequestHeader('Cache-Control', 'no-cache'); + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + // captures state changes xhr.onreadystatechange = function() { + // status change + //console.log("Status changed: " + xhr.readyState + "."); + // check for request completed, server connection closed if (xhr.readyState != xhr.DONE) return; @@ -264,14 +249,14 @@ // pass any error to the error option if (xhr.status < 200 || xhr.status > 299) { - // format error + // format status var text = xhr.statusText; - if (!xhr.statusText) { - if (xhr.status == 0) - text = opts.error_server; - else - text = opts.error_default; - } + if (xhr.status == 403) + text = opts.error_login; + else if (xhr.status == 0) + text = opts.error_server; + else if (!text) + text = opts.error_default; // request error error(index, file, text + " (" + xhr.status + ")"); @@ -284,13 +269,12 @@ xhr.upload.index = index; xhr.upload.file = file; xhr.upload.addEventListener('progress', progress, false); - - // open request - xhr.open('POST', opts.url, true); - xhr.setRequestHeader('Accept', 'application/json'); - xhr.setRequestHeader('Cache-Control', 'no-cache'); - xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + + // send request xhr.send(formData); + + // sending file + //console.log("Sending file ('" + file.name + "')."); } // success @@ -360,7 +344,7 @@ // verify browser compatibility function compatible() { - return window.File && window.FileReader && window.FormData && window.XMLHttpRequest && window.FileList; + return window.File && window.FormData && window.XMLHttpRequest && window.FileList; } // export functions diff --git a/static/style/src/less/base.less b/static/style/src/less/base.less index 3ca807a8925..33b0ce8c5fd 100644 --- a/static/style/src/less/base.less +++ b/static/style/src/less/base.less @@ -1851,3 +1851,9 @@ div.toolTitleNoSection .icon-button.chevron-expand { .sprite(@chevron-expand-bw); } + +// honeypot for registration form + +#for_bears { + display: none; +} diff --git a/templates/user/register.mako b/templates/user/register.mako index 95580c588e9..45b9e2aa6c9 100644 --- a/templates/user/register.mako +++ b/templates/user/register.mako @@ -37,25 +37,82 @@ subscribe_check_box = CheckboxField( 'subscribe' ) %> +
Create account
- +
- +
- +
- + %if t.webapp.name == 'galaxy':
Your public name is an identifier that will be used to generate addresses for information @@ -103,8 +160,12 @@ %endif %endif +
+ If you see this, please leave following field blank. + +
- +
%if registration_warning_message: diff --git a/test/base/twilltestcase.py b/test/base/twilltestcase.py index b78a11e54cd..0e3a4ef9d0a 100644 --- a/test/base/twilltestcase.py +++ b/test/base/twilltestcase.py @@ -952,11 +952,11 @@ class TwillTestCase( unittest.TestCase ): # HACK: don't use panels because late_javascripts() messes up the twill browser and it # can't find form fields (and hence user can't be logged in). self.visit_url( "%s/user/create?cntrller=%s&use_panels=False" % ( self.url, cntrller ) ) - tc.fv( '1', 'email', email ) - tc.fv( '1', 'redirect', redirect ) - tc.fv( '1', 'password', password ) - tc.fv( '1', 'confirm', password ) - tc.fv( '1', 'username', username ) + tc.fv( 'registration', 'email', email ) + tc.fv( 'registration', 'redirect', redirect ) + tc.fv( 'registration', 'password', password ) + tc.fv( 'registration', 'confirm', password ) + tc.fv( 'registration', 'username', username ) tc.submit( 'create_user_button' ) previously_created = False username_taken = False diff --git a/test/install_and_test_tool_shed_repositories/base/test_db_util.py b/test/install_and_test_tool_shed_repositories/base/test_db_util.py index 0cd53cafa44..7afade375b7 100644 --- a/test/install_and_test_tool_shed_repositories/base/test_db_util.py +++ b/test/install_and_test_tool_shed_repositories/base/test_db_util.py @@ -8,39 +8,59 @@ log = logging.getLogger(__name__) def delete_obj( obj ): sa_session.delete( obj ) sa_session.flush() + def delete_user_roles( user ): for ura in user.roles: sa_session.delete( ura ) sa_session.flush() + def flush( obj ): sa_session.add( obj ) sa_session.flush() + def get_repository( repository_id ): return sa_session.query( model.ToolShedRepository ) \ .filter( model.ToolShedRepository.table.c.id == repository_id ) \ .first() + def get_installed_repository_by_name_owner_changeset_revision( name, owner, changeset_revision ): return sa_session.query( model.ToolShedRepository ) \ .filter( and_( model.ToolShedRepository.table.c.name == name, model.ToolShedRepository.table.c.owner == owner, model.ToolShedRepository.table.c.installed_changeset_revision == changeset_revision ) ) \ .one() + def get_private_role( user ): for role in user.all_roles(): if role.name == user.email and role.description == 'Private Role for %s' % user.email: return role raise AssertionError( "Private role not found for user '%s'" % user.email ) + +def get_tool_dependencies_for_installed_repository( repository_id, status=None ): + if status is not None: + return sa_session.query( model.ToolDependency ) \ + .filter( and_( model.ToolDependency.table.c.tool_shed_repository_id == repository_id, + model.ToolDependency.table.c.status == status ) ) \ + .all() + else: + return sa_session.query( model.ToolDependency ) \ + .filter( model.ToolDependency.table.c.tool_shed_repository_id == repository_id ) \ + .all() + def mark_obj_deleted( obj ): obj.deleted = True sa_session.add( obj ) sa_session.flush() + def refresh( obj ): sa_session.refresh( obj ) + def get_private_role( user ): for role in user.all_roles(): if role.name == user.email and role.description == 'Private Role for %s' % user.email: return role raise AssertionError( "Private role not found for user '%s'" % user.email ) + def get_user( email ): return sa_session.query( model.User ) \ .filter( model.User.table.c.email==email ) \ diff --git a/test/install_and_test_tool_shed_repositories/base/twilltestcase.py b/test/install_and_test_tool_shed_repositories/base/twilltestcase.py index 435861b0a96..7f6232956ac 100644 --- a/test/install_and_test_tool_shed_repositories/base/twilltestcase.py +++ b/test/install_and_test_tool_shed_repositories/base/twilltestcase.py @@ -149,4 +149,20 @@ class InstallTestRepository( TwillTestCase ): strings_displayed.append( 'has been deactivated' ) else: strings_displayed.append( 'has been uninstalled' ) - self.check_for_strings( strings_displayed, strings_not_displayed=[] ) \ No newline at end of file + self.check_for_strings( strings_displayed, strings_not_displayed=[] ) + # Get all tool dependencies that are in an error state and uninstall them explicitly, so that the next installation attempt + # may succeed. + error_state = model.ToolDependency.installation_status.ERROR + tool_dependencies = test_db_util.get_tool_dependencies_for_installed_repository( installed_repository.id, status=error_state ) + if len( tool_dependencies ) > 0: + encoded_tool_dependency_ids = [ self.security.encode_id( tool_dependency.id ) for tool_dependency in tool_dependencies ] + self.uninstall_tool_dependencies( self.security.encode_id( installed_repository.id ), encoded_tool_dependency_ids ) + + def uninstall_tool_dependencies( self, encoded_repository_id, encoded_tool_dependency_ids ): + tool_dependency_ids = ','.join( encoded_tool_dependency_ids ) + url = '/admin_toolshed/uninstall_tool_dependencies?repository_id=%s&inst_td_ids=%s&operation=uninstall' % \ + ( encoded_repository_id, tool_dependency_ids ) + self.visit_url( url ) + tc.fv( 'uninstall_tool_dependencies', 'tool_dependency_ids', tool_dependency_ids ) + tc.submit( 'uninstall_tool_dependencies_button' ) + \ No newline at end of file