(merge conflicts with dev)

This commit is contained in:
carlfeberhard
2016-04-15 15:23:08 -04:00
45 changed files with 368 additions and 141 deletions
+2 -2
View File
@@ -28,9 +28,9 @@ var PageLayoutView = Backbone.View.extend( BaseMVC.LoggableMixin ).extend({
// TODO: remove globals
this.log( this + '.initialize:', options );
_.extend( this, _.pick( options, this._panelIds ) );
this.options = _.defaults( _.omit( options, this._panelIds ), this.defaultOptions );
this.options = _.defaults( _.omit( options.config, this._panelIds ), this.defaultOptions );
Galaxy.modal = this.modal = new Modal.View();
this.masthead = new Masthead.View( this.options.config );
this.masthead = new Masthead.View( this.options );
this.$el.attr( 'scroll', 'no' );
this.$el.html( this._template() );
this.$el.append( this.masthead.frame.$el );
@@ -14,28 +14,40 @@ var logNamespace = 'citation';
* @name Citation
* @augments Backbone.Model
*/
var Citation = Backbone.Model.extend( baseMVC.LoggableMixin ).extend( {
var Citation = Backbone.Model.extend( baseMVC.LoggableMixin ).extend({
_logNamespace : logNamespace,
initialize: function() {
var bibtex = this.get( 'content' );
var entry = parseBibtex(bibtex).entries[0];
this.entry = entry;
var bibtex = this.attributes.content;
var parsed = BibtexParser( bibtex );
// bibtex returns successfully parsed in .entries and any parsing errors in .errors
if( parsed.errors.length ){
// the gen. form of these errors seems to be [ line, col, char, error message ]
var errors = parsed.errors.reduce( function( all, current ){ return all + '; ' + current; });
// throw new Error( 'Error parsing bibtex: ' + errors );
this.log( 'Error parsing bibtex: ' + errors );
}
this._fields = {};
var rawFields = entry.Fields;
for(var key in rawFields) {
var value = rawFields[ key ];
var lowerKey = key.toLowerCase();
this._fields[ lowerKey ] = value;
this.entry = _.first( parsed.entries );
if( this.entry ){
var rawFields = this.entry.Fields;
for( var key in rawFields ){
var value = rawFields[ key ];
var lowerKey = key.toLowerCase();
this._fields[ lowerKey ] = value;
}
}
},
entryType: function() {
return this.entry.EntryType;
return this.entry? this.entry.EntryType : undefined;
},
fields: function() {
return this._fields;
}
} );
});
//==============================================================================
/** @class Backbone collection of citations.
@@ -86,6 +86,12 @@ var HistoryViewColumn = Backbone.View.extend( baseMVC.LoggableMixin ).extend({
// assumes panel will take the longest to render
'rendered': function(){
column.trigger( 'rendered', column );
},
// when a panel's view expands turn off the click handler on the rerun button so that it uses it's href
// this allows the button to open the tool rerun form in a new tab (instead of erroring)
// TODO: hack
'view:expanded view:rendered': function( view ){
view.$( '.rerun-btn' ).off();
}
}, this );
},
@@ -320,7 +320,7 @@ define(['mvc/workflow/workflow-globals'], function( Globals ) {
// FIXME: No idea what to do about case when datatype is 'input'
for ( var other_datatype_i in cat_outputs ) {
var other_datatype = cat_outputs[other_datatype_i];
if ( other_datatype == "input" || other_datatype == "input_collection" || Globals.app.isSubType( cat_outputs[other_datatype_i], thisDatatype ) ) {
if ( other_datatype == "input" || other_datatype == "_sniff_" || other_datatype == "input_collection" || Globals.app.isSubType( cat_outputs[other_datatype_i], thisDatatype ) ) {
return true;
}
}
+4 -4
View File
@@ -874,7 +874,6 @@ table.tabletip tbody tr:hover td {
background-color: #eee;
}
table.colored {
border-top: solid @table-border-color 1px;
border-bottom: solid @table-border-color 1px;
@@ -916,16 +915,13 @@ div.debug {
.grid-header {
padding-bottom: 1em;
}
.grid-header h2 {
margin: 0;
margin-bottom: 0.5em;
}
.grid-header .title {
font-weight: bold;
}
.grid {
padding-top: 1em;
border-collapse: collapse;
@@ -1369,6 +1365,10 @@ div.permissionContainer {
}
.preserve-text-breaks {
white-space: pre-line;
}
// Icon buttons.
.icon-button {
+26 -2
View File
@@ -767,9 +767,12 @@ use_interactive = True
# Log to statsd
# Statsd is an external statistics aggregator (https://github.com/etsy/statsd)
# Enabling the following options will cause galaxy to log request timing and
# other statistics to the configured statsd instance.
# other statistics to the configured statsd instance. The statsd_prefix is
# useful if you are running multiple Galaxy instances and want to segment
# statistics between them within the same aggregator.
#statsd_host=
#statsd_port=8125
#statsd_prefix=galaxy
# -- Data Libraries
@@ -881,6 +884,13 @@ use_interactive = True
# to True to force these to lower case.
#normalize_remote_user_email = False
# If an e-mail address is specified here, it will hijack remote user mechanics
# (``use_remote_user``) and have the webapp inject a single fixed user. This
# has the effect of turning Galaxy into a single user application with no
# login or external proxy required. Such applications should not be exposed to
# the world.
#single_user =
# Administrative users - set this to a comma-separated list of valid Galaxy
# users (email addresses). These users will have access to the Admin section
# of the server, and will have access to create users, groups, roles,
@@ -1013,13 +1023,27 @@ use_interactive = True
# database for authentication) and set the following two options.
# This should point to a directory containing subdirectories matching users'
# email addresses, where Galaxy will look for files.
# identifier (defaults to e-mail), where Galaxy will look for files.
#ftp_upload_dir = None
# This should be the hostname of your FTP server, which will be provided to
# users in the help text.
#ftp_upload_site = None
# User attribute to use as subdirectory in calculating default ftp_upload_dir
# pattern. By default this will be email so a user's FTP upload directory will be
# ${ftp_upload_dir}/${user.email}. Can set this to other attributes such as id or
# username though.
#ftp_upload_dir_identifier = email
# Python string template used to determine an FTP upload directory for a
# particular user.
#ftp_upload_dir_template = ${ftp_upload_dir}/${ftp_upload_dir_identifier}
# This should be set to False to prevent Galaxy from deleting uploaded FTP files
# as it imports them.
#ftp_upload_purge = True
# Enable enforcement of quotas. Quotas can be set from the Admin interface.
#enable_quotas = False
+5 -1
View File
@@ -151,7 +151,8 @@ class Configuration( object ):
self.id_secret = kwargs.get( "id_secret", "USING THE DEFAULT IS NOT SECURE!" )
self.retry_metadata_internally = string_as_bool( kwargs.get( "retry_metadata_internally", "True" ) )
self.max_metadata_value_size = int( kwargs.get( "max_metadata_value_size", 5242880 ) )
self.use_remote_user = string_as_bool( kwargs.get( "use_remote_user", "False" ) )
self.single_user = kwargs.get( "single_user", None )
self.use_remote_user = string_as_bool( kwargs.get( "use_remote_user", "False" ) ) or self.single_user
self.normalize_remote_user_email = string_as_bool( kwargs.get( "normalize_remote_user_email", "False" ) )
self.remote_user_maildomain = kwargs.get( "remote_user_maildomain", None )
self.remote_user_header = kwargs.get( "remote_user_header", 'HTTP_REMOTE_USER' )
@@ -292,6 +293,8 @@ class Configuration( object ):
self.whoosh_index_dir = resolve_path( kwargs.get( "whoosh_index_dir", "database/whoosh_indexes" ), self.root )
self.ftp_upload_dir = kwargs.get( 'ftp_upload_dir', None )
self.ftp_upload_dir_identifier = kwargs.get( 'ftp_upload_dir_identifier', 'email' ) # attribute on user - email, username, id, etc...
self.ftp_upload_dir_template = kwargs.get( 'ftp_upload_dir_template', '${ftp_upload_dir}%s${ftp_upload_dir_identifier}' % os.path.sep )
self.ftp_upload_purge = string_as_bool( kwargs.get( 'ftp_upload_purge', 'True' ) )
self.ftp_upload_site = kwargs.get( 'ftp_upload_site', None )
self.allow_library_path_paste = kwargs.get( 'allow_library_path_paste', False )
self.disable_library_comptypes = kwargs.get( 'disable_library_comptypes', '' ).lower().split( ',' )
@@ -446,6 +449,7 @@ class Configuration( object ):
# Statistics and profiling with statsd
self.statsd_host = kwargs.get( 'statsd_host', '')
self.statsd_port = int( kwargs.get( 'statsd_port', 8125 ) )
self.statsd_prefix = kwargs.get( 'statsd_prefix', 'galaxy' )
# Logging with fluentd
self.fluent_log = string_as_bool( kwargs.get( 'fluent_log', False ) )
self.fluent_host = kwargs.get( 'fluent_host', 'localhost' )
+3
View File
@@ -66,6 +66,9 @@ class ConditionalDependencies( object ):
def check_raven( self ):
return self.config.get("sentry_dsn", None) is not None
def check_statsd( self ):
return self.config.get("statsd_host", None) is not None
def check_weberror( self ):
return ( asbool( self.config["debug"] ) and
asbool( self.config["use_interactive"] ) )
@@ -10,4 +10,5 @@ fluent-logger
raven
pbs_python
drmaa
statsd
# PyRods not in PyPI
@@ -43,7 +43,7 @@ anyjson==0.3.3
# Pulsar requirements
psutil==4.1.0
pulsar-galaxy-lib==0.7.0.dev2
pulsar-galaxy-lib==0.7.0.dev3
# sqlalchemy-migrate and dependencies
sqlalchemy-migrate==0.10.0
@@ -15,6 +15,8 @@ elif [ -n "$SLURM_NTASKS" ] || [ -n "$SLURM_CPUS_PER_TASK" ]; then
GALAXY_SLOTS=`expr "${SLURM_NTASKS:-1}" \* "${SLURM_CPUS_PER_TASK:-1}"`
elif [ -n "$NSLOTS" ]; then
GALAXY_SLOTS="$NSLOTS"
elif [ -n "$NCPUS" ]; then
GALAXY_SLOTS="$NCPUS"
elif [ -n "$PBS_NCPUS" ]; then
GALAXY_SLOTS="$PBS_NCPUS"
elif [ -f "$PBS_NODEFILE" ]; then
@@ -1,7 +1,7 @@
#!$shell
$integrity_injection
$headers
$integrity_injection
$slots_statement
export GALAXY_SLOTS
GALAXY_LIB="$galaxy_lib"
+8 -3
View File
@@ -2,8 +2,8 @@
Mixins for transaction-like objects.
"""
import os
from json import dumps
import string
from galaxy.util import bunch
@@ -139,12 +139,17 @@ class ProvidesUserContext( object ):
@property
def user_ftp_dir( self ):
identifier = self.app.config.ftp_upload_dir_identifier
base_dir = self.app.config.ftp_upload_dir
if base_dir is None:
return None
else:
return os.path.join( base_dir, getattr( self.user, identifier ) )
identifier = self.app.config.ftp_upload_dir_identifier
template = self.app.config.ftp_upload_dir_template
path = string.Template(template).safe_substitute(dict(
ftp_upload_dir=base_dir,
ftp_upload_dir_identifier=identifier,
))
return path
class ProvidesHistoryContext( object ):
@@ -325,6 +325,10 @@ def create_paramfile( trans, uploaded_datasets ):
uuid_str = uploaded_dataset.uuid
except:
uuid_str = None
try:
purge_source = uploaded_dataset.purge_source
except:
purge_source = True
json = dict( file_type=uploaded_dataset.file_type,
ext=uploaded_dataset.ext,
name=uploaded_dataset.name,
@@ -335,6 +339,7 @@ def create_paramfile( trans, uploaded_datasets ):
link_data_only=link_data_only,
uuid=uuid_str,
to_posix_lines=getattr(uploaded_dataset, "to_posix_lines", True),
purge_source=purge_source,
space_to_tab=uploaded_dataset.space_to_tab,
in_place=trans.app.config.external_chown_script is None,
path=uploaded_dataset.path )
+122 -25
View File
@@ -3,6 +3,7 @@ Functionality for dealing with tool errors.
"""
import string
from galaxy import model, util, web
import cgi
error_report_template = """
GALAXY TOOL ERROR REPORT
@@ -51,6 +52,91 @@ ${job_traceback}
(This is an automated message).
"""
error_report_template_html = """
<html><head></head>
<body>
<style type="text/css">
tr:nth-child(even) {background-color: #f2f2f2}
table{margin: 1em;}
.mono{font-family: monospace;}
pre {
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
background: #eee;
border:1px solid black;
padding:10px;
}
</style>
<h1>Galaxy Tool Error Report</h1>
<span class="sub"><i>from</i> <span class="mono"><a href="${host}">${host}</a></span>
<h3>Error Localization</h3>
<table>
<tbody>
<tr><td>Dataset</td><td>${dataset_id} (${dataset_id_encoded})</td></tr>
<tr><td>History</td><td><a href="${history_view_link}">${history_id} (${history_id_encoded})</a></td></tr>
<tr><td>Failed Job</td><td>${hid}: ${history_item_name} (${hda_id_encoded})</td></tr>
</tbody>
</table>
<h3>User Provided Information</h3>
The user <a href="mailto:${email_str}"><span class="mono">${email_str}</span></a> provided the following information:
<pre>
${message}
</pre>
<h3>Detailed Job Information</h3>
Job environment and execution information is available at the job <a href="${hda_show_params_link}">Info Page</a>.
<table>
<tbody>
<tr><td>Job ID</td><td>${job_id} (${job_id_encoded})</td></tr>
<tr><td>Tool ID</td><td>${job_tool_id}</td></tr>
<tr><td>Tool Version</td><td>${tool_version}</td></tr>
<tr><td>Job PID or DRM id</td><td>${job_runner_external_id}</td></tr>
<tr><td>Job Tool Version</td><td>${job_tool_version}</td></tr>
</tbody>
</table>
<h3>Job Execution and Failure Information</h3>
<h4>Command Line</h4>
<pre>
${job_command_line}
</pre>
<h4>stderr</h4>
<pre>
${job_stderr}
</pre>
<h4>stdout</h4>
<pre>
${job_stdout}
</pre>
<h4>Job Information</h4>
<pre>
${job_info}
</pre>
<h4>Job Traceback</h4>
<pre>
${job_traceback}
</pre>
This is an automated message. Do not reply to this address.
</body></html>
"""
class ErrorReporter( object ):
def __init__( self, hda, app ):
@@ -91,30 +177,40 @@ class ErrorReporter( object ):
email_str = "'%s' (providing preferred contact email '%s')" % (user.email, email)
else:
email_str = "'%s'" % (email or 'anonymously')
self.report = string.Template( error_report_template ) \
.safe_substitute( host=host,
dataset_id_encoded=self.app.security.encode_id( hda.dataset_id ),
dataset_id=hda.dataset_id,
history_id_encoded=history_id_encoded,
history_id=hda.history_id,
hda_id_encoded=hda_id_encoded,
hid=hda.hid,
history_item_name=hda.get_display_name(),
history_view_link=history_view_link,
hda_show_params_link=hda_show_params_link,
job_id_encoded=self.app.security.encode_id( job.id ),
job_id=job.id,
tool_version=job.tool_version,
job_tool_id=job.tool_id,
job_tool_version=hda.tool_version,
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_str=email_str,
message=util.unicodify( message ) )
report_variables = dict(
host=host,
dataset_id_encoded=self.app.security.encode_id( hda.dataset_id ),
dataset_id=hda.dataset_id,
history_id_encoded=history_id_encoded,
history_id=hda.history_id,
hda_id_encoded=hda_id_encoded,
hid=hda.hid,
history_item_name=hda.get_display_name(),
history_view_link=history_view_link,
hda_show_params_link=hda_show_params_link,
job_id_encoded=self.app.security.encode_id( job.id ),
job_id=job.id,
tool_version=job.tool_version,
job_tool_id=job.tool_id,
job_tool_version=hda.tool_version,
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_str=email_str,
message=util.unicodify( message )
)
self.report = string.Template( error_report_template ).safe_substitute( report_variables )
# Escape all of the content for use in the HTML report
for parameter in report_variables.keys():
report_variables[parameter] = cgi.escape(report_variables[parameter])
self.html_report = string.Template( error_report_template_html ).safe_substitute( report_variables )
def _send_report( self, user, email=None, message=None, **kwd ):
return self.report
@@ -146,5 +242,6 @@ class EmailErrorReporter( ErrorReporter ):
subject = "%s (%s)" % ( subject, self.app.toolbox.get_tool( self.job.tool_id, self.job.tool_version ).old_id )
except Exception:
pass
# Send it
return util.send_mail( frm, to, subject, self.report, self.app.config )
return util.send_mail( frm, to, subject, self.report, self.app.config, html=self.html_report )
+4 -1
View File
@@ -4,13 +4,16 @@ Classes encapsulating Galaxy tool parameters.
import re
from json import dumps, loads
from basic import RuntimeValue
from basic import RuntimeValue, DataCollectionToolParameter, DataToolParameter, SelectToolParameter
from grouping import Conditional, Repeat, Section, UploadDataset
from galaxy.util.expressions import ExpressionContext
from galaxy.util.json import json_fix
REPLACE_ON_TRUTHY = object()
# Some tools use the code tag and access the code base, expecting certain tool parameters to be available here.
__all__ = [ DataCollectionToolParameter, DataToolParameter, SelectToolParameter ]
def visit_input_values( inputs, input_values, callback, name_prefix='', label_prefix='', parent_prefix='', context=None, no_replacement_value=REPLACE_ON_TRUTHY ):
"""
+11 -4
View File
@@ -283,7 +283,7 @@ class UploadDataset( Group ):
return rval
def get_uploaded_datasets( self, trans, context, override_name=None, override_info=None ):
def get_data_file_filename( data_file, override_name=None, override_info=None ):
def get_data_file_filename( data_file, override_name=None, override_info=None, purge=True ):
dataset_name = override_name
dataset_info = override_info
@@ -297,7 +297,7 @@ class UploadDataset( Group ):
dataset_name = get_file_name( data_file['filename'] )
if not dataset_info:
dataset_info = 'uploaded file'
return Bunch( type='file', path=data_file['local_filename'], name=dataset_name )
return Bunch( type='file', path=data_file['local_filename'], name=dataset_name, purge_source=purge )
except:
# The uploaded file should've been persisted by the upload tool action
return Bunch( type=None, path=None, name=None )
@@ -364,7 +364,13 @@ class UploadDataset( Group ):
if not os.path.islink( os.path.join( dirpath, filename ) ):
ftp_data_file = { 'local_filename' : os.path.abspath( os.path.join( user_ftp_dir, path ) ),
'filename' : os.path.basename( path ) }
file_bunch = get_data_file_filename( ftp_data_file, override_name=name, override_info=info )
purge = getattr(trans.app.config, 'ftp_upload_purge', True)
file_bunch = get_data_file_filename(
ftp_data_file,
override_name=name,
override_info=info,
purge=purge,
)
if file_bunch.path:
break
if file_bunch.path:
@@ -432,7 +438,8 @@ class UploadDataset( Group ):
# TODO: warning to the user (could happen if file is already imported)
ftp_data_file = { 'local_filename' : os.path.abspath( os.path.join( user_ftp_dir, ftp_file ) ),
'filename' : os.path.basename( ftp_file ) }
file_bunch = get_data_file_filename( ftp_data_file, override_name=name, override_info=info )
purge = getattr(trans.app.config, 'ftp_upload_purge', True)
file_bunch = get_data_file_filename( ftp_data_file, override_name=name, override_info=info, purge=purge )
if file_bunch.path:
file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
+6
View File
@@ -81,6 +81,9 @@ class InputValueWrapper( ToolParameterValueWrapper ):
else:
return super( InputValueWrapper, self ) == other
def __ne__( self, other ):
return not self == other
def __str__( self ):
to_param_dict_string = self.input.to_param_dict_string( self.value, self._other_values )
if isinstance( to_param_dict_string, list ):
@@ -146,6 +149,9 @@ class SelectToolParameterWrapper( ToolParameterValueWrapper ):
else:
return super( SelectToolParameterWrapper, self ) == other
def __ne__( self, other ):
return not self == other
def __str__( self ):
# Assuming value is never a path - otherwise would need to pass
# along following argument value_map=self._path_rewriter.
+35 -3
View File
@@ -28,7 +28,7 @@ from os.path import normpath, relpath
from xml.etree import ElementInclude, ElementTree
from six import binary_type, iteritems, PY3, string_types, text_type
from six.moves import email_mime_text, xrange, zip
from six.moves import email_mime_text, email_mime_multipart, xrange, zip
from six.moves.urllib import parse as urlparse
from six.moves.urllib import request as urlrequest
@@ -1205,19 +1205,51 @@ def size_to_bytes( size ):
return int( size )
def send_mail( frm, to, subject, body, config ):
def send_mail( frm, to, subject, body, config, html=None ):
"""
Sends an email.
:type frm: str
:param frm: from address
:type to: str
:param to: to address
:type subject: str
:param subject: Subject line
:type body: str
:param body: Body text (should be plain text)
:type config: object
:param config: Galaxy configuration object
:type html: str
:param html: Alternative HTML representation of the body content. If
provided will convert the message to a MIMEMultipart. (Default 'None')
"""
to = listify( to )
msg = email_mime_text.MIMEText( body.encode( 'ascii', 'replace' ) )
if html:
msg = email_mime_multipart.MIMEMultipart('alternative')
else:
msg = email_mime_text.MIMEText( body.encode( 'ascii', 'replace' ) )
msg[ 'To' ] = ', '.join( to )
msg[ 'From' ] = frm
msg[ 'Subject' ] = subject
if config.smtp_server is None:
log.error( "Mail is not configured for this Galaxy instance." )
log.info( msg )
return
if html:
mp_text = email_mime_text.MIMEText( body.encode( 'ascii', 'replace' ), 'plain' )
mp_html = email_mime_text.MIMEText( html.encode( 'ascii', 'replace' ), 'html' )
msg.attach(mp_text)
msg.attach(mp_html)
smtp_ssl = asbool( getattr(config, 'smtp_ssl', False ) )
if smtp_ssl:
s = smtplib.SMTP_SSL()
+2 -2
View File
@@ -7,7 +7,7 @@ from six import string_types, text_type
from sqlalchemy.sql.expression import and_, false, func, null, or_, true
from galaxy.model.item_attrs import RuntimeException, UsesAnnotations, UsesItemRatings
from galaxy.util import sanitize_text
from galaxy.util import sanitize_text, unicodify
from galaxy.util.odict import odict
from galaxy.web.framework import decorators, url_for
from galaxy.web.framework.helpers import iff
@@ -372,7 +372,7 @@ class GridColumn( object ):
value = None
if self.format:
value = self.format( value )
return escape(value)
return escape(unicodify(value))
def get_link( self, trans, grid, item ):
if self.link and self.link( item ):
@@ -40,12 +40,16 @@ errorpage = """
class RemoteUser( object ):
def __init__( self, app, maildomain=None, display_servers=None, admin_users=None, remote_user_header=None, remote_user_secret_header=None ):
def __init__(
self, app, maildomain=None, display_servers=None, admin_users=None,
single_user=None, remote_user_header=None, remote_user_secret_header=None,
):
self.app = app
self.maildomain = maildomain
self.display_servers = display_servers or []
self.admin_users = admin_users or []
self.remote_user_header = remote_user_header or 'HTTP_REMOTE_USER'
self.single_user = single_user
self.config_secret_header = remote_user_secret_header
def __call__( self, environ, start_response ):
@@ -59,6 +63,11 @@ class RemoteUser( object ):
if host in self.display_servers:
environ[ self.remote_user_header ] = 'remote_display_server@%s' % ( self.maildomain or 'example.org' )
return self.app( environ, start_response )
if self.single_user:
assert self.remote_user_header not in environ
environ[ self.remote_user_header ] = self.single_user
# Apache sets REMOTE_USER to the string '(null)' when using the
# Rewrite* method for passing REMOTE_USER and a user is
# un-authenticated. Any other possible values need to go here as well.
@@ -76,7 +85,12 @@ class RemoteUser( object ):
# seems improbable that an attacker with access to the server hosting
# Galaxy would not have access to Galaxy itself, and be attempting to
# attack the system
if self.config_secret_header is not None:
if path_info.startswith( '/api/' ):
# The API handles its own authentication via keys
# Check for API key before checking for header
return self.app( environ, start_response )
elif self.config_secret_header is not None:
if environ.get('HTTP_GX_SECRET') is None:
title = "Access to Galaxy is denied"
message = """
@@ -91,7 +105,7 @@ class RemoteUser( object ):
"""
return self.error( start_response, title, message )
if not safe_str_cmp(environ.get('HTTP_GX_SECRET'), self.config_secret_header):
if not safe_str_cmp(environ.get('HTTP_GX_SECRET', ''), self.config_secret_header):
title = "Access to Galaxy is denied"
message = """
Galaxy is configured to authenticate users via an external
@@ -161,9 +175,6 @@ class RemoteUser( object ):
"""
return self.error( start_response, title, message )
return self.app( environ, start_response )
elif path_info.startswith( '/api/' ):
# The API handles its own authentication via keys
return self.app( environ, start_response )
else:
log.debug("Unable to identify user. %s not found" % self.remote_user_header)
for k, v in environ.iteritems():
@@ -21,12 +21,13 @@ class StatsdMiddleware(object):
def __init__(self,
application,
statsd_host,
statsd_port):
statsd_port,
statsd_prefix):
if not statsd:
raise ImportError( "Statsd middleware configured, but no statsd python module found. "
"Please install the python statsd module to use this functionality." )
self.application = application
self.statsd_client = statsd.StatsClient(statsd_host, statsd_port, prefix='galaxy')
self.statsd_client = statsd.StatsClient(statsd_host, statsd_port, prefix=statsd_prefix)
def __call__(self, environ, start_response):
start_time = time.time()
@@ -90,9 +90,7 @@ class RemoteFilesAPIController( BaseAPIController ):
if user_ftp_base_dir is None:
raise exceptions.ConfigDoesNotAllowException( 'The configuration of this Galaxy instance does not allow upload from FTP directories.' )
try:
user_ftp_dir = None
identifier = trans.app.config.ftp_upload_dir_identifier
user_ftp_dir = os.path.join( user_ftp_base_dir, getattr(trans.user, identifier) )
user_ftp_dir = trans.user_ftp_dir
if user_ftp_dir is not None:
response = self.__load_all_filenames( user_ftp_dir )
else:
+8 -2
View File
@@ -717,10 +717,13 @@ def wrap_in_middleware( app, global_conf, **local_conf ):
# If we're using remote_user authentication, add middleware that
# protects Galaxy from improperly configured authentication in the
# upstream server
if asbool(conf.get( 'use_remote_user', False )):
single_user = conf.get( 'single_user', None )
use_remote_user = asbool(conf.get( 'use_remote_user', False )) or single_user
if use_remote_user:
from galaxy.web.framework.middleware.remoteuser import RemoteUser
app = RemoteUser( app, maildomain=conf.get( 'remote_user_maildomain', None ),
display_servers=util.listify( conf.get( 'display_servers', '' ) ),
single_user=single_user,
admin_users=conf.get( 'admin_users', '' ).split( ',' ),
remote_user_header=conf.get( 'remote_user_header', 'HTTP_REMOTE_USER' ),
remote_user_secret_header=conf.get('remote_user_secret', None) )
@@ -775,7 +778,10 @@ def wrap_in_middleware( app, global_conf, **local_conf ):
statsd_host = conf.get('statsd_host', None)
if statsd_host:
from galaxy.web.framework.middleware.statsd import StatsdMiddleware
app = StatsdMiddleware( app, statsd_host, conf.get('statsd_port'))
app = StatsdMiddleware( app,
statsd_host,
conf.get('statsd_port'),
conf.get('statsd_prefix') )
log.debug( "Enabling 'statsd' middleware" )
# X-Forwarded-Host handling
+17 -16
View File
@@ -904,22 +904,23 @@ class ToolModule( WorkflowModule ):
data_inputs = []
def callback( input, prefixed_name, prefixed_label, **kwargs ):
if isinstance( input, DataToolParameter ):
data_inputs.append( dict(
name=prefixed_name,
label=prefixed_label,
multiple=input.multiple,
extensions=input.extensions,
input_type="dataset", ) )
if isinstance( input, DataCollectionToolParameter ):
data_inputs.append( dict(
name=prefixed_name,
label=prefixed_label,
multiple=input.multiple,
input_type="dataset_collection",
collection_types=input.collection_types,
extensions=input.extensions,
) )
if not hasattr( input, 'hidden' ) or not input.hidden:
if isinstance( input, DataToolParameter ):
data_inputs.append( dict(
name=prefixed_name,
label=prefixed_label,
multiple=input.multiple,
extensions=input.extensions,
input_type="dataset", ) )
elif isinstance( input, DataCollectionToolParameter ):
data_inputs.append( dict(
name=prefixed_name,
label=prefixed_label,
multiple=input.multiple,
input_type="dataset_collection",
collection_types=input.collection_types,
extensions=input.extensions,
) )
visit_input_values( self.tool.inputs, self.state.inputs, callback )
return data_inputs
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"page.js","sources":["../../src/layout/page.js"],"names":["define","Masthead","Panel","Modal","BaseMVC","PageLayoutView","Backbone","View","extend","LoggableMixin","_logNamespace","el","className","_panelIds","defaultOptions","message_box_visible","message_box_content","message_box_class","show_inactivity_warning","inactivity_box_content","initialize","options","this","log","_","pick","defaults","omit","Galaxy","modal","masthead","config","$el","attr","html","_template","append","frame","$messagebox","$","$inactivebox","render","remove","renderMessageBox","renderInactivityBox","renderPanels","content","level","addClass","toggle","show","removeClass","hide","verificationLink","root","text","page","forEach","panelId","has","setElement","left","center","css","right","join","hideSidePanels","toString"],"mappings":"AAAAA,QACI,kBACA,eACA,kBACA,gBACD,SAAUC,EAAUC,EAAOC,EAAOC,GAGrC,GAAIC,GAAiBC,SAASC,KAAKC,OAAQJ,EAAQK,eAAgBD,QAC/DE,cAAgB,SAEhBC,GAAK,OACLC,UAAY,eAEZC,WACI,OAAQ,SAAU,SAGtBC,gBACIC,qBAA0B,EAC1BC,oBAA0B,GAC1BC,kBAA0B,OAC1BC,yBAA0B,EAC1BC,uBAA0B,IAG9BC,WAAa,SAAUC,GAEnBC,KAAKC,IAAKD,KAAO,eAAgBD,GACjCG,EAAEhB,OAAQc,KAAME,EAAEC,KAAMJ,EAASC,KAAKT,YACtCS,KAAKD,QAAUG,EAAEE,SAAUF,EAAEG,KAAMN,EAASC,KAAKT,WAAaS,KAAKR,gBACnEc,OAAOC,MAAQP,KAAKO,MAAQ,GAAI1B,GAAMI,KACtCe,KAAKQ,SAAW,GAAI7B,GAASM,KAAMe,KAAKD,QAAQU,QAChDT,KAAKU,IAAIC,KAAM,SAAU,MACzBX,KAAKU,IAAIE,KAAMZ,KAAKa,aACpBb,KAAKU,IAAII,OAAQd,KAAKQ,SAASO,MAAML,KACrCV,KAAKU,IAAII,OAAQd,KAAKQ,SAASE,KAC/BV,KAAKU,IAAII,OAAQd,KAAKO,MAAMG,KAC5BV,KAAKgB,YAAchB,KAAKiB,EAAG,eAC3BjB,KAAKkB,aAAelB,KAAKiB,EAAG,iBAGhCE,OAAS,WAQL,MANAF,GAAG,8BAA+BG,SAClCpB,KAAKC,IAAKD,KAAO,YACjBA,KAAKQ,SAASW,SACdnB,KAAKqB,mBACLrB,KAAKsB,sBACLtB,KAAKuB,eACEvB,MAIXqB,iBAAmB,WACf,GAAKrB,KAAKD,QAAQN,oBAAqB,CACnC,GAAI+B,GAAUxB,KAAKD,QAAQL,qBAAuB,GAC9C+B,EAAQzB,KAAKD,QAAQJ,mBAAqB,MAC9CK,MAAKU,IAAIgB,SAAU,mBACnB1B,KAAKgB,YACAL,KAAM,QAAS,SAAWc,EAAQ,YAClCb,KAAMY,GACNG,SAAUH,GACVI,WAEL5B,MAAKU,IAAImB,YAAa,mBACtB7B,KAAKgB,YAAYc,MAErB,OAAO9B,OAIXsB,oBAAsB,WAClB,GAAItB,KAAKD,QAAQH,wBAAyB,CACtC,GAAI4B,GAAUxB,KAAKD,QAAQF,wBAA0B,GACjDkC,EAAmBd,EAAG,QAASN,KAAM,OAAQL,OAAO0B,KAAO,4BAA6BC,KAAM,sBAClGjC,MAAKU,IAAIgB,SAAU,sBACnB1B,KAAKkB,aACAN,KAAMY,EAAU,KAChBV,OAAQiB,GACRJ,SAAUH,GACVI,WAEL5B,MAAKU,IAAImB,YAAa,sBACtB7B,KAAKkB,aAAaY,MAEtB,OAAO9B,OAIXuB,aAAe,WACX,GAAIW,GAAOlC,IAaX,OAZAA,MAAKT,UAAU4C,QAAS,SAAUC,GAC1BlC,EAAEmC,IAAKH,EAAME,KACbF,EAAME,GAAUE,WAAY,IAAMF,GAClCF,EAAME,GAAUjB,YAGnBnB,KAAKuC,MACNvC,KAAKwC,OAAO9B,IAAI+B,IAAK,OAAQ,GAE5BzC,KAAK0C,OACN1C,KAAKwC,OAAO9B,IAAI+B,IAAK,QAAS,GAE3BzC,MAIXa,UAAW,WACP,OACI,wBACI,yBACA,yBACA,yDACAb,KAAKuC,KAAQ,oBAAsB,GACnCvC,KAAKwC,OAAQ,sCAAwC,GACrDxC,KAAK0C,MAAQ,qBAAuB,GACxC,SACA,0BACFC,KAAK,KAIXC,eAAiB,WACT5C,KAAKuC,MACLvC,KAAKuC,KAAKT,OAEV9B,KAAK0C,OACL1C,KAAK0C,MAAMZ,QAInBe,SAAW,WAAa,MAAO,mBAI/B,QACI9D,eAAgBA"}
{"version":3,"file":"page.js","sources":["../../src/layout/page.js"],"names":["define","Masthead","Panel","Modal","BaseMVC","PageLayoutView","Backbone","View","extend","LoggableMixin","_logNamespace","el","className","_panelIds","defaultOptions","message_box_visible","message_box_content","message_box_class","show_inactivity_warning","inactivity_box_content","initialize","options","this","log","_","pick","defaults","omit","config","Galaxy","modal","masthead","$el","attr","html","_template","append","frame","$messagebox","$","$inactivebox","render","remove","renderMessageBox","renderInactivityBox","renderPanels","content","level","addClass","toggle","show","removeClass","hide","verificationLink","root","text","page","forEach","panelId","has","setElement","left","center","css","right","join","hideSidePanels","toString"],"mappings":"AAAAA,QACI,kBACA,eACA,kBACA,gBACD,SAAUC,EAAUC,EAAOC,EAAOC,GAGrC,GAAIC,GAAiBC,SAASC,KAAKC,OAAQJ,EAAQK,eAAgBD,QAC/DE,cAAgB,SAEhBC,GAAK,OACLC,UAAY,eAEZC,WACI,OAAQ,SAAU,SAGtBC,gBACIC,qBAA0B,EAC1BC,oBAA0B,GAC1BC,kBAA0B,OAC1BC,yBAA0B,EAC1BC,uBAA0B,IAG9BC,WAAa,SAAUC,GAEnBC,KAAKC,IAAKD,KAAO,eAAgBD,GACjCG,EAAEhB,OAAQc,KAAME,EAAEC,KAAMJ,EAASC,KAAKT,YACtCS,KAAKD,QAAUG,EAAEE,SAAUF,EAAEG,KAAMN,EAAQO,OAAQN,KAAKT,WAAaS,KAAKR,gBAC1Ee,OAAOC,MAAQR,KAAKQ,MAAQ,GAAI3B,GAAMI,KACtCe,KAAKS,SAAW,GAAI9B,GAASM,KAAMe,KAAKD,SACxCC,KAAKU,IAAIC,KAAM,SAAU,MACzBX,KAAKU,IAAIE,KAAMZ,KAAKa,aACpBb,KAAKU,IAAII,OAAQd,KAAKS,SAASM,MAAML,KACrCV,KAAKU,IAAII,OAAQd,KAAKS,SAASC,KAC/BV,KAAKU,IAAII,OAAQd,KAAKQ,MAAME,KAC5BV,KAAKgB,YAAchB,KAAKiB,EAAG,eAC3BjB,KAAKkB,aAAelB,KAAKiB,EAAG,iBAGhCE,OAAS,WAQL,MANAF,GAAG,8BAA+BG,SAClCpB,KAAKC,IAAKD,KAAO,YACjBA,KAAKS,SAASU,SACdnB,KAAKqB,mBACLrB,KAAKsB,sBACLtB,KAAKuB,eACEvB,MAIXqB,iBAAmB,WACf,GAAKrB,KAAKD,QAAQN,oBAAqB,CACnC,GAAI+B,GAAUxB,KAAKD,QAAQL,qBAAuB,GAC9C+B,EAAQzB,KAAKD,QAAQJ,mBAAqB,MAC9CK,MAAKU,IAAIgB,SAAU,mBACnB1B,KAAKgB,YACAL,KAAM,QAAS,SAAWc,EAAQ,YAClCb,KAAMY,GACNG,SAAUH,GACVI,WAEL5B,MAAKU,IAAImB,YAAa,mBACtB7B,KAAKgB,YAAYc,MAErB,OAAO9B,OAIXsB,oBAAsB,WAClB,GAAItB,KAAKD,QAAQH,wBAAyB,CACtC,GAAI4B,GAAUxB,KAAKD,QAAQF,wBAA0B,GACjDkC,EAAmBd,EAAG,QAASN,KAAM,OAAQJ,OAAOyB,KAAO,4BAA6BC,KAAM,sBAClGjC,MAAKU,IAAIgB,SAAU,sBACnB1B,KAAKkB,aACAN,KAAMY,EAAU,KAChBV,OAAQiB,GACRJ,SAAUH,GACVI,WAEL5B,MAAKU,IAAImB,YAAa,sBACtB7B,KAAKkB,aAAaY,MAEtB,OAAO9B,OAIXuB,aAAe,WACX,GAAIW,GAAOlC,IAaX,OAZAA,MAAKT,UAAU4C,QAAS,SAAUC,GAC1BlC,EAAEmC,IAAKH,EAAME,KACbF,EAAME,GAAUE,WAAY,IAAMF,GAClCF,EAAME,GAAUjB,YAGnBnB,KAAKuC,MACNvC,KAAKwC,OAAO9B,IAAI+B,IAAK,OAAQ,GAE5BzC,KAAK0C,OACN1C,KAAKwC,OAAO9B,IAAI+B,IAAK,QAAS,GAE3BzC,MAIXa,UAAW,WACP,OACI,wBACI,yBACA,yBACA,yDACAb,KAAKuC,KAAQ,oBAAsB,GACnCvC,KAAKwC,OAAQ,sCAAwC,GACrDxC,KAAK0C,MAAQ,qBAAuB,GACxC,SACA,0BACFC,KAAK,KAIXC,eAAiB,WACT5C,KAAKuC,MACLvC,KAAKuC,KAAKT,OAEV9B,KAAK0C,OACL1C,KAAK0C,MAAMZ,QAInBe,SAAW,WAAa,MAAO,mBAI/B,QACI9D,eAAgBA"}
@@ -1 +1 @@
{"version":3,"file":"citation-model.js","sources":["../../../src/mvc/citation/citation-model.js"],"names":["define","parseBibtex","baseMVC","window","BibtexParser","logNamespace","Citation","Backbone","Model","extend","LoggableMixin","_logNamespace","initialize","bibtex","this","get","entry","entries","_fields","rawFields","Fields","key","value","lowerKey","toLowerCase","entryType","EntryType","fields","BaseCitationCollection","Collection","urlRoot","Galaxy","root","partial","model","HistoryCitationCollection","url","history_id","ToolCitationCollection","tool_id"],"mappings":"AAAAA,QACI,cACA,eACA,sBACD,SAAUC,EAAaC,GAI1BD,EAAcA,GAAeE,OAAOC,YAEpC,IAAIC,GAAe,WAMfC,EAAWC,SAASC,MAAMC,OAAQP,EAAQQ,eAAgBD,QAC1DE,cAAgBN,EAEhBO,WAAY,WACR,GAAIC,GAASC,KAAKC,IAAK,WACnBC,EAAQf,EAAYY,GAAQI,QAAQ,EACxCH,MAAKE,MAAQA,EACbF,KAAKI,UACL,IAAIC,GAAYH,EAAMI,MACtB,KAAI,GAAIC,KAAOF,GAAW,CACtB,GAAIG,GAAQH,EAAWE,GACnBE,EAAWF,EAAIG,aACnBV,MAAKI,QAASK,GAAaD,IAGnCG,UAAW,WACP,MAAOX,MAAKE,MAAMU,WAEtBC,OAAQ,WACJ,MAAOb,MAAKI,WAOhBU,EAAyBrB,SAASsB,WAAWpB,OAAQP,EAAQQ,eAAgBD,QAC7EE,cAAgBN,EAGhByB,QAAUC,OAAOC,KAAO,MACxBC,SAAU,EACVC,MAAQ5B,IAGR6B,EAA4BP,EAAuBnB,QAEnD2B,IAAM,WACF,MAAOtB,MAAKgB,QAAU,cAAgBhB,KAAKuB,WAAa,gBAI5DC,EAAyBV,EAAuBnB,QAEhD2B,IAAM,WACF,MAAOtB,MAAKgB,QAAU,UAAYhB,KAAKyB,QAAU,cAErDN,SAAU,GAKd,QACI3B,SAAWA,EACX6B,0BAA6BA,EAC7BG,uBAAwBA"}
{"version":3,"file":"citation-model.js","sources":["../../../src/mvc/citation/citation-model.js"],"names":["define","parseBibtex","baseMVC","window","BibtexParser","logNamespace","Citation","Backbone","Model","extend","LoggableMixin","_logNamespace","initialize","bibtex","this","attributes","content","parsed","errors","length","reduce","all","current","log","_fields","entry","_","first","entries","rawFields","Fields","key","value","lowerKey","toLowerCase","entryType","EntryType","undefined","fields","BaseCitationCollection","Collection","urlRoot","Galaxy","root","partial","model","HistoryCitationCollection","url","history_id","ToolCitationCollection","tool_id"],"mappings":"AAAAA,QACI,cACA,eACA,sBACD,SAAUC,EAAaC,GAI1BD,EAAcA,GAAeE,OAAOC,YAEpC,IAAIC,GAAe,WAMfC,EAAWC,SAASC,MAAMC,OAAQP,EAAQQ,eAAgBD,QAC1DE,cAAgBN,EAEhBO,WAAY,WAER,GAAIC,GAASC,KAAKC,WAAWC,QACzBC,EAASb,aAAcS,EAE3B,IAAII,EAAOC,OAAOC,OAAQ,CAEtB,GAAID,GAASD,EAAOC,OAAOE,OAAQ,SAAUC,EAAKC,GAAW,MAAOD,GAAM,KAAOC,GAEjFR,MAAKS,IAAK,yBAA2BL,GAKzC,GAFAJ,KAAKU,WACLV,KAAKW,MAAQC,EAAEC,MAAOV,EAAOW,SACzBd,KAAKW,MAAO,CACZ,GAAII,GAAYf,KAAKW,MAAMK,MAC3B,KAAK,GAAIC,KAAOF,GAAW,CACvB,GAAIG,GAAQH,EAAWE,GACnBE,EAAWF,EAAIG,aACnBpB,MAAKU,QAASS,GAAaD,KAIvCG,UAAW,WACP,MAAOrB,MAAKW,MAAOX,KAAKW,MAAMW,UAAYC,QAE9CC,OAAQ,WACJ,MAAOxB,MAAKU,WAQhBe,EAAyBhC,SAASiC,WAAW/B,OAAQP,EAAQQ,eAAgBD,QAC7EE,cAAgBN,EAGhBoC,QAAUC,OAAOC,KAAO,MACxBC,SAAU,EACVC,MAAQvC,IAGRwC,EAA4BP,EAAuB9B,QAEnDsC,IAAM,WACF,MAAOjC,MAAK2B,QAAU,cAAgB3B,KAAKkC,WAAa,gBAI5DC,EAAyBV,EAAuB9B,QAEhDsC,IAAM,WACF,MAAOjC,MAAK2B,QAAU,UAAY3B,KAAKoC,QAAU,cAErDN,SAAU,GAKd,QACItC,SAAWA,EACXwC,0BAA6BA,EAC7BG,uBAAwBA"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
define(["layout/masthead","layout/panel","mvc/ui/ui-modal","mvc/base-mvc"],function(a,b,c,d){var e=Backbone.View.extend(d.LoggableMixin).extend({_logNamespace:"layout",el:"body",className:"full-content",_panelIds:["left","center","right"],defaultOptions:{message_box_visible:!1,message_box_content:"",message_box_class:"info",show_inactivity_warning:!1,inactivity_box_content:""},initialize:function(b){this.log(this+".initialize:",b),_.extend(this,_.pick(b,this._panelIds)),this.options=_.defaults(_.omit(b,this._panelIds),this.defaultOptions),Galaxy.modal=this.modal=new c.View,this.masthead=new a.View(this.options.config),this.$el.attr("scroll","no"),this.$el.html(this._template()),this.$el.append(this.masthead.frame.$el),this.$el.append(this.masthead.$el),this.$el.append(this.modal.$el),this.$messagebox=this.$("#messagebox"),this.$inactivebox=this.$("#inactivebox")},render:function(){return $(".select2-hidden-accessible").remove(),this.log(this+".render:"),this.masthead.render(),this.renderMessageBox(),this.renderInactivityBox(),this.renderPanels(),this},renderMessageBox:function(){if(this.options.message_box_visible){var a=this.options.message_box_content||"",b=this.options.message_box_class||"info";this.$el.addClass("has-message-box"),this.$messagebox.attr("class","panel-"+b+"-message").html(a).toggle(!!a).show()}else this.$el.removeClass("has-message-box"),this.$messagebox.hide();return this},renderInactivityBox:function(){if(this.options.show_inactivity_warning){var a=this.options.inactivity_box_content||"",b=$("<a/>").attr("href",Galaxy.root+"user/resend_verification").text("Resend verification");this.$el.addClass("has-inactivity-box"),this.$inactivebox.html(a+" ").append(b).toggle(!!a).show()}else this.$el.removeClass("has-inactivity-box"),this.$inactivebox.hide();return this},renderPanels:function(){var a=this;return this._panelIds.forEach(function(b){_.has(a,b)&&(a[b].setElement("#"+b),a[b].render())}),this.left||this.center.$el.css("left",0),this.right||this.center.$el.css("right",0),this},_template:function(){return['<div id="everything">','<div id="background"/>','<div id="messagebox"/>','<div id="inactivebox" class="panel-warning-message" />',this.left?'<div id="left" />':"",this.center?'<div id="center" class="inbound" />':"",this.right?'<div id="right" />':"","</div>",'<div id="dd-helper" />'].join("")},hideSidePanels:function(){this.left&&this.left.hide(),this.right&&this.right.hide()},toString:function(){return"PageLayoutView"}});return{PageLayoutView:e}});
define(["layout/masthead","layout/panel","mvc/ui/ui-modal","mvc/base-mvc"],function(a,b,c,d){var e=Backbone.View.extend(d.LoggableMixin).extend({_logNamespace:"layout",el:"body",className:"full-content",_panelIds:["left","center","right"],defaultOptions:{message_box_visible:!1,message_box_content:"",message_box_class:"info",show_inactivity_warning:!1,inactivity_box_content:""},initialize:function(b){this.log(this+".initialize:",b),_.extend(this,_.pick(b,this._panelIds)),this.options=_.defaults(_.omit(b.config,this._panelIds),this.defaultOptions),Galaxy.modal=this.modal=new c.View,this.masthead=new a.View(this.options),this.$el.attr("scroll","no"),this.$el.html(this._template()),this.$el.append(this.masthead.frame.$el),this.$el.append(this.masthead.$el),this.$el.append(this.modal.$el),this.$messagebox=this.$("#messagebox"),this.$inactivebox=this.$("#inactivebox")},render:function(){return $(".select2-hidden-accessible").remove(),this.log(this+".render:"),this.masthead.render(),this.renderMessageBox(),this.renderInactivityBox(),this.renderPanels(),this},renderMessageBox:function(){if(this.options.message_box_visible){var a=this.options.message_box_content||"",b=this.options.message_box_class||"info";this.$el.addClass("has-message-box"),this.$messagebox.attr("class","panel-"+b+"-message").html(a).toggle(!!a).show()}else this.$el.removeClass("has-message-box"),this.$messagebox.hide();return this},renderInactivityBox:function(){if(this.options.show_inactivity_warning){var a=this.options.inactivity_box_content||"",b=$("<a/>").attr("href",Galaxy.root+"user/resend_verification").text("Resend verification");this.$el.addClass("has-inactivity-box"),this.$inactivebox.html(a+" ").append(b).toggle(!!a).show()}else this.$el.removeClass("has-inactivity-box"),this.$inactivebox.hide();return this},renderPanels:function(){var a=this;return this._panelIds.forEach(function(b){_.has(a,b)&&(a[b].setElement("#"+b),a[b].render())}),this.left||this.center.$el.css("left",0),this.right||this.center.$el.css("right",0),this},_template:function(){return['<div id="everything">','<div id="background"/>','<div id="messagebox"/>','<div id="inactivebox" class="panel-warning-message" />',this.left?'<div id="left" />':"",this.center?'<div id="center" class="inbound" />':"",this.right?'<div id="right" />':"","</div>",'<div id="dd-helper" />'].join("")},hideSidePanels:function(){this.left&&this.left.hide(),this.right&&this.right.hide()},toString:function(){return"PageLayoutView"}});return{PageLayoutView:e}});
//# sourceMappingURL=../../maps/layout/page.js.map
@@ -1,2 +1,2 @@
define(["libs/bibtex","mvc/base-mvc","utils/localization"],function(a,b){a=a||window.BibtexParser;var c="citation",d=Backbone.Model.extend(b.LoggableMixin).extend({_logNamespace:c,initialize:function(){var b=this.get("content"),c=a(b).entries[0];this.entry=c,this._fields={};var d=c.Fields;for(var e in d){var f=d[e],g=e.toLowerCase();this._fields[g]=f}},entryType:function(){return this.entry.EntryType},fields:function(){return this._fields}}),e=Backbone.Collection.extend(b.LoggableMixin).extend({_logNamespace:c,urlRoot:Galaxy.root+"api",partial:!0,model:d}),f=e.extend({url:function(){return this.urlRoot+"/histories/"+this.history_id+"/citations"}}),g=e.extend({url:function(){return this.urlRoot+"/tools/"+this.tool_id+"/citations"},partial:!1});return{Citation:d,HistoryCitationCollection:f,ToolCitationCollection:g}});
define(["libs/bibtex","mvc/base-mvc","utils/localization"],function(a,b){a=a||window.BibtexParser;var c="citation",d=Backbone.Model.extend(b.LoggableMixin).extend({_logNamespace:c,initialize:function(){var a=this.attributes.content,b=BibtexParser(a);if(b.errors.length){var c=b.errors.reduce(function(a,b){return a+"; "+b});this.log("Error parsing bibtex: "+c)}if(this._fields={},this.entry=_.first(b.entries),this.entry){var d=this.entry.Fields;for(var e in d){var f=d[e],g=e.toLowerCase();this._fields[g]=f}}},entryType:function(){return this.entry?this.entry.EntryType:void 0},fields:function(){return this._fields}}),e=Backbone.Collection.extend(b.LoggableMixin).extend({_logNamespace:c,urlRoot:Galaxy.root+"api",partial:!0,model:d}),f=e.extend({url:function(){return this.urlRoot+"/histories/"+this.history_id+"/citations"}}),g=e.extend({url:function(){return this.urlRoot+"/tools/"+this.tool_id+"/citations"},partial:!1});return{Citation:d,HistoryCitationCollection:f,ToolCitationCollection:g}});
//# sourceMappingURL=../../../maps/mvc/citation/citation-model.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -144,7 +144,6 @@
## Scripts can be loaded later since they progressively add features to
## the panels, but do not change layout
<script type="text/javascript">
## configure left panel
%if self.galaxy_config['left_panel']:
var lp = new panels.LeftPanel({ el: '#left' });
@@ -74,7 +74,7 @@ ${render_tool_shed_repository_actions( repository=repository, metadata=metadata
</tr>
%endif
<tr>
<td>
<td class="preserve-text-breaks">
<b>Commit message:</b>
<br/>${ util.unicodify( ctx.description() ) | h}<br/>
</td>
+4
View File
@@ -382,7 +382,11 @@ class GalaxyInteractorApi( object ):
except IndexError:
username = re.sub('[^a-z-]', '--', email.lower())
password = password or 'testpass'
# If remote user middleware is enabled - this endpoint consumes
# ``remote_user_email`` otherwise it requires ``email``, ``password``
# and ``username``.
data = dict(
remote_user_email=email,
email=email,
password=password,
username=username,
+10 -14
View File
@@ -11,7 +11,6 @@ from json import loads
import twill.commands as tc
from mercurial import commands, hg, ui
from mercurial.util import Abort
import galaxy.model.tool_shed_install as galaxy_model
import galaxy.util
@@ -259,20 +258,17 @@ class ShedTwillTestCase( TwillTestCase ):
def commit_and_push( self, repository, hgrepo, options, username, password ):
url = 'http://%s:%s@%s:%s/repos/%s/%s' % ( username, password, self.host, self.port, repository.user.username, repository.name )
commands.commit( ui.ui(), hgrepo, **options )
try:
commands.push( ui.ui(), hgrepo, dest=url )
except Abort as a:
message = a
if 'authorization failed' in message:
return False
# Try pushing multiple times as it transiently fails on Jenkins.
# TODO: Figure out why that happens
for i in range(2):
try:
commands.push( ui.ui(), hgrepo, dest=url )
except Exception as e:
if str(e).find('Pushing to Tool Shed is disabled') != -1:
return False
else:
raise
except Exception as e:
if str(e).find('Pushing to Tool Shed is disabled') != -1:
return False
else:
raise
return True
return True
raise
def create_category( self, **kwd ):
category = test_db_util.get_category_by_name( kwd[ 'name' ] )
+5 -2
View File
@@ -85,7 +85,7 @@ def add_file( dataset, registry, json_file, output_path ):
stdout = None
link_data_only = dataset.get( 'link_data_only', 'copy_files' )
in_place = dataset.get( 'in_place', True )
purge_source = dataset.get( 'purge_source', True )
try:
ext = dataset.file_type
except AttributeError:
@@ -329,7 +329,10 @@ def add_file( dataset, registry, json_file, output_path ):
# This should not happen, but it's here just in case
shutil.copy( dataset.path, output_path )
elif link_data_only == 'copy_files':
shutil.move( dataset.path, output_path )
if purge_source:
shutil.move( dataset.path, output_path )
else:
shutil.copy( dataset.path, output_path )
# Write the job info
stdout = stdout or 'uploaded %s file' % data_type
info = dict( type='dataset',
+14 -13
View File
@@ -38,19 +38,20 @@ def main():
round_val = []
if sys.argv[5] != "None":
oldfile = open(inputfile, 'r')
oldfilelines = oldfile.readlines()
newinputfile = "input_cleaned.tsv"
newfile = open(newinputfile, 'w')
asciitodelete = sys.argv[5].split(',')
for i in range(len(asciitodelete)):
asciitodelete[i] = chr(int(asciitodelete[i]))
for line in oldfilelines:
if line[0] not in asciitodelete:
newfile.write(line)
oldfile.close()
newfile.close()
inputfile = newinputfile
asciitodelete = sys.argv[5]
if asciitodelete:
oldfile = open(inputfile, 'r')
newinputfile = "input_cleaned.tsv"
newfile = open(newinputfile, 'w')
asciitodelete = asciitodelete.split(',')
for i in range(len(asciitodelete)):
asciitodelete[i] = chr(int(asciitodelete[i]))
for line in oldfile:
if line[0] not in asciitodelete:
newfile.write(line)
oldfile.close()
newfile.close()
inputfile = newinputfile
for var in sys.argv[6:]:
op, col, do_round = var.split()
+6 -6
View File
@@ -1,12 +1,12 @@
<tool id="Grouping1" name="Group" version="2.1.0">
<tool id="Grouping1" name="Group" version="2.1.1">
<description>data by a column and perform aggregate operation on other columns.</description>
<command interpreter="python">
grouping.py
$out_file1
$input1
$groupcol
$ignorecase
$ignorelines
"${out_file1}"
"${input1}"
"${groupcol}"
"${ignorecase}"
"${ignorelines}"
#for $op in $operations
'${op.optype}
${op.opcol}