Merge branch 'dev' into registration_mako

This commit is contained in:
guerler
2019-01-22 00:08:52 -05:00
19 changed files with 169 additions and 172 deletions
@@ -483,8 +483,7 @@ var HistoryViewEdit = _super.extend(
this.$list().before([this._renderDropTargetHelp(), $dropTarget]);
for (var evName in dropHandlers) {
if (dropHandlers.hasOwnProperty(evName)) {
//console.debug( evName, dropHandlers[ evName ] );
$dropTarget.on(evName, dropHandlers[evName]);
$dropTarget.get(0).addEventListener(evName, dropHandlers[evName]);
}
}
return this;
@@ -551,8 +550,7 @@ var HistoryViewEdit = _super.extend(
drop: function(ev) {
ev.preventDefault();
//ev.stopPropagation();
var dataTransfer = ev.originalEvent.dataTransfer;
var dataTransfer = ev.dataTransfer;
var data = dataTransfer.getData("text");
dataTransfer.dropEffect = "move";
@@ -187,7 +187,7 @@ class Workflow {
id: node.id,
type: node.type,
content_id: node.content_id,
tool_version: node.config_form.version,
tool_version: node.config_form ? node.config_form.version : null,
tool_state: node.tool_state,
errors: node.errors,
input_connections: input_connections,
+1 -1
View File
@@ -248,7 +248,7 @@ class LibraryActions(object):
uploaded_dataset.dbkey = params.get('dbkey', None)
uploaded_dataset.to_posix_lines = params.get('to_posix_lines', None)
uploaded_dataset.space_to_tab = params.get('space_to_tab', None)
uploaded_dataset.tag_using_filenames = params.get('tag_using_filenames', True)
uploaded_dataset.tag_using_filenames = params.get('tag_using_filenames', False)
uploaded_dataset.purge_source = getattr(trans.app.config, 'ftp_upload_purge', True)
if in_folder:
uploaded_dataset.in_folder = in_folder
+1 -1
View File
@@ -430,7 +430,7 @@ class Data(object):
else:
trans.response.set_content_type("text/html")
return trans.stream_template_mako("/dataset/large_file.mako",
truncated_data=open(data.file_name).read(max_peek_size),
truncated_data=open(data.file_name, 'rb').read(max_peek_size),
data=data)
def _yield_user_file_content(self, trans, from_dataset, filename):
+1 -1
View File
@@ -68,7 +68,7 @@ class GenomeGraphs(Tabular):
"""
Returns file
"""
return open(dataset.file_name, 'r')
return open(dataset.file_name, 'rb')
def ucsc_links(self, dataset, type, app, base_url):
"""
+102 -122
View File
@@ -100,42 +100,38 @@ class Interval(Tabular):
else:
# Header lines in Interval files are optional. For example, BED is Interval but has no header.
# We'll make a best guess at the location of the metadata columns.
metadata_is_set = False
elems = line.split('\t')
if len(elems) > 2:
for str in data.col1_startswith:
if line.lower().startswith(str):
if overwrite or not dataset.metadata.element_is_set('chromCol'):
dataset.metadata.chromCol = 1
try:
int(elems[1])
if overwrite or not dataset.metadata.element_is_set('startCol'):
dataset.metadata.startCol = 2
except Exception:
pass # Metadata default will be used
try:
int(elems[2])
if overwrite or not dataset.metadata.element_is_set('endCol'):
dataset.metadata.endCol = 3
except Exception:
pass # Metadata default will be used
# we no longer want to guess that this column is the 'name', name must now be set manually for interval files
# we will still guess at the strand, as we can make a more educated guess
# if len( elems ) > 3:
# try:
# int( elems[3] )
# except Exception:
# if overwrite or not dataset.metadata.element_is_set( 'nameCol' ):
# dataset.metadata.nameCol = 4
if len(elems) < 6 or elems[5] not in data.valid_strand:
if overwrite or not dataset.metadata.element_is_set('strandCol'):
dataset.metadata.strandCol = 0
else:
if overwrite or not dataset.metadata.element_is_set('strandCol'):
dataset.metadata.strandCol = 6
metadata_is_set = True
break
if metadata_is_set or (i - empty_line_count) > num_check_lines:
if overwrite or not dataset.metadata.element_is_set('chromCol'):
dataset.metadata.chromCol = 1
try:
int(elems[1])
if overwrite or not dataset.metadata.element_is_set('startCol'):
dataset.metadata.startCol = 2
except Exception:
pass # Metadata default will be used
try:
int(elems[2])
if overwrite or not dataset.metadata.element_is_set('endCol'):
dataset.metadata.endCol = 3
except Exception:
pass # Metadata default will be used
# we no longer want to guess that this column is the 'name', name must now be set manually for interval files
# we will still guess at the strand, as we can make a more educated guess
# if len( elems ) > 3:
# try:
# int( elems[3] )
# except Exception:
# if overwrite or not dataset.metadata.element_is_set( 'nameCol' ):
# dataset.metadata.nameCol = 4
if len(elems) < 6 or elems[5] not in data.valid_strand:
if overwrite or not dataset.metadata.element_is_set('strandCol'):
dataset.metadata.strandCol = 0
else:
if overwrite or not dataset.metadata.element_is_set('strandCol'):
dataset.metadata.strandCol = 6
break
if (i - empty_line_count) > num_check_lines:
break # Our metadata is set or we examined 100 non-empty lines, so break out of the outer loop
else:
empty_line_count += 1
@@ -238,7 +234,7 @@ class Interval(Tabular):
for elems in util.file_iter(dataset.file_name):
tmp = [elems[c], elems[s], elems[e]]
fh.write('%s\n' % '\t'.join(tmp))
return open(fh.name)
return open(fh.name, 'rb')
def display_peek(self, dataset):
"""Returns formated html of peek"""
@@ -371,7 +367,7 @@ class BedGraph(Interval):
Returns file contents as is with no modifications.
TODO: this is a functional stub and will need to be enhanced moving forward to provide additional support for bedgraph.
"""
return open(dataset.file_name)
return open(dataset.file_name, 'rb')
def get_estimated_display_viewport(self, dataset, chrom_col=0, start_col=1, end_col=2):
"""
@@ -403,26 +399,20 @@ class Bed(Interval):
i = 0
if dataset.has_data():
for i, line in enumerate(open(dataset.file_name)):
metadata_set = False
line = line.rstrip('\r\n')
if line and not line.startswith('#'):
elems = line.split('\t')
if len(elems) > 2:
for startswith in data.col1_startswith:
if line.lower().startswith(startswith):
if len(elems) > 3:
if overwrite or not dataset.metadata.element_is_set('nameCol'):
dataset.metadata.nameCol = 4
if len(elems) < 6:
if overwrite or not dataset.metadata.element_is_set('strandCol'):
dataset.metadata.strandCol = 0
else:
if overwrite or not dataset.metadata.element_is_set('strandCol'):
dataset.metadata.strandCol = 6
metadata_set = True
break
if metadata_set:
break
if len(elems) > 3:
if overwrite or not dataset.metadata.element_is_set('nameCol'):
dataset.metadata.nameCol = 4
if len(elems) < 6:
if overwrite or not dataset.metadata.element_is_set('strandCol'):
dataset.metadata.strandCol = 0
else:
if overwrite or not dataset.metadata.element_is_set('strandCol'):
dataset.metadata.strandCol = 6
break
Tabular.set_meta(self, dataset, overwrite=overwrite, skip=i)
def as_ucsc_display_file(self, dataset, **kwd):
@@ -459,7 +449,7 @@ class Bed(Interval):
break
try:
return open(dataset.file_name)
return open(dataset.file_name, 'rb')
except Exception:
return "This item contains no content"
@@ -494,75 +484,67 @@ class Bed(Interval):
for hdr in headers:
if hdr[0] == '':
continue
valid_col1 = False
if len(hdr) < 3 or len(hdr) > 12:
return False
for str in data.col1_startswith:
if hdr[0].lower().startswith(str):
valid_col1 = True
break
if valid_col1:
try:
int(hdr[1])
int(hdr[2])
except Exception:
return False
if len(hdr) > 4:
# hdr[3] is a string, 'name', which defines the name of the BED line - difficult to test for this.
# hdr[4] is an int, 'score', a score between 0 and 1000.
try:
int(hdr[1])
int(hdr[2])
if int(hdr[4]) < 0 or int(hdr[4]) > 1000:
return False
except Exception:
return False
if len(hdr) > 4:
# hdr[3] is a string, 'name', which defines the name of the BED line - difficult to test for this.
# hdr[4] is an int, 'score', a score between 0 and 1000.
if len(hdr) > 5:
# hdr[5] is strand
if hdr[5] not in data.valid_strand:
return False
if len(hdr) > 6:
# hdr[6] is thickStart, the starting position at which the feature is drawn thickly.
try:
int(hdr[6])
except Exception:
return False
if len(hdr) > 7:
# hdr[7] is thickEnd, the ending position at which the feature is drawn thickly
try:
int(hdr[7])
except Exception:
return False
if len(hdr) > 8:
# hdr[8] is itemRgb, an RGB value of the form R,G,B (e.g. 255,0,0). However, this could also be an int (e.g., 0)
try:
int(hdr[8])
except Exception:
try:
if int(hdr[4]) < 0 or int(hdr[4]) > 1000:
return False
hdr[8].split(',')
except Exception:
return False
if len(hdr) > 5:
# hdr[5] is strand
if hdr[5] not in data.valid_strand:
return False
if len(hdr) > 6:
# hdr[6] is thickStart, the starting position at which the feature is drawn thickly.
try:
int(hdr[6])
except Exception:
return False
if len(hdr) > 7:
# hdr[7] is thickEnd, the ending position at which the feature is drawn thickly
try:
int(hdr[7])
except Exception:
return False
if len(hdr) > 8:
# hdr[8] is itemRgb, an RGB value of the form R,G,B (e.g. 255,0,0). However, this could also be an int (e.g., 0)
try:
int(hdr[8])
except Exception:
try:
hdr[8].split(',')
except Exception:
return False
if len(hdr) > 9:
# hdr[9] is blockCount, the number of blocks (exons) in the BED line.
try:
block_count = int(hdr[9])
except Exception:
return False
if len(hdr) > 10:
# hdr[10] is blockSizes - A comma-separated list of the block sizes.
# Sometimes the blosck_sizes and block_starts lists end in extra commas
try:
block_sizes = hdr[10].rstrip(',').split(',')
except Exception:
return False
if len(hdr) > 11:
# hdr[11] is blockStarts - A comma-separated list of block starts.
try:
block_starts = hdr[11].rstrip(',').split(',')
except Exception:
return False
if len(block_sizes) != block_count or len(block_starts) != block_count:
return False
else:
return False
if len(hdr) > 9:
# hdr[9] is blockCount, the number of blocks (exons) in the BED line.
try:
block_count = int(hdr[9])
except Exception:
return False
if len(hdr) > 10:
# hdr[10] is blockSizes - A comma-separated list of the block sizes.
# Sometimes the blosck_sizes and block_starts lists end in extra commas
try:
block_sizes = hdr[10].rstrip(',').split(',')
except Exception:
return False
if len(hdr) > 11:
# hdr[11] is blockStarts - A comma-separated list of block starts.
try:
block_starts = hdr[11].rstrip(',').split(',')
except Exception:
return False
if len(block_sizes) != block_count or len(block_starts) != block_count:
return False
return True
except Exception:
return False
@@ -1201,16 +1183,14 @@ class Wiggle(Tabular, _RemoteCallMixin):
if line and not line.startswith('#'):
elems = line.split('\t')
try:
float(elems[0]) # "Wiggle track data values can be integer or real, positive or negative values"
# variableStep format is nucleotide position\tvalue\n,
# fixedStep is value\n
# "Wiggle track data values can be integer or real, positive or negative values"
float(elems[0])
break
except Exception:
do_break = False
for col_startswith in data.col1_startswith:
if elems[0].lower().startswith(col_startswith):
do_break = True
break
if do_break:
break
# We are either in the track definition line or in a declaration line
pass
if self.max_optional_metadata_filesize >= 0 and dataset.get_size() > self.max_optional_metadata_filesize:
# we'll arbitrarily only use the first 100 data lines in this wig file to calculate tabular attributes (column types)
# this should be sufficient, except when we have mixed wig track types (bed, variable, fixed),
+11 -19
View File
@@ -199,27 +199,19 @@ def convert_newlines_sep2tabs(fname, in_place=True, patt=r"\s+", tmp_dir=None, t
def iter_headers(fname_or_file_prefix, sep, count=60, comment_designator=None):
idx = 0
if isinstance(fname_or_file_prefix, FilePrefix):
idx = 0
for line in fname_or_file_prefix.line_iterator():
line = line.rstrip('\n\r')
if comment_designator is not None and comment_designator != '' and line.startswith(comment_designator):
continue
yield line.split(sep)
idx += 1
if idx == count:
break
file_iterator = fname_or_file_prefix.line_iterator()
else:
with compression_utils.get_fileobj(fname_or_file_prefix) as in_file:
idx = 0
for line in in_file:
line = line.rstrip('\n\r')
if comment_designator is not None and comment_designator != '' and line.startswith(comment_designator):
continue
yield line.split(sep)
idx += 1
if idx == count:
break
file_iterator = compression_utils.get_fileobj(fname_or_file_prefix)
for line in file_iterator:
line = line.rstrip('\n\r')
if comment_designator is not None and comment_designator != '' and line.startswith(comment_designator):
continue
yield line.split(sep)
idx += 1
if idx == count:
break
def get_headers(fname_or_file_prefix, sep, count=60, comment_designator=None):
+2 -2
View File
@@ -394,10 +394,10 @@ class Tabular(TabularData):
dataset.metadata.delimiter = '\t'
def as_gbrowse_display_file(self, dataset, **kwd):
return open(dataset.file_name)
return open(dataset.file_name, 'rb')
def as_ucsc_display_file(self, dataset, **kwd):
return open(dataset.file_name)
return open(dataset.file_name, 'rb')
class Taxonomy(Tabular):
+4
View File
@@ -103,6 +103,10 @@ class ToolMissingException(MessageException):
status_code = 400
err_code = error_codes.USER_TOOL_MISSING_PROBLEM
def __init__(self, err_msg=None, type="info", tool_id=None, **extra_error_info):
super(ToolMissingException, self).__init__(err_msg, type, **extra_error_info)
self.tool_id = tool_id
class RequestParameterInvalidException(MessageException):
status_code = 400
+4 -3
View File
@@ -505,9 +505,10 @@ class WorkflowContentsManager(UsesAnnotations):
for step in workflow.steps:
try:
module_injector.inject(step, steps=workflow.steps, exact_tools=False)
except exceptions.ToolMissingException:
if step.tool_id not in missing_tools:
missing_tools.append(step.tool_id)
except exceptions.ToolMissingException as e:
# FIXME: if a subworkflow lacks multiple tools we report only the first missing tool
if e.tool_id not in missing_tools:
missing_tools.append(e.tool_id)
continue
if step.upgrade_messages:
has_upgrade_messages = True
@@ -230,6 +230,8 @@ class LibraryContentsController(BaseAPIController, UsesLibraryMixin, UsesLibrary
# The rest of the security happens in the library_common controller.
real_folder_id = trans.security.encode_id(parent.id)
payload['tag_using_filenames'] = util.string_as_bool(payload.get('tag_using_filenames', None))
# are we copying an HDA to the library folder?
# we'll need the id and any message to attach, then branch to that private function
from_hda_id, from_hdca_id, ldda_message = (payload.pop('from_hda_id', None), payload.pop('from_hdca_id', None), payload.pop('ldda_message', ''))
@@ -706,7 +706,7 @@ class LibraryDatasetsController(BaseAPIController, UsesVisualizationMixin, Libra
fname = ''.join(c in util.FILENAME_VALID_CHARS and c or '_' for c in fname)[0:150]
trans.response.headers["Content-Disposition"] = 'attachment; filename="%s"' % fname
try:
return open(dataset.file_name)
return open(dataset.file_name, 'rb')
except Exception:
raise exceptions.InternalServerError("This dataset contains no content.")
else:
@@ -276,7 +276,7 @@ class AdminToolshed(AdminGalaxy):
mimetype = trans.app.datatypes_registry.get_mimetype_by_extension(extension)
if mimetype:
trans.response.set_content_type(mimetype)
return open(path_to_file, 'r')
return open(path_to_file, 'rb')
return None
@web.expose
@@ -186,7 +186,7 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
file_ext = data.metadata.spec.get(metadata_name).get("file_ext", metadata_name)
trans.response.headers["Content-Type"] = "application/octet-stream"
trans.response.headers["Content-Disposition"] = 'attachment; filename="Galaxy%s-[%s].%s"' % (data.hid, fname, file_ext)
return open(data.metadata.get(metadata_name).file_name)
return open(data.metadata.get(metadata_name).file_name, 'rb')
def _check_dataset(self, trans, hda_id):
# DEPRECATION: We still support unencoded ids for backward compatibility
@@ -677,7 +677,7 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
# TODO: figure out a way to display images in display template.
if isinstance(dataset.datatype, datatypes.binary.Binary) or isinstance(dataset.datatype, datatypes.images.Image) or isinstance(dataset.datatype, datatypes.text.Html):
trans.response.set_content_type(dataset.get_mime())
return open(dataset.file_name)
return open(dataset.file_name, 'rb')
else:
# Get rating data.
user_item_rating = 0
@@ -216,7 +216,7 @@ class RootController(controller.JSAppLauncher, UsesAnnotations):
trans.response.headers["Content-Disposition"] = 'attachment; filename="GalaxyHistoryItem-%s-[%s]%s"' % (data.hid, fname, toext)
trans.log_event("Display dataset id: %s" % str(id))
try:
return open(data.file_name)
return open(data.file_name, 'rb')
except Exception:
return "This dataset contains no content"
else:
@@ -601,7 +601,7 @@ class WorkflowController(BaseUIController, SharableMixin, UsesStoredWorkflowMixi
session.flush()
try:
workflow, errors = workflow_contents_manager.update_workflow_from_dict(
workflow, errors = workflow_contents_manager.update_workflow_from_raw_description(
trans,
stored_workflow,
workflow_data,
@@ -870,7 +870,7 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
mimetype = trans.app.datatypes_registry.get_mimetype_by_extension(extension)
if mimetype:
trans.response.set_content_type(mimetype)
return open(path_to_file, 'r')
return open(path_to_file, 'rb')
return None
@web.expose
+30 -10
View File
@@ -144,7 +144,7 @@ class WorkflowModule(object):
else:
self.state.inputs = safe_loads(state) or {}
def get_errors(self):
def get_errors(self, **kwargs):
""" This returns a step related error message as string or None """
return None
@@ -414,6 +414,16 @@ class SubWorkflowModule(WorkflowModule):
inputs.append(input)
return inputs
def get_modules(self):
return [module_factory.from_workflow_step(self.trans, step) for step in self.subworkflow.steps]
def get_errors(self, **kwargs):
errors = (module.get_errors(include_tool_id=True) for module in self.get_modules())
errors = [e for e in errors if e]
if any(errors):
return errors
return None
def get_all_outputs(self, data_only=False):
outputs = []
if hasattr(self.subworkflow, 'workflow_outputs'):
@@ -425,20 +435,23 @@ class SubWorkflowModule(WorkflowModule):
tooltip=False)
for order_index in sorted(subworkflow_dict['steps']):
step = subworkflow_dict['steps'][order_index]
data_outputs = subworkflow_dict['steps'][order_index]['outputs']
data_outputs = step['outputs']
for workflow_output in step['workflow_outputs']:
label = workflow_output['label']
if not label:
label = "%s:%s" % (order_index, workflow_output['output_name'])
for data_output in data_outputs:
if data_output['name'] == workflow_output['output_name']:
if data_output['name'] == workflow_output['output_name'] or data_output['uuid'] == workflow_output['uuid']:
data_output['label'] = label
data_output['name'] = label
# That's the right data_output
break
else:
# This hopefully can't happen, but let's be clear
raise Exception("Workflow output '%s' defined, but not listed among data outputs" % workflow_output['output_name'])
# This can happen when importing workflows with missing tools.
# We can't raise an exception here, as that would prevent loading
# the workflow.
log.error("Workflow output '%s' defined, but not listed among data outputs" % workflow_output['output_name'])
continue
outputs.append(data_output)
return outputs
@@ -841,8 +854,12 @@ class ToolModule(WorkflowModule):
# ---- Configuration time -----------------------------------------------
def get_errors(self):
return None if self.tool else "Tool is not installed."
def get_errors(self, include_tool_id=False, **kwargs):
if not self.tool:
if include_tool_id:
return "%s is not installed" % self.tool_id
else:
return "Tool is not installed"
def get_inputs(self):
return self.tool.inputs if self.tool else {}
@@ -982,7 +999,8 @@ class ToolModule(WorkflowModule):
return ConnectedValue()
visit_input_values(self.tool.inputs, self.state.inputs, callback)
else:
raise ToolMissingException("Tool %s missing. Cannot add dummy datasets." % self.tool_id)
raise ToolMissingException("Tool %s missing. Cannot add dummy datasets." % self.tool_id,
tool_id=self.tool_id)
def get_post_job_actions(self, incoming):
return ActionBox.handle_incoming(incoming)
@@ -1082,7 +1100,8 @@ class ToolModule(WorkflowModule):
state.inputs[RUNTIME_STEP_META_STATE_KEY] = step_metadata_runtime_state
return state, step_errors
else:
raise ToolMissingException("Tool %s missing. Cannot compute runtime state." % self.tool_id)
raise ToolMissingException("Tool %s missing. Cannot compute runtime state." % self.tool_id,
tool_id=self.tool_id)
def decode_runtime_state(self, runtime_state):
""" Take runtime state from persisted invocation and convert it
@@ -1094,7 +1113,8 @@ class ToolModule(WorkflowModule):
self.__restore_step_meta_runtime_state(loads(runtime_state[RUNTIME_STEP_META_STATE_KEY]))
return state
else:
raise ToolMissingException("Tool %s missing. Cannot recover runtime state." % self.tool_id)
raise ToolMissingException("Tool %s missing. Cannot recover runtime state." % self.tool_id,
tool_id=self.tool_id)
def execute(self, trans, progress, invocation_step, use_cached_job=False):
invocation = invocation_step.workflow_invocation
+1 -1
View File
@@ -89,7 +89,7 @@ def __main__():
if not URL_method or URL_method == 'get':
page = urlopen(cur_URL)
elif URL_method == 'post':
page = urlopen(cur_URL, urlencode(params))
page = urlopen(cur_URL, urlencode(params).encode("utf-8"))
except Exception as e:
stop_err('The remote data source application may be off line, please try again later. Error: %s' % str(e))
if max_file_size: