galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
7 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/045da9050e44/
Changeset: 045da9050e44
Branch: workflow_params
User: simleo
Date: 2014-01-30 12:15:55
Summary: Created new branch workflow_params
Affected #: 0 files
https://bitbucket.org/galaxy/galaxy-central/commits/cb881765cb99/
Changeset: cb881765cb99
Branch: workflow_params
User: simleo
Date: 2014-01-30 12:18:58
Summary: changed step_id passing convention in the workflows API
Affected #: 1 file
diff -r 045da9050e4489f7f559ec0e106790410856e35d -r cb881765cb992eb4aff08d8d62a74f2ca6dfa5de lib/galaxy/webapps/galaxy/api/workflows.py
--- a/lib/galaxy/webapps/galaxy/api/workflows.py
+++ b/lib/galaxy/webapps/galaxy/api/workflows.py
@@ -214,19 +214,12 @@
step.state = step.module.state
# Update step parameters as directed by payload's parameter mapping.
- if step.tool_id in param_map:
- param_dict = param_map[ step.tool_id ]
- step_id = param_dict.get( 'step_id', '' )
-
+ param_dict = param_map.get(str(step.id), param_map.get(step.tool_id))
+ if param_dict is not None:
# Backward compatibility: convert param/value dict to new 'name': 'value' format.
if 'param' in param_dict and 'value' in param_dict:
param_dict[ param_dict['param'] ] = param_dict['value']
-
- # Update step if there's no step id (i.e. all steps with tool are
- # updated) or update if step ids match.
- if not step_id or ( step_id and int( step_id ) == step.id ):
- for name, value in param_dict.items():
- step.state.inputs[ name ] = value
+ step.state.inputs.update(param_dict)
if step.tool_errors:
trans.response.status = 400
https://bitbucket.org/galaxy/galaxy-central/commits/713b2604e8ce/
Changeset: 713b2604e8ce
Branch: workflow_params
User: simleo
Date: 2014-02-02 14:21:49
Summary: workflow API: more flexible step parameter updating
Affected #: 1 file
diff -r cb881765cb992eb4aff08d8d62a74f2ca6dfa5de -r 713b2604e8cec21b762222cc193b17d057eb680e lib/galaxy/webapps/galaxy/api/workflows.py
--- a/lib/galaxy/webapps/galaxy/api/workflows.py
+++ b/lib/galaxy/webapps/galaxy/api/workflows.py
@@ -19,6 +19,39 @@
log = logging.getLogger(__name__)
+def _update_step_parameters(step, param_map):
+ """
+ Update ``step`` parameters based on the user-provided ``param_map`` dict.
+
+ ``param_map`` should be structured as follows::
+
+ PARAM_MAP = {STEP_ID: PARAM_DICT, ...}
+ PARAM_DICT = {NAME: VALUE, ...}
+
+ For backwards compatibility, the following (deprecated) formats is
+ also supported for ``param_map``::
+
+ PARAM_MAP = {TOOL_ID: PARAM_DICT, ...}
+
+ in which case PARAM_DICT affects all steps with the given tool id.
+ If both by-tool-id and by-step-id specifications are used, the
+ latter takes precedence.
+
+ Finally (again, for backwards compatibility), PARAM_DICT can also
+ be specified as::
+
+ PARAM_DICT = {'param': NAME, 'value': VALUE}
+
+ Note that this format allows only one parameter to be set per step.
+ """
+ param_dict = param_map.get(step.tool_id, {}).copy()
+ param_dict.update(param_map.get(str(step.id), {}))
+ if param_dict:
+ if 'param' in param_dict and 'value' in param_dict:
+ param_dict[param_dict['param']] = param_dict['value']
+ step.state.inputs.update(param_dict)
+
+
class WorkflowsAPIController(BaseAPIController, UsesStoredWorkflowMixin):
@web.expose_api
@@ -212,15 +245,7 @@
# are not persisted so we need to do it every time)
step.module.add_dummy_datasets( connections=step.input_connections )
step.state = step.module.state
-
- # Update step parameters as directed by payload's parameter mapping.
- param_dict = param_map.get(str(step.id), param_map.get(step.tool_id))
- if param_dict is not None:
- # Backward compatibility: convert param/value dict to new 'name': 'value' format.
- if 'param' in param_dict and 'value' in param_dict:
- param_dict[ param_dict['param'] ] = param_dict['value']
- step.state.inputs.update(param_dict)
-
+ _update_step_parameters(step, param_map)
if step.tool_errors:
trans.response.status = 400
return "Workflow cannot be run because of validation errors in some steps: %s" % step_errors
https://bitbucket.org/galaxy/galaxy-central/commits/d8a1b16c94e2/
Changeset: d8a1b16c94e2
Branch: workflow_params
User: simleo
Date: 2014-02-02 14:35:57
Summary: fixed a typo
Affected #: 1 file
diff -r 713b2604e8cec21b762222cc193b17d057eb680e -r d8a1b16c94e26e89be0ce0d1b3b696be4ac7957e lib/galaxy/webapps/galaxy/api/workflows.py
--- a/lib/galaxy/webapps/galaxy/api/workflows.py
+++ b/lib/galaxy/webapps/galaxy/api/workflows.py
@@ -28,7 +28,7 @@
PARAM_MAP = {STEP_ID: PARAM_DICT, ...}
PARAM_DICT = {NAME: VALUE, ...}
- For backwards compatibility, the following (deprecated) formats is
+ For backwards compatibility, the following (deprecated) format is
also supported for ``param_map``::
PARAM_MAP = {TOOL_ID: PARAM_DICT, ...}
https://bitbucket.org/galaxy/galaxy-central/commits/19bff78d5c91/
Changeset: 19bff78d5c91
User: jmchilton
Date: 2014-02-03 00:44:50
Summary: Merge pull request #317.
Affected #: 1 file
diff -r 6788cffb792bc88bb6cfb3a15aff1d29a8c4a700 -r 19bff78d5c91db39a34cc18ea467faf7e5129736 lib/galaxy/webapps/galaxy/api/workflows.py
--- a/lib/galaxy/webapps/galaxy/api/workflows.py
+++ b/lib/galaxy/webapps/galaxy/api/workflows.py
@@ -19,6 +19,39 @@
log = logging.getLogger(__name__)
+def _update_step_parameters(step, param_map):
+ """
+ Update ``step`` parameters based on the user-provided ``param_map`` dict.
+
+ ``param_map`` should be structured as follows::
+
+ PARAM_MAP = {STEP_ID: PARAM_DICT, ...}
+ PARAM_DICT = {NAME: VALUE, ...}
+
+ For backwards compatibility, the following (deprecated) format is
+ also supported for ``param_map``::
+
+ PARAM_MAP = {TOOL_ID: PARAM_DICT, ...}
+
+ in which case PARAM_DICT affects all steps with the given tool id.
+ If both by-tool-id and by-step-id specifications are used, the
+ latter takes precedence.
+
+ Finally (again, for backwards compatibility), PARAM_DICT can also
+ be specified as::
+
+ PARAM_DICT = {'param': NAME, 'value': VALUE}
+
+ Note that this format allows only one parameter to be set per step.
+ """
+ param_dict = param_map.get(step.tool_id, {}).copy()
+ param_dict.update(param_map.get(str(step.id), {}))
+ if param_dict:
+ if 'param' in param_dict and 'value' in param_dict:
+ param_dict[param_dict['param']] = param_dict['value']
+ step.state.inputs.update(param_dict)
+
+
class WorkflowsAPIController(BaseAPIController, UsesStoredWorkflowMixin):
@web.expose_api
@@ -212,22 +245,7 @@
# are not persisted so we need to do it every time)
step.module.add_dummy_datasets( connections=step.input_connections )
step.state = step.module.state
-
- # Update step parameters as directed by payload's parameter mapping.
- if step.tool_id in param_map:
- param_dict = param_map[ step.tool_id ]
- step_id = param_dict.get( 'step_id', '' )
-
- # Backward compatibility: convert param/value dict to new 'name': 'value' format.
- if 'param' in param_dict and 'value' in param_dict:
- param_dict[ param_dict['param'] ] = param_dict['value']
-
- # Update step if there's no step id (i.e. all steps with tool are
- # updated) or update if step ids match.
- if not step_id or ( step_id and int( step_id ) == step.id ):
- for name, value in param_dict.items():
- step.state.inputs[ name ] = value
-
+ _update_step_parameters(step, param_map)
if step.tool_errors:
trans.response.status = 400
return "Workflow cannot be run because of validation errors in some steps: %s" % step_errors
https://bitbucket.org/galaxy/galaxy-central/commits/0f636b29e4f5/
Changeset: 0f636b29e4f5
User: jmchilton
Date: 2014-02-03 00:54:28
Summary: Workflow API functional testing - parameter replacement.
Test parameter replacement while running workflows - both by tool id (deprecated) and new post pull request #317 replacement by step id.
Affected #: 3 files
diff -r 19bff78d5c91db39a34cc18ea467faf7e5129736 -r 0f636b29e4f58d1568e8658dcae57e3c45a14563 test/functional/api/helpers.py
--- a/test/functional/api/helpers.py
+++ b/test/functional/api/helpers.py
@@ -3,7 +3,11 @@
from json import loads
from pkg_resources import resource_string
+# Simple workflow that takes an input and call cat wrapper on it.
workflow_str = resource_string( __name__, "test_workflow_1.ga" )
+# Simple workflow that takes an input and filters with random lines twice in a
+# row - first grabbing 8 lines at random and then 6.
+workflow_random_x2_str = resource_string( __name__, "test_workflow_2.ga" )
class TestsDatasets:
@@ -68,8 +72,8 @@
def __init__( self, api_test_case ):
self.api_test_case = api_test_case
- def load_workflow( self, name, add_pja=False ):
- workflow = loads( workflow_str )
+ def load_workflow( self, name, content=workflow_str, add_pja=False ):
+ workflow = loads( content )
workflow[ "name" ] = name
if add_pja:
tool_step = workflow[ "steps" ][ "2" ]
@@ -80,6 +84,9 @@
)
return workflow
+ def load_random_x2_workflow( self, name ):
+ return self.load_workflow( name, content=workflow_random_x2_str )
+
def simple_workflow( self, name, **create_kwds ):
workflow = self.load_workflow( name )
return self.create_workflow( workflow, **create_kwds )
diff -r 19bff78d5c91db39a34cc18ea467faf7e5129736 -r 0f636b29e4f58d1568e8658dcae57e3c45a14563 test/functional/api/test_workflow_2.ga
--- /dev/null
+++ b/test/functional/api/test_workflow_2.ga
@@ -0,0 +1,89 @@
+{
+ "a_galaxy_workflow": "true",
+ "annotation": "",
+ "format-version": "0.1",
+ "name": "random_lines_x2",
+ "steps": {
+ "0": {
+ "annotation": "",
+ "id": 0,
+ "input_connections": {},
+ "inputs": [
+ {
+ "description": "",
+ "name": "Input Dataset"
+ }
+ ],
+ "name": "Input dataset",
+ "outputs": [],
+ "position": {
+ "left": 10,
+ "top": 10
+ },
+ "tool_errors": null,
+ "tool_id": null,
+ "tool_state": "{\"name\": \"Input Dataset\"}",
+ "tool_version": null,
+ "type": "data_input",
+ "user_outputs": []
+ },
+ "1": {
+ "annotation": "",
+ "id": 1,
+ "input_connections": {
+ "input": {
+ "id": 0,
+ "output_name": "output"
+ }
+ },
+ "inputs": [],
+ "name": "Select random lines",
+ "outputs": [
+ {
+ "name": "out_file1",
+ "type": "input"
+ }
+ ],
+ "position": {
+ "left": 230,
+ "top": 10
+ },
+ "post_job_actions": {},
+ "tool_errors": null,
+ "tool_id": "random_lines1",
+ "tool_state": "{\"__page__\": 0, \"num_lines\": \"\\\"8\\\"\", \"seed_source\": \"{\\\"__current_case__\\\": 0, \\\"seed_source_selector\\\": \\\"no_seed\\\"}\", \"input\": \"null\", \"chromInfo\": \"\\\"/home/john/workspace/galaxy-central-workflows-params/tool-data/shared/ucsc/chrom/?.len\\\"\", \"__rerun_remap_job_id__\": null}",
+ "tool_version": null,
+ "type": "tool",
+ "user_outputs": []
+ },
+ "2": {
+ "annotation": "",
+ "id": 2,
+ "input_connections": {
+ "input": {
+ "id": 1,
+ "output_name": "out_file1"
+ }
+ },
+ "inputs": [],
+ "name": "Select random lines",
+ "outputs": [
+ {
+ "name": "out_file1",
+ "type": "input"
+ }
+ ],
+ "position": {
+ "left": 450,
+ "top": 10
+ },
+ "post_job_actions": {},
+ "tool_errors": null,
+ "tool_id": "random_lines1",
+ "tool_state": "{\"__page__\": 0, \"num_lines\": \"\\\"6\\\"\", \"seed_source\": \"{\\\"__current_case__\\\": 0, \\\"seed_source_selector\\\": \\\"no_seed\\\"}\", \"input\": \"null\", \"chromInfo\": \"\\\"/home/john/workspace/galaxy-central-workflows-params/tool-data/shared/ucsc/chrom/?.len\\\"\", \"__rerun_remap_job_id__\": null}",
+ "tool_version": null,
+ "type": "tool",
+ "user_outputs": []
+ }
+ }
+}
\ No newline at end of file
diff -r 19bff78d5c91db39a34cc18ea467faf7e5129736 -r 0f636b29e4f58d1568e8658dcae57e3c45a14563 test/functional/api/test_workflows.py
--- a/test/functional/api/test_workflows.py
+++ b/test/functional/api/test_workflows.py
@@ -67,6 +67,31 @@
self._assert_status_code_is( run_workflow_response, 200 )
self._wait_for_history( history_id, assert_ok=True )
+ def test_run_replace_params_by_tool( self ):
+ workflow_request, history_id = self._setup_random_x2_workflow( "test_for_replace_tool_params" )
+ workflow_request[ "parameters" ] = dumps( dict( random_lines1=dict( num_lines=5 ) ) )
+ run_workflow_response = self._post( "workflows", data=workflow_request )
+ self._assert_status_code_is( run_workflow_response, 200 )
+ self._wait_for_history( history_id, assert_ok=True )
+ # Would be 8 and 6 without modification
+ self.__assert_lines_hid_line_count_is( history_id, 2, 5 )
+ self.__assert_lines_hid_line_count_is( history_id, 3, 5 )
+
+ def test_run_replace_params_by_steps( self ):
+ workflow_request, history_id = self._setup_random_x2_workflow( "test_for_replace_step_params" )
+ workflow_summary_response = self._get( "workflows/%s" % workflow_request[ "workflow_id" ] )
+ self._assert_status_code_is( workflow_summary_response, 200 )
+ steps = workflow_summary_response.json()[ "steps" ]
+ last_step_id = str( max( map( int, steps.keys() ) ) )
+ params = dumps( { last_step_id: dict( num_lines=5 ) } )
+ workflow_request[ "parameters" ] = params
+ run_workflow_response = self._post( "workflows", data=workflow_request )
+ self._assert_status_code_is( run_workflow_response, 200 )
+ self._wait_for_history( history_id, assert_ok=True )
+ # Would be 8 and 6 without modification
+ self.__assert_lines_hid_line_count_is( history_id, 2, 8 )
+ self.__assert_lines_hid_line_count_is( history_id, 3, 5 )
+
def test_pja_import_export( self ):
workflow = self.workflow_populator.load_workflow( name="test_for_pja_import", add_pja=True )
uploaded_workflow_id = self.workflow_populator.create_workflow( workflow )
@@ -94,9 +119,7 @@
def _setup_workflow_run( self, workflow ):
uploaded_workflow_id = self.workflow_populator.create_workflow( workflow )
- workflow_show_resposne = self._get( "workflows/%s" % uploaded_workflow_id )
- self._assert_status_code_is( workflow_show_resposne, 200 )
- workflow_inputs = workflow_show_resposne.json()[ "inputs" ]
+ workflow_inputs = self._workflow_inputs( uploaded_workflow_id )
step_1 = step_2 = None
for key, value in workflow_inputs.iteritems():
label = value[ "label" ]
@@ -117,6 +140,29 @@
)
return workflow_request, history_id
+ def _setup_random_x2_workflow( self, name ):
+ workflow = self.workflow_populator.load_random_x2_workflow( name )
+ uploaded_workflow_id = self.workflow_populator.create_workflow( workflow )
+ workflow_inputs = self._workflow_inputs( uploaded_workflow_id )
+ key = workflow_inputs.keys()[ 0 ]
+ history_id = self._new_history()
+ ten_lines = "\n".join( map( str, range( 10 ) ) )
+ hda1 = self._new_dataset( history_id, content=ten_lines )
+ workflow_request = dict(
+ history="hist_id=%s" % history_id,
+ workflow_id=uploaded_workflow_id,
+ ds_map=dumps( {
+ key: self._ds_entry(hda1),
+ } ),
+ )
+ return workflow_request, history_id
+
+ def _workflow_inputs( self, uploaded_workflow_id ):
+ workflow_show_resposne = self._get( "workflows/%s" % uploaded_workflow_id )
+ self._assert_status_code_is( workflow_show_resposne, 200 )
+ workflow_inputs = workflow_show_resposne.json()[ "inputs" ]
+ return workflow_inputs
+
def _ds_entry( self, hda ):
return dict( src="hda", id=hda[ "id" ] )
@@ -124,6 +170,15 @@
names = self.__workflow_names()
assert name in names, "No workflows with name %s in users workflows <%s>" % ( name, names )
+ def __assert_lines_hid_line_count_is( self, history, hid, lines ):
+ contents_url = "histories/%s/contents" % history
+ history_contents_response = self._get( contents_url )
+ self._assert_status_code_is( history_contents_response, 200 )
+ hda_summary = filter( lambda hc: hc[ "hid" ] == hid, history_contents_response.json() )[ 0 ]
+ hda_info_response = self._get( "%s/%s" % ( contents_url, hda_summary[ "id" ] ) )
+ self._assert_status_code_is( hda_info_response, 200 )
+ self.assertEquals( hda_info_response.json()[ "metadata_data_lines" ], lines )
+
def __workflow_names( self ):
index_response = self._get( "workflows" )
self._assert_status_code_is( index_response, 200 )
https://bitbucket.org/galaxy/galaxy-central/commits/0617610e18a6/
Changeset: 0617610e18a6
Branch: workflow_params
User: jmchilton
Date: 2014-02-03 00:55:31
Summary: Close branch workflow_params.
Affected #: 0 files
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.
1
0
7 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5f373922d077/
Changeset: 5f373922d077
User: jmchilton
Date: 2014-01-29 15:42:39
Summary: Move some history export logic out of controller into model...
For reuse by API.
Affected #: 3 files
diff -r 6b627e15f18b13a489ca4e4343703931d9333021 -r 5f373922d0773eccab37f51145b8e880760e86b4 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -647,6 +647,7 @@
return self.library_dataset_dataset_association
return None
+
class JobExportHistoryArchive( object ):
def __init__( self, job=None, history=None, dataset=None, compressed=False, \
history_attrs_filename=None, datasets_attrs_filename=None,
@@ -659,6 +660,35 @@
self.datasets_attrs_filename = datasets_attrs_filename
self.jobs_attrs_filename = jobs_attrs_filename
+ @property
+ def up_to_date( self ):
+ """ Return False, if a new export should be generated for corresponding
+ history.
+ """
+ job = self.job
+ return job.state not in [ Job.states.ERROR, Job.states.DELETED ] \
+ and job.update_time > self.history.update_time
+
+ @property
+ def ready( self ):
+ return self.job.state == Job.states.OK
+
+ @property
+ def preparing( self ):
+ return self.job.state in [ Job.states.RUNNING, Job.states.QUEUED, Job.states.WAITING ]
+
+ @property
+ def export_name( self ):
+ # Stream archive.
+ valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ hname = self.history.name
+ hname = ''.join(c in valid_chars and c or '_' for c in hname)[0:150]
+ hname = "Galaxy-History-%s.tar" % ( hname )
+ if self.compressed:
+ hname += ".gz"
+ return hname
+
+
class JobImportHistoryArchive( object ):
def __init__( self, job=None, history=None, archive_dir=None ):
self.job = job
@@ -875,6 +905,11 @@
return changed
@property
+ def latest_export( self ):
+ exports = self.exports
+ return exports and exports[ 0 ]
+
+ @property
def get_disk_size_bytes( self ):
return self.get_disk_size( nice_size=False )
diff -r 6b627e15f18b13a489ca4e4343703931d9333021 -r 5f373922d0773eccab37f51145b8e880760e86b4 lib/galaxy/model/mapping.py
--- a/lib/galaxy/model/mapping.py
+++ b/lib/galaxy/model/mapping.py
@@ -1295,6 +1295,7 @@
mapper( model.History, model.History.table,
properties=dict( galaxy_sessions=relation( model.GalaxySessionToHistoryAssociation ),
datasets=relation( model.HistoryDatasetAssociation, backref="history", order_by=asc(model.HistoryDatasetAssociation.table.c.hid) ),
+ exports=relation( model.JobExportHistoryArchive, primaryjoin=( model.JobExportHistoryArchive.table.c.history_id == model.History.table.c.id ), order_by=desc( model.JobExportHistoryArchive.table.c.id ) ),
active_datasets=relation( model.HistoryDatasetAssociation, primaryjoin=( ( model.HistoryDatasetAssociation.table.c.history_id == model.History.table.c.id ) & not_( model.HistoryDatasetAssociation.table.c.deleted ) ), order_by=asc( model.HistoryDatasetAssociation.table.c.hid ), viewonly=True ),
visible_datasets=relation( model.HistoryDatasetAssociation, primaryjoin=( ( model.HistoryDatasetAssociation.table.c.history_id == model.History.table.c.id ) & not_( model.HistoryDatasetAssociation.table.c.deleted ) & model.HistoryDatasetAssociation.table.c.visible ),
order_by=asc( model.HistoryDatasetAssociation.table.c.hid ), viewonly=True ),
diff -r 6b627e15f18b13a489ca4e4343703931d9333021 -r 5f373922d0773eccab37f51145b8e880760e86b4 lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -704,24 +704,17 @@
#
# If history has already been exported and it has not changed since export, stream it.
#
- jeha = trans.sa_session.query( model.JobExportHistoryArchive ).filter_by( history=history ) \
- .order_by( model.JobExportHistoryArchive.id.desc() ).first()
- if jeha and ( jeha.job.state not in [ model.Job.states.ERROR, model.Job.states.DELETED ] ) \
- and jeha.job.update_time > history.update_time:
- if jeha.job.state == model.Job.states.OK:
- # Stream archive.
- valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
- hname = history.name
- hname = ''.join(c in valid_chars and c or '_' for c in hname)[0:150]
- hname = "Galaxy-History-%s.tar" % ( hname )
+ jeha = history.latest_export
+ if jeha and jeha.up_to_date:
+ if jeha.ready:
if jeha.compressed:
- hname += ".gz"
trans.response.set_content_type( 'application/x-gzip' )
else:
trans.response.set_content_type( 'application/x-tar' )
- trans.response.headers["Content-Disposition"] = 'attachment; filename="%s"' % ( hname )
+ disposition = 'attachment; filename="%s"' % jeha.export_name
+ trans.response.headers["Content-Disposition"] = disposition
return open( trans.app.object_store.get_filename( jeha.dataset ) )
- elif jeha.job.state in [ model.Job.states.RUNNING, model.Job.states.QUEUED, model.Job.states.WAITING ]:
+ elif jeha.preparing:
return trans.show_message( "Still exporting history %(n)s; please check back soon. Link: <a href='%(s)s'>%(s)s</a>" \
% ( { 'n' : history.name, 's' : url_for( controller='history', action="export_archive", id=id, qualified=True ) } ) )
https://bitbucket.org/galaxy/galaxy-central/commits/e0a4bdd5b89f/
Changeset: e0a4bdd5b89f
User: jmchilton
Date: 2014-01-29 15:42:39
Summary: Refactor history export functionality into ExportsHistoryMixin...
... for reuse in API.
Affected #: 2 files
diff -r 5f373922d0773eccab37f51145b8e880760e86b4 -r e0a4bdd5b89f326b6b1c8ed17aec084b89c5e1ac lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -562,6 +562,40 @@
return changed
+class ExportsHistoryMixin:
+
+ def serve_ready_history_export( self, trans, jeha ):
+ assert jeha.ready
+ if jeha.compressed:
+ trans.response.set_content_type( 'application/x-gzip' )
+ else:
+ trans.response.set_content_type( 'application/x-tar' )
+ disposition = 'attachment; filename="%s"' % jeha.export_name
+ trans.response.headers["Content-Disposition"] = disposition
+ return open( trans.app.object_store.get_filename( jeha.dataset ) )
+
+ def queue_history_export( self, trans, history, gzip=True, include_hidden=False, include_deleted=False ):
+ # Convert options to booleans.
+ #
+ if isinstance( gzip, basestring ):
+ gzip = ( gzip in [ 'True', 'true', 'T', 't' ] )
+ if isinstance( include_hidden, basestring ):
+ include_hidden = ( include_hidden in [ 'True', 'true', 'T', 't' ] )
+ if isinstance( include_deleted, basestring ):
+ include_deleted = ( include_deleted in [ 'True', 'true', 'T', 't' ] )
+
+ # Run job to do export.
+ history_exp_tool = trans.app.toolbox.get_tool( '__EXPORT_HISTORY__' )
+ params = {
+ 'history_to_export': history,
+ 'compress': gzip,
+ 'include_hidden': include_hidden,
+ 'include_deleted': include_deleted
+ }
+
+ history_exp_tool.execute( trans, incoming=params, set_output_hid=True )
+
+
class UsesHistoryDatasetAssociationMixin:
"""
Mixin for controllers that use HistoryDatasetAssociation objects.
diff -r 5f373922d0773eccab37f51145b8e880760e86b4 -r e0a4bdd5b89f326b6b1c8ed17aec084b89c5e1ac lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -13,6 +13,7 @@
from galaxy.util.sanitize_html import sanitize_html
from galaxy.web import error, url_for
from galaxy.web.base.controller import BaseUIController, SharableMixin, UsesHistoryDatasetAssociationMixin, UsesHistoryMixin
+from galaxy.web.base.controller import ExportsHistoryMixin
from galaxy.web.base.controller import ERROR, INFO, SUCCESS, WARNING
from galaxy.web.framework.helpers import grids, iff, time_ago
@@ -187,7 +188,7 @@
return query.filter( self.model_class.published == True ).filter( self.model_class.slug != None ).filter( self.model_class.deleted == False )
class HistoryController( BaseUIController, SharableMixin, UsesAnnotations, UsesItemRatings,
- UsesHistoryMixin, UsesHistoryDatasetAssociationMixin ):
+ UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, ExportsHistoryMixin ):
@web.expose
def index( self, trans ):
return ""
@@ -679,16 +680,6 @@
def export_archive( self, trans, id=None, gzip=True, include_hidden=False, include_deleted=False ):
""" Export a history to an archive. """
#
- # Convert options to booleans.
- #
- if isinstance( gzip, basestring ):
- gzip = ( gzip in [ 'True', 'true', 'T', 't' ] )
- if isinstance( include_hidden, basestring ):
- include_hidden = ( include_hidden in [ 'True', 'true', 'T', 't' ] )
- if isinstance( include_deleted, basestring ):
- include_deleted = ( include_deleted in [ 'True', 'true', 'T', 't' ] )
-
- #
# Get history to export.
#
if id:
@@ -707,25 +698,12 @@
jeha = history.latest_export
if jeha and jeha.up_to_date:
if jeha.ready:
- if jeha.compressed:
- trans.response.set_content_type( 'application/x-gzip' )
- else:
- trans.response.set_content_type( 'application/x-tar' )
- disposition = 'attachment; filename="%s"' % jeha.export_name
- trans.response.headers["Content-Disposition"] = disposition
- return open( trans.app.object_store.get_filename( jeha.dataset ) )
+ return self.serve_ready_history_export( trans, jeha )
elif jeha.preparing:
return trans.show_message( "Still exporting history %(n)s; please check back soon. Link: <a href='%(s)s'>%(s)s</a>" \
% ( { 'n' : history.name, 's' : url_for( controller='history', action="export_archive", id=id, qualified=True ) } ) )
- # Run job to do export.
- history_exp_tool = trans.app.toolbox.get_tool( '__EXPORT_HISTORY__' )
- params = {
- 'history_to_export' : history,
- 'compress' : gzip,
- 'include_hidden' : include_hidden,
- 'include_deleted' : include_deleted }
- history_exp_tool.execute( trans, incoming = params, set_output_hid = True )
+ self.queue_history_export( trans, history, gzip=gzip, include_hidden=include_hidden, include_deleted=include_deleted )
url = url_for( controller='history', action="export_archive", id=id, qualified=True )
return trans.show_message( "Exporting History '%(n)s'. Use this link to download \
the archive or import it to another Galaxy server: \
https://bitbucket.org/galaxy/galaxy-central/commits/3a3561fa8df3/
Changeset: 3a3561fa8df3
User: jmchilton
Date: 2014-01-29 15:42:41
Summary: Refactor history import functionality into ImportsHistoryMixin...
... for reuse in API.
Affected #: 2 files
diff -r e0a4bdd5b89f326b6b1c8ed17aec084b89c5e1ac -r 3a3561fa8df334b43eff9ce0d648b38932bb27e6 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -596,6 +596,15 @@
history_exp_tool.execute( trans, incoming=params, set_output_hid=True )
+class ImportsHistoryMixin:
+
+ def queue_history_import( self, trans, archive_type, archive_source ):
+ # Run job to do import.
+ history_imp_tool = trans.app.toolbox.get_tool( '__IMPORT_HISTORY__' )
+ incoming = { '__ARCHIVE_SOURCE__' : archive_source, '__ARCHIVE_TYPE__' : archive_type }
+ history_imp_tool.execute( trans, incoming=incoming )
+
+
class UsesHistoryDatasetAssociationMixin:
"""
Mixin for controllers that use HistoryDatasetAssociation objects.
diff -r e0a4bdd5b89f326b6b1c8ed17aec084b89c5e1ac -r 3a3561fa8df334b43eff9ce0d648b38932bb27e6 lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -14,6 +14,7 @@
from galaxy.web import error, url_for
from galaxy.web.base.controller import BaseUIController, SharableMixin, UsesHistoryDatasetAssociationMixin, UsesHistoryMixin
from galaxy.web.base.controller import ExportsHistoryMixin
+from galaxy.web.base.controller import ImportsHistoryMixin
from galaxy.web.base.controller import ERROR, INFO, SUCCESS, WARNING
from galaxy.web.framework.helpers import grids, iff, time_ago
@@ -188,7 +189,8 @@
return query.filter( self.model_class.published == True ).filter( self.model_class.slug != None ).filter( self.model_class.deleted == False )
class HistoryController( BaseUIController, SharableMixin, UsesAnnotations, UsesItemRatings,
- UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, ExportsHistoryMixin ):
+ UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, ExportsHistoryMixin,
+ ImportsHistoryMixin ):
@web.expose
def index( self, trans ):
return ""
@@ -669,10 +671,7 @@
# TODO: add support for importing via a file.
#.add_input( "file", "Archived History File", "archive_file", value=None, error=None )
)
- # Run job to do import.
- history_imp_tool = trans.app.toolbox.get_tool( '__IMPORT_HISTORY__' )
- incoming = { '__ARCHIVE_SOURCE__' : archive_source, '__ARCHIVE_TYPE__' : archive_type }
- history_imp_tool.execute( trans, incoming=incoming )
+ self.queue_history_import( trans, archive_type=archive_type, archive_source=archive_source )
return trans.show_message( "Importing history from '%s'. \
This history will be visible when the import is complete" % archive_source )
https://bitbucket.org/galaxy/galaxy-central/commits/17f1d214f8a4/
Changeset: 17f1d214f8a4
User: jmchilton
Date: 2014-01-29 15:42:42
Summary: Add new API decorator for raw downloads.
Affected #: 2 files
diff -r 3a3561fa8df334b43eff9ce0d648b38932bb27e6 -r 17f1d214f8a44995f082e0fd32d3801edef02303 lib/galaxy/web/__init__.py
--- a/lib/galaxy/web/__init__.py
+++ b/lib/galaxy/web/__init__.py
@@ -19,3 +19,4 @@
# TODO: Drop and make these the default.
from framework import _future_expose_api
from framework import _future_expose_api_anonymous
+from framework import _future_expose_api_raw
diff -r 3a3561fa8df334b43eff9ce0d648b38932bb27e6 -r 17f1d214f8a44995f082e0fd32d3801edef02303 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -274,6 +274,10 @@
return _future_expose_api( func, to_json=to_json, user_required=False )
+def _future_expose_api_raw( func ):
+ return _future_expose_api( func, to_json=False, user_required=True )
+
+
# TODO: rename as expose_api and make default.
def _future_expose_api( func, to_json=True, user_required=True ):
"""
https://bitbucket.org/galaxy/galaxy-central/commits/ea320e650645/
Changeset: ea320e650645
User: jmchilton
Date: 2014-01-29 15:42:42
Summary: Implement history exporting via API.
Two new routes one that can be PUT against to poll for download_url and one to fetch a completed download via a GET. Includes simple test case. This doesn't cleanly map to REST to my mind so I have hobbled together this approach, happy for further input.
Good reading:
https://restful-api-design.readthedocs.org/en/latest/methods.html#asynchron…
http://stackoverflow.com/questions/4099869/is-it-wrong-to-return-202-accept…
Affected #: 5 files
diff -r 17f1d214f8a44995f082e0fd32d3801edef02303 -r ea320e650645a2512b1ac9ab7c35a8cec4ef2bda lib/galaxy/tools/actions/history_imp_exp.py
--- a/lib/galaxy/tools/actions/history_imp_exp.py
+++ b/lib/galaxy/tools/actions/history_imp_exp.py
@@ -14,7 +14,8 @@
# Create job.
#
job = trans.app.model.Job()
- job.session_id = trans.get_galaxy_session().id
+ session = trans.get_galaxy_session()
+ job.session_id = session and session.id
job.history_id = trans.history.id
job.tool_id = tool.id
job.user_id = trans.user.id
@@ -76,8 +77,13 @@
# Create the job and output dataset objects
#
job = trans.app.model.Job()
- job.session_id = trans.get_galaxy_session().id
- job.history_id = trans.history.id
+ session = trans.get_galaxy_session()
+ job.session_id = session and session.id
+ if history:
+ history_id = history.id
+ else:
+ history_id = trans.history.id
+ job.history_id = history_id
job.tool_id = tool.id
if trans.user:
# If this is an actual user, run the job as that individual. Otherwise we're running as guest.
diff -r 17f1d214f8a44995f082e0fd32d3801edef02303 -r ea320e650645a2512b1ac9ab7c35a8cec4ef2bda lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -593,7 +593,7 @@
'include_deleted': include_deleted
}
- history_exp_tool.execute( trans, incoming=params, set_output_hid=True )
+ history_exp_tool.execute( trans, incoming=params, history=history, set_output_hid=True )
class ImportsHistoryMixin:
diff -r 17f1d214f8a44995f082e0fd32d3801edef02303 -r ea320e650645a2512b1ac9ab7c35a8cec4ef2bda lib/galaxy/webapps/galaxy/api/histories.py
--- a/lib/galaxy/webapps/galaxy/api/histories.py
+++ b/lib/galaxy/webapps/galaxy/api/histories.py
@@ -8,21 +8,25 @@
pkg_resources.require( "Paste" )
from paste.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPInternalServerError, HTTPException
+from galaxy import exceptions
from galaxy import web
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
+from galaxy.web import _future_expose_api_raw as expose_api_raw
from galaxy.util import string_as_bool
from galaxy.util import restore_text
from galaxy.web.base.controller import BaseAPIController
from galaxy.web.base.controller import UsesHistoryMixin
from galaxy.web.base.controller import UsesTagsMixin
+from galaxy.web.base.controller import ExportsHistoryMixin
from galaxy.web import url_for
import logging
log = logging.getLogger( __name__ )
-class HistoriesController( BaseAPIController, UsesHistoryMixin, UsesTagsMixin ):
+class HistoriesController( BaseAPIController, UsesHistoryMixin, UsesTagsMixin,
+ ExportsHistoryMixin ):
@expose_api_anonymous
def index( self, trans, deleted='False', **kwd ):
@@ -329,6 +333,67 @@
return changed
+ @expose_api
+ def archive_export( self, trans, id, **kwds ):
+ """
+ export_archive( self, trans, id, payload )
+ * PUT /api/histories/{id}/exports:
+ start job (if needed) to create history export for corresponding
+ history.
+
+ :type id: str
+ :param id: the encoded id of the history to undelete
+
+ :rtype: dict
+ :returns: object containing url to fetch export from.
+ """
+ # PUT instead of POST because multiple requests should just result
+ # in one object being created.
+ history_id = id
+ history = self.get_history( trans, history_id, check_ownership=False, check_accessible=True )
+ jeha = history.latest_export
+ up_to_date = jeha and jeha.up_to_date
+ if not up_to_date:
+ # Need to create new JEHA + job.
+ gzip = kwds.get( "gzip", True )
+ include_hidden = kwds.get( "include_hidden", False )
+ include_deleted = kwds.get( "include_deleted", False )
+ self.queue_history_export( trans, history, gzip=gzip, include_hidden=include_hidden, include_deleted=include_deleted )
+
+ if up_to_date and jeha.ready:
+ jeha_id = trans.security.encode_id( jeha.id )
+ return dict( download_url=url_for( "history_archive_download", id=history_id, jeha_id=jeha_id ) )
+ else:
+ # Valid request, just resource is not ready yet.
+ trans.response.status = "202 Accepted"
+ return ''
+
+ @expose_api_raw
+ def archive_download( self, trans, id, jeha_id, **kwds ):
+ """
+ export_download( self, trans, id, jeha_id )
+ * GET /api/histories/{id}/exports/{jeha_id}:
+ If ready and available, return raw contents of exported history.
+ Use/poll "PUT /api/histories/{id}/exports" to initiate the creation
+ of such an export - when ready that route will return 200 status
+ code (instead of 202) with a JSON dictionary containing a
+ `download_url`.
+ """
+ # Seems silly to put jeha_id in here, but want GET to be immuatable?
+ # and this is being accomplished this way.
+ history = self.get_history( trans, id, check_ownership=False, check_accessible=True )
+ matching_exports = filter( lambda e: trans.security.encode_id( e.id ) == jeha_id, history.exports )
+ if not matching_exports:
+ raise exceptions.ObjectNotFound()
+
+ jeha = matching_exports[ 0 ]
+ if not jeha.ready:
+ # User should not have been given this URL, PUT export should have
+ # return a 202.
+ raise exceptions.MessageException( "Export not available or not yet ready." )
+
+ return self.serve_ready_history_export( trans, jeha )
+
def _validate_and_parse_update_payload( self, payload ):
"""
Validate and parse incomming data payload for a history.
diff -r 17f1d214f8a44995f082e0fd32d3801edef02303 -r ea320e650645a2512b1ac9ab7c35a8cec4ef2bda lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -154,6 +154,11 @@
webapp.mapper.connect( "set_as_current", "/api/histories/{id}/set_as_current",
controller="histories", action="set_as_current", conditions=dict( method=["POST"] ) )
+ webapp.mapper.connect( "history_archive_export", "/api/histories/{id}/exports",
+ controller="histories", action="archive_export", conditions=dict( method=[ "PUT" ] ) )
+ webapp.mapper.connect( "history_archive_download", "/api/histories/{id}/exports/{jeha_id}",
+ controller="histories", action="archive_download", conditions=dict( method=[ "GET" ] ) )
+
webapp.mapper.connect( "create_api_key", "/api/users/:user_id/api_key",
controller="users", action="api_key", user_id=None, conditions=dict( method=["POST"] ) )
diff -r 17f1d214f8a44995f082e0fd32d3801edef02303 -r ea320e650645a2512b1ac9ab7c35a8cec4ef2bda test/functional/api/test_histories.py
--- a/test/functional/api/test_histories.py
+++ b/test/functional/api/test_histories.py
@@ -1,9 +1,14 @@
+import time
from base import api
-# requests.post or something like it if unavailable
+# requests.{post,put,get} or something like it if unavailable
from base.interactor import post_request
+from base.interactor import put_request
+from base.interactor import get_request
+from .helpers import TestsDatasets
-class HistoriesApiTestCase( api.ApiTestCase ):
+
+class HistoriesApiTestCase( api.ApiTestCase, TestsDatasets ):
def test_create_history( self ):
# Create a history.
@@ -24,3 +29,24 @@
histories_url = self._api_url( "histories" )
create_response = post_request( url=histories_url, data=post_data )
self._assert_status_code_is( create_response, 403 )
+
+ def test_export( self ):
+ history_id = self._new_history()
+ self._new_dataset( history_id, content="1 2 3" )
+ self._wait_for_history( history_id, assert_ok=True )
+ export_url = self._api_url( "histories/%s/exports" % history_id , use_key=True )
+ put_response = put_request( export_url )
+ self._assert_status_code_is( put_response, 202 )
+ while True:
+ put_response = put_request( export_url )
+ if put_response.status_code == 202:
+ time.sleep( .1 )
+ else:
+ break
+ self._assert_status_code_is( put_response, 200 )
+ response = put_response.json()
+ self._assert_has_keys( response, "download_url" )
+ download_path = response[ "download_url" ]
+ full_download_url = "%s%s?key=%s" % ( self.url, download_path, self.galaxy_interactor.api_key )
+ download_response = get_request( full_download_url )
+ self._assert_status_code_is( download_response, 200 )
https://bitbucket.org/galaxy/galaxy-central/commits/f456b2eaf3dc/
Changeset: f456b2eaf3dc
User: jmchilton
Date: 2014-01-29 15:42:42
Summary: Implement history import via API.
Affected #: 3 files
diff -r ea320e650645a2512b1ac9ab7c35a8cec4ef2bda -r f456b2eaf3dc61df52d710f710590d37b31386ca lib/galaxy/tools/actions/history_imp_exp.py
--- a/lib/galaxy/tools/actions/history_imp_exp.py
+++ b/lib/galaxy/tools/actions/history_imp_exp.py
@@ -16,7 +16,13 @@
job = trans.app.model.Job()
session = trans.get_galaxy_session()
job.session_id = session and session.id
- job.history_id = trans.history.id
+ if history:
+ history_id = history.id
+ elif trans.history:
+ history_id = trans.history.id
+ else:
+ history_id = None
+ job.history_id = history_id
job.tool_id = tool.id
job.user_id = trans.user.id
start_job_state = job.state #should be job.states.NEW
diff -r ea320e650645a2512b1ac9ab7c35a8cec4ef2bda -r f456b2eaf3dc61df52d710f710590d37b31386ca lib/galaxy/webapps/galaxy/api/histories.py
--- a/lib/galaxy/webapps/galaxy/api/histories.py
+++ b/lib/galaxy/webapps/galaxy/api/histories.py
@@ -19,6 +19,7 @@
from galaxy.web.base.controller import UsesHistoryMixin
from galaxy.web.base.controller import UsesTagsMixin
from galaxy.web.base.controller import ExportsHistoryMixin
+from galaxy.web.base.controller import ImportsHistoryMixin
from galaxy.web import url_for
import logging
@@ -26,7 +27,7 @@
class HistoriesController( BaseAPIController, UsesHistoryMixin, UsesTagsMixin,
- ExportsHistoryMixin ):
+ ExportsHistoryMixin, ImportsHistoryMixin ):
@expose_api_anonymous
def index( self, trans, deleted='False', **kwd ):
@@ -176,6 +177,9 @@
:rtype: dict
:returns: element view of new history
"""
+ if self.__create_via_import( payload ):
+ return self.__import_archive( trans, payload )
+
hist_name = None
if payload.get( 'name', None ):
hist_name = restore_text( payload['name'] )
@@ -394,6 +398,14 @@
return self.serve_ready_history_export( trans, jeha )
+ def __create_via_import( self, payload ):
+ return "archive_source" in payload
+
+ def __import_archive( self, trans, payload ):
+ archive_type = payload.get( "archive_type", "url" )
+ archive_source = payload[ "archive_source" ]
+ self.queue_history_import( trans, archive_type=archive_type, archive_source=archive_source )
+
def _validate_and_parse_update_payload( self, payload ):
"""
Validate and parse incomming data payload for a history.
diff -r ea320e650645a2512b1ac9ab7c35a8cec4ef2bda -r f456b2eaf3dc61df52d710f710590d37b31386ca test/functional/api/test_histories.py
--- a/test/functional/api/test_histories.py
+++ b/test/functional/api/test_histories.py
@@ -7,7 +7,6 @@
from .helpers import TestsDatasets
-
class HistoriesApiTestCase( api.ApiTestCase, TestsDatasets ):
def test_create_history( self ):
@@ -31,12 +30,13 @@
self._assert_status_code_is( create_response, 403 )
def test_export( self ):
- history_id = self._new_history()
+ history_id = self._new_history( name="for_export" )
self._new_dataset( history_id, content="1 2 3" )
self._wait_for_history( history_id, assert_ok=True )
export_url = self._api_url( "histories/%s/exports" % history_id , use_key=True )
put_response = put_request( export_url )
self._assert_status_code_is( put_response, 202 )
+ # TODO: Break after some period of time.
while True:
put_response = put_request( export_url )
if put_response.status_code == 202:
@@ -50,3 +50,21 @@
full_download_url = "%s%s?key=%s" % ( self.url, download_path, self.galaxy_interactor.api_key )
download_response = get_request( full_download_url )
self._assert_status_code_is( download_response, 200 )
+
+ def history_names():
+ history_index = self._get( "histories" )
+ return map( lambda h: h[ "name" ], history_index.json() )
+
+ import_name = "imported from archive: for_export"
+ assert import_name not in history_names()
+
+ import_data = dict( archive_source=full_download_url, archive_type="url" )
+ import_response = self._post( "histories", data=import_data )
+
+ self._assert_status_code_is( import_response, 200 )
+ found = False
+ while not found:
+ time.sleep( .1 )
+ if import_name in history_names():
+ found = True
+ assert found, "%s not in history names %s" % ( import_name, history_names() )
https://bitbucket.org/galaxy/galaxy-central/commits/6788cffb792b/
Changeset: 6788cffb792b
User: jmchilton
Date: 2014-02-02 22:23:46
Summary: Introduce method ready_name_for_url.
Pulled code out of create_item_slug placed in util for reused in other operations - such as creating a history export. Update history export to use this. Slugs mapped names to a signficantly more restricted character set so history export file names will now be all lower case for instance and will never contain parens, commas, periods, or underscores for instance.
Previous incarnation of this idea (not committed) also 'lower'-ed the name - this behavior is not desired for history exports the way it is for slugs - hence moved .lower() back to create_item_slug and renamed the method ready_name_for_url instead of ready_name_for_slug.
Idea from Jeremy Goecks (https://bitbucket.org/galaxy/galaxy-central/pull-request/314/history-import…)
Affected #: 3 files
diff -r f456b2eaf3dc61df52d710f710590d37b31386ca -r 6788cffb792bc88bb6cfb3a15aff1d29a8c4a700 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -27,6 +27,7 @@
from galaxy.model.item_attrs import Dictifiable, UsesAnnotations
from galaxy.security import get_permitted_actions
from galaxy.util import is_multi_byte, nice_size, Params, restore_text, send_mail
+from galaxy.util import ready_name_for_url
from galaxy.util.bunch import Bunch
from galaxy.util.hash_util import new_secure_hash
from galaxy.util.directory_hash import directory_hash_id
@@ -680,9 +681,7 @@
@property
def export_name( self ):
# Stream archive.
- valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
- hname = self.history.name
- hname = ''.join(c in valid_chars and c or '_' for c in hname)[0:150]
+ hname = ready_name_for_url( self.history.name )
hname = "Galaxy-History-%s.tar" % ( hname )
if self.compressed:
hname += ".gz"
diff -r f456b2eaf3dc61df52d710f710590d37b31386ca -r 6788cffb792bc88bb6cfb3a15aff1d29a8c4a700 lib/galaxy/util/__init__.py
--- a/lib/galaxy/util/__init__.py
+++ b/lib/galaxy/util/__init__.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
"""
Utility functions used systemwide.
@@ -391,6 +392,28 @@
return out
+def ready_name_for_url( raw_name ):
+ """ General method to convert a string (i.e. object name) to a URL-ready
+ slug.
+
+ >>> ready_name_for_url( "My Cool Object" )
+ 'My-Cool-Object'
+ >>> ready_name_for_url( "!My Cool Object!" )
+ 'My-Cool-Object'
+ >>> ready_name_for_url( "Hello₩◎ґʟⅾ" )
+ 'Hello'
+ """
+
+ # Replace whitespace with '-'
+ slug_base = re.sub( "\s+", "-", raw_name )
+ # Remove all non-alphanumeric characters.
+ slug_base = re.sub( "[^a-zA-Z0-9\-]", "", slug_base )
+ # Remove trailing '-'.
+ if slug_base.endswith('-'):
+ slug_base = slug_base[:-1]
+ return slug_base
+
+
def in_directory( file, directory ):
"""
Return true, if the common prefix of both is equal to directory
diff -r f456b2eaf3dc61df52d710f710590d37b31386ca -r 6788cffb792bc88bb6cfb3a15aff1d29a8c4a700 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -2643,13 +2643,7 @@
item_name = item.name
elif hasattr( item, 'title' ):
item_name = item.title
- # Replace whitespace with '-'
- slug_base = re.sub( "\s+", "-", item_name.lower() )
- # Remove all non-alphanumeric characters.
- slug_base = re.sub( "[^a-zA-Z0-9\-]", "", slug_base )
- # Remove trailing '-'.
- if slug_base.endswith('-'):
- slug_base = slug_base[:-1]
+ slug_base = util.ready_name_for_url( item_name.lower() )
else:
slug_base = cur_slug
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.
1
0
commit/galaxy-central: jmchilton: Refactor duplicated get_display_name code out of galaxy.model.
by commits-noreply@bitbucket.org 02 Feb '14
by commits-noreply@bitbucket.org 02 Feb '14
02 Feb '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6b627e15f18b/
Changeset: 6b627e15f18b
User: jmchilton
Date: 2014-02-02 19:47:15
Summary: Refactor duplicated get_display_name code out of galaxy.model.
Also added test cases. Need to use this downstream in for dataset collections.
Affected #: 2 files
diff -r 89d7cf67241f36e5f2c4de0aa31328fb7823e7d5 -r 6b627e15f18b13a489ca4e4343703931d9333021 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -71,6 +71,19 @@
datatypes_registry = d_registry
+class HasName:
+
+ def get_display_name( self ):
+ """
+ These objects have a name attribute can be either a string or a unicode
+ object. If string, convert to unicode object assuming 'utf-8' format.
+ """
+ name = self.name
+ if isinstance(name, str):
+ name = unicode(name, 'utf-8')
+ return name
+
+
class User( object, Dictifiable ):
use_pbkdf2 = True
"""
@@ -716,7 +729,7 @@
self.user = user
self.group = group
-class History( object, Dictifiable, UsesAnnotations ):
+class History( object, Dictifiable, UsesAnnotations, HasName ):
dict_collection_visible_keys = ( 'id', 'name', 'published', 'deleted' )
dict_element_visible_keys = ( 'id', 'name', 'published', 'deleted', 'genome_build', 'purged' )
@@ -823,16 +836,6 @@
# This needs to be a list
return [ hda for hda in self.datasets if not hda.dataset.deleted ]
- def get_display_name( self ):
- """
- History name can be either a string or a unicode object.
- If string, convert to unicode object assuming 'utf-8' format.
- """
- history_name = self.name
- if isinstance(history_name, str):
- history_name = unicode(history_name, 'utf-8')
- return history_name
-
def to_dict( self, view='collection', value_mapper = None ):
# Get basic value.
@@ -1604,7 +1607,7 @@
return msg
-class HistoryDatasetAssociation( DatasetInstance, Dictifiable, UsesAnnotations ):
+class HistoryDatasetAssociation( DatasetInstance, Dictifiable, UsesAnnotations, HasName ):
"""
Resource class that creates a relation between a dataset and a user history.
"""
@@ -1734,17 +1737,6 @@
for assoc in self.implicitly_converted_parent_datasets:
assoc.clear( purge = purge, delete_dataset = False )
- def get_display_name( self ):
- """
- Return the name of this HDA in either ascii or utf-8 encoding.
- """
- # Name can be either a string or a unicode object.
- # If string, convert to unicode object assuming 'utf-8' format.
- hda_name = self.name
- if isinstance(hda_name, str):
- hda_name = unicode(hda_name, 'utf-8')
- return hda_name
-
def get_access_roles( self, trans ):
"""
Return The access roles associated with this HDA's dataset.
@@ -1878,7 +1870,7 @@
self.subset = subset
self.location = location
-class Library( object, Dictifiable ):
+class Library( object, Dictifiable, HasName ):
permitted_actions = get_permitted_actions( filter='LIBRARY' )
dict_collection_visible_keys = ( 'id', 'name' )
dict_element_visible_keys = ( 'id', 'deleted', 'name', 'description', 'synopsis', 'root_folder_id' )
@@ -1939,15 +1931,8 @@
if lp.action == trans.app.security_agent.permitted_actions.LIBRARY_ACCESS.action:
roles.append( lp.role )
return roles
- def get_display_name( self ):
- # Library name can be either a string or a unicode object. If string,
- # convert to unicode object assuming 'utf-8' format.
- name = self.name
- if isinstance( name, str ):
- name = unicode( name, 'utf-8' )
- return name
-class LibraryFolder( object, Dictifiable ):
+class LibraryFolder( object, Dictifiable, HasName ):
dict_element_visible_keys = ( 'id', 'parent_id', 'name', 'description', 'item_count', 'genome_build', 'update_time' )
def __init__( self, name=None, description=None, item_count=0, order_id=None ):
self.name = name or "Unnamed folder"
@@ -2012,13 +1997,7 @@
def activatable_library_datasets( self ):
# This needs to be a list
return [ ld for ld in self.datasets if ld.library_dataset_dataset_association and not ld.library_dataset_dataset_association.dataset.deleted ]
- def get_display_name( self ):
- # Library folder name can be either a string or a unicode object. If string,
- # convert to unicode object assuming 'utf-8' format.
- name = self.name
- if isinstance( name, str ):
- name = unicode( name, 'utf-8' )
- return name
+
def to_dict( self, view='collection' ):
rval = super( LibraryFolder, self ).to_dict( view=view )
info_association, inherited = self.get_info_association()
@@ -2129,7 +2108,7 @@
rval['metadata_' + name] = val
return rval
-class LibraryDatasetDatasetAssociation( DatasetInstance ):
+class LibraryDatasetDatasetAssociation( DatasetInstance, HasName ):
def __init__( self,
copied_from_history_dataset_association=None,
copied_from_library_dataset_dataset_association=None,
@@ -2304,15 +2283,6 @@
def templates_json( self, use_name=False ):
return json.dumps( self.templates_dict( use_name=use_name ) )
- def get_display_name( self ):
- """
- LibraryDatasetDatasetAssociation name can be either a string or a unicode object.
- If string, convert to unicode object assuming 'utf-8' format.
- """
- ldda_name = self.name
- if isinstance( ldda_name, str ):
- ldda_name = unicode( ldda_name, 'utf-8' )
- return ldda_name
class ExtendedMetadata( object ):
def __init__(self, data):
diff -r 89d7cf67241f36e5f2c4de0aa31328fb7823e7d5 -r 6b627e15f18b13a489ca4e4343703931d9333021 test/unit/test_galaxy_mapping.py
--- a/test/unit/test_galaxy_mapping.py
+++ b/test/unit/test_galaxy_mapping.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
import unittest
import galaxy.model.mapping as mapping
@@ -95,6 +96,35 @@
self.persist( visualization )
persist_and_check_rating( model.VisualizationRatingAssociation, visualization=visualization )
+ def test_display_name( self ):
+
+ def assert_display_name_converts_to_unicode( item, name ):
+ assert not isinstance( item.name, unicode )
+ assert isinstance( item.get_display_name(), unicode )
+ assert item.get_display_name() == name
+
+ ldda = self.model.LibraryDatasetDatasetAssociation( name='ldda_name' )
+ assert_display_name_converts_to_unicode( ldda, 'ldda_name' )
+
+ hda = self.model.HistoryDatasetAssociation( name='hda_name' )
+ assert_display_name_converts_to_unicode( hda, 'hda_name' )
+
+ history = self.model.History( name='history_name' )
+ assert_display_name_converts_to_unicode( history, 'history_name' )
+
+ library = self.model.Library( name='library_name' )
+ assert_display_name_converts_to_unicode( library, 'library_name' )
+
+ library_folder = self.model.LibraryFolder( name='library_folder' )
+ assert_display_name_converts_to_unicode( library_folder, 'library_folder' )
+
+ history = self.model.History(
+ name=u'Hello₩◎ґʟⅾ'
+ )
+ assert isinstance( history.name, unicode )
+ assert isinstance( history.get_display_name(), unicode )
+ assert history.get_display_name() == u'Hello₩◎ґʟⅾ'
+
def test_tags( self ):
model = self.model
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.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a658be4c5c37/
Changeset: a658be4c5c37
User: jmchilton
Date: 2014-02-02 02:49:54
Summary: Search API - allow non-admins to search their own workflows.
Just makes sense, but also enables easier functional tests of search.
Affected #: 1 file
diff -r a629ff293db60b781a9abb29309bc56a2107d366 -r a658be4c5c37165c790ab7bf95801cc230a1a04c lib/galaxy/webapps/galaxy/api/search.py
--- a/lib/galaxy/webapps/galaxy/api/search.py
+++ b/lib/galaxy/webapps/galaxy/api/search.py
@@ -43,7 +43,7 @@
elif type( item ) in [ trans.app.model.Job ]:
if item.used_id == trans.user or trans.user_is_admin():
append = True
- elif type( item ) in [ trans.app.model.Page ]:
+ elif type( item ) in [ trans.app.model.Page, trans.app.model.StoredWorkflow ]:
try:
if self.security_check( trans, item, False, True):
append = True
https://bitbucket.org/galaxy/galaxy-central/commits/89d7cf67241f/
Changeset: 89d7cf67241f
User: jmchilton
Date: 2014-02-02 02:53:04
Summary: Add some intial functional testing of search API.
Refactored workflow creation stuff in test_workflows to allow it to be used other places (namely test_search.py). Tests searching for workflows and filtering out deleted workflows.
Affected #: 3 files
diff -r a658be4c5c37165c790ab7bf95801cc230a1a04c -r 89d7cf67241f36e5f2c4de0aa31328fb7823e7d5 test/functional/api/helpers.py
--- a/test/functional/api/helpers.py
+++ b/test/functional/api/helpers.py
@@ -1,5 +1,9 @@
import time
from json import dumps
+from json import loads
+from pkg_resources import resource_string
+
+workflow_str = resource_string( __name__, "test_workflow_1.ga" )
class TestsDatasets:
@@ -56,3 +60,35 @@
history_id=history_id,
**kwds
)
+
+
+class WorkflowPopulator( object ):
+ # Impulse is to make this a Mixin, but probably better as an object.
+
+ def __init__( self, api_test_case ):
+ self.api_test_case = api_test_case
+
+ def load_workflow( self, name, add_pja=False ):
+ workflow = loads( workflow_str )
+ workflow[ "name" ] = name
+ if add_pja:
+ tool_step = workflow[ "steps" ][ "2" ]
+ tool_step[ "post_job_actions" ][ "RenameDatasetActionout_file1" ] = dict(
+ action_type="RenameDatasetAction",
+ output_name="out_file1",
+ action_arguments=dict( newname="the_new_name" ),
+ )
+ return workflow
+
+ def simple_workflow( self, name, **create_kwds ):
+ workflow = self.load_workflow( name )
+ return self.create_workflow( workflow, **create_kwds )
+
+ def create_workflow( self, workflow, **create_kwds ):
+ data = dict(
+ workflow=dumps( workflow ),
+ **create_kwds
+ )
+ upload_response = self.api_test_case._post( "workflows/upload", data=data )
+ uploaded_workflow_id = upload_response.json()[ "id" ]
+ return uploaded_workflow_id
diff -r a658be4c5c37165c790ab7bf95801cc230a1a04c -r 89d7cf67241f36e5f2c4de0aa31328fb7823e7d5 test/functional/api/test_search.py
--- /dev/null
+++ b/test/functional/api/test_search.py
@@ -0,0 +1,32 @@
+from base import api
+from base.interactor import delete_request
+
+from .helpers import WorkflowPopulator
+
+
+class SearchApiTestCase( api.ApiTestCase ):
+
+ def test_search_workflows( self ):
+ workflow_populator = WorkflowPopulator( self )
+ workflow_id = workflow_populator.simple_workflow( "test_for_search" )
+ search_response = self.__search( "select * from workflow" )
+ assert self.__has_result_with_name( search_response, "test_for_search (imported from API)" ), search_response.json()
+
+ # Deleted
+ delete_url = self._api_url( "workflows/%s" % workflow_id, use_key=True )
+ delete_request( delete_url )
+
+ search_response = self.__search( "select * from workflow where not deleted" )
+ assert not self.__has_result_with_name( search_response, "test_for_search (imported from API)" ), search_response.json()
+
+ def __search( self, query ):
+ data = dict( query=query )
+ search_response = self._post( "search", data=data )
+ self._assert_status_code_is( search_response, 200 )
+ return search_response
+
+ def __has_result_with_name( self, search_response, name ):
+ search_response_object = search_response.json()
+ assert "results" in search_response_object, search_response_object
+ results = search_response_object[ "results" ]
+ return name in map( lambda r: r.get( "name", None ), results )
diff -r a658be4c5c37165c790ab7bf95801cc230a1a04c -r 89d7cf67241f36e5f2c4de0aa31328fb7823e7d5 test/functional/api/test_workflows.py
--- a/test/functional/api/test_workflows.py
+++ b/test/functional/api/test_workflows.py
@@ -1,14 +1,11 @@
from base import api
-from json import loads
from json import dumps
-from pkg_resources import resource_string
import time
from .helpers import TestsDatasets
+from .helpers import WorkflowPopulator
from base.interactor import delete_request # requests like delete
-workflow_str = resource_string( __name__, "test_workflow_1.ga" )
-
# Workflow API TODO:
# - Allow history_id as param to workflow run action. (hist_id)
@@ -17,8 +14,12 @@
# - Much more testing obviously, always more testing.
class WorkflowsApiTestCase( api.ApiTestCase, TestsDatasets ):
+ def setUp( self ):
+ super( WorkflowsApiTestCase, self ).setUp()
+ self.workflow_populator = WorkflowPopulator( self )
+
def test_delete( self ):
- workflow_id = self._simple_workflow( "test_delete" )
+ workflow_id = self.workflow_populator.simple_workflow( "test_delete" )
workflow_name = "test_delete (imported from API)"
self._assert_user_has_workflow_with_name( workflow_name )
workflow_url = self._api_url( "workflows/%s" % workflow_id, use_key=True )
@@ -28,7 +29,7 @@
assert workflow_name not in self.__workflow_names()
def test_other_cannot_delete( self ):
- workflow_id = self._simple_workflow( "test_other_delete" )
+ workflow_id = self.workflow_populator.simple_workflow( "test_other_delete" )
with self._different_user():
workflow_url = self._api_url( "workflows/%s" % workflow_id, use_key=True )
delete_response = delete_request( workflow_url )
@@ -41,14 +42,14 @@
def test_import( self ):
data = dict(
- workflow=dumps( self._load_workflow( name="test_import" ) ),
+ workflow=dumps( self.workflow_populator.load_workflow( name="test_import" ) ),
)
upload_response = self._post( "workflows/upload", data=data )
self._assert_status_code_is( upload_response, 200 )
self._assert_user_has_workflow_with_name( "test_import (imported from API)" )
def test_export( self ):
- uploaded_workflow_id = self._simple_workflow( "test_for_export" )
+ uploaded_workflow_id = self.workflow_populator.simple_workflow( "test_for_export" )
download_response = self._get( "workflows/%s/download" % uploaded_workflow_id )
self._assert_status_code_is( download_response, 200 )
downloaded_workflow = download_response.json()
@@ -58,7 +59,7 @@
assert first_input[ "name" ] == "WorkflowInput1"
def test_run_workflow( self ):
- workflow = self._load_workflow( name="test_for_run" )
+ workflow = self.workflow_populator.load_workflow( name="test_for_run" )
workflow_request, history_id = self._setup_workflow_run( workflow )
# TODO: This should really be a post to workflows/<workflow_id>/run or
# something like that.
@@ -67,8 +68,8 @@
self._wait_for_history( history_id, assert_ok=True )
def test_pja_import_export( self ):
- workflow = self._load_workflow( name="test_for_pja_import", add_pja=True )
- uploaded_workflow_id = self._create_workflow( workflow )
+ workflow = self.workflow_populator.load_workflow( name="test_for_pja_import", add_pja=True )
+ uploaded_workflow_id = self.workflow_populator.create_workflow( workflow )
download_response = self._get( "workflows/%s/download" % uploaded_workflow_id )
downloaded_workflow = download_response.json()
self._assert_has_keys( downloaded_workflow[ "steps" ], "0", "1", "2" )
@@ -80,7 +81,7 @@
def test_post_job_action( self ):
""" Tests both import and execution of post job actions.
"""
- workflow = self._load_workflow( name="test_for_pja_run", add_pja=True )
+ workflow = self.workflow_populator.load_workflow( name="test_for_pja_run", add_pja=True )
workflow_request, history_id = self._setup_workflow_run( workflow )
run_workflow_response = self._post( "workflows", data=workflow_request )
self._assert_status_code_is( run_workflow_response, 200 )
@@ -92,7 +93,7 @@
assert "the_new_name" in map( lambda hda: hda[ "name" ], contents )
def _setup_workflow_run( self, workflow ):
- uploaded_workflow_id = self._create_workflow( workflow )
+ uploaded_workflow_id = self.workflow_populator.create_workflow( workflow )
workflow_show_resposne = self._get( "workflows/%s" % uploaded_workflow_id )
self._assert_status_code_is( workflow_show_resposne, 200 )
workflow_inputs = workflow_show_resposne.json()[ "inputs" ]
@@ -119,20 +120,6 @@
def _ds_entry( self, hda ):
return dict( src="hda", id=hda[ "id" ] )
- def _simple_workflow( self, name, **create_kwds ):
- workflow = self._load_workflow( name )
- return self._create_workflow( workflow, **create_kwds )
-
- def _create_workflow( self, workflow, **create_kwds ):
- data = dict(
- workflow=dumps( workflow ),
- **create_kwds
- )
- upload_response = self._post( "workflows/upload", data=data )
- self._assert_status_code_is( upload_response, 200 )
- uploaded_workflow_id = upload_response.json()[ "id" ]
- return uploaded_workflow_id
-
def _assert_user_has_workflow_with_name( self, name ):
names = self.__workflow_names()
assert name in names, "No workflows with name %s in users workflows <%s>" % ( name, names )
@@ -142,15 +129,3 @@
self._assert_status_code_is( index_response, 200 )
names = map( lambda w: w[ "name" ], index_response.json() )
return names
-
- def _load_workflow( self, name, add_pja=False ):
- workflow = loads( workflow_str )
- workflow[ "name" ] = name
- if add_pja:
- tool_step = workflow[ "steps" ][ "2" ]
- tool_step[ "post_job_actions" ][ "RenameDatasetActionout_file1" ] = dict(
- action_type="RenameDatasetAction",
- output_name="out_file1",
- action_arguments=dict( newname="the_new_name" ),
- )
- return workflow
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.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a47f9e36d1d0/
Changeset: a47f9e36d1d0
Branch: search
User: Kyle Ellrott
Date: 2014-01-31 01:54:44
Summary: Adding deleted field to StoredWorkflow 'to_dict' and ability to use deleted as selection field in search
Affected #: 2 files
diff -r 985e3d88f9ac85a90de7aa541b5844037cccd120 -r a47f9e36d1d001a2e96ee1043fa7a563cb7e60bd lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -2430,8 +2430,8 @@
class StoredWorkflow( object, Dictifiable):
- dict_collection_visible_keys = ( 'id', 'name', 'published' )
- dict_element_visible_keys = ( 'id', 'name', 'published' )
+ dict_collection_visible_keys = ( 'id', 'name', 'published', 'deleted' )
+ dict_element_visible_keys = ( 'id', 'name', 'published', 'deleted' )
def __init__( self ):
self.id = None
diff -r 985e3d88f9ac85a90de7aa541b5844037cccd120 -r a47f9e36d1d001a2e96ee1043fa7a563cb7e60bd lib/galaxy/model/search.py
--- a/lib/galaxy/model/search.py
+++ b/lib/galaxy/model/search.py
@@ -407,7 +407,8 @@
FIELDS = {
'name': ViewField('name', sqlalchemy_field=(StoredWorkflow, "name")),
'id': ViewField('id', sqlalchemy_field=(StoredWorkflow, "id"), id_decode=True),
- 'tag': ViewField('tag', handler=workflow_tag_handler)
+ 'tag': ViewField('tag', handler=workflow_tag_handler),
+ 'deleted': ViewField('deleted', sqlalchemy_field=(StoredWorkflow, "deleted")),
}
def search(self, trans):
https://bitbucket.org/galaxy/galaxy-central/commits/b5c16a375e42/
Changeset: b5c16a375e42
Branch: search
User: Kyle Ellrott
Date: 2014-01-31 01:56:57
Summary: Adding ability to select Histories based on 'deleted' status during search
Affected #: 1 file
diff -r a47f9e36d1d001a2e96ee1043fa7a563cb7e60bd -r b5c16a375e42932c8416b4c235d777b3e4088ad8 lib/galaxy/model/search.py
--- a/lib/galaxy/model/search.py
+++ b/lib/galaxy/model/search.py
@@ -376,7 +376,8 @@
'name': ViewField('name', sqlalchemy_field=(History, "name")),
'id': ViewField('id', sqlalchemy_field=(History, "id"), id_decode=True),
'tag': ViewField("tag", handler=history_handle_tag),
- 'annotation': ViewField("annotation", handler=history_handle_annotation)
+ 'annotation': ViewField("annotation", handler=history_handle_annotation),
+ 'deleted': ViewField('deleted', sqlalchemy_field=(History, "deleted"))
}
def search(self, trans):
https://bitbucket.org/galaxy/galaxy-central/commits/a629ff293db6/
Changeset: a629ff293db6
User: jmchilton
Date: 2014-02-02 02:57:47
Summary: Merged in kellrott/galaxy-central/search (pull request #318)
Adding deleted field to 'to_dict' and search selection of Workflows
Affected #: 2 files
diff -r 00810d29c09d351e6e582d4868907b989e686059 -r a629ff293db60b781a9abb29309bc56a2107d366 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -2448,8 +2448,8 @@
class StoredWorkflow( object, Dictifiable):
- dict_collection_visible_keys = ( 'id', 'name', 'published' )
- dict_element_visible_keys = ( 'id', 'name', 'published' )
+ dict_collection_visible_keys = ( 'id', 'name', 'published', 'deleted' )
+ dict_element_visible_keys = ( 'id', 'name', 'published', 'deleted' )
def __init__( self ):
self.id = None
diff -r 00810d29c09d351e6e582d4868907b989e686059 -r a629ff293db60b781a9abb29309bc56a2107d366 lib/galaxy/model/search.py
--- a/lib/galaxy/model/search.py
+++ b/lib/galaxy/model/search.py
@@ -376,7 +376,8 @@
'name': ViewField('name', sqlalchemy_field=(History, "name")),
'id': ViewField('id', sqlalchemy_field=(History, "id"), id_decode=True),
'tag': ViewField("tag", handler=history_handle_tag),
- 'annotation': ViewField("annotation", handler=history_handle_annotation)
+ 'annotation': ViewField("annotation", handler=history_handle_annotation),
+ 'deleted': ViewField('deleted', sqlalchemy_field=(History, "deleted"))
}
def search(self, trans):
@@ -407,7 +408,8 @@
FIELDS = {
'name': ViewField('name', sqlalchemy_field=(StoredWorkflow, "name")),
'id': ViewField('id', sqlalchemy_field=(StoredWorkflow, "id"), id_decode=True),
- 'tag': ViewField('tag', handler=workflow_tag_handler)
+ 'tag': ViewField('tag', handler=workflow_tag_handler),
+ 'deleted': ViewField('deleted', sqlalchemy_field=(StoredWorkflow, "deleted")),
}
def search(self, trans):
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.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f2ee4ba93917/
Changeset: f2ee4ba93917
User: dannon
Date: 2014-01-31 15:36:37
Summary: Require pytz in web framework where Babel depends on it.
Affected #: 1 file
diff -r b3e8c0ab30c94906be2bb5d76776b22f120c9c8e -r f2ee4ba93917f89e95971f198f96117ed67fda55 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -37,6 +37,7 @@
import mako.lookup
import mako.runtime
+pkg_resources.require( "pytz" ) # Used by Babel.
pkg_resources.require( "Babel" )
from babel.support import Translations
from babel import Locale, UnknownLocaleError
https://bitbucket.org/galaxy/galaxy-central/commits/00810d29c09d/
Changeset: 00810d29c09d
User: dannon
Date: 2014-01-31 15:42:24
Summary: Slight import cleanup in galaxy.web.framework, remove unsafe relative imports.
Affected #: 1 file
diff -r f2ee4ba93917f89e95971f198f96117ed67fda55 -r 00810d29c09d351e6e582d4868907b989e686059 lib/galaxy/web/framework/__init__.py
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -5,7 +5,6 @@
import hashlib
import inspect
import os
-import pkg_resources
import random
import socket
import string
@@ -14,40 +13,39 @@
from Cookie import CookieError
from functools import wraps
-pkg_resources.require( "Cheetah" )
+from galaxy import eggs
+
+eggs.require( "Cheetah" )
from Cheetah.Template import Template
-#TODO: Relative imports to be removed
-import base
-import helpers
-
from galaxy import util
+from galaxy.exceptions import error_codes
from galaxy.exceptions import MessageException
-from galaxy.exceptions import error_codes
from galaxy.util import asbool
from galaxy.util import safe_str_cmp
from galaxy.util.backports.importlib import import_module
from galaxy.util.json import from_json_string, to_json_string
from galaxy.util.sanitize_html import sanitize_html
+from galaxy.web.framework import base, helpers
import paste.httpexceptions
-pkg_resources.require( "Mako" )
+eggs.require( "Mako" )
import mako.template
import mako.lookup
import mako.runtime
-pkg_resources.require( "pytz" ) # Used by Babel.
-pkg_resources.require( "Babel" )
+eggs.require( "pytz" ) # Used by Babel.
+eggs.require( "Babel" )
from babel.support import Translations
from babel import Locale, UnknownLocaleError
-pkg_resources.require( "SQLAlchemy >= 0.4" )
+eggs.require( "SQLAlchemy >= 0.4" )
from sqlalchemy import and_
from sqlalchemy.orm.exc import NoResultFound
-pkg_resources.require( "pexpect" )
-pkg_resources.require( "amqplib" )
+eggs.require( "pexpect" )
+eggs.require( "amqplib" )
import logging
log = logging.getLogger( __name__ )
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.
1
0
commit/galaxy-central: dannon: Update guppy egg to 0.1.10. This resolves issues encountered on particular platforms (http://sourceforge.net/p/guppy-pe/bugs/10/)
by commits-noreply@bitbucket.org 31 Jan '14
by commits-noreply@bitbucket.org 31 Jan '14
31 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b3e8c0ab30c9/
Changeset: b3e8c0ab30c9
User: dannon
Date: 2014-01-31 15:29:24
Summary: Update guppy egg to 0.1.10. This resolves issues encountered on particular platforms (http://sourceforge.net/p/guppy-pe/bugs/10/)
Affected #: 1 file
diff -r b99981d64dc4d214032a059f7d0302b96bf9e2ad -r b3e8c0ab30c94906be2bb5d76776b22f120c9c8e eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -27,7 +27,7 @@
pysqlite = 2.5.6
python_lzo = 1.08_2.03_static
threadframe = 0.2
-guppy = 0.1.8
+guppy = 0.1.10
SQLAlchemy = 0.7.9
; msgpack_python = 0.2.4
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.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/324474c3c17f/
Changeset: 324474c3c17f
User: dannon
Date: 2014-01-31 15:26:07
Summary: Add pytz egg.
Affected #: 1 file
diff -r 4368f2b00150fd01840773711600c73abb8590ca -r 324474c3c17f3569bc7d9a715b8195727fb3f3b7 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -53,6 +53,7 @@
pexpect = 2.4
python_openid = 2.2.5
python_daemon = 1.5.5
+pytz = 2013.9
Routes = 1.12.3
sqlalchemy_migrate = 0.7.2
ssh = 1.7.14
https://bitbucket.org/galaxy/galaxy-central/commits/b99981d64dc4/
Changeset: b99981d64dc4
User: dannon
Date: 2014-01-31 15:26:21
Summary: Merge
Affected #: 2 files
diff -r 324474c3c17f3569bc7d9a715b8195727fb3f3b7 -r b99981d64dc4d214032a059f7d0302b96bf9e2ad static/scripts/mvc/grid/grid-template.js
--- a/static/scripts/mvc/grid/grid-template.js
+++ b/static/scripts/mvc/grid/grid-template.js
@@ -548,16 +548,16 @@
if (size < 20) {
size = 20;
}
- // +4 to account for search icon/button.
+ // +4 to account for space after placeholder
size = size + 4;
}
// print input field for column
tmpl += '<span class="search-box">' +
'<input class="search-box-input" id="input-' + column_key + '-filter" name="f-' + column_key + '" type="text" placeholder="' + value + '" size="' + size + '"/>' +
- //'<button type="submit" style="background: transparent; border: none; padding: 4px; margin: 0px;">' +
- // '<i class="fa fa-plus-circle" style="font-size: 1.2em;"></i>' +
- //'</button>' +
+ '<button type="submit" style="background: transparent; border: none; padding: 4px; margin: 0px;">' +
+ '<i class="fa fa-plus-circle"></i>' +
+ '</button>' +
'</span>' +
'</form>';
} else {
diff -r 324474c3c17f3569bc7d9a715b8195727fb3f3b7 -r b99981d64dc4d214032a059f7d0302b96bf9e2ad static/scripts/packed/mvc/grid/grid-template.js
--- a/static/scripts/packed/mvc/grid/grid-template.js
+++ b/static/scripts/packed/mvc/grid/grid-template.js
@@ -1,1 +1,1 @@
-define([],function(){return{grid:function(b){var a="";if(b.embedded){a=this.grid_header(b)+this.grid_table(b)}else{a='<div class="loading-elt-overlay"></div><table><tr><td width="75%">'+this.grid_header(b)+'</td><td></td><td></td></tr><tr><td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>'+this.grid_table(b)}if(b.info_text){a+='<br><div class="toolParamHelp" style="clear: both;">'+b.info_text+"</div>"}return a},grid_table:function(a){return'<form method="post" onsubmit="return false;"><table id="grid-table" class="grid"><thead id="grid-table-header"></thead><tbody id="grid-table-body"></tbody><tfoot id="grid-table-footer"></tfoot></table></form>'},grid_header:function(c){var b='<div class="grid-header">';if(!c.embedded){b+="<h2>"+c.title+"</h2>"}if(c.global_actions){b+='<ul class="manage-table-actions">';var d=(c.global_actions.length>=3);if(d){b+='<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li><div popupmenu="popup-global-actions">'}for(i in c.global_actions){var e=c.global_actions[i];var a="";if(e.inbound){a="use-inbound"}else{a="use-outbound"}b+='<li><a class="action-button '+a+'" href="'+e.url_args+'" onclick="return false;">'+e.label+"</a></li>"}if(d){b+="</div>"}b+="</ul>"}if(c.insert){b+=c.insert}b+=this.grid_filters(c);b+="</div>";return b},header:function(b){var a="<tr>";if(b.show_item_checkboxes){a+="<th>";if(b.items.length>0){a+='<input type="checkbox" id="check_all" name=select_all_checkbox value="true"><input type="hidden" name=select_all_checkbox value="true">'}a+="</th>"}for(var c in b.columns){var d=b.columns[c];if(d.visible){a+='<th id="'+d.key+'-header">';if(d.href){a+='<a href="'+d.href+'" class="sort-link" sort_key="'+d.key+'">'+d.label+"</a>"}else{a+=d.label}a+='<span class="sort-arrow">'+d.extra+"</span></th>"}}a+="</tr>";return a},body:function(r){var k="";var s=0;var e=r.items.length;if(e==0){k+='<tr><td colspan="100"><em>No Items</em></td></tr>';s=1}for(var f in r.items){var p=r.items[f];var a=p.encode_id;var g="grid-"+f+"-popup";k+="<tr ";if(r.current_item_id==p.id){k+='class="current"'}k+=">";if(r.show_item_checkboxes){k+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+a+'" id="'+a+'" class="grid-row-select-checkbox" /></td>'}for(j in r.columns){var d=r.columns[j];if(d.visible){var c="";if(d.nowrap){c='style="white-space:nowrap;"'}var q=p.column_config[d.label];var h=q.link;var l=q.value;var o=q.inbound;if(jQuery.type(l)==="string"){l=l.replace(/\/\//g,"/")}var b="";var n="";if(d.attach_popup){b="grid-"+f+"-popup";n="menubutton";if(h!=""){n+=" split"}n+=" popup"}k+="<td "+c+">";if(h){if(r.operations.length!=0){k+='<div id="'+b+'" class="'+n+'" style="float: left;">'}var m="";if(o){m="use-inbound"}else{m="use-outbound"}k+='<a class="label '+m+'" href="'+h+'" onclick="return false;">'+l+"</a>";if(r.operations.length!=0){k+="</div>"}}else{k+='<div id="'+b+'" class="'+n+'"><label id="'+d.label_id_prefix+a+'" for="'+a+'">'+l+"</label></div>"}k+="</td>"}}k+="</tr>";s++}return k},footer:function(o){var k="";if(o.use_paging&&o.num_pages>1){var m=o.num_page_links;var a=o.cur_page_num;var n=o.num_pages;var h=m/2;var g=a-h;var e=0;if(g==0){g=1;e=h-(a-g)}var d=h+e;var c=a+d;if(c<=n){max_offset=0}else{c=n;max_offset=d-(c+1-a)}if(max_offset!=0){g-=max_offset;if(g<1){g=1}}k+='<tr id="page-links-row">';if(o.show_item_checkboxes){k+="<td></td>"}k+='<td colspan="100"><span id="page-link-container">Page:';if(g>1){k+='<span class="page-link" id="page-link-1"><a href="javascript:void(0);" page_num="1" onclick="return false;">1</a></span> ...'}for(var l=g;l<c+1;l++){if(l==o.cur_page_num){k+='<span class="page-link inactive-link" id="page-link-'+l+'">'+l+"</span>"}else{k+='<span class="page-link" id="page-link-'+l+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+l+'">'+l+"</a></span>"}}if(c<n){k+='...<span class="page-link" id="page-link-'+n+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}k+="</span>";k+='<span class="page-link" id="show-all-link-span"> | <a href="javascript:void(0);" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(o.show_item_checkboxes){k+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+o.get_class_plural+": ";for(i in o.operations){var b=o.operations[i];if(b.allow_multiple){k+='<input type="button" value="'+b.label+'" class="operation-button action-button"> '}}k+="</td></tr>"}var f=false;for(i in o.operations){if(o.operations[i].global_operation){f=true;break}}if(f){k+='<tr><td colspan="100">';for(i in o.operations){var b=o.operations[i];if(b.global_operation){k+='<a class="action-button" href="'+b.global_operation+'">'+b.label+"</a>"}}k+="</td></tr>"}if(o.legend){k+='<tr><td colspan="100">'+o.legend+"</td></tr>"}return k},message:function(a){return'<p><div class="'+a.status+'message transient-message">'+a.message+'</div><div style="clear: both"></div></p>'},grid_filters:function(n){var a=n.default_filter_dict;var b=n.filters;var e="none";if(n.advanced_search){e="block"}var m=false;for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){var l=d.key;var c=b[l];var f=a[l];if(c&&f&&c!=f){e="block"}m=true}}var k="block";if(e=="block"){k="none"}var h='<div id="standard-search" style="display: '+k+';"><table><tr><td style="padding: 0;"><table>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="standard"){h+=this.grid_column_filter(n,d)}}h+="</table></td></tr><tr><td>";if(m){h+='<a href="" class="advanced-search-toggle">Advanced Search</a>'}h+="</td></tr></table></div>";h+='<div id="advanced-search" style="display: '+e+'; margin-top: 5px; border: 1px solid #ccc;"><table><tr><td style="text-align: left" colspan="100"><a href="" class="advanced-search-toggle">Close Advanced Search</a></td></tr>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){h+=this.grid_column_filter(n,d)}}h+="</table></div>";return h},grid_column_filter:function(e,c){var t=e.default_filter_dict;var l=e.filters;var a=c.label;var b=c.key;if(c.filterable=="advanced"){a=a.toLowerCase()}var k="<tr>";if(c.filterable=="advanced"){k+='<td align="left" style="padding-left: 10px">'+a+":</td>"}k+='<td style="padding-bottom: 1px;">';if(c.is_text){k+='<form class="text-filter-form" column_key="'+b+'" action="'+e.url+'" method="get" >';for(u in e.columns){var g=e.columns[u];var p=l[g.key];if(p){if(p!="All"){if(g.is_text){p=JSON.stringify(p)}k+='<input type="hidden" id="'+g.key+'" name="f-'+g.key+'" value="'+p+'"/>'}}}k+='<span id="'+b+'-filtering-criteria">';var h=l[b];if(h){var f=jQuery.type(h);if(f=="string"){if(h!="All"){k+=this.filter_element(b,h)}}if(f=="array"){for(var u in h){var n=h[u];var v=h;v=v.slice(u);k+=this.filter_element(b,n)}}}k+="</span>";var r="";if(c.filterable=="standard"){r=c.label.toLowerCase();var q=r.length;if(q<20){q=20}q=q+4}k+='<span class="search-box"><input class="search-box-input" id="input-'+b+'-filter" name="f-'+b+'" type="text" placeholder="'+r+'" size="'+q+'"/></span></form>'}else{k+='<span id="'+b+'-filtering-criteria">';var s=false;for(cf_label in e.categorical_filters[b]){var o=e.categorical_filters[b][cf_label];var d="";var m="";for(key in o){d=key;m=o[key]}if(s){k+=" | "}s=true;var n=l[b];if(n&&o[b]&&n==m){k+='<span class="categorical-filter '+b+'-filter current-filter">'+cf_label+"</span>"}else{k+='<span class="categorical-filter '+b+'-filter"><a href="javascript:void(0);" filter_key="'+d+'" filter_val="'+m+'">'+cf_label+"</a></span>"}}k+="</span>"}k+="</td></tr>";return k},filter_element:function(b,a){return'<span class="text-filter-val">'+a+'<a href="javascript:void(0);" filter_key="'+b+'" filter_val="'+a+'"><i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/></a></span>'}}});
\ No newline at end of file
+define([],function(){return{grid:function(b){var a="";if(b.embedded){a=this.grid_header(b)+this.grid_table(b)}else{a='<div class="loading-elt-overlay"></div><table><tr><td width="75%">'+this.grid_header(b)+'</td><td></td><td></td></tr><tr><td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>'+this.grid_table(b)}if(b.info_text){a+='<br><div class="toolParamHelp" style="clear: both;">'+b.info_text+"</div>"}return a},grid_table:function(a){return'<form method="post" onsubmit="return false;"><table id="grid-table" class="grid"><thead id="grid-table-header"></thead><tbody id="grid-table-body"></tbody><tfoot id="grid-table-footer"></tfoot></table></form>'},grid_header:function(c){var b='<div class="grid-header">';if(!c.embedded){b+="<h2>"+c.title+"</h2>"}if(c.global_actions){b+='<ul class="manage-table-actions">';var d=(c.global_actions.length>=3);if(d){b+='<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li><div popupmenu="popup-global-actions">'}for(i in c.global_actions){var e=c.global_actions[i];var a="";if(e.inbound){a="use-inbound"}else{a="use-outbound"}b+='<li><a class="action-button '+a+'" href="'+e.url_args+'" onclick="return false;">'+e.label+"</a></li>"}if(d){b+="</div>"}b+="</ul>"}if(c.insert){b+=c.insert}b+=this.grid_filters(c);b+="</div>";return b},header:function(b){var a="<tr>";if(b.show_item_checkboxes){a+="<th>";if(b.items.length>0){a+='<input type="checkbox" id="check_all" name=select_all_checkbox value="true"><input type="hidden" name=select_all_checkbox value="true">'}a+="</th>"}for(var c in b.columns){var d=b.columns[c];if(d.visible){a+='<th id="'+d.key+'-header">';if(d.href){a+='<a href="'+d.href+'" class="sort-link" sort_key="'+d.key+'">'+d.label+"</a>"}else{a+=d.label}a+='<span class="sort-arrow">'+d.extra+"</span></th>"}}a+="</tr>";return a},body:function(r){var k="";var s=0;var e=r.items.length;if(e==0){k+='<tr><td colspan="100"><em>No Items</em></td></tr>';s=1}for(var f in r.items){var p=r.items[f];var a=p.encode_id;var g="grid-"+f+"-popup";k+="<tr ";if(r.current_item_id==p.id){k+='class="current"'}k+=">";if(r.show_item_checkboxes){k+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+a+'" id="'+a+'" class="grid-row-select-checkbox" /></td>'}for(j in r.columns){var d=r.columns[j];if(d.visible){var c="";if(d.nowrap){c='style="white-space:nowrap;"'}var q=p.column_config[d.label];var h=q.link;var l=q.value;var o=q.inbound;if(jQuery.type(l)==="string"){l=l.replace(/\/\//g,"/")}var b="";var n="";if(d.attach_popup){b="grid-"+f+"-popup";n="menubutton";if(h!=""){n+=" split"}n+=" popup"}k+="<td "+c+">";if(h){if(r.operations.length!=0){k+='<div id="'+b+'" class="'+n+'" style="float: left;">'}var m="";if(o){m="use-inbound"}else{m="use-outbound"}k+='<a class="label '+m+'" href="'+h+'" onclick="return false;">'+l+"</a>";if(r.operations.length!=0){k+="</div>"}}else{k+='<div id="'+b+'" class="'+n+'"><label id="'+d.label_id_prefix+a+'" for="'+a+'">'+l+"</label></div>"}k+="</td>"}}k+="</tr>";s++}return k},footer:function(o){var k="";if(o.use_paging&&o.num_pages>1){var m=o.num_page_links;var a=o.cur_page_num;var n=o.num_pages;var h=m/2;var g=a-h;var e=0;if(g==0){g=1;e=h-(a-g)}var d=h+e;var c=a+d;if(c<=n){max_offset=0}else{c=n;max_offset=d-(c+1-a)}if(max_offset!=0){g-=max_offset;if(g<1){g=1}}k+='<tr id="page-links-row">';if(o.show_item_checkboxes){k+="<td></td>"}k+='<td colspan="100"><span id="page-link-container">Page:';if(g>1){k+='<span class="page-link" id="page-link-1"><a href="javascript:void(0);" page_num="1" onclick="return false;">1</a></span> ...'}for(var l=g;l<c+1;l++){if(l==o.cur_page_num){k+='<span class="page-link inactive-link" id="page-link-'+l+'">'+l+"</span>"}else{k+='<span class="page-link" id="page-link-'+l+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+l+'">'+l+"</a></span>"}}if(c<n){k+='...<span class="page-link" id="page-link-'+n+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}k+="</span>";k+='<span class="page-link" id="show-all-link-span"> | <a href="javascript:void(0);" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(o.show_item_checkboxes){k+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+o.get_class_plural+": ";for(i in o.operations){var b=o.operations[i];if(b.allow_multiple){k+='<input type="button" value="'+b.label+'" class="operation-button action-button"> '}}k+="</td></tr>"}var f=false;for(i in o.operations){if(o.operations[i].global_operation){f=true;break}}if(f){k+='<tr><td colspan="100">';for(i in o.operations){var b=o.operations[i];if(b.global_operation){k+='<a class="action-button" href="'+b.global_operation+'">'+b.label+"</a>"}}k+="</td></tr>"}if(o.legend){k+='<tr><td colspan="100">'+o.legend+"</td></tr>"}return k},message:function(a){return'<p><div class="'+a.status+'message transient-message">'+a.message+'</div><div style="clear: both"></div></p>'},grid_filters:function(n){var a=n.default_filter_dict;var b=n.filters;var e="none";if(n.advanced_search){e="block"}var m=false;for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){var l=d.key;var c=b[l];var f=a[l];if(c&&f&&c!=f){e="block"}m=true}}var k="block";if(e=="block"){k="none"}var h='<div id="standard-search" style="display: '+k+';"><table><tr><td style="padding: 0;"><table>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="standard"){h+=this.grid_column_filter(n,d)}}h+="</table></td></tr><tr><td>";if(m){h+='<a href="" class="advanced-search-toggle">Advanced Search</a>'}h+="</td></tr></table></div>";h+='<div id="advanced-search" style="display: '+e+'; margin-top: 5px; border: 1px solid #ccc;"><table><tr><td style="text-align: left" colspan="100"><a href="" class="advanced-search-toggle">Close Advanced Search</a></td></tr>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){h+=this.grid_column_filter(n,d)}}h+="</table></div>";return h},grid_column_filter:function(e,c){var t=e.default_filter_dict;var l=e.filters;var a=c.label;var b=c.key;if(c.filterable=="advanced"){a=a.toLowerCase()}var k="<tr>";if(c.filterable=="advanced"){k+='<td align="left" style="padding-left: 10px">'+a+":</td>"}k+='<td style="padding-bottom: 1px;">';if(c.is_text){k+='<form class="text-filter-form" column_key="'+b+'" action="'+e.url+'" method="get" >';for(u in e.columns){var g=e.columns[u];var p=l[g.key];if(p){if(p!="All"){if(g.is_text){p=JSON.stringify(p)}k+='<input type="hidden" id="'+g.key+'" name="f-'+g.key+'" value="'+p+'"/>'}}}k+='<span id="'+b+'-filtering-criteria">';var h=l[b];if(h){var f=jQuery.type(h);if(f=="string"){if(h!="All"){k+=this.filter_element(b,h)}}if(f=="array"){for(var u in h){var n=h[u];var v=h;v=v.slice(u);k+=this.filter_element(b,n)}}}k+="</span>";var r="";if(c.filterable=="standard"){r=c.label.toLowerCase();var q=r.length;if(q<20){q=20}q=q+4}k+='<span class="search-box"><input class="search-box-input" id="input-'+b+'-filter" name="f-'+b+'" type="text" placeholder="'+r+'" size="'+q+'"/><button type="submit" style="background: transparent; border: none; padding: 4px; margin: 0px;"><i class="fa fa-plus-circle"></i></button></span></form>'}else{k+='<span id="'+b+'-filtering-criteria">';var s=false;for(cf_label in e.categorical_filters[b]){var o=e.categorical_filters[b][cf_label];var d="";var m="";for(key in o){d=key;m=o[key]}if(s){k+=" | "}s=true;var n=l[b];if(n&&o[b]&&n==m){k+='<span class="categorical-filter '+b+'-filter current-filter">'+cf_label+"</span>"}else{k+='<span class="categorical-filter '+b+'-filter"><a href="javascript:void(0);" filter_key="'+d+'" filter_val="'+m+'">'+cf_label+"</a></span>"}}k+="</span>"}k+="</td></tr>";return k},filter_element:function(b,a){return'<span class="text-filter-val">'+a+'<a href="javascript:void(0);" filter_key="'+b+'" filter_val="'+a+'"><i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/></a></span>'}}});
\ No newline at end of file
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.
1
0
commit/galaxy-central: guerler: Grids: Add search button
by commits-noreply@bitbucket.org 31 Jan '14
by commits-noreply@bitbucket.org 31 Jan '14
31 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4b6a0e598c54/
Changeset: 4b6a0e598c54
User: guerler
Date: 2014-01-31 15:02:33
Summary: Grids: Add search button
Affected #: 2 files
diff -r 4368f2b00150fd01840773711600c73abb8590ca -r 4b6a0e598c5400e5bc4f731f153e32c46da5d98e static/scripts/mvc/grid/grid-template.js
--- a/static/scripts/mvc/grid/grid-template.js
+++ b/static/scripts/mvc/grid/grid-template.js
@@ -548,16 +548,16 @@
if (size < 20) {
size = 20;
}
- // +4 to account for search icon/button.
+ // +4 to account for space after placeholder
size = size + 4;
}
// print input field for column
tmpl += '<span class="search-box">' +
'<input class="search-box-input" id="input-' + column_key + '-filter" name="f-' + column_key + '" type="text" placeholder="' + value + '" size="' + size + '"/>' +
- //'<button type="submit" style="background: transparent; border: none; padding: 4px; margin: 0px;">' +
- // '<i class="fa fa-plus-circle" style="font-size: 1.2em;"></i>' +
- //'</button>' +
+ '<button type="submit" style="background: transparent; border: none; padding: 4px; margin: 0px;">' +
+ '<i class="fa fa-plus-circle"></i>' +
+ '</button>' +
'</span>' +
'</form>';
} else {
diff -r 4368f2b00150fd01840773711600c73abb8590ca -r 4b6a0e598c5400e5bc4f731f153e32c46da5d98e static/scripts/packed/mvc/grid/grid-template.js
--- a/static/scripts/packed/mvc/grid/grid-template.js
+++ b/static/scripts/packed/mvc/grid/grid-template.js
@@ -1,1 +1,1 @@
-define([],function(){return{grid:function(b){var a="";if(b.embedded){a=this.grid_header(b)+this.grid_table(b)}else{a='<div class="loading-elt-overlay"></div><table><tr><td width="75%">'+this.grid_header(b)+'</td><td></td><td></td></tr><tr><td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>'+this.grid_table(b)}if(b.info_text){a+='<br><div class="toolParamHelp" style="clear: both;">'+b.info_text+"</div>"}return a},grid_table:function(a){return'<form method="post" onsubmit="return false;"><table id="grid-table" class="grid"><thead id="grid-table-header"></thead><tbody id="grid-table-body"></tbody><tfoot id="grid-table-footer"></tfoot></table></form>'},grid_header:function(c){var b='<div class="grid-header">';if(!c.embedded){b+="<h2>"+c.title+"</h2>"}if(c.global_actions){b+='<ul class="manage-table-actions">';var d=(c.global_actions.length>=3);if(d){b+='<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li><div popupmenu="popup-global-actions">'}for(i in c.global_actions){var e=c.global_actions[i];var a="";if(e.inbound){a="use-inbound"}else{a="use-outbound"}b+='<li><a class="action-button '+a+'" href="'+e.url_args+'" onclick="return false;">'+e.label+"</a></li>"}if(d){b+="</div>"}b+="</ul>"}if(c.insert){b+=c.insert}b+=this.grid_filters(c);b+="</div>";return b},header:function(b){var a="<tr>";if(b.show_item_checkboxes){a+="<th>";if(b.items.length>0){a+='<input type="checkbox" id="check_all" name=select_all_checkbox value="true"><input type="hidden" name=select_all_checkbox value="true">'}a+="</th>"}for(var c in b.columns){var d=b.columns[c];if(d.visible){a+='<th id="'+d.key+'-header">';if(d.href){a+='<a href="'+d.href+'" class="sort-link" sort_key="'+d.key+'">'+d.label+"</a>"}else{a+=d.label}a+='<span class="sort-arrow">'+d.extra+"</span></th>"}}a+="</tr>";return a},body:function(r){var k="";var s=0;var e=r.items.length;if(e==0){k+='<tr><td colspan="100"><em>No Items</em></td></tr>';s=1}for(var f in r.items){var p=r.items[f];var a=p.encode_id;var g="grid-"+f+"-popup";k+="<tr ";if(r.current_item_id==p.id){k+='class="current"'}k+=">";if(r.show_item_checkboxes){k+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+a+'" id="'+a+'" class="grid-row-select-checkbox" /></td>'}for(j in r.columns){var d=r.columns[j];if(d.visible){var c="";if(d.nowrap){c='style="white-space:nowrap;"'}var q=p.column_config[d.label];var h=q.link;var l=q.value;var o=q.inbound;if(jQuery.type(l)==="string"){l=l.replace(/\/\//g,"/")}var b="";var n="";if(d.attach_popup){b="grid-"+f+"-popup";n="menubutton";if(h!=""){n+=" split"}n+=" popup"}k+="<td "+c+">";if(h){if(r.operations.length!=0){k+='<div id="'+b+'" class="'+n+'" style="float: left;">'}var m="";if(o){m="use-inbound"}else{m="use-outbound"}k+='<a class="label '+m+'" href="'+h+'" onclick="return false;">'+l+"</a>";if(r.operations.length!=0){k+="</div>"}}else{k+='<div id="'+b+'" class="'+n+'"><label id="'+d.label_id_prefix+a+'" for="'+a+'">'+l+"</label></div>"}k+="</td>"}}k+="</tr>";s++}return k},footer:function(o){var k="";if(o.use_paging&&o.num_pages>1){var m=o.num_page_links;var a=o.cur_page_num;var n=o.num_pages;var h=m/2;var g=a-h;var e=0;if(g==0){g=1;e=h-(a-g)}var d=h+e;var c=a+d;if(c<=n){max_offset=0}else{c=n;max_offset=d-(c+1-a)}if(max_offset!=0){g-=max_offset;if(g<1){g=1}}k+='<tr id="page-links-row">';if(o.show_item_checkboxes){k+="<td></td>"}k+='<td colspan="100"><span id="page-link-container">Page:';if(g>1){k+='<span class="page-link" id="page-link-1"><a href="javascript:void(0);" page_num="1" onclick="return false;">1</a></span> ...'}for(var l=g;l<c+1;l++){if(l==o.cur_page_num){k+='<span class="page-link inactive-link" id="page-link-'+l+'">'+l+"</span>"}else{k+='<span class="page-link" id="page-link-'+l+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+l+'">'+l+"</a></span>"}}if(c<n){k+='...<span class="page-link" id="page-link-'+n+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}k+="</span>";k+='<span class="page-link" id="show-all-link-span"> | <a href="javascript:void(0);" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(o.show_item_checkboxes){k+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+o.get_class_plural+": ";for(i in o.operations){var b=o.operations[i];if(b.allow_multiple){k+='<input type="button" value="'+b.label+'" class="operation-button action-button"> '}}k+="</td></tr>"}var f=false;for(i in o.operations){if(o.operations[i].global_operation){f=true;break}}if(f){k+='<tr><td colspan="100">';for(i in o.operations){var b=o.operations[i];if(b.global_operation){k+='<a class="action-button" href="'+b.global_operation+'">'+b.label+"</a>"}}k+="</td></tr>"}if(o.legend){k+='<tr><td colspan="100">'+o.legend+"</td></tr>"}return k},message:function(a){return'<p><div class="'+a.status+'message transient-message">'+a.message+'</div><div style="clear: both"></div></p>'},grid_filters:function(n){var a=n.default_filter_dict;var b=n.filters;var e="none";if(n.advanced_search){e="block"}var m=false;for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){var l=d.key;var c=b[l];var f=a[l];if(c&&f&&c!=f){e="block"}m=true}}var k="block";if(e=="block"){k="none"}var h='<div id="standard-search" style="display: '+k+';"><table><tr><td style="padding: 0;"><table>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="standard"){h+=this.grid_column_filter(n,d)}}h+="</table></td></tr><tr><td>";if(m){h+='<a href="" class="advanced-search-toggle">Advanced Search</a>'}h+="</td></tr></table></div>";h+='<div id="advanced-search" style="display: '+e+'; margin-top: 5px; border: 1px solid #ccc;"><table><tr><td style="text-align: left" colspan="100"><a href="" class="advanced-search-toggle">Close Advanced Search</a></td></tr>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){h+=this.grid_column_filter(n,d)}}h+="</table></div>";return h},grid_column_filter:function(e,c){var t=e.default_filter_dict;var l=e.filters;var a=c.label;var b=c.key;if(c.filterable=="advanced"){a=a.toLowerCase()}var k="<tr>";if(c.filterable=="advanced"){k+='<td align="left" style="padding-left: 10px">'+a+":</td>"}k+='<td style="padding-bottom: 1px;">';if(c.is_text){k+='<form class="text-filter-form" column_key="'+b+'" action="'+e.url+'" method="get" >';for(u in e.columns){var g=e.columns[u];var p=l[g.key];if(p){if(p!="All"){if(g.is_text){p=JSON.stringify(p)}k+='<input type="hidden" id="'+g.key+'" name="f-'+g.key+'" value="'+p+'"/>'}}}k+='<span id="'+b+'-filtering-criteria">';var h=l[b];if(h){var f=jQuery.type(h);if(f=="string"){if(h!="All"){k+=this.filter_element(b,h)}}if(f=="array"){for(var u in h){var n=h[u];var v=h;v=v.slice(u);k+=this.filter_element(b,n)}}}k+="</span>";var r="";if(c.filterable=="standard"){r=c.label.toLowerCase();var q=r.length;if(q<20){q=20}q=q+4}k+='<span class="search-box"><input class="search-box-input" id="input-'+b+'-filter" name="f-'+b+'" type="text" placeholder="'+r+'" size="'+q+'"/></span></form>'}else{k+='<span id="'+b+'-filtering-criteria">';var s=false;for(cf_label in e.categorical_filters[b]){var o=e.categorical_filters[b][cf_label];var d="";var m="";for(key in o){d=key;m=o[key]}if(s){k+=" | "}s=true;var n=l[b];if(n&&o[b]&&n==m){k+='<span class="categorical-filter '+b+'-filter current-filter">'+cf_label+"</span>"}else{k+='<span class="categorical-filter '+b+'-filter"><a href="javascript:void(0);" filter_key="'+d+'" filter_val="'+m+'">'+cf_label+"</a></span>"}}k+="</span>"}k+="</td></tr>";return k},filter_element:function(b,a){return'<span class="text-filter-val">'+a+'<a href="javascript:void(0);" filter_key="'+b+'" filter_val="'+a+'"><i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/></a></span>'}}});
\ No newline at end of file
+define([],function(){return{grid:function(b){var a="";if(b.embedded){a=this.grid_header(b)+this.grid_table(b)}else{a='<div class="loading-elt-overlay"></div><table><tr><td width="75%">'+this.grid_header(b)+'</td><td></td><td></td></tr><tr><td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>'+this.grid_table(b)}if(b.info_text){a+='<br><div class="toolParamHelp" style="clear: both;">'+b.info_text+"</div>"}return a},grid_table:function(a){return'<form method="post" onsubmit="return false;"><table id="grid-table" class="grid"><thead id="grid-table-header"></thead><tbody id="grid-table-body"></tbody><tfoot id="grid-table-footer"></tfoot></table></form>'},grid_header:function(c){var b='<div class="grid-header">';if(!c.embedded){b+="<h2>"+c.title+"</h2>"}if(c.global_actions){b+='<ul class="manage-table-actions">';var d=(c.global_actions.length>=3);if(d){b+='<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li><div popupmenu="popup-global-actions">'}for(i in c.global_actions){var e=c.global_actions[i];var a="";if(e.inbound){a="use-inbound"}else{a="use-outbound"}b+='<li><a class="action-button '+a+'" href="'+e.url_args+'" onclick="return false;">'+e.label+"</a></li>"}if(d){b+="</div>"}b+="</ul>"}if(c.insert){b+=c.insert}b+=this.grid_filters(c);b+="</div>";return b},header:function(b){var a="<tr>";if(b.show_item_checkboxes){a+="<th>";if(b.items.length>0){a+='<input type="checkbox" id="check_all" name=select_all_checkbox value="true"><input type="hidden" name=select_all_checkbox value="true">'}a+="</th>"}for(var c in b.columns){var d=b.columns[c];if(d.visible){a+='<th id="'+d.key+'-header">';if(d.href){a+='<a href="'+d.href+'" class="sort-link" sort_key="'+d.key+'">'+d.label+"</a>"}else{a+=d.label}a+='<span class="sort-arrow">'+d.extra+"</span></th>"}}a+="</tr>";return a},body:function(r){var k="";var s=0;var e=r.items.length;if(e==0){k+='<tr><td colspan="100"><em>No Items</em></td></tr>';s=1}for(var f in r.items){var p=r.items[f];var a=p.encode_id;var g="grid-"+f+"-popup";k+="<tr ";if(r.current_item_id==p.id){k+='class="current"'}k+=">";if(r.show_item_checkboxes){k+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+a+'" id="'+a+'" class="grid-row-select-checkbox" /></td>'}for(j in r.columns){var d=r.columns[j];if(d.visible){var c="";if(d.nowrap){c='style="white-space:nowrap;"'}var q=p.column_config[d.label];var h=q.link;var l=q.value;var o=q.inbound;if(jQuery.type(l)==="string"){l=l.replace(/\/\//g,"/")}var b="";var n="";if(d.attach_popup){b="grid-"+f+"-popup";n="menubutton";if(h!=""){n+=" split"}n+=" popup"}k+="<td "+c+">";if(h){if(r.operations.length!=0){k+='<div id="'+b+'" class="'+n+'" style="float: left;">'}var m="";if(o){m="use-inbound"}else{m="use-outbound"}k+='<a class="label '+m+'" href="'+h+'" onclick="return false;">'+l+"</a>";if(r.operations.length!=0){k+="</div>"}}else{k+='<div id="'+b+'" class="'+n+'"><label id="'+d.label_id_prefix+a+'" for="'+a+'">'+l+"</label></div>"}k+="</td>"}}k+="</tr>";s++}return k},footer:function(o){var k="";if(o.use_paging&&o.num_pages>1){var m=o.num_page_links;var a=o.cur_page_num;var n=o.num_pages;var h=m/2;var g=a-h;var e=0;if(g==0){g=1;e=h-(a-g)}var d=h+e;var c=a+d;if(c<=n){max_offset=0}else{c=n;max_offset=d-(c+1-a)}if(max_offset!=0){g-=max_offset;if(g<1){g=1}}k+='<tr id="page-links-row">';if(o.show_item_checkboxes){k+="<td></td>"}k+='<td colspan="100"><span id="page-link-container">Page:';if(g>1){k+='<span class="page-link" id="page-link-1"><a href="javascript:void(0);" page_num="1" onclick="return false;">1</a></span> ...'}for(var l=g;l<c+1;l++){if(l==o.cur_page_num){k+='<span class="page-link inactive-link" id="page-link-'+l+'">'+l+"</span>"}else{k+='<span class="page-link" id="page-link-'+l+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+l+'">'+l+"</a></span>"}}if(c<n){k+='...<span class="page-link" id="page-link-'+n+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}k+="</span>";k+='<span class="page-link" id="show-all-link-span"> | <a href="javascript:void(0);" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(o.show_item_checkboxes){k+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+o.get_class_plural+": ";for(i in o.operations){var b=o.operations[i];if(b.allow_multiple){k+='<input type="button" value="'+b.label+'" class="operation-button action-button"> '}}k+="</td></tr>"}var f=false;for(i in o.operations){if(o.operations[i].global_operation){f=true;break}}if(f){k+='<tr><td colspan="100">';for(i in o.operations){var b=o.operations[i];if(b.global_operation){k+='<a class="action-button" href="'+b.global_operation+'">'+b.label+"</a>"}}k+="</td></tr>"}if(o.legend){k+='<tr><td colspan="100">'+o.legend+"</td></tr>"}return k},message:function(a){return'<p><div class="'+a.status+'message transient-message">'+a.message+'</div><div style="clear: both"></div></p>'},grid_filters:function(n){var a=n.default_filter_dict;var b=n.filters;var e="none";if(n.advanced_search){e="block"}var m=false;for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){var l=d.key;var c=b[l];var f=a[l];if(c&&f&&c!=f){e="block"}m=true}}var k="block";if(e=="block"){k="none"}var h='<div id="standard-search" style="display: '+k+';"><table><tr><td style="padding: 0;"><table>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="standard"){h+=this.grid_column_filter(n,d)}}h+="</table></td></tr><tr><td>";if(m){h+='<a href="" class="advanced-search-toggle">Advanced Search</a>'}h+="</td></tr></table></div>";h+='<div id="advanced-search" style="display: '+e+'; margin-top: 5px; border: 1px solid #ccc;"><table><tr><td style="text-align: left" colspan="100"><a href="" class="advanced-search-toggle">Close Advanced Search</a></td></tr>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){h+=this.grid_column_filter(n,d)}}h+="</table></div>";return h},grid_column_filter:function(e,c){var t=e.default_filter_dict;var l=e.filters;var a=c.label;var b=c.key;if(c.filterable=="advanced"){a=a.toLowerCase()}var k="<tr>";if(c.filterable=="advanced"){k+='<td align="left" style="padding-left: 10px">'+a+":</td>"}k+='<td style="padding-bottom: 1px;">';if(c.is_text){k+='<form class="text-filter-form" column_key="'+b+'" action="'+e.url+'" method="get" >';for(u in e.columns){var g=e.columns[u];var p=l[g.key];if(p){if(p!="All"){if(g.is_text){p=JSON.stringify(p)}k+='<input type="hidden" id="'+g.key+'" name="f-'+g.key+'" value="'+p+'"/>'}}}k+='<span id="'+b+'-filtering-criteria">';var h=l[b];if(h){var f=jQuery.type(h);if(f=="string"){if(h!="All"){k+=this.filter_element(b,h)}}if(f=="array"){for(var u in h){var n=h[u];var v=h;v=v.slice(u);k+=this.filter_element(b,n)}}}k+="</span>";var r="";if(c.filterable=="standard"){r=c.label.toLowerCase();var q=r.length;if(q<20){q=20}q=q+4}k+='<span class="search-box"><input class="search-box-input" id="input-'+b+'-filter" name="f-'+b+'" type="text" placeholder="'+r+'" size="'+q+'"/><button type="submit" style="background: transparent; border: none; padding: 4px; margin: 0px;"><i class="fa fa-plus-circle"></i></button></span></form>'}else{k+='<span id="'+b+'-filtering-criteria">';var s=false;for(cf_label in e.categorical_filters[b]){var o=e.categorical_filters[b][cf_label];var d="";var m="";for(key in o){d=key;m=o[key]}if(s){k+=" | "}s=true;var n=l[b];if(n&&o[b]&&n==m){k+='<span class="categorical-filter '+b+'-filter current-filter">'+cf_label+"</span>"}else{k+='<span class="categorical-filter '+b+'-filter"><a href="javascript:void(0);" filter_key="'+d+'" filter_val="'+m+'">'+cf_label+"</a></span>"}}k+="</span>"}k+="</td></tr>";return k},filter_element:function(b,a){return'<span class="text-filter-val">'+a+'<a href="javascript:void(0);" filter_key="'+b+'" filter_val="'+a+'"><i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/></a></span>'}}});
\ No newline at end of file
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.
1
0
commit/galaxy-central: guerler: Grids: Remove url generation from js template
by commits-noreply@bitbucket.org 31 Jan '14
by commits-noreply@bitbucket.org 31 Jan '14
31 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4368f2b00150/
Changeset: 4368f2b00150
User: guerler
Date: 2014-01-31 14:24:39
Summary: Grids: Remove url generation from js template
Affected #: 4 files
diff -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 -r 4368f2b00150fd01840773711600c73abb8590ca static/scripts/mvc/grid/grid-template.js
--- a/static/scripts/mvc/grid/grid-template.js
+++ b/static/scripts/mvc/grid/grid-template.js
@@ -230,7 +230,7 @@
},
// template
- footer: function(grid_model, options) {
+ footer: function(options) {
// create template string
var tmpl = '';
@@ -284,7 +284,7 @@
'Page:';
if (min_page > 1) {
- tmpl += '<span class="page-link" id="page-link-1"><a href="' + grid_model.get_url({page : page_index}) + '" page_num="1" onclick="return false;">1</a></span> ...';
+ tmpl += '<span class="page-link" id="page-link-1"><a href="javascript:void(0);" page_num="1" onclick="return false;">1</a></span> ...';
}
// create page urls
@@ -293,19 +293,19 @@
if (page_index == options.cur_page_num) {
tmpl += '<span class="page-link inactive-link" id="page-link-' + page_index + '">' + page_index + '</span>';
} else {
- tmpl += '<span class="page-link" id="page-link-' + page_index + '"><a href="' + grid_model.get_url({page : page_index}) + '" onclick="return false;" page_num="' + page_index + '">' + page_index + '</a></span>';
+ tmpl += '<span class="page-link" id="page-link-' + page_index + '"><a href="javascript:void(0);" onclick="return false;" page_num="' + page_index + '">' + page_index + '</a></span>';
}
}
// show last page
if (max_page < num_pages) {
tmpl += '...' +
- '<span class="page-link" id="page-link-' + num_pages + '"><a href="' + grid_model.get_url({page : num_pages}) + '" onclick="return false;" page_num="' + num_pages + '">' + num_pages + '</a></span>';
+ '<span class="page-link" id="page-link-' + num_pages + '"><a href="javascript:void(0);" onclick="return false;" page_num="' + num_pages + '">' + num_pages + '</a></span>';
}
tmpl += '</span>';
// Show all link
- tmpl += '<span class="page-link" id="show-all-link-span"> | <a href="' + grid_model.get_url({page : 'all'}) + '" onclick="return false;" page_num="all">Show All</a></span>' +
+ tmpl += '<span class="page-link" id="show-all-link-span"> | <a href="javascript:void(0);" onclick="return false;" page_num="all">Show All</a></span>' +
'</td>' +
'</tr>';
}
diff -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 -r 4368f2b00150fd01840773711600c73abb8590ca static/scripts/mvc/grid/grid-view.js
--- a/static/scripts/mvc/grid/grid-view.js
+++ b/static/scripts/mvc/grid/grid-view.js
@@ -63,7 +63,7 @@
// update div contents
this.$el.find('#grid-table-header').html(Templates.header(options));
this.$el.find('#grid-table-body').html(Templates.body(options));
- this.$el.find('#grid-table-footer').html(Templates.footer(this.grid, options));
+ this.$el.find('#grid-table-footer').html(Templates.footer(options));
// update message
if (options.message) {
diff -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 -r 4368f2b00150fd01840773711600c73abb8590ca static/scripts/packed/mvc/grid/grid-template.js
--- a/static/scripts/packed/mvc/grid/grid-template.js
+++ b/static/scripts/packed/mvc/grid/grid-template.js
@@ -1,1 +1,1 @@
-define([],function(){return{grid:function(b){var a="";if(b.embedded){a=this.grid_header(b)+this.grid_table(b)}else{a='<div class="loading-elt-overlay"></div><table><tr><td width="75%">'+this.grid_header(b)+'</td><td></td><td></td></tr><tr><td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>'+this.grid_table(b)}if(b.info_text){a+='<br><div class="toolParamHelp" style="clear: both;">'+b.info_text+"</div>"}return a},grid_table:function(a){return'<form method="post" onsubmit="return false;"><table id="grid-table" class="grid"><thead id="grid-table-header"></thead><tbody id="grid-table-body"></tbody><tfoot id="grid-table-footer"></tfoot></table></form>'},grid_header:function(c){var b='<div class="grid-header">';if(!c.embedded){b+="<h2>"+c.title+"</h2>"}if(c.global_actions){b+='<ul class="manage-table-actions">';var d=(c.global_actions.length>=3);if(d){b+='<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li><div popupmenu="popup-global-actions">'}for(i in c.global_actions){var e=c.global_actions[i];var a="";if(e.inbound){a="use-inbound"}else{a="use-outbound"}b+='<li><a class="action-button '+a+'" href="'+e.url_args+'" onclick="return false;">'+e.label+"</a></li>"}if(d){b+="</div>"}b+="</ul>"}if(c.insert){b+=c.insert}b+=this.grid_filters(c);b+="</div>";return b},header:function(b){var a="<tr>";if(b.show_item_checkboxes){a+="<th>";if(b.items.length>0){a+='<input type="checkbox" id="check_all" name=select_all_checkbox value="true"><input type="hidden" name=select_all_checkbox value="true">'}a+="</th>"}for(var c in b.columns){var d=b.columns[c];if(d.visible){a+='<th id="'+d.key+'-header">';if(d.href){a+='<a href="'+d.href+'" class="sort-link" sort_key="'+d.key+'">'+d.label+"</a>"}else{a+=d.label}a+='<span class="sort-arrow">'+d.extra+"</span></th>"}}a+="</tr>";return a},body:function(r){var k="";var s=0;var e=r.items.length;if(e==0){k+='<tr><td colspan="100"><em>No Items</em></td></tr>';s=1}for(var f in r.items){var p=r.items[f];var a=p.encode_id;var g="grid-"+f+"-popup";k+="<tr ";if(r.current_item_id==p.id){k+='class="current"'}k+=">";if(r.show_item_checkboxes){k+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+a+'" id="'+a+'" class="grid-row-select-checkbox" /></td>'}for(j in r.columns){var d=r.columns[j];if(d.visible){var c="";if(d.nowrap){c='style="white-space:nowrap;"'}var q=p.column_config[d.label];var h=q.link;var l=q.value;var o=q.inbound;if(jQuery.type(l)==="string"){l=l.replace(/\/\//g,"/")}var b="";var n="";if(d.attach_popup){b="grid-"+f+"-popup";n="menubutton";if(h!=""){n+=" split"}n+=" popup"}k+="<td "+c+">";if(h){if(r.operations.length!=0){k+='<div id="'+b+'" class="'+n+'" style="float: left;">'}var m="";if(o){m="use-inbound"}else{m="use-outbound"}k+='<a class="label '+m+'" href="'+h+'" onclick="return false;">'+l+"</a>";if(r.operations.length!=0){k+="</div>"}}else{k+='<div id="'+b+'" class="'+n+'"><label id="'+d.label_id_prefix+a+'" for="'+a+'">'+l+"</label></div>"}k+="</td>"}}k+="</tr>";s++}return k},footer:function(h,p){var l="";if(p.use_paging&&p.num_pages>1){var n=p.num_page_links;var a=p.cur_page_num;var o=p.num_pages;var k=n/2;var g=a-k;var e=0;if(g==0){g=1;e=k-(a-g)}var d=k+e;var c=a+d;if(c<=o){max_offset=0}else{c=o;max_offset=d-(c+1-a)}if(max_offset!=0){g-=max_offset;if(g<1){g=1}}l+='<tr id="page-links-row">';if(p.show_item_checkboxes){l+="<td></td>"}l+='<td colspan="100"><span id="page-link-container">Page:';if(g>1){l+='<span class="page-link" id="page-link-1"><a href="'+h.get_url({page:m})+'" page_num="1" onclick="return false;">1</a></span> ...'}for(var m=g;m<c+1;m++){if(m==p.cur_page_num){l+='<span class="page-link inactive-link" id="page-link-'+m+'">'+m+"</span>"}else{l+='<span class="page-link" id="page-link-'+m+'"><a href="'+h.get_url({page:m})+'" onclick="return false;" page_num="'+m+'">'+m+"</a></span>"}}if(c<o){l+='...<span class="page-link" id="page-link-'+o+'"><a href="'+h.get_url({page:o})+'" onclick="return false;" page_num="'+o+'">'+o+"</a></span>"}l+="</span>";l+='<span class="page-link" id="show-all-link-span"> | <a href="'+h.get_url({page:"all"})+'" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(p.show_item_checkboxes){l+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+p.get_class_plural+": ";for(i in p.operations){var b=p.operations[i];if(b.allow_multiple){l+='<input type="button" value="'+b.label+'" class="operation-button action-button"> '}}l+="</td></tr>"}var f=false;for(i in p.operations){if(p.operations[i].global_operation){f=true;break}}if(f){l+='<tr><td colspan="100">';for(i in p.operations){var b=p.operations[i];if(b.global_operation){l+='<a class="action-button" href="'+b.global_operation+'">'+b.label+"</a>"}}l+="</td></tr>"}if(p.legend){l+='<tr><td colspan="100">'+p.legend+"</td></tr>"}return l},message:function(a){return'<p><div class="'+a.status+'message transient-message">'+a.message+'</div><div style="clear: both"></div></p>'},grid_filters:function(n){var a=n.default_filter_dict;var b=n.filters;var e="none";if(n.advanced_search){e="block"}var m=false;for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){var l=d.key;var c=b[l];var f=a[l];if(c&&f&&c!=f){e="block"}m=true}}var k="block";if(e=="block"){k="none"}var h='<div id="standard-search" style="display: '+k+';"><table><tr><td style="padding: 0;"><table>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="standard"){h+=this.grid_column_filter(n,d)}}h+="</table></td></tr><tr><td>";if(m){h+='<a href="" class="advanced-search-toggle">Advanced Search</a>'}h+="</td></tr></table></div>";h+='<div id="advanced-search" style="display: '+e+'; margin-top: 5px; border: 1px solid #ccc;"><table><tr><td style="text-align: left" colspan="100"><a href="" class="advanced-search-toggle">Close Advanced Search</a></td></tr>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){h+=this.grid_column_filter(n,d)}}h+="</table></div>";return h},grid_column_filter:function(e,c){var t=e.default_filter_dict;var l=e.filters;var a=c.label;var b=c.key;if(c.filterable=="advanced"){a=a.toLowerCase()}var k="<tr>";if(c.filterable=="advanced"){k+='<td align="left" style="padding-left: 10px">'+a+":</td>"}k+='<td style="padding-bottom: 1px;">';if(c.is_text){k+='<form class="text-filter-form" column_key="'+b+'" action="'+e.url+'" method="get" >';for(u in e.columns){var g=e.columns[u];var p=l[g.key];if(p){if(p!="All"){if(g.is_text){p=JSON.stringify(p)}k+='<input type="hidden" id="'+g.key+'" name="f-'+g.key+'" value="'+p+'"/>'}}}k+='<span id="'+b+'-filtering-criteria">';var h=l[b];if(h){var f=jQuery.type(h);if(f=="string"){if(h!="All"){k+=this.filter_element(b,h)}}if(f=="array"){for(var u in h){var n=h[u];var v=h;v=v.slice(u);k+=this.filter_element(b,n)}}}k+="</span>";var r="";if(c.filterable=="standard"){r=c.label.toLowerCase();var q=r.length;if(q<20){q=20}q=q+4}k+='<span class="search-box"><input class="search-box-input" id="input-'+b+'-filter" name="f-'+b+'" type="text" placeholder="'+r+'" size="'+q+'"/></span></form>'}else{k+='<span id="'+b+'-filtering-criteria">';var s=false;for(cf_label in e.categorical_filters[b]){var o=e.categorical_filters[b][cf_label];var d="";var m="";for(key in o){d=key;m=o[key]}if(s){k+=" | "}s=true;var n=l[b];if(n&&o[b]&&n==m){k+='<span class="categorical-filter '+b+'-filter current-filter">'+cf_label+"</span>"}else{k+='<span class="categorical-filter '+b+'-filter"><a href="javascript:void(0);" filter_key="'+d+'" filter_val="'+m+'">'+cf_label+"</a></span>"}}k+="</span>"}k+="</td></tr>";return k},filter_element:function(b,a){return'<span class="text-filter-val">'+a+'<a href="javascript:void(0);" filter_key="'+b+'" filter_val="'+a+'"><i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/></a></span>'}}});
\ No newline at end of file
+define([],function(){return{grid:function(b){var a="";if(b.embedded){a=this.grid_header(b)+this.grid_table(b)}else{a='<div class="loading-elt-overlay"></div><table><tr><td width="75%">'+this.grid_header(b)+'</td><td></td><td></td></tr><tr><td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>'+this.grid_table(b)}if(b.info_text){a+='<br><div class="toolParamHelp" style="clear: both;">'+b.info_text+"</div>"}return a},grid_table:function(a){return'<form method="post" onsubmit="return false;"><table id="grid-table" class="grid"><thead id="grid-table-header"></thead><tbody id="grid-table-body"></tbody><tfoot id="grid-table-footer"></tfoot></table></form>'},grid_header:function(c){var b='<div class="grid-header">';if(!c.embedded){b+="<h2>"+c.title+"</h2>"}if(c.global_actions){b+='<ul class="manage-table-actions">';var d=(c.global_actions.length>=3);if(d){b+='<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li><div popupmenu="popup-global-actions">'}for(i in c.global_actions){var e=c.global_actions[i];var a="";if(e.inbound){a="use-inbound"}else{a="use-outbound"}b+='<li><a class="action-button '+a+'" href="'+e.url_args+'" onclick="return false;">'+e.label+"</a></li>"}if(d){b+="</div>"}b+="</ul>"}if(c.insert){b+=c.insert}b+=this.grid_filters(c);b+="</div>";return b},header:function(b){var a="<tr>";if(b.show_item_checkboxes){a+="<th>";if(b.items.length>0){a+='<input type="checkbox" id="check_all" name=select_all_checkbox value="true"><input type="hidden" name=select_all_checkbox value="true">'}a+="</th>"}for(var c in b.columns){var d=b.columns[c];if(d.visible){a+='<th id="'+d.key+'-header">';if(d.href){a+='<a href="'+d.href+'" class="sort-link" sort_key="'+d.key+'">'+d.label+"</a>"}else{a+=d.label}a+='<span class="sort-arrow">'+d.extra+"</span></th>"}}a+="</tr>";return a},body:function(r){var k="";var s=0;var e=r.items.length;if(e==0){k+='<tr><td colspan="100"><em>No Items</em></td></tr>';s=1}for(var f in r.items){var p=r.items[f];var a=p.encode_id;var g="grid-"+f+"-popup";k+="<tr ";if(r.current_item_id==p.id){k+='class="current"'}k+=">";if(r.show_item_checkboxes){k+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+a+'" id="'+a+'" class="grid-row-select-checkbox" /></td>'}for(j in r.columns){var d=r.columns[j];if(d.visible){var c="";if(d.nowrap){c='style="white-space:nowrap;"'}var q=p.column_config[d.label];var h=q.link;var l=q.value;var o=q.inbound;if(jQuery.type(l)==="string"){l=l.replace(/\/\//g,"/")}var b="";var n="";if(d.attach_popup){b="grid-"+f+"-popup";n="menubutton";if(h!=""){n+=" split"}n+=" popup"}k+="<td "+c+">";if(h){if(r.operations.length!=0){k+='<div id="'+b+'" class="'+n+'" style="float: left;">'}var m="";if(o){m="use-inbound"}else{m="use-outbound"}k+='<a class="label '+m+'" href="'+h+'" onclick="return false;">'+l+"</a>";if(r.operations.length!=0){k+="</div>"}}else{k+='<div id="'+b+'" class="'+n+'"><label id="'+d.label_id_prefix+a+'" for="'+a+'">'+l+"</label></div>"}k+="</td>"}}k+="</tr>";s++}return k},footer:function(o){var k="";if(o.use_paging&&o.num_pages>1){var m=o.num_page_links;var a=o.cur_page_num;var n=o.num_pages;var h=m/2;var g=a-h;var e=0;if(g==0){g=1;e=h-(a-g)}var d=h+e;var c=a+d;if(c<=n){max_offset=0}else{c=n;max_offset=d-(c+1-a)}if(max_offset!=0){g-=max_offset;if(g<1){g=1}}k+='<tr id="page-links-row">';if(o.show_item_checkboxes){k+="<td></td>"}k+='<td colspan="100"><span id="page-link-container">Page:';if(g>1){k+='<span class="page-link" id="page-link-1"><a href="javascript:void(0);" page_num="1" onclick="return false;">1</a></span> ...'}for(var l=g;l<c+1;l++){if(l==o.cur_page_num){k+='<span class="page-link inactive-link" id="page-link-'+l+'">'+l+"</span>"}else{k+='<span class="page-link" id="page-link-'+l+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+l+'">'+l+"</a></span>"}}if(c<n){k+='...<span class="page-link" id="page-link-'+n+'"><a href="javascript:void(0);" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}k+="</span>";k+='<span class="page-link" id="show-all-link-span"> | <a href="javascript:void(0);" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(o.show_item_checkboxes){k+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+o.get_class_plural+": ";for(i in o.operations){var b=o.operations[i];if(b.allow_multiple){k+='<input type="button" value="'+b.label+'" class="operation-button action-button"> '}}k+="</td></tr>"}var f=false;for(i in o.operations){if(o.operations[i].global_operation){f=true;break}}if(f){k+='<tr><td colspan="100">';for(i in o.operations){var b=o.operations[i];if(b.global_operation){k+='<a class="action-button" href="'+b.global_operation+'">'+b.label+"</a>"}}k+="</td></tr>"}if(o.legend){k+='<tr><td colspan="100">'+o.legend+"</td></tr>"}return k},message:function(a){return'<p><div class="'+a.status+'message transient-message">'+a.message+'</div><div style="clear: both"></div></p>'},grid_filters:function(n){var a=n.default_filter_dict;var b=n.filters;var e="none";if(n.advanced_search){e="block"}var m=false;for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){var l=d.key;var c=b[l];var f=a[l];if(c&&f&&c!=f){e="block"}m=true}}var k="block";if(e=="block"){k="none"}var h='<div id="standard-search" style="display: '+k+';"><table><tr><td style="padding: 0;"><table>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="standard"){h+=this.grid_column_filter(n,d)}}h+="</table></td></tr><tr><td>";if(m){h+='<a href="" class="advanced-search-toggle">Advanced Search</a>'}h+="</td></tr></table></div>";h+='<div id="advanced-search" style="display: '+e+'; margin-top: 5px; border: 1px solid #ccc;"><table><tr><td style="text-align: left" colspan="100"><a href="" class="advanced-search-toggle">Close Advanced Search</a></td></tr>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){h+=this.grid_column_filter(n,d)}}h+="</table></div>";return h},grid_column_filter:function(e,c){var t=e.default_filter_dict;var l=e.filters;var a=c.label;var b=c.key;if(c.filterable=="advanced"){a=a.toLowerCase()}var k="<tr>";if(c.filterable=="advanced"){k+='<td align="left" style="padding-left: 10px">'+a+":</td>"}k+='<td style="padding-bottom: 1px;">';if(c.is_text){k+='<form class="text-filter-form" column_key="'+b+'" action="'+e.url+'" method="get" >';for(u in e.columns){var g=e.columns[u];var p=l[g.key];if(p){if(p!="All"){if(g.is_text){p=JSON.stringify(p)}k+='<input type="hidden" id="'+g.key+'" name="f-'+g.key+'" value="'+p+'"/>'}}}k+='<span id="'+b+'-filtering-criteria">';var h=l[b];if(h){var f=jQuery.type(h);if(f=="string"){if(h!="All"){k+=this.filter_element(b,h)}}if(f=="array"){for(var u in h){var n=h[u];var v=h;v=v.slice(u);k+=this.filter_element(b,n)}}}k+="</span>";var r="";if(c.filterable=="standard"){r=c.label.toLowerCase();var q=r.length;if(q<20){q=20}q=q+4}k+='<span class="search-box"><input class="search-box-input" id="input-'+b+'-filter" name="f-'+b+'" type="text" placeholder="'+r+'" size="'+q+'"/></span></form>'}else{k+='<span id="'+b+'-filtering-criteria">';var s=false;for(cf_label in e.categorical_filters[b]){var o=e.categorical_filters[b][cf_label];var d="";var m="";for(key in o){d=key;m=o[key]}if(s){k+=" | "}s=true;var n=l[b];if(n&&o[b]&&n==m){k+='<span class="categorical-filter '+b+'-filter current-filter">'+cf_label+"</span>"}else{k+='<span class="categorical-filter '+b+'-filter"><a href="javascript:void(0);" filter_key="'+d+'" filter_val="'+m+'">'+cf_label+"</a></span>"}}k+="</span>"}k+="</td></tr>";return k},filter_element:function(b,a){return'<span class="text-filter-val">'+a+'<a href="javascript:void(0);" filter_key="'+b+'" filter_val="'+a+'"><i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/></a></span>'}}});
\ No newline at end of file
diff -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 -r 4368f2b00150fd01840773711600c73abb8590ca static/scripts/packed/mvc/grid/grid-view.js
--- a/static/scripts/packed/mvc/grid/grid-view.js
+++ b/static/scripts/packed/mvc/grid/grid-view.js
@@ -1,1 +1,1 @@
-jQuery.ajaxSettings.traditional=true;define(["mvc/grid/grid-model","mvc/grid/grid-template","mvc/ui"],function(b,a){return Backbone.View.extend({grid:null,initialize:function(c){this.setElement("#grid-container");if(c.use_panels){$("#center").css({padding:"10px",overflow:"auto"})}this.init_grid(c)},handle_refresh:function(c){if(c){if($.inArray("history",c)>-1){if(top.Galaxy&&top.Galaxy.currHistoryPanel){top.Galaxy.currHistoryPanel.loadCurrentHistory()}}}},init_grid:function(f){this.grid=new b(f);var e=this.grid.attributes;this.handle_refresh(e.refresh_frames);var d=this.grid.get("url_base");d=d.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",d);this.$el.html(a.grid(e));this.$el.find("#grid-table-header").html(a.header(e));this.$el.find("#grid-table-body").html(a.body(e));this.$el.find("#grid-table-footer").html(a.footer(this.grid,e));if(e.message){this.$el.find("#grid-message").html(a.message(e));var c=this;if(e.use_hide_message){setTimeout(function(){c.$el.find("#grid-message").html("")},5000)}}this.init_grid_elements();this.init_grid_controls();init_refresh_on_change()},init_grid_controls:function(){var c=this;this.$el.find(".operation-button").each(function(){$(this).off();$(this).click(function(){c.submit_operation(this,operation.confirm);return false})});this.$el.find("input[type=text]").each(function(){$(this).off();$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})});this.$el.find(".sort-link").each(function(){$(this).off();$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});this.$el.find(".text-filter-form").each(function(){$(this).off();$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});this.$el.find(".text-filter-val > a").each(function(){$(this).off();$(this).click(function(){$(this).parent().remove();c.remove_filter_condition($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});this.$el.find(".categorical-filter > a").each(function(){$(this).off();$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});var e=this.$el.find("#input-tags-filter");if(e.length){e.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var d=this.$el.find("#input-name-filter");if(d.length){d.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}this.$el.find(".advanced-search-toggle").each(function(){$(this).off();$(this).click(function(){c.$el.find("#standard-search").slideToggle("fast");c.$el.find("#advanced-search").slideToggle("fast");return false})});this.$el.find("#check_all").off();this.$el.find("#check_all").on("click",function(){c.check_all_items()})},init_grid_elements:function(){this.$el.find(".grid").each(function(){var j=$(this).find("input.grid-row-select-checkbox");var i=$(this).find("span.grid-selected-count");var r=function(){i.text($(j).filter(":checked").length)};$(j).each(function(){$(this).change(r)});r()});if(this.$el.find(".community_rating_star").length!==0){this.$el.find(".community_rating_star").rating({})}var q=this.grid.attributes;var p=this;this.$el.find(".page-link > a").each(function(){$(this).click(function(){p.set_page($(this).attr("page_num"));return false})});this.$el.find(".use-inbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href"),inbound:true});return false})});this.$el.find(".use-outbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href")});return false})});var f=q.items.length;if(f==0){return}for(var k in q.items){var o=q.items[k];var l=this.$el.find("#grid-"+k+"-popup");l.off();var d=new PopupMenu(l);for(var h in q.operations){var e=q.operations[h];var m=e.label;var c=o.operation_config[m];var g=o.encode_id;if(c.allowed&&e.allow_popup){var n={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};n.func=function(r){r.preventDefault();var j=$(r.target).html();var i=this.findItemByHtml(j);p.execute(i)};d.addItem(n)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$(a.filter_element(e,g));var d=this;f.click(function(){$(this).remove();d.remove_filter_condition(e,g)});var c=this.$el.find("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},remove_filter_condition:function(c,d){this.grid.remove_filter(c,d);this.go_page_one();this.execute()},set_sort_condition:function(g){var f=this.grid.get("sort_key");var e=g;if(f.indexOf(g)!==-1){if(f.substring(0,1)!=="-"){e="-"+g}}this.$el.find(".sort-arrow").remove();var d=(e.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+d+"</span>").addClass("sort-arrow");this.$el.find("#"+g+"-header").append(c);this.grid.set("sort_key",e);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;this.$el.find("."+e+"-filter").each(function(){var k=$.trim($(this).text());var i=d[k];var j=i[e];if(j==g){$(this).empty();$(this).addClass("current-filter");$(this).append(k)}else{if(j==f){$(this).empty();var h=$('<a href="#">'+k+"</a>");h.click(function(){c.set_categorical_filter(e,j)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;this.$el.find(".page-link").each(function(){var i=$(this).attr("id"),g=parseInt(i.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$('<a href="#">'+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(d,g){var e=$(d).val();var f=this.$el.find('input[name="id"]:checked').length;if(!f>0){return false}var c=[];this.$el.find("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:e,id:c,confirmation_text:g});return true},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}},execute:function(l){var f=null;var e=null;var g=null;var c=null;var k=null;if(l){e=l.href;g=l.operation;f=l.id;c=l.confirmation_text;k=l.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var j=e.split("?");if(j.length>1){var i=j[1];var d=i.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"&&c!="null"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(k,"")}return false}if(e){this.go_to(k,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(k,"")}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=this.$el.find("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");this.$el.find(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(e){var g=c.grid.get("embedded");var h=c.grid.get("insert");var f=$.parseJSON(e);f.embedded=g;f.insert=h;c.init_grid(f);c.$el.find(".loading-elt-overlay").hide()},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})}})});
\ No newline at end of file
+jQuery.ajaxSettings.traditional=true;define(["mvc/grid/grid-model","mvc/grid/grid-template","mvc/ui"],function(b,a){return Backbone.View.extend({grid:null,initialize:function(c){this.setElement("#grid-container");if(c.use_panels){$("#center").css({padding:"10px",overflow:"auto"})}this.init_grid(c)},handle_refresh:function(c){if(c){if($.inArray("history",c)>-1){if(top.Galaxy&&top.Galaxy.currHistoryPanel){top.Galaxy.currHistoryPanel.loadCurrentHistory()}}}},init_grid:function(f){this.grid=new b(f);var e=this.grid.attributes;this.handle_refresh(e.refresh_frames);var d=this.grid.get("url_base");d=d.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",d);this.$el.html(a.grid(e));this.$el.find("#grid-table-header").html(a.header(e));this.$el.find("#grid-table-body").html(a.body(e));this.$el.find("#grid-table-footer").html(a.footer(e));if(e.message){this.$el.find("#grid-message").html(a.message(e));var c=this;if(e.use_hide_message){setTimeout(function(){c.$el.find("#grid-message").html("")},5000)}}this.init_grid_elements();this.init_grid_controls();init_refresh_on_change()},init_grid_controls:function(){var c=this;this.$el.find(".operation-button").each(function(){$(this).off();$(this).click(function(){c.submit_operation(this,operation.confirm);return false})});this.$el.find("input[type=text]").each(function(){$(this).off();$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})});this.$el.find(".sort-link").each(function(){$(this).off();$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});this.$el.find(".text-filter-form").each(function(){$(this).off();$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});this.$el.find(".text-filter-val > a").each(function(){$(this).off();$(this).click(function(){$(this).parent().remove();c.remove_filter_condition($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});this.$el.find(".categorical-filter > a").each(function(){$(this).off();$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});var e=this.$el.find("#input-tags-filter");if(e.length){e.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var d=this.$el.find("#input-name-filter");if(d.length){d.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}this.$el.find(".advanced-search-toggle").each(function(){$(this).off();$(this).click(function(){c.$el.find("#standard-search").slideToggle("fast");c.$el.find("#advanced-search").slideToggle("fast");return false})});this.$el.find("#check_all").off();this.$el.find("#check_all").on("click",function(){c.check_all_items()})},init_grid_elements:function(){this.$el.find(".grid").each(function(){var j=$(this).find("input.grid-row-select-checkbox");var i=$(this).find("span.grid-selected-count");var r=function(){i.text($(j).filter(":checked").length)};$(j).each(function(){$(this).change(r)});r()});if(this.$el.find(".community_rating_star").length!==0){this.$el.find(".community_rating_star").rating({})}var q=this.grid.attributes;var p=this;this.$el.find(".page-link > a").each(function(){$(this).click(function(){p.set_page($(this).attr("page_num"));return false})});this.$el.find(".use-inbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href"),inbound:true});return false})});this.$el.find(".use-outbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href")});return false})});var f=q.items.length;if(f==0){return}for(var k in q.items){var o=q.items[k];var l=this.$el.find("#grid-"+k+"-popup");l.off();var d=new PopupMenu(l);for(var h in q.operations){var e=q.operations[h];var m=e.label;var c=o.operation_config[m];var g=o.encode_id;if(c.allowed&&e.allow_popup){var n={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};n.func=function(r){r.preventDefault();var j=$(r.target).html();var i=this.findItemByHtml(j);p.execute(i)};d.addItem(n)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$(a.filter_element(e,g));var d=this;f.click(function(){$(this).remove();d.remove_filter_condition(e,g)});var c=this.$el.find("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},remove_filter_condition:function(c,d){this.grid.remove_filter(c,d);this.go_page_one();this.execute()},set_sort_condition:function(g){var f=this.grid.get("sort_key");var e=g;if(f.indexOf(g)!==-1){if(f.substring(0,1)!=="-"){e="-"+g}}this.$el.find(".sort-arrow").remove();var d=(e.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+d+"</span>").addClass("sort-arrow");this.$el.find("#"+g+"-header").append(c);this.grid.set("sort_key",e);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;this.$el.find("."+e+"-filter").each(function(){var k=$.trim($(this).text());var i=d[k];var j=i[e];if(j==g){$(this).empty();$(this).addClass("current-filter");$(this).append(k)}else{if(j==f){$(this).empty();var h=$('<a href="#">'+k+"</a>");h.click(function(){c.set_categorical_filter(e,j)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;this.$el.find(".page-link").each(function(){var i=$(this).attr("id"),g=parseInt(i.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$('<a href="#">'+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(d,g){var e=$(d).val();var f=this.$el.find('input[name="id"]:checked').length;if(!f>0){return false}var c=[];this.$el.find("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:e,id:c,confirmation_text:g});return true},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}},execute:function(l){var f=null;var e=null;var g=null;var c=null;var k=null;if(l){e=l.href;g=l.operation;f=l.id;c=l.confirmation_text;k=l.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var j=e.split("?");if(j.length>1){var i=j[1];var d=i.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"&&c!="null"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(k,"")}return false}if(e){this.go_to(k,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(k,"")}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=this.$el.find("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");this.$el.find(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(e){var g=c.grid.get("embedded");var h=c.grid.get("insert");var f=$.parseJSON(e);f.embedded=g;f.insert=h;c.init_grid(f);c.$el.find(".loading-elt-overlay").hide()},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})}})});
\ No newline at end of file
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.
1
0
31 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2abb0622cf6a/
Changeset: 2abb0622cf6a
User: guerler
Date: 2014-01-31 13:52:49
Summary: Grids: Fix pages
Affected #: 5 files
diff -r 50012b1e7bbc5c181d6678f56cd2899d6a6b4511 -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 static/scripts/mvc/grid/grid-template.js
--- a/static/scripts/mvc/grid/grid-template.js
+++ b/static/scripts/mvc/grid/grid-template.js
@@ -230,7 +230,7 @@
},
// template
- footer: function(options) {
+ footer: function(grid_model, options) {
// create template string
var tmpl = '';
@@ -284,7 +284,7 @@
'Page:';
if (min_page > 1) {
- tmpl += '<span class="page-link" id="page-link-1"><a href="' + this.grid.get_url({page : page_index}) + '" page_num="1" onclick="return false;">1</a></span> ...';
+ tmpl += '<span class="page-link" id="page-link-1"><a href="' + grid_model.get_url({page : page_index}) + '" page_num="1" onclick="return false;">1</a></span> ...';
}
// create page urls
@@ -293,19 +293,19 @@
if (page_index == options.cur_page_num) {
tmpl += '<span class="page-link inactive-link" id="page-link-' + page_index + '">' + page_index + '</span>';
} else {
- tmpl += '<span class="page-link" id="page-link-' + page_index + '"><a href="' + this.grid.get_url({page : page_index}) + '" onclick="return false;" page_num="' + page_index + '">' + page_index + '</a></span>';
+ tmpl += '<span class="page-link" id="page-link-' + page_index + '"><a href="' + grid_model.get_url({page : page_index}) + '" onclick="return false;" page_num="' + page_index + '">' + page_index + '</a></span>';
}
}
// show last page
if (max_page < num_pages) {
tmpl += '...' +
- '<span class="page-link" id="page-link-' + num_pages + '"><a href="' + this.grid.get_url({page : num_pages}) + '" onclick="return false;" page_num="' + num_pages + '">' + num_pages + '</a></span>';
+ '<span class="page-link" id="page-link-' + num_pages + '"><a href="' + grid_model.get_url({page : num_pages}) + '" onclick="return false;" page_num="' + num_pages + '">' + num_pages + '</a></span>';
}
tmpl += '</span>';
// Show all link
- tmpl += '<span class="page-link" id="show-all-link-span"> | <a href="' + this.grid.get_url({page : 'all'}) + '" onclick="return false;" page_num="all">Show All</a></span>' +
+ tmpl += '<span class="page-link" id="show-all-link-span"> | <a href="' + grid_model.get_url({page : 'all'}) + '" onclick="return false;" page_num="all">Show All</a></span>' +
'</td>' +
'</tr>';
}
diff -r 50012b1e7bbc5c181d6678f56cd2899d6a6b4511 -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 static/scripts/mvc/grid/grid-view.js
--- a/static/scripts/mvc/grid/grid-view.js
+++ b/static/scripts/mvc/grid/grid-view.js
@@ -63,7 +63,7 @@
// update div contents
this.$el.find('#grid-table-header').html(Templates.header(options));
this.$el.find('#grid-table-body').html(Templates.body(options));
- this.$el.find('#grid-table-footer').html(Templates.footer(options));
+ this.$el.find('#grid-table-footer').html(Templates.footer(this.grid, options));
// update message
if (options.message) {
diff -r 50012b1e7bbc5c181d6678f56cd2899d6a6b4511 -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 static/scripts/packed/mvc/grid/grid-template.js
--- a/static/scripts/packed/mvc/grid/grid-template.js
+++ b/static/scripts/packed/mvc/grid/grid-template.js
@@ -1,1 +1,1 @@
-define([],function(){return{grid:function(b){var a="";if(b.embedded){a=this.grid_header(b)+this.grid_table(b)}else{a='<div class="loading-elt-overlay"></div><table><tr><td width="75%">'+this.grid_header(b)+'</td><td></td><td></td></tr><tr><td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>'+this.grid_table(b)}if(b.info_text){a+='<br><div class="toolParamHelp" style="clear: both;">'+b.info_text+"</div>"}return a},grid_table:function(a){return'<form method="post" onsubmit="return false;"><table id="grid-table" class="grid"><thead id="grid-table-header"></thead><tbody id="grid-table-body"></tbody><tfoot id="grid-table-footer"></tfoot></table></form>'},grid_header:function(c){var b='<div class="grid-header">';if(!c.embedded){b+="<h2>"+c.title+"</h2>"}if(c.global_actions){b+='<ul class="manage-table-actions">';var d=(c.global_actions.length>=3);if(d){b+='<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li><div popupmenu="popup-global-actions">'}for(i in c.global_actions){var e=c.global_actions[i];var a="";if(e.inbound){a="use-inbound"}else{a="use-outbound"}b+='<li><a class="action-button '+a+'" href="'+e.url_args+'" onclick="return false;">'+e.label+"</a></li>"}if(d){b+="</div>"}b+="</ul>"}if(c.insert){b+=c.insert}b+=this.grid_filters(c);b+="</div>";return b},header:function(b){var a="<tr>";if(b.show_item_checkboxes){a+="<th>";if(b.items.length>0){a+='<input type="checkbox" id="check_all" name=select_all_checkbox value="true"><input type="hidden" name=select_all_checkbox value="true">'}a+="</th>"}for(var c in b.columns){var d=b.columns[c];if(d.visible){a+='<th id="'+d.key+'-header">';if(d.href){a+='<a href="'+d.href+'" class="sort-link" sort_key="'+d.key+'">'+d.label+"</a>"}else{a+=d.label}a+='<span class="sort-arrow">'+d.extra+"</span></th>"}}a+="</tr>";return a},body:function(r){var k="";var s=0;var e=r.items.length;if(e==0){k+='<tr><td colspan="100"><em>No Items</em></td></tr>';s=1}for(var f in r.items){var p=r.items[f];var a=p.encode_id;var g="grid-"+f+"-popup";k+="<tr ";if(r.current_item_id==p.id){k+='class="current"'}k+=">";if(r.show_item_checkboxes){k+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+a+'" id="'+a+'" class="grid-row-select-checkbox" /></td>'}for(j in r.columns){var d=r.columns[j];if(d.visible){var c="";if(d.nowrap){c='style="white-space:nowrap;"'}var q=p.column_config[d.label];var h=q.link;var l=q.value;var o=q.inbound;if(jQuery.type(l)==="string"){l=l.replace(/\/\//g,"/")}var b="";var n="";if(d.attach_popup){b="grid-"+f+"-popup";n="menubutton";if(h!=""){n+=" split"}n+=" popup"}k+="<td "+c+">";if(h){if(r.operations.length!=0){k+='<div id="'+b+'" class="'+n+'" style="float: left;">'}var m="";if(o){m="use-inbound"}else{m="use-outbound"}k+='<a class="label '+m+'" href="'+h+'" onclick="return false;">'+l+"</a>";if(r.operations.length!=0){k+="</div>"}}else{k+='<div id="'+b+'" class="'+n+'"><label id="'+d.label_id_prefix+a+'" for="'+a+'">'+l+"</label></div>"}k+="</td>"}}k+="</tr>";s++}return k},footer:function(o){var k="";if(o.use_paging&&o.num_pages>1){var m=o.num_page_links;var a=o.cur_page_num;var n=o.num_pages;var h=m/2;var g=a-h;var e=0;if(g==0){g=1;e=h-(a-g)}var d=h+e;var c=a+d;if(c<=n){max_offset=0}else{c=n;max_offset=d-(c+1-a)}if(max_offset!=0){g-=max_offset;if(g<1){g=1}}k+='<tr id="page-links-row">';if(o.show_item_checkboxes){k+="<td></td>"}k+='<td colspan="100"><span id="page-link-container">Page:';if(g>1){k+='<span class="page-link" id="page-link-1"><a href="'+this.grid.get_url({page:l})+'" page_num="1" onclick="return false;">1</a></span> ...'}for(var l=g;l<c+1;l++){if(l==o.cur_page_num){k+='<span class="page-link inactive-link" id="page-link-'+l+'">'+l+"</span>"}else{k+='<span class="page-link" id="page-link-'+l+'"><a href="'+this.grid.get_url({page:l})+'" onclick="return false;" page_num="'+l+'">'+l+"</a></span>"}}if(c<n){k+='...<span class="page-link" id="page-link-'+n+'"><a href="'+this.grid.get_url({page:n})+'" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}k+="</span>";k+='<span class="page-link" id="show-all-link-span"> | <a href="'+this.grid.get_url({page:"all"})+'" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(o.show_item_checkboxes){k+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+o.get_class_plural+": ";for(i in o.operations){var b=o.operations[i];if(b.allow_multiple){k+='<input type="button" value="'+b.label+'" class="operation-button action-button"> '}}k+="</td></tr>"}var f=false;for(i in o.operations){if(o.operations[i].global_operation){f=true;break}}if(f){k+='<tr><td colspan="100">';for(i in o.operations){var b=o.operations[i];if(b.global_operation){k+='<a class="action-button" href="'+b.global_operation+'">'+b.label+"</a>"}}k+="</td></tr>"}if(o.legend){k+='<tr><td colspan="100">'+o.legend+"</td></tr>"}return k},message:function(a){return'<p><div class="'+a.status+'message transient-message">'+a.message+'</div><div style="clear: both"></div></p>'},grid_filters:function(n){var a=n.default_filter_dict;var b=n.filters;var e="none";if(n.advanced_search){e="block"}var m=false;for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){var l=d.key;var c=b[l];var f=a[l];if(c&&f&&c!=f){e="block"}m=true}}var k="block";if(e=="block"){k="none"}var h='<div id="standard-search" style="display: '+k+';"><table><tr><td style="padding: 0;"><table>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="standard"){h+=this.grid_column_filter(n,d)}}h+="</table></td></tr><tr><td>";if(m){h+='<a href="" class="advanced-search-toggle">Advanced Search</a>'}h+="</td></tr></table></div>";h+='<div id="advanced-search" style="display: '+e+'; margin-top: 5px; border: 1px solid #ccc;"><table><tr><td style="text-align: left" colspan="100"><a href="" class="advanced-search-toggle">Close Advanced Search</a></td></tr>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){h+=this.grid_column_filter(n,d)}}h+="</table></div>";return h},grid_column_filter:function(e,c){var t=e.default_filter_dict;var l=e.filters;var a=c.label;var b=c.key;if(c.filterable=="advanced"){a=a.toLowerCase()}var k="<tr>";if(c.filterable=="advanced"){k+='<td align="left" style="padding-left: 10px">'+a+":</td>"}k+='<td style="padding-bottom: 1px;">';if(c.is_text){k+='<form class="text-filter-form" column_key="'+b+'" action="'+e.url+'" method="get" >';for(u in e.columns){var g=e.columns[u];var p=l[g.key];if(p){if(p!="All"){if(g.is_text){p=JSON.stringify(p)}k+='<input type="hidden" id="'+g.key+'" name="f-'+g.key+'" value="'+p+'"/>'}}}k+='<span id="'+b+'-filtering-criteria">';var h=l[b];if(h){var f=jQuery.type(h);if(f=="string"){if(h!="All"){k+=this.filter_element(b,h)}}if(f=="array"){for(var u in h){var n=h[u];var v=h;v=v.slice(u);k+=this.filter_element(b,n)}}}k+="</span>";var r="";if(c.filterable=="standard"){r=c.label.toLowerCase();var q=r.length;if(q<20){q=20}q=q+4}k+='<span class="search-box"><input class="search-box-input" id="input-'+b+'-filter" name="f-'+b+'" type="text" placeholder="'+r+'" size="'+q+'"/></span></form>'}else{k+='<span id="'+b+'-filtering-criteria">';var s=false;for(cf_label in e.categorical_filters[b]){var o=e.categorical_filters[b][cf_label];var d="";var m="";for(key in o){d=key;m=o[key]}if(s){k+=" | "}s=true;var n=l[b];if(n&&o[b]&&n==m){k+='<span class="categorical-filter '+b+'-filter current-filter">'+cf_label+"</span>"}else{k+='<span class="categorical-filter '+b+'-filter"><a href="javascript:void(0);" filter_key="'+d+'" filter_val="'+m+'">'+cf_label+"</a></span>"}}k+="</span>"}k+="</td></tr>";return k},filter_element:function(b,a){return'<span class="text-filter-val">'+a+'<a href="javascript:void(0);" filter_key="'+b+'" filter_val="'+a+'"><i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/></a></span>'}}});
\ No newline at end of file
+define([],function(){return{grid:function(b){var a="";if(b.embedded){a=this.grid_header(b)+this.grid_table(b)}else{a='<div class="loading-elt-overlay"></div><table><tr><td width="75%">'+this.grid_header(b)+'</td><td></td><td></td></tr><tr><td width="100%" id="grid-message" valign="top"></td><td></td><td></td></tr></table>'+this.grid_table(b)}if(b.info_text){a+='<br><div class="toolParamHelp" style="clear: both;">'+b.info_text+"</div>"}return a},grid_table:function(a){return'<form method="post" onsubmit="return false;"><table id="grid-table" class="grid"><thead id="grid-table-header"></thead><tbody id="grid-table-body"></tbody><tfoot id="grid-table-footer"></tfoot></table></form>'},grid_header:function(c){var b='<div class="grid-header">';if(!c.embedded){b+="<h2>"+c.title+"</h2>"}if(c.global_actions){b+='<ul class="manage-table-actions">';var d=(c.global_actions.length>=3);if(d){b+='<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li><div popupmenu="popup-global-actions">'}for(i in c.global_actions){var e=c.global_actions[i];var a="";if(e.inbound){a="use-inbound"}else{a="use-outbound"}b+='<li><a class="action-button '+a+'" href="'+e.url_args+'" onclick="return false;">'+e.label+"</a></li>"}if(d){b+="</div>"}b+="</ul>"}if(c.insert){b+=c.insert}b+=this.grid_filters(c);b+="</div>";return b},header:function(b){var a="<tr>";if(b.show_item_checkboxes){a+="<th>";if(b.items.length>0){a+='<input type="checkbox" id="check_all" name=select_all_checkbox value="true"><input type="hidden" name=select_all_checkbox value="true">'}a+="</th>"}for(var c in b.columns){var d=b.columns[c];if(d.visible){a+='<th id="'+d.key+'-header">';if(d.href){a+='<a href="'+d.href+'" class="sort-link" sort_key="'+d.key+'">'+d.label+"</a>"}else{a+=d.label}a+='<span class="sort-arrow">'+d.extra+"</span></th>"}}a+="</tr>";return a},body:function(r){var k="";var s=0;var e=r.items.length;if(e==0){k+='<tr><td colspan="100"><em>No Items</em></td></tr>';s=1}for(var f in r.items){var p=r.items[f];var a=p.encode_id;var g="grid-"+f+"-popup";k+="<tr ";if(r.current_item_id==p.id){k+='class="current"'}k+=">";if(r.show_item_checkboxes){k+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+a+'" id="'+a+'" class="grid-row-select-checkbox" /></td>'}for(j in r.columns){var d=r.columns[j];if(d.visible){var c="";if(d.nowrap){c='style="white-space:nowrap;"'}var q=p.column_config[d.label];var h=q.link;var l=q.value;var o=q.inbound;if(jQuery.type(l)==="string"){l=l.replace(/\/\//g,"/")}var b="";var n="";if(d.attach_popup){b="grid-"+f+"-popup";n="menubutton";if(h!=""){n+=" split"}n+=" popup"}k+="<td "+c+">";if(h){if(r.operations.length!=0){k+='<div id="'+b+'" class="'+n+'" style="float: left;">'}var m="";if(o){m="use-inbound"}else{m="use-outbound"}k+='<a class="label '+m+'" href="'+h+'" onclick="return false;">'+l+"</a>";if(r.operations.length!=0){k+="</div>"}}else{k+='<div id="'+b+'" class="'+n+'"><label id="'+d.label_id_prefix+a+'" for="'+a+'">'+l+"</label></div>"}k+="</td>"}}k+="</tr>";s++}return k},footer:function(h,p){var l="";if(p.use_paging&&p.num_pages>1){var n=p.num_page_links;var a=p.cur_page_num;var o=p.num_pages;var k=n/2;var g=a-k;var e=0;if(g==0){g=1;e=k-(a-g)}var d=k+e;var c=a+d;if(c<=o){max_offset=0}else{c=o;max_offset=d-(c+1-a)}if(max_offset!=0){g-=max_offset;if(g<1){g=1}}l+='<tr id="page-links-row">';if(p.show_item_checkboxes){l+="<td></td>"}l+='<td colspan="100"><span id="page-link-container">Page:';if(g>1){l+='<span class="page-link" id="page-link-1"><a href="'+h.get_url({page:m})+'" page_num="1" onclick="return false;">1</a></span> ...'}for(var m=g;m<c+1;m++){if(m==p.cur_page_num){l+='<span class="page-link inactive-link" id="page-link-'+m+'">'+m+"</span>"}else{l+='<span class="page-link" id="page-link-'+m+'"><a href="'+h.get_url({page:m})+'" onclick="return false;" page_num="'+m+'">'+m+"</a></span>"}}if(c<o){l+='...<span class="page-link" id="page-link-'+o+'"><a href="'+h.get_url({page:o})+'" onclick="return false;" page_num="'+o+'">'+o+"</a></span>"}l+="</span>";l+='<span class="page-link" id="show-all-link-span"> | <a href="'+h.get_url({page:"all"})+'" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(p.show_item_checkboxes){l+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+p.get_class_plural+": ";for(i in p.operations){var b=p.operations[i];if(b.allow_multiple){l+='<input type="button" value="'+b.label+'" class="operation-button action-button"> '}}l+="</td></tr>"}var f=false;for(i in p.operations){if(p.operations[i].global_operation){f=true;break}}if(f){l+='<tr><td colspan="100">';for(i in p.operations){var b=p.operations[i];if(b.global_operation){l+='<a class="action-button" href="'+b.global_operation+'">'+b.label+"</a>"}}l+="</td></tr>"}if(p.legend){l+='<tr><td colspan="100">'+p.legend+"</td></tr>"}return l},message:function(a){return'<p><div class="'+a.status+'message transient-message">'+a.message+'</div><div style="clear: both"></div></p>'},grid_filters:function(n){var a=n.default_filter_dict;var b=n.filters;var e="none";if(n.advanced_search){e="block"}var m=false;for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){var l=d.key;var c=b[l];var f=a[l];if(c&&f&&c!=f){e="block"}m=true}}var k="block";if(e=="block"){k="none"}var h='<div id="standard-search" style="display: '+k+';"><table><tr><td style="padding: 0;"><table>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="standard"){h+=this.grid_column_filter(n,d)}}h+="</table></td></tr><tr><td>";if(m){h+='<a href="" class="advanced-search-toggle">Advanced Search</a>'}h+="</td></tr></table></div>";h+='<div id="advanced-search" style="display: '+e+'; margin-top: 5px; border: 1px solid #ccc;"><table><tr><td style="text-align: left" colspan="100"><a href="" class="advanced-search-toggle">Close Advanced Search</a></td></tr>';for(var g in n.columns){var d=n.columns[g];if(d.filterable=="advanced"){h+=this.grid_column_filter(n,d)}}h+="</table></div>";return h},grid_column_filter:function(e,c){var t=e.default_filter_dict;var l=e.filters;var a=c.label;var b=c.key;if(c.filterable=="advanced"){a=a.toLowerCase()}var k="<tr>";if(c.filterable=="advanced"){k+='<td align="left" style="padding-left: 10px">'+a+":</td>"}k+='<td style="padding-bottom: 1px;">';if(c.is_text){k+='<form class="text-filter-form" column_key="'+b+'" action="'+e.url+'" method="get" >';for(u in e.columns){var g=e.columns[u];var p=l[g.key];if(p){if(p!="All"){if(g.is_text){p=JSON.stringify(p)}k+='<input type="hidden" id="'+g.key+'" name="f-'+g.key+'" value="'+p+'"/>'}}}k+='<span id="'+b+'-filtering-criteria">';var h=l[b];if(h){var f=jQuery.type(h);if(f=="string"){if(h!="All"){k+=this.filter_element(b,h)}}if(f=="array"){for(var u in h){var n=h[u];var v=h;v=v.slice(u);k+=this.filter_element(b,n)}}}k+="</span>";var r="";if(c.filterable=="standard"){r=c.label.toLowerCase();var q=r.length;if(q<20){q=20}q=q+4}k+='<span class="search-box"><input class="search-box-input" id="input-'+b+'-filter" name="f-'+b+'" type="text" placeholder="'+r+'" size="'+q+'"/></span></form>'}else{k+='<span id="'+b+'-filtering-criteria">';var s=false;for(cf_label in e.categorical_filters[b]){var o=e.categorical_filters[b][cf_label];var d="";var m="";for(key in o){d=key;m=o[key]}if(s){k+=" | "}s=true;var n=l[b];if(n&&o[b]&&n==m){k+='<span class="categorical-filter '+b+'-filter current-filter">'+cf_label+"</span>"}else{k+='<span class="categorical-filter '+b+'-filter"><a href="javascript:void(0);" filter_key="'+d+'" filter_val="'+m+'">'+cf_label+"</a></span>"}}k+="</span>"}k+="</td></tr>";return k},filter_element:function(b,a){return'<span class="text-filter-val">'+a+'<a href="javascript:void(0);" filter_key="'+b+'" filter_val="'+a+'"><i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/></a></span>'}}});
\ No newline at end of file
diff -r 50012b1e7bbc5c181d6678f56cd2899d6a6b4511 -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 static/scripts/packed/mvc/grid/grid-view.js
--- a/static/scripts/packed/mvc/grid/grid-view.js
+++ b/static/scripts/packed/mvc/grid/grid-view.js
@@ -1,1 +1,1 @@
-jQuery.ajaxSettings.traditional=true;define(["mvc/grid/grid-model","mvc/grid/grid-template","mvc/ui"],function(b,a){return Backbone.View.extend({grid:null,initialize:function(c){this.setElement("#grid-container");if(c.use_panels){$("#center").css({padding:"10px",overflow:"auto"})}this.init_grid(c)},handle_refresh:function(c){if(c){if($.inArray("history",c)>-1){if(top.Galaxy&&top.Galaxy.currHistoryPanel){top.Galaxy.currHistoryPanel.loadCurrentHistory()}}}},init_grid:function(f){this.grid=new b(f);var e=this.grid.attributes;this.handle_refresh(e.refresh_frames);var d=this.grid.get("url_base");d=d.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",d);this.$el.html(a.grid(e));this.$el.find("#grid-table-header").html(a.header(e));this.$el.find("#grid-table-body").html(a.body(e));this.$el.find("#grid-table-footer").html(a.footer(e));if(e.message){this.$el.find("#grid-message").html(a.message(e));var c=this;if(e.use_hide_message){setTimeout(function(){c.$el.find("#grid-message").html("")},5000)}}this.init_grid_elements();this.init_grid_controls();init_refresh_on_change()},init_grid_controls:function(){var c=this;this.$el.find(".operation-button").each(function(){$(this).off();$(this).click(function(){c.submit_operation(this,operation.confirm);return false})});this.$el.find("input[type=text]").each(function(){$(this).off();$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})});this.$el.find(".sort-link").each(function(){$(this).off();$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});this.$el.find(".text-filter-form").each(function(){$(this).off();$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});this.$el.find(".text-filter-val > a").each(function(){$(this).off();$(this).click(function(){$(this).parent().remove();c.remove_filter_condition($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});this.$el.find(".categorical-filter > a").each(function(){$(this).off();$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});var e=this.$el.find("#input-tags-filter");if(e.length){e.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var d=this.$el.find("#input-name-filter");if(d.length){d.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}this.$el.find(".advanced-search-toggle").each(function(){$(this).off();$(this).click(function(){c.$el.find("#standard-search").slideToggle("fast");c.$el.find("#advanced-search").slideToggle("fast");return false})});this.$el.find("#check_all").off();this.$el.find("#check_all").on("click",function(){c.check_all_items()})},init_grid_elements:function(){this.$el.find(".grid").each(function(){var j=$(this).find("input.grid-row-select-checkbox");var i=$(this).find("span.grid-selected-count");var r=function(){i.text($(j).filter(":checked").length)};$(j).each(function(){$(this).change(r)});r()});if(this.$el.find(".community_rating_star").length!==0){this.$el.find(".community_rating_star").rating({})}var q=this.grid.attributes;var p=this;this.$el.find(".page-link > a").each(function(){$(this).click(function(){p.set_page($(this).attr("page_num"));return false})});this.$el.find(".use-inbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href"),inbound:true});return false})});this.$el.find(".use-outbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href")});return false})});var f=q.items.length;if(f==0){return}for(var k in q.items){var o=q.items[k];var l=this.$el.find("#grid-"+k+"-popup");l.off();var d=new PopupMenu(l);for(var h in q.operations){var e=q.operations[h];var m=e.label;var c=o.operation_config[m];var g=o.encode_id;if(c.allowed&&e.allow_popup){var n={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};n.func=function(r){r.preventDefault();var j=$(r.target).html();var i=this.findItemByHtml(j);p.execute(i)};d.addItem(n)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$(a.filter_element(e,g));var d=this;f.click(function(){$(this).remove();d.remove_filter_condition(e,g)});var c=this.$el.find("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},remove_filter_condition:function(c,d){this.grid.remove_filter(c,d);this.go_page_one();this.execute()},set_sort_condition:function(g){var f=this.grid.get("sort_key");var e=g;if(f.indexOf(g)!==-1){if(f.substring(0,1)!=="-"){e="-"+g}}this.$el.find(".sort-arrow").remove();var d=(e.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+d+"</span>").addClass("sort-arrow");this.$el.find("#"+g+"-header").append(c);this.grid.set("sort_key",e);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;this.$el.find("."+e+"-filter").each(function(){var k=$.trim($(this).text());var i=d[k];var j=i[e];if(j==g){$(this).empty();$(this).addClass("current-filter");$(this).append(k)}else{if(j==f){$(this).empty();var h=$('<a href="#">'+k+"</a>");h.click(function(){c.set_categorical_filter(e,j)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;this.$el.find(".page-link").each(function(){var i=$(this).attr("id"),g=parseInt(i.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$('<a href="#">'+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(d,g){var e=$(d).val();var f=this.$el.find('input[name="id"]:checked').length;if(!f>0){return false}var c=[];this.$el.find("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:e,id:c,confirmation_text:g});return true},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}},execute:function(l){var f=null;var e=null;var g=null;var c=null;var k=null;if(l){e=l.href;g=l.operation;f=l.id;c=l.confirmation_text;k=l.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var j=e.split("?");if(j.length>1){var i=j[1];var d=i.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"&&c!="null"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(k,"")}return false}if(e){this.go_to(k,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(k,"")}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=this.$el.find("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");this.$el.find(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(e){var g=c.grid.get("embedded");var h=c.grid.get("insert");var f=$.parseJSON(e);f.embedded=g;f.insert=h;c.init_grid(f);c.$el.find(".loading-elt-overlay").hide()},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})}})});
\ No newline at end of file
+jQuery.ajaxSettings.traditional=true;define(["mvc/grid/grid-model","mvc/grid/grid-template","mvc/ui"],function(b,a){return Backbone.View.extend({grid:null,initialize:function(c){this.setElement("#grid-container");if(c.use_panels){$("#center").css({padding:"10px",overflow:"auto"})}this.init_grid(c)},handle_refresh:function(c){if(c){if($.inArray("history",c)>-1){if(top.Galaxy&&top.Galaxy.currHistoryPanel){top.Galaxy.currHistoryPanel.loadCurrentHistory()}}}},init_grid:function(f){this.grid=new b(f);var e=this.grid.attributes;this.handle_refresh(e.refresh_frames);var d=this.grid.get("url_base");d=d.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",d);this.$el.html(a.grid(e));this.$el.find("#grid-table-header").html(a.header(e));this.$el.find("#grid-table-body").html(a.body(e));this.$el.find("#grid-table-footer").html(a.footer(this.grid,e));if(e.message){this.$el.find("#grid-message").html(a.message(e));var c=this;if(e.use_hide_message){setTimeout(function(){c.$el.find("#grid-message").html("")},5000)}}this.init_grid_elements();this.init_grid_controls();init_refresh_on_change()},init_grid_controls:function(){var c=this;this.$el.find(".operation-button").each(function(){$(this).off();$(this).click(function(){c.submit_operation(this,operation.confirm);return false})});this.$el.find("input[type=text]").each(function(){$(this).off();$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})});this.$el.find(".sort-link").each(function(){$(this).off();$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});this.$el.find(".text-filter-form").each(function(){$(this).off();$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});this.$el.find(".text-filter-val > a").each(function(){$(this).off();$(this).click(function(){$(this).parent().remove();c.remove_filter_condition($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});this.$el.find(".categorical-filter > a").each(function(){$(this).off();$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});var e=this.$el.find("#input-tags-filter");if(e.length){e.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var d=this.$el.find("#input-name-filter");if(d.length){d.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}this.$el.find(".advanced-search-toggle").each(function(){$(this).off();$(this).click(function(){c.$el.find("#standard-search").slideToggle("fast");c.$el.find("#advanced-search").slideToggle("fast");return false})});this.$el.find("#check_all").off();this.$el.find("#check_all").on("click",function(){c.check_all_items()})},init_grid_elements:function(){this.$el.find(".grid").each(function(){var j=$(this).find("input.grid-row-select-checkbox");var i=$(this).find("span.grid-selected-count");var r=function(){i.text($(j).filter(":checked").length)};$(j).each(function(){$(this).change(r)});r()});if(this.$el.find(".community_rating_star").length!==0){this.$el.find(".community_rating_star").rating({})}var q=this.grid.attributes;var p=this;this.$el.find(".page-link > a").each(function(){$(this).click(function(){p.set_page($(this).attr("page_num"));return false})});this.$el.find(".use-inbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href"),inbound:true});return false})});this.$el.find(".use-outbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href")});return false})});var f=q.items.length;if(f==0){return}for(var k in q.items){var o=q.items[k];var l=this.$el.find("#grid-"+k+"-popup");l.off();var d=new PopupMenu(l);for(var h in q.operations){var e=q.operations[h];var m=e.label;var c=o.operation_config[m];var g=o.encode_id;if(c.allowed&&e.allow_popup){var n={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};n.func=function(r){r.preventDefault();var j=$(r.target).html();var i=this.findItemByHtml(j);p.execute(i)};d.addItem(n)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$(a.filter_element(e,g));var d=this;f.click(function(){$(this).remove();d.remove_filter_condition(e,g)});var c=this.$el.find("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},remove_filter_condition:function(c,d){this.grid.remove_filter(c,d);this.go_page_one();this.execute()},set_sort_condition:function(g){var f=this.grid.get("sort_key");var e=g;if(f.indexOf(g)!==-1){if(f.substring(0,1)!=="-"){e="-"+g}}this.$el.find(".sort-arrow").remove();var d=(e.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+d+"</span>").addClass("sort-arrow");this.$el.find("#"+g+"-header").append(c);this.grid.set("sort_key",e);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;this.$el.find("."+e+"-filter").each(function(){var k=$.trim($(this).text());var i=d[k];var j=i[e];if(j==g){$(this).empty();$(this).addClass("current-filter");$(this).append(k)}else{if(j==f){$(this).empty();var h=$('<a href="#">'+k+"</a>");h.click(function(){c.set_categorical_filter(e,j)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;this.$el.find(".page-link").each(function(){var i=$(this).attr("id"),g=parseInt(i.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$('<a href="#">'+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(d,g){var e=$(d).val();var f=this.$el.find('input[name="id"]:checked').length;if(!f>0){return false}var c=[];this.$el.find("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:e,id:c,confirmation_text:g});return true},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}},execute:function(l){var f=null;var e=null;var g=null;var c=null;var k=null;if(l){e=l.href;g=l.operation;f=l.id;c=l.confirmation_text;k=l.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var j=e.split("?");if(j.length>1){var i=j[1];var d=i.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"&&c!="null"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(k,"")}return false}if(e){this.go_to(k,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(k,"")}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=this.$el.find("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");this.$el.find(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(e){var g=c.grid.get("embedded");var h=c.grid.get("insert");var f=$.parseJSON(e);f.embedded=g;f.insert=h;c.init_grid(f);c.$el.find(".loading-elt-overlay").hide()},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})}})});
\ No newline at end of file
diff -r 50012b1e7bbc5c181d6678f56cd2899d6a6b4511 -r 2abb0622cf6ad5172a14a85c450230b8f5df2070 templates/grid_base.mako
--- a/templates/grid_base.mako
+++ b/templates/grid_base.mako
@@ -97,7 +97,7 @@
'url' : url(dict())
}
- # add refresh frames
+ ## add refresh frames
if refresh_frames:
self.grid_config['refresh_frames'] = refresh_frames
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.
1
0
commit/galaxy-central: dannon: Upgrade Babel egg from 0.9.4 to 1.3. This resolves several known issues with utf-8 for particular distributions.
by commits-noreply@bitbucket.org 31 Jan '14
by commits-noreply@bitbucket.org 31 Jan '14
31 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/50012b1e7bbc/
Changeset: 50012b1e7bbc
User: dannon
Date: 2014-01-31 13:43:28
Summary: Upgrade Babel egg from 0.9.4 to 1.3. This resolves several known issues with utf-8 for particular distributions.
Affected #: 1 file
diff -r b20d93e643068f3154752582db3d17e16c499633 -r 50012b1e7bbc5c181d6678f56cd2899d6a6b4511 eggs.ini
--- a/eggs.ini
+++ b/eggs.ini
@@ -63,7 +63,7 @@
WebHelpers = 1.3
WebOb = 0.8.5
wsgiref = 0.1.2
-Babel = 0.9.4
+Babel = 1.3
wchartype = 0.1
Whoosh = 0.3.18
; fluent_logger = 0.3.3
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.
1
0
commit/galaxy-central: guerler: Grids: Finalize code separation, refactor filters and apply coding conventions
by commits-noreply@bitbucket.org 31 Jan '14
by commits-noreply@bitbucket.org 31 Jan '14
31 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b20d93e64306/
Changeset: b20d93e64306
User: guerler
Date: 2014-01-31 11:20:23
Summary: Grids: Finalize code separation, refactor filters and apply coding conventions
iG: removed static/scripts/packed/galaxy.grids.js
Affected #: 12 files
diff -r be7ece9454471d655668f3997c29b90c2f6c312d -r b20d93e643068f3154752582db3d17e16c499633 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py
+++ b/lib/galaxy/web/framework/helpers/grids.py
@@ -41,6 +41,7 @@
cur_sort_key_pref_name = ".sort_key"
pass_through_operations = {}
legend = None
+ info_text = None
def __init__( self ):
# Determine if any multiple row operations are defined
self.has_multiple_item_operations = False
@@ -286,6 +287,7 @@
url = url,
status = status,
message = message,
+ info_text=self.info_text,
use_panels=self.use_panels,
use_hide_message=self.use_hide_message,
advanced_search=self.advanced_search,
diff -r be7ece9454471d655668f3997c29b90c2f6c312d -r b20d93e643068f3154752582db3d17e16c499633 lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -104,6 +104,7 @@
preserve_state = False
use_async = True
use_paging = True
+ info_text = "Histories that have been deleted for more than a time period specified by the Galaxy administrator(s) may be permanently deleted."
def get_current_item( self, trans, **kwargs ):
return trans.get_history()
diff -r be7ece9454471d655668f3997c29b90c2f6c312d -r b20d93e643068f3154752582db3d17e16c499633 static/scripts/galaxy.grids.js
--- a/static/scripts/galaxy.grids.js
+++ /dev/null
@@ -1,984 +0,0 @@
-// External dependencies (for module management eventually): jQuery, Backbone, underscore
-
-// This is necessary so that, when nested arrays are used in ajax/post/get methods, square brackets ('[]') are
-// not appended to the identifier of a nested array.
-jQuery.ajaxSettings.traditional = true;
-
-// dependencies
-define(['mvc/ui'], function() {
-
-/**
- * A Galaxy grid.
- */
-var Grid = Backbone.Model.extend({
- defaults: {
- url_base: '',
- async: false,
- async_ops: [],
- categorical_filters: [],
- filters: {},
- sort_key: null,
- show_item_checkboxes: false,
- advanced_search: false,
- cur_page: 1,
- num_pages: 1,
- operation: undefined,
- item_ids: undefined
- },
-
- /**
- * Return true if operation can be done asynchronously.
- */
- can_async_op: function(op) {
- return _.indexOf(this.attributes.async_ops, op) !== -1;
- },
-
- /**
- * Add filtering criterion.
- */
- add_filter: function(key, value, append) {
- // Update URL arg with new condition.
- if (append) {
- // Update or append value.
- var cur_val = this.attributes.filters[key],
- new_val;
- if (cur_val === null || cur_val === undefined) {
- new_val = value;
- }
- else if (typeof(cur_val) == "string") {
- if (cur_val == "All") {
- new_val = value;
- } else {
- // Replace string with array.
- var values = [];
- values[0] = cur_val;
- values[1] = value;
- new_val = values;
- }
- }
- else {
- // Current value is an array.
- new_val = cur_val;
- new_val.push(value);
- }
- this.attributes.filters[key] = new_val;
- }
- else {
- // Replace value.
- this.attributes.filters[key] = value;
- }
- },
-
- /**
- * Remove filtering criterion.
- */
- remove_filter: function(key, condition) {
- var cur_val = this.attributes.filters[key];
- if (cur_val === null || cur_val === undefined) {
- return false;
- }
-
- var removed = true;
- if (typeof(cur_val) === "string") {
- if (cur_val == "All") {
- // Unexpected. Throw error?
- removed = false;
- }
- else {
- // Remove condition.
- delete this.attributes.filters[key];
- }
- }
- else {
- // Filter contains an array of conditions.
- var condition_index = _.indexOf(cur_val, condition);
- if (condition_index !== -1) {
- cur_val.splice(condition_index, 1);
- }
- else {
- removed = false;
- }
- }
-
- return removed;
- },
-
- /**
- * Returns URL data for obtaining a new grid.
- */
- get_url_data: function() {
- var url_data = {
- async: this.attributes.async,
- sort: this.attributes.sort_key,
- page: this.attributes.cur_page,
- show_item_checkboxes: this.attributes.show_item_checkboxes,
- advanced_search: this.attributes.advanced_search
- };
-
- // Add operation, item_ids only if they have values.
- if (this.attributes.operation) {
- url_data.operation = this.attributes.operation;
- }
- if (this.attributes.item_ids) {
- url_data.id = this.attributes.item_ids;
- }
-
- // Add filter arguments to data, placing "f-" in front of all arguments.
- var self = this;
- _.each(_.pairs(self.attributes.filters), function(k) {
- url_data['f-' + k[0]] = k[1];
- });
-
- return url_data;
- },
-
- // Return URL for obtaining a new grid
- get_url: function (args) {
- return this.get('url_base') + "?" + $.param(this.get_url_data()) + '&' + $.param(args);
- }
-
-});
-
-// grid view
-var GridView = Backbone.View.extend({
-
- // model
- grid: null,
-
- // Initialize
- initialize: function(grid_config)
- {
- // initialize controls
- this.init_grid(grid_config);
- this.init_grid_controls();
-
- // Initialize text filters to select text on click and use normal font when user is typing.
- $('input[type=text]').each(function() {
- $(this).click(function() { $(this).select(); } )
- .keyup(function () { $(this).css("font-style", "normal"); });
- });
- },
-
- // refresh frames
- handle_refresh: function (refresh_frames) {
- if (refresh_frames) {
- if ($.inArray('history', refresh_frames) > -1) {
- if( top.Galaxy && top.Galaxy.currHistoryPanel ){
- top.Galaxy.currHistoryPanel.loadCurrentHistory();
- }
- }
- }
- },
-
- // Initialize
- init_grid: function(grid_config)
- {
- // link grid model
- this.grid = new Grid(grid_config);
-
- // get options
- var options = this.grid.attributes;
-
- // handle refresh requests
- this.handle_refresh(options.refresh_frames);
-
- // strip protocol and domain
- var url = this.grid.get('url_base');
- url = url.replace(/^.*\/\/[^\/]+/, '');
- this.grid.set('url_base', url);
-
- // update div contents
- $('#grid-table-body').html(this.template_body(options));
- $('#grid-table-footer').html(this.template_footer(options));
-
- // update message
- if (options.message) {
- $('#grid-message').html(this.template_message(options));
- if (options.use_hide_message) {
- setTimeout( function() { $('#grid-message').html(''); }, 5000);
- }
- }
-
- // configure elements
- this.init_grid_elements();
-
- // attach global event handler
- init_refresh_on_change();
- },
-
- // Initialize grid controls
- init_grid_controls: function() {
- // Initialize submit image elements.
- $('.submit-image').each( function() {
- // On mousedown, add class to simulate click.
- $(this).mousedown( function() {
- $(this).addClass('gray-background');
- });
-
- // On mouseup, add class to simulate click.
- $(this).mouseup( function() {
- $(this).removeClass('gray-background');
- });
- });
-
- // link
- var self = this;
-
- // Initialize sort links.
- $('.sort-link').each( function() {
- $(this).click( function() {
- self.set_sort_condition( $(this).attr('sort_key') );
- return false;
- });
- });
-
- // Initialize categorical filters.
- $('.categorical-filter > a').each( function() {
- $(this).click( function() {
- self.set_categorical_filter( $(this).attr('filter_key'), $(this).attr('filter_val') );
- return false;
- });
- });
-
- // Initialize text filters.
- $('.text-filter-form').each( function() {
- $(this).submit( function() {
- var column_key = $(this).attr('column_key');
- var text_input_obj = $('#input-' + column_key + '-filter');
- var text_input = text_input_obj.val();
- text_input_obj.val('');
- self.add_filter_condition(column_key, text_input);
- return false;
- });
- });
-
- // Initialize autocomplete for text inputs in search UI.
- var t = $("#input-tags-filter");
- if (t.length) {
- t.autocomplete(this.grid.history_tag_autocomplete_url,
- { selectFirst: false, autoFill: false, highlight: false, mustMatch: false });
- }
-
- var t2 = $("#input-name-filter");
- if (t2.length) {
- t2.autocomplete(this.grid.history_name_autocomplete_url,
- { selectFirst: false, autoFill: false, highlight: false, mustMatch: false });
- }
-
- // Initialize standard, advanced search toggles.
- $('.advanced-search-toggle').each( function() {
- $(this).click( function() {
- $('#standard-search').slideToggle('fast');
- $('#advanced-search').slideToggle('fast');
- return false;
- });
- });
- },
-
- // Initialize grid elements.
- init_grid_elements : function() {
- // Initialize grid selection checkboxes.
- $(".grid").each( function() {
- var checkboxes = $(this).find("input.grid-row-select-checkbox");
- var check_count = $(this).find("span.grid-selected-count");
- var update_checked = function() {
- check_count.text( $(checkboxes).filter(":checked").length );
- };
-
- $(checkboxes).each( function() {
- $(this).change(update_checked);
- });
- update_checked();
- });
-
- // Initialize ratings.
- if ($('.community_rating_star').length !== 0)
- $('.community_rating_star').rating({});
-
- // get options
- var options = this.grid.attributes;
- var self = this;
-
- //
- // add page click events
- //
- $('.page-link > a').each( function() {
- $(this).click( function() {
- self.set_page( $(this).attr('page_num') );
- return false;
- });
- });
-
- //
- // add inbound/outbound events
- //
- $(".use-inbound").each( function() {
- $(this).click( function(e) {
- self.execute({
- href : $(this).attr('href'),
- inbound : true
- });
- return false;
-
- });
- });
-
- $(".use-outbound").each( function() {
- $(this).click( function(e) {
- self.execute({
- href : $(this).attr('href')
- });
- return false;
- });
- });
-
- // empty grid?
- var items_length = options.items.length;
- if (items_length == 0) {
- return;
- }
-
- //
- // add operation popup menus
- //
- for (var i in options.items)
- {
- // get items
- var item = options.items[i];
-
- // get identifiers
- var button = $('#grid-' + i + '-popup');
- button.off();
- var popup = new PopupMenu(button);
-
- // load details
- for (var j in options['operations'])
- {
- // get operation details
- var operation = options['operations'][j];
- var operation_id = operation['label'];
- var operation_settings = item['operation_config'][operation_id];
- var encode_id = item['encode_id'];
-
- // check
- if (operation_settings['allowed'] && operation['allow_popup'])
- {
- // popup configuration
- var popupConfig =
- {
- html : operation['label'],
- href : operation_settings['url_args'],
- target : operation_settings['target'],
- confirmation_text : operation['confirm'],
- inbound : operation['inbound']
- };
-
- // add popup function
- popupConfig.func = function(e)
- {
- e.preventDefault();
- var label = $(e.target).html();
- var options = this.findItemByHtml(label);
- self.execute(options);
- };
-
- // add item
- popup.addItem(popupConfig);
- }
- }
- }
- },
-
- // Add a condition to the grid filter; this adds the condition and refreshes the grid.
- add_filter_condition: function (name, value) {
- // Do nothing is value is empty.
- if (value === "") {
- return false;
- }
-
- // Add condition to grid.
- this.grid.add_filter(name, value, true);
-
- // Add button that displays filter and provides a button to delete it.
- var t = $("<span>" + value + "<a href='javascript:void(0);'><span class='delete-search-icon' /></span></a>");
- t.addClass('text-filter-val');
- var self = this;
- t.click(function() {
- // Remove filter condition.
- self.grid.remove_filter(name, value);
-
- // Remove visible element.
- $(this).remove();
-
- self.go_page_one();
- self.execute();
- });
-
- var container = $('#' + name + "-filtering-criteria");
- container.append(t);
-
- this.go_page_one();
- this.execute();
- },
-
- // Set sort condition for grid.
- set_sort_condition: function (col_key) {
- // Set new sort condition. New sort is col_key if sorting new column; if reversing sort on
- // currently sorted column, sort is reversed.
- var cur_sort = this.grid.get('sort_key');
- var new_sort = col_key;
- if (cur_sort.indexOf(col_key) !== -1) {
- // Reverse sort.
- if (cur_sort.substring(0,1) !== '-') {
- new_sort = '-' + col_key;
- } else {
- // Sort reversed by using just col_key.
- }
- }
-
- // Remove sort arrows elements.
- $('.sort-arrow').remove();
-
- // Add sort arrow element to new sort column.
- var sort_arrow = (new_sort.substring(0,1) == '-') ? "↑" : "↓";
- var t = $("<span>" + sort_arrow + "</span>").addClass('sort-arrow');
- var th = $("#" + col_key + '-header');
- th.append(t);
-
- // Update grid.
- this.grid.set('sort_key', new_sort);
- this.go_page_one();
- this.execute();
- },
-
- // Set new value for categorical filter.
- set_categorical_filter: function (name, new_value) {
- // Update filter hyperlinks to reflect new filter value.
- var category_filter = this.grid.get('categorical_filters')[name],
- cur_value = this.grid.get('filters')[name];
- var self = this;
- $("." + name + "-filter").each( function() {
- var text = $.trim( $(this).text() );
- var filter = category_filter[text];
- var filter_value = filter[name];
- if (filter_value == new_value) {
- // Remove filter link since grid will be using this filter. It is assumed that
- // this element has a single child, a hyperlink/anchor with text.
- $(this).empty();
- $(this).addClass("current-filter");
- $(this).append(text);
- } else if (filter_value == cur_value) {
- // Add hyperlink for this filter since grid will no longer be using this filter. It is assumed that
- // this element has a single child, a hyperlink/anchor.
- $(this).empty();
- var t = $("<a href='#'>" + text + "</a>");
- t.click(function() {
- self.set_categorical_filter( name, filter_value );
- });
- $(this).removeClass("current-filter");
- $(this).append(t);
- }
- });
-
- // Update grid.
- this.grid.add_filter(name, new_value);
- this.go_page_one();
- this.execute();
- },
-
- // Set page to view.
- set_page: function (new_page) {
- // Update page hyperlink to reflect new page.
- var self = this;
- $(".page-link").each( function() {
- var id = $(this).attr('id'),
- page_num = parseInt( id.split("-")[2], 10 ), // Id has form 'page-link-<page_num>
- cur_page = self.grid.get('cur_page'),
- text;
- if (page_num === new_page) {
- // Remove link to page since grid will be on this page. It is assumed that
- // this element has a single child, a hyperlink/anchor with text.
- text = $(this).children().text();
- $(this).empty();
- $(this).addClass("inactive-link");
- $(this).text(text);
- }
- else if (page_num === cur_page) {
- // Add hyperlink to this page since grid will no longer be on this page. It is assumed that
- // this element has a single child, a hyperlink/anchor.
- text = $(this).text();
- $(this).empty();
- $(this).removeClass("inactive-link");
- var t = $("<a href='#'>" + text + "</a>");
- t.click(function() {
- self.set_page(page_num);
- });
- $(this).append(t);
- }
- });
-
- if (new_page === "all") {
- this.grid.set('cur_page', new_page);
- } else {
- this.grid.set('cur_page', parseInt(new_page, 10));
- }
- this.execute();
- },
-
- // confirmation/submission of operation request
- submit_operation: function (selected_button, confirmation_text)
- {
- // verify in any item is selected
- var number_of_checked_ids = $('input[name="id"]:checked').length;
- if (!number_of_checked_ids > 0)
- return false;
-
- // collect ids
- var operation_name = $(selected_button).val();
- var item_ids = [];
- $('input[name=id]:checked').each(function() {
- item_ids.push( $(this).val() );
- });
- this.execute({
- operation: operation_name,
- id: item_ids,
- confirmation_text: confirmation_text
- });
-
- // return
- return true;
- },
-
- // execute operations and hyperlink requests
- execute: function (options) {
- // get url
- var id = null;
- var href = null;
- var operation = null;
- var confirmation_text = null;
- var inbound = null;
-
- // check for options
- if (options)
- {
- // get options
- href = options.href;
- operation = options.operation;
- id = options.id;
- confirmation_text = options.confirmation_text;
- inbound = options.inbound;
-
- // check if input contains the operation tag
- if (href !== undefined && href.indexOf('operation=') != -1) {
- // Get operation, id in hyperlink's href.
- var href_parts = href.split("?");
- if (href_parts.length > 1) {
- var href_parms_str = href_parts[1];
- var href_parms = href_parms_str.split("&");
- for (var index = 0; index < href_parms.length; index++) {
- if (href_parms[index].indexOf('operation') != -1) {
- // Found operation parm; get operation value.
- operation = href_parms[index].split('=')[1];
- operation = operation.replace (/\+/g, ' ');
- } else if (href_parms[index].indexOf('id') != -1) {
- // Found id parm; get id value.
- id = href_parms[index].split('=')[1];
- }
- }
- }
- }
- }
-
- // check for operation details
- if (operation && id) {
- // show confirmation box
- if (confirmation_text && confirmation_text != '' && confirmation_text != 'None' && confirmation_text != 'null')
- if(!confirm(confirmation_text))
- return false;
-
- // use small characters for operation?!
- operation = operation.toLowerCase();
-
- // Update grid.
- this.grid.set({
- operation: operation,
- item_ids: id
- });
-
- // Do operation. If operation cannot be performed asynchronously, redirect to location.
- if (this.grid.can_async_op(operation)) {
- this.update_grid();
- } else {
- this.go_to(inbound, '');
- }
-
- // done
- return false;
- }
-
- // check for href details
- if (href)
- {
- this.go_to(inbound, href);
- return false;
- }
-
- // refresh grid
- if (this.grid.get('async')) {
- this.update_grid();
- } else {
- this.go_to(inbound, '');
- }
-
- // done
- return false;
- },
-
- // go to url
- go_to: function (inbound, href) {
- // get aysnc status
- var async = this.grid.get('async');
- this.grid.set('async', false);
-
- // get slide status
- advanced_search = $('#advanced-search').is(":visible");
- this.grid.set('advanced_search', advanced_search);
-
- // get default url
- if(!href)
- href = this.grid.get('url_base') + "?" + $.param(this.grid.get_url_data());
-
- // clear grid of transient request attributes.
- this.grid.set({
- operation: undefined,
- item_ids: undefined,
- async: async
- });
-
- if (inbound) {
- // this currently assumes that there is only a single grid shown at a time
- var $div = $('.grid-header').closest('.inbound');
- if ($div.length !== 0) {
- $div.load(href);
- return;
- }
- }
-
- window.location = href;
- },
-
- // Update grid.
- update_grid: function () {
- // If there's an operation, do POST; otherwise, do GET.
- var method = (this.grid.get('operation') ? "POST" : "GET" );
- $('.loading-elt-overlay').show(); // Show overlay to indicate loading and prevent user actions.
- var self = this;
- $.ajax({
- type: method,
- url: self.grid.get('url_base'),
- data: self.grid.get_url_data(),
- error: function(response) { alert( 'Grid refresh failed' );},
- success: function(response_text) {
- // Initialize new grid config
- self.init_grid($.parseJSON(response_text));
-
- // Hide loading overlay.
- $('.loading-elt-overlay').hide();
- },
- complete: function() {
- // Clear grid of transient request attributes.
- self.grid.set({
- operation: undefined,
- item_ids: undefined
- });
- }
- });
- },
-
- check_all_items: function () {
- var chk_all = document.getElementById('check_all'),
- checks = document.getElementsByTagName('input'),
- total = 0,
- i;
- if ( chk_all.checked === true ) {
- for ( i=0; i < checks.length; i++ ) {
- if ( checks[i].name.indexOf( 'id' ) !== -1) {
- checks[i].checked = true;
- total++;
- }
- }
- }
- else {
- for ( i=0; i < checks.length; i++ ) {
- if ( checks[i].name.indexOf( 'id' ) !== -1) {
- checks[i].checked = false;
- }
-
- }
- }
- this.init_grid_elements();
- },
-
- // Go back to page one; this is useful when a filter is applied.
- go_page_one: function () {
- // Need to go back to page 1 if not showing all.
- var cur_page = this.grid.get('cur_page');
- if (cur_page !== null && cur_page !== undefined && cur_page !== 'all') {
- this.grid.set('cur_page', 1);
- }
- },
-
- // template
- template_body: function(options) {
- // initialize
- var tmpl = '';
- var num_rows_rendered = 0;
- var items_length = options.items.length;
-
- // empty grid?
- if (items_length == 0) {
- // No results.
- tmpl += '<tr><td colspan="100"><em>No Items</em></td></tr>';
- num_rows_rendered = 1;
- }
-
- // create rows
- for (var i in options.items) {
-
- // encode ids
- var item = options.items[i];
- var encoded_id = item.encode_id;
- var popupmenu_id = 'grid-' + i + '-popup';
-
- // Tag current
- tmpl += '<tr ';
- if (options.current_item_id == item.id) {
- tmpl += 'class="current"';
- }
- tmpl += '>';
-
- // Item selection column
- if (options.show_item_checkboxes) {
- tmpl += '<td style="width: 1.5em;">' +
- '<input type="checkbox" name="id" value="' + encoded_id + '" id="' + encoded_id + '" class="grid-row-select-checkbox" />' +
- '</td>';
- }
-
- // Data columns
- for (j in options.columns) {
- var column = options.columns[j];
- if (column.visible) {
- // Nowrap
- var nowrap = '';
- if (column.nowrap) {
- nowrap = 'style="white-space:nowrap;"';
- }
-
- // get column settings
- var column_settings = item.column_config[column.label];
-
- // load attributes
- var link = column_settings.link;
- var value = column_settings.value;
- var inbound = column_settings.inbound;
-
- // unescape value
- if (jQuery.type( value ) === 'string') {
- value = value.replace(/\/\//g, '/');
- }
-
- // Attach popup menu?
- var id = "";
- var cls = "";
- if (column.attach_popup) {
- id = 'grid-' + i + '-popup';
- cls = "menubutton"
- if (link != '') {
- cls += " split";
- }
- cls += " popup";
- }
-
- // Check for row wrapping
- tmpl += '<td ' + nowrap + '>';
-
- // Link
- if (link) {
- if (options.operations.length != 0) {
- tmpl += '<div id="' + id + '" class="' + cls + '" style="float: left;">';
- }
-
- var label_class = "";
- if (inbound) {
- label_class = "use-inbound"
- } else {
- label_class = "use-outbound"
- }
- tmpl += '<a class="label ' + label_class + '" href="' + link + '" onclick="return false;">' + value + '</a>';
- if (options.operations.length != 0) {
- tmpl += '</div>';
- }
- } else {
- tmpl += '<div id="' + id + '" class="' + cls + '"><label id="' + column.label_id_prefix + encoded_id + '" for="' + encoded_id + '">' + value + '</label></div>';
- }
- tmpl += '</td>';
- }
- }
- tmpl += '</tr>';
- num_rows_rendered++;
- }
- return tmpl;
- },
-
- // template
- template_footer: function(options) {
-
- // create template string
- var tmpl = '';
-
- // paging
- if (options.use_paging && options.num_pages > 1) {
- // get configuration
- var num_page_links = options.num_page_links;
- var cur_page_num = options.cur_page_num;
- var num_pages = options.num_pages;
-
- // First pass on min page.
- var page_link_range = num_page_links / 2;
- var min_page = cur_page_num - page_link_range
- var min_offset = 0;
- if (min_page == 0) {
- // Min page is too low.
- min_page = 1;
- min_offset = page_link_range - ( cur_page_num - min_page );
- }
-
- // Set max page.
- var max_range = page_link_range + min_offset;
- var max_page = cur_page_num + max_range;
- if (max_page <= num_pages) {
- // Max page is fine.
- max_offset = 0;
- } else {
- // Max page is too high.
- max_page = num_pages;
- // +1 to account for the +1 in the loop below.
- max_offset = max_range - ( max_page + 1 - cur_page_num );
- }
-
- // Second and final pass on min page to add any unused
- // offset from max to min.
- if (max_offset != 0) {
- min_page -= max_offset
- if (min_page < 1) {
- min_page = 1
- }
- }
-
- // template header
- tmpl += '<tr id="page-links-row">';
- if (options.show_item_checkboxes) {
- tmpl += '<td></td>';
- }
- tmpl += '<td colspan="100">' +
- '<span id="page-link-container">' +
- 'Page:';
-
- if (min_page > 1) {
- tmpl += '<span class="page-link" id="page-link-1"><a href="' + this.grid.get_url({page : page_index}) + '" page_num="1" onclick="return false;">1</a></span> ...';
- }
-
- // create page urls
- for (var page_index = min_page; page_index < max_page + 1; page_index++) {
-
- if (page_index == options.cur_page_num) {
- tmpl += '<span class="page-link inactive-link" id="page-link-' + page_index + '">' + page_index + '</span>';
- } else {
- tmpl += '<span class="page-link" id="page-link-' + page_index + '"><a href="' + this.grid.get_url({page : page_index}) + '" onclick="return false;" page_num="' + page_index + '">' + page_index + '</a></span>';
- }
- }
-
- // show last page
- if (max_page < num_pages) {
- tmpl += '...' +
- '<span class="page-link" id="page-link-' + num_pages + '"><a href="' + this.grid.get_url({page : num_pages}) + '" onclick="return false;" page_num="' + num_pages + '">' + num_pages + '</a></span>';
- }
- tmpl += '</span>';
-
- // Show all link
- tmpl += '<span class="page-link" id="show-all-link-span"> | <a href="' + this.grid.get_url({page : 'all'}) + '" onclick="return false;" page_num="all">Show All</a></span>' +
- '</td>' +
- '</tr>';
- }
-
- // Grid operations for multiple items.
- if (options.show_item_checkboxes) {
- // start template
- tmpl += '<tr>' +
- '<input type="hidden" id="operation" name="operation" value="">' +
- '<td></td>' +
- '<td colspan="100">' +
- 'For <span class="grid-selected-count"></span> selected ' + options.get_class_plural + ': ';
-
- // configure buttons for operations
- for (i in options.operations) {
- var operation = options.operations[i];
- if (operation.allow_multiple) {
- tmpl += '<input type="button" value="' + operation.label + '" class="action-button" onclick="gridView.submit_operation(this, \'' + operation.confirm + '\')"> ';
- }
- }
-
- // finalize template
- tmpl += '</td>' +
- '</tr>';
- }
-
- // count global operations
- var found_global = false;
- for (i in options.operations) {
- if (options.operations[i].global_operation) {
- found_global = true;
- break;
- }
- }
-
- // add global operations
- if (found_global) {
- tmpl += '<tr>' +
- '<td colspan="100">';
- for (i in options.operations) {
- var operation = options.operations[i];
- if (operation.global_operation) {
- tmpl += '<a class="action-button" href="' + operation.global_operation + '">' + operation.label + '</a>';
- }
- }
- tmpl += '</td>' +
- '</tr>';
- }
-
- // add legend
- if (options.legend) {
- tmpl += '<tr>' +
- '<td colspan="100">' + options.legend + '</td>' +
- '</tr>';
- }
-
- // return
- return tmpl;
- },
-
- // template
- template_message: function(options) {
- return '<p>' +
- '<div class="' + options.status + 'message transient-message">' + options.message + '</div>' +
- '<div style="clear: both"></div>' +
- '</p>';
- }
-});
-
-return {
- Grid : Grid,
- GridView : GridView
-};
-
-});
\ No newline at end of file
diff -r be7ece9454471d655668f3997c29b90c2f6c312d -r b20d93e643068f3154752582db3d17e16c499633 static/scripts/mvc/grid/grid-model.js
--- /dev/null
+++ b/static/scripts/mvc/grid/grid-model.js
@@ -0,0 +1,134 @@
+// dependencies
+define([], function() {
+
+// grid model
+return Backbone.Model.extend({
+ defaults: {
+ url_base: '',
+ async: false,
+ async_ops: [],
+ categorical_filters: [],
+ filters: {},
+ sort_key: null,
+ show_item_checkboxes: false,
+ advanced_search: false,
+ cur_page: 1,
+ num_pages: 1,
+ operation: undefined,
+ item_ids: undefined
+ },
+
+ /**
+ * Return true if operation can be done asynchronously.
+ */
+ can_async_op: function(op) {
+ return _.indexOf(this.attributes.async_ops, op) !== -1;
+ },
+
+ /**
+ * Add filtering criterion.
+ */
+ add_filter: function(key, value, append) {
+ // Update URL arg with new condition.
+ if (append) {
+ // Update or append value.
+ var cur_val = this.attributes.filters[key],
+ new_val;
+ if (cur_val === null || cur_val === undefined) {
+ new_val = value;
+ }
+ else if (typeof(cur_val) == "string") {
+ if (cur_val == "All") {
+ new_val = value;
+ } else {
+ // Replace string with array.
+ var values = [];
+ values[0] = cur_val;
+ values[1] = value;
+ new_val = values;
+ }
+ }
+ else {
+ // Current value is an array.
+ new_val = cur_val;
+ new_val.push(value);
+ }
+ this.attributes.filters[key] = new_val;
+ }
+ else {
+ // Replace value.
+ this.attributes.filters[key] = value;
+ }
+ },
+
+ /**
+ * Remove filtering criterion.
+ */
+ remove_filter: function(key, condition) {
+ var cur_val = this.attributes.filters[key];
+ if (cur_val === null || cur_val === undefined) {
+ return false;
+ }
+
+ var removed = true;
+ if (typeof(cur_val) === "string") {
+ if (cur_val == "All") {
+ // Unexpected. Throw error?
+ removed = false;
+ }
+ else {
+ // Remove condition.
+ delete this.attributes.filters[key];
+ }
+ }
+ else {
+ // Filter contains an array of conditions.
+ var condition_index = _.indexOf(cur_val, condition);
+ if (condition_index !== -1) {
+ cur_val.splice(condition_index, 1);
+ }
+ else {
+ removed = false;
+ }
+ }
+
+ return removed;
+ },
+
+ /**
+ * Returns URL data for obtaining a new grid.
+ */
+ get_url_data: function() {
+ var url_data = {
+ async: this.attributes.async,
+ sort: this.attributes.sort_key,
+ page: this.attributes.cur_page,
+ show_item_checkboxes: this.attributes.show_item_checkboxes,
+ advanced_search: this.attributes.advanced_search
+ };
+
+ // Add operation, item_ids only if they have values.
+ if (this.attributes.operation) {
+ url_data.operation = this.attributes.operation;
+ }
+ if (this.attributes.item_ids) {
+ url_data.id = this.attributes.item_ids;
+ }
+
+ // Add filter arguments to data, placing "f-" in front of all arguments.
+ var self = this;
+ _.each(_.pairs(self.attributes.filters), function(k) {
+ url_data['f-' + k[0]] = k[1];
+ });
+
+ return url_data;
+ },
+
+ // Return URL for obtaining a new grid
+ get_url: function (args) {
+ return this.get('url_base') + "?" + $.param(this.get_url_data()) + '&' + $.param(args);
+ }
+
+});
+
+});
\ No newline at end of file
diff -r be7ece9454471d655668f3997c29b90c2f6c312d -r b20d93e643068f3154752582db3d17e16c499633 static/scripts/mvc/grid/grid-template.js
--- /dev/null
+++ b/static/scripts/mvc/grid/grid-template.js
@@ -0,0 +1,617 @@
+// dependencies
+define([], function() {
+
+// grid view templates
+return {
+ // template
+ grid: function(options) {
+ var tmpl = '';
+ if (options.embedded) {
+ tmpl = this.grid_header(options) + this.grid_table(options);
+ } else {
+ tmpl = '<div class="loading-elt-overlay"></div>' +
+ '<table>' +
+ '<tr>' +
+ '<td width="75%">' +
+ this.grid_header(options) +
+ '</td>' +
+ '<td></td>' +
+ '<td></td>' +
+ '</tr>' +
+ '<tr>' +
+ '<td width="100%" id="grid-message" valign="top"></td>' +
+ '<td></td>' +
+ '<td></td>' +
+ '</tr>' +
+ '</table>' +
+ this.grid_table(options);
+ }
+
+ // add info text
+ if (options.info_text) {
+ tmpl += '<br><div class="toolParamHelp" style="clear: both;">' + options.info_text + '</div>';
+ }
+
+ // return
+ return tmpl;
+ },
+
+ // template
+ grid_table: function(options) {
+ return '<form method="post" onsubmit="return false;">' +
+ '<table id="grid-table" class="grid">' +
+ '<thead id="grid-table-header"></thead>' +
+ '<tbody id="grid-table-body"></tbody>' +
+ '<tfoot id="grid-table-footer"></tfoot>' +
+ '</table>' +
+ '</form>';
+ },
+
+ // template
+ grid_header: function(options) {
+ var tmpl = '<div class="grid-header">';
+ if (!options.embedded) {
+ tmpl += '<h2>' + options.title + '</h2>';
+ }
+ if (options.global_actions) {
+ tmpl += '<ul class="manage-table-actions">';
+ var show_popup = (options.global_actions.length >= 3);
+ if (show_popup) {
+ tmpl += '<li><a class="action-button" id="popup-global-actions" class="menubutton">Actions</a></li>' +
+ '<div popupmenu="popup-global-actions">';
+ }
+ for (i in options.global_actions) {
+ var action = options.global_actions[i];
+ var label_cls = '';
+ if (action.inbound) {
+ label_cls = 'use-inbound'
+ } else {
+ label_cls = 'use-outbound'
+ }
+ tmpl += '<li>' +
+ '<a class="action-button ' + label_cls + '" href="' + action.url_args + '" onclick="return false;">' + action.label + '</a>' +
+ '</li>';
+ }
+ if (show_popup) {
+ tmpl += '</div>';
+ }
+ tmpl += '</ul>';
+ }
+ if (options.insert) {
+ tmpl += options.insert;
+ }
+
+ // add grid filters
+ tmpl += this.grid_filters(options);
+ tmpl += '</div>'
+
+ // return template
+ return tmpl;
+ },
+
+ // template
+ header: function(options) {
+
+ // start
+ var tmpl = '<tr>';
+
+ // add checkbox
+ if (options.show_item_checkboxes) {
+ tmpl += '<th>';
+ if (options.items.length > 0) {
+ tmpl += '<input type="checkbox" id="check_all" name=select_all_checkbox value="true">' +
+ '<input type="hidden" name=select_all_checkbox value="true">';
+ }
+ tmpl += '</th>';
+ }
+
+ // create header elements
+ for (var i in options.columns) {
+ var column = options.columns[i];
+ if (column.visible) {
+ tmpl += '<th id="' + column.key + '-header">';
+ if (column.href) {
+ tmpl += '<a href="' + column.href + '" class="sort-link" sort_key="' + column.key + '">' + column.label + '</a>';
+ } else {
+ tmpl += column.label;
+ }
+ tmpl += '<span class="sort-arrow">' + column.extra + '</span>' +
+ '</th>';
+ }
+ }
+
+ // finalize
+ tmpl += '</tr>';
+
+ // return template
+ return tmpl;
+ },
+
+ // template
+ body: function(options) {
+ // initialize
+ var tmpl = '';
+ var num_rows_rendered = 0;
+ var items_length = options.items.length;
+
+ // empty grid?
+ if (items_length == 0) {
+ // No results.
+ tmpl += '<tr><td colspan="100"><em>No Items</em></td></tr>';
+ num_rows_rendered = 1;
+ }
+
+ // create rows
+ for (var i in options.items) {
+
+ // encode ids
+ var item = options.items[i];
+ var encoded_id = item.encode_id;
+ var popupmenu_id = 'grid-' + i + '-popup';
+
+ // Tag current
+ tmpl += '<tr ';
+ if (options.current_item_id == item.id) {
+ tmpl += 'class="current"';
+ }
+ tmpl += '>';
+
+ // Item selection column
+ if (options.show_item_checkboxes) {
+ tmpl += '<td style="width: 1.5em;">' +
+ '<input type="checkbox" name="id" value="' + encoded_id + '" id="' + encoded_id + '" class="grid-row-select-checkbox" />' +
+ '</td>';
+ }
+
+ // Data columns
+ for (j in options.columns) {
+ var column = options.columns[j];
+ if (column.visible) {
+ // Nowrap
+ var nowrap = '';
+ if (column.nowrap) {
+ nowrap = 'style="white-space:nowrap;"';
+ }
+
+ // get column settings
+ var column_settings = item.column_config[column.label];
+
+ // load attributes
+ var link = column_settings.link;
+ var value = column_settings.value;
+ var inbound = column_settings.inbound;
+
+ // unescape value
+ if (jQuery.type( value ) === 'string') {
+ value = value.replace(/\/\//g, '/');
+ }
+
+ // Attach popup menu?
+ var id = '';
+ var cls = '';
+ if (column.attach_popup) {
+ id = 'grid-' + i + '-popup';
+ cls = 'menubutton';
+ if (link != '') {
+ cls += ' split';
+ }
+ cls += ' popup';
+ }
+
+ // Check for row wrapping
+ tmpl += '<td ' + nowrap + '>';
+
+ // Link
+ if (link) {
+ if (options.operations.length != 0) {
+ tmpl += '<div id="' + id + '" class="' + cls + '" style="float: left;">';
+ }
+
+ var label_class = '';
+ if (inbound) {
+ label_class = 'use-inbound';
+ } else {
+ label_class = 'use-outbound';
+ }
+ tmpl += '<a class="label ' + label_class + '" href="' + link + '" onclick="return false;">' + value + '</a>';
+ if (options.operations.length != 0) {
+ tmpl += '</div>';
+ }
+ } else {
+ tmpl += '<div id="' + id + '" class="' + cls + '"><label id="' + column.label_id_prefix + encoded_id + '" for="' + encoded_id + '">' + value + '</label></div>';
+ }
+ tmpl += '</td>';
+ }
+ }
+ tmpl += '</tr>';
+ num_rows_rendered++;
+ }
+ return tmpl;
+ },
+
+ // template
+ footer: function(options) {
+
+ // create template string
+ var tmpl = '';
+
+ // paging
+ if (options.use_paging && options.num_pages > 1) {
+ // get configuration
+ var num_page_links = options.num_page_links;
+ var cur_page_num = options.cur_page_num;
+ var num_pages = options.num_pages;
+
+ // First pass on min page.
+ var page_link_range = num_page_links / 2;
+ var min_page = cur_page_num - page_link_range
+ var min_offset = 0;
+ if (min_page == 0) {
+ // Min page is too low.
+ min_page = 1;
+ min_offset = page_link_range - ( cur_page_num - min_page );
+ }
+
+ // Set max page.
+ var max_range = page_link_range + min_offset;
+ var max_page = cur_page_num + max_range;
+ if (max_page <= num_pages) {
+ // Max page is fine.
+ max_offset = 0;
+ } else {
+ // Max page is too high.
+ max_page = num_pages;
+ // +1 to account for the +1 in the loop below.
+ max_offset = max_range - ( max_page + 1 - cur_page_num );
+ }
+
+ // Second and final pass on min page to add any unused
+ // offset from max to min.
+ if (max_offset != 0) {
+ min_page -= max_offset
+ if (min_page < 1) {
+ min_page = 1
+ }
+ }
+
+ // template header
+ tmpl += '<tr id="page-links-row">';
+ if (options.show_item_checkboxes) {
+ tmpl += '<td></td>';
+ }
+ tmpl += '<td colspan="100">' +
+ '<span id="page-link-container">' +
+ 'Page:';
+
+ if (min_page > 1) {
+ tmpl += '<span class="page-link" id="page-link-1"><a href="' + this.grid.get_url({page : page_index}) + '" page_num="1" onclick="return false;">1</a></span> ...';
+ }
+
+ // create page urls
+ for (var page_index = min_page; page_index < max_page + 1; page_index++) {
+
+ if (page_index == options.cur_page_num) {
+ tmpl += '<span class="page-link inactive-link" id="page-link-' + page_index + '">' + page_index + '</span>';
+ } else {
+ tmpl += '<span class="page-link" id="page-link-' + page_index + '"><a href="' + this.grid.get_url({page : page_index}) + '" onclick="return false;" page_num="' + page_index + '">' + page_index + '</a></span>';
+ }
+ }
+
+ // show last page
+ if (max_page < num_pages) {
+ tmpl += '...' +
+ '<span class="page-link" id="page-link-' + num_pages + '"><a href="' + this.grid.get_url({page : num_pages}) + '" onclick="return false;" page_num="' + num_pages + '">' + num_pages + '</a></span>';
+ }
+ tmpl += '</span>';
+
+ // Show all link
+ tmpl += '<span class="page-link" id="show-all-link-span"> | <a href="' + this.grid.get_url({page : 'all'}) + '" onclick="return false;" page_num="all">Show All</a></span>' +
+ '</td>' +
+ '</tr>';
+ }
+
+ // Grid operations for multiple items.
+ if (options.show_item_checkboxes) {
+ // start template
+ tmpl += '<tr>' +
+ '<input type="hidden" id="operation" name="operation" value="">' +
+ '<td></td>' +
+ '<td colspan="100">' +
+ 'For <span class="grid-selected-count"></span> selected ' + options.get_class_plural + ': ';
+
+ // configure buttons for operations
+ for (i in options.operations) {
+ var operation = options.operations[i];
+ if (operation.allow_multiple) {
+ tmpl += '<input type="button" value="' + operation.label + '" class="operation-button action-button"> ';
+ }
+ }
+
+ // finalize template
+ tmpl += '</td>' +
+ '</tr>';
+ }
+
+ // count global operations
+ var found_global = false;
+ for (i in options.operations) {
+ if (options.operations[i].global_operation) {
+ found_global = true;
+ break;
+ }
+ }
+
+ // add global operations
+ if (found_global) {
+ tmpl += '<tr>' +
+ '<td colspan="100">';
+ for (i in options.operations) {
+ var operation = options.operations[i];
+ if (operation.global_operation) {
+ tmpl += '<a class="action-button" href="' + operation.global_operation + '">' + operation.label + '</a>';
+ }
+ }
+ tmpl += '</td>' +
+ '</tr>';
+ }
+
+ // add legend
+ if (options.legend) {
+ tmpl += '<tr>' +
+ '<td colspan="100">' + options.legend + '</td>' +
+ '</tr>';
+ }
+
+ // return
+ return tmpl;
+ },
+
+ // template
+ message: function(options) {
+ return '<p>' +
+ '<div class="' + options.status + 'message transient-message">' + options.message + '</div>' +
+ '<div style="clear: both"></div>' +
+ '</p>';
+ },
+
+ // template
+ grid_filters: function (options) {
+
+ // get filters
+ var default_filter_dict = options.default_filter_dict;
+ var filters = options.filters;
+
+ // show advanced search if flag set or if there are filters for advanced search fields
+ var advanced_search_display = 'none';
+ if (options.advanced_search) {
+ advanced_search_display = 'block';
+ }
+
+ // identify columns with advanced filtering
+ var show_advanced_search_link = false;
+ for (var i in options.columns) {
+ var column = options.columns[i];
+ if (column.filterable == 'advanced') {
+ var column_key = column.key;
+ var f_key = filters[column_key];
+ var d_key = default_filter_dict[column_key];
+ if (f_key && d_key && f_key != d_key) {
+ advanced_search_display = 'block';
+ }
+ show_advanced_search_link = true;
+ }
+ }
+
+ // hide standard search if advanced is shown
+ var standard_search_display = 'block';
+ if (advanced_search_display == 'block') {
+ standard_search_display = 'none';
+ }
+
+ //
+ // standard search
+ //
+ var tmpl = '<div id="standard-search" style="display: ' + standard_search_display + ';">' +
+ '<table>' +
+ '<tr>' +
+ '<td style="padding: 0;">' +
+ '<table>';
+
+ // add standard filters
+ for (var i in options.columns) {
+ var column = options.columns[i];
+ if (column.filterable == 'standard') {
+ tmpl += this.grid_column_filter(options, column);
+ }
+ }
+
+ // finalize standard search
+ tmpl += '</table>' +
+ '</td>' +
+ '</tr>' +
+ '<tr>' +
+ '<td>';
+
+ // show advanced search link in standard display
+ if (show_advanced_search_link) {
+ tmpl += '<a href="" class="advanced-search-toggle">Advanced Search</a>';
+ }
+
+ // finalize standard search display
+ tmpl += '</td>' +
+ '</tr>' +
+ '</table>' +
+ '</div>';
+
+ //
+ // advanced search
+ //
+ tmpl += '<div id="advanced-search" style="display: ' + advanced_search_display + '; margin-top: 5px; border: 1px solid #ccc;">' +
+ '<table>' +
+ '<tr>' +
+ '<td style="text-align: left" colspan="100">' +
+ '<a href="" class="advanced-search-toggle">Close Advanced Search</a>' +
+ '</td>' +
+ '</tr>';
+
+ // add advanced filters
+ for (var i in options.columns) {
+ var column = options.columns[i];
+ if (column.filterable == 'advanced') {
+ tmpl += this.grid_column_filter(options, column);
+ }
+ }
+
+ // finalize advanced search template
+ tmpl += '</table>' +
+ '</div>';
+
+ // return template
+ return tmpl;
+ },
+
+ // template
+ grid_column_filter: function(options, column) {
+
+ // collect parameters
+ var default_filter_dict = options.default_filter_dict;
+ var filters = options.filters;
+ var column_label = column.label;
+ var column_key = column.key;
+ if (column.filterable == 'advanced') {
+ column_label = column_label.toLowerCase();
+ }
+
+ // start
+ var tmpl = '<tr>';
+
+ if (column.filterable == 'advanced') {
+ tmpl += '<td align="left" style="padding-left: 10px">' + column_label + ':</td>';
+ }
+ tmpl += '<td style="padding-bottom: 1px;">';
+ if (column.is_text) {
+ tmpl += '<form class="text-filter-form" column_key="' + column_key + '" action="' + options.url + '" method="get" >';
+ // Carry forward filtering criteria with hidden inputs.
+ for (i in options.columns) {
+ var temp_column = options.columns[i];
+ var filter_value = filters[temp_column.key];
+ if (filter_value) {
+ if (filter_value != 'All') {
+ if (temp_column.is_text) {
+ filter_value = JSON.stringify( filter_value )
+ }
+ tmpl += '<input type="hidden" id="' + temp_column.key + '" name="f-' + temp_column.key + '" value="' + filter_value + '"/>';
+ }
+ }
+ }
+ // Print current filtering criteria and links to delete.
+ tmpl += '<span id="' + column_key + '-filtering-criteria">';
+
+ // add filters
+ var column_filter = filters[column_key];
+ if (column_filter) {
+ // identify type
+ var type = jQuery.type(column_filter);
+
+ // single filter value
+ if (type == 'string') {
+ if (column_filter != 'All') {
+ // append template
+ tmpl += this.filter_element(column_key, column_filter);
+ }
+ }
+
+ // multiple filter values
+ if (type == 'array') {
+ for (var i in column_filter ) {
+ // get filter
+ var filter = column_filter[i];
+
+ // copy filters and remove entry
+ var params = column_filter;
+ params = params.slice(i);
+
+ // append template
+ tmpl += this.filter_element(column_key, filter);
+ }
+ }
+ }
+
+ // close span
+ tmpl += '</span>';
+
+ // Set value, size of search input field. Minimum size is 20 characters.
+ var value = '';
+ if (column.filterable == 'standard') {
+ value = column.label.toLowerCase();
+ var size = value.length;
+ if (size < 20) {
+ size = 20;
+ }
+ // +4 to account for search icon/button.
+ size = size + 4;
+ }
+
+ // print input field for column
+ tmpl += '<span class="search-box">' +
+ '<input class="search-box-input" id="input-' + column_key + '-filter" name="f-' + column_key + '" type="text" placeholder="' + value + '" size="' + size + '"/>' +
+ //'<button type="submit" style="background: transparent; border: none; padding: 4px; margin: 0px;">' +
+ // '<i class="fa fa-plus-circle" style="font-size: 1.2em;"></i>' +
+ //'</button>' +
+ '</span>' +
+ '</form>';
+ } else {
+ // filter criteria
+ tmpl += '<span id="' + column_key + '-filtering-criteria">';
+
+ // add category filters
+ var seperator = false;
+ for (cf_label in options.categorical_filters[column_key]) {
+ // get category filter
+ var cf = options.categorical_filters[column_key][cf_label];
+
+ // each filter will have only a single argument, so get that single argument
+ var cf_key = '';
+ var cf_arg = '';
+ for (key in cf) {
+ cf_key = key;
+ cf_arg = cf[key];
+ }
+
+ // add seperator
+ if (seperator) {
+ tmpl += ' | ';
+ }
+ seperator = true;
+
+ // add category
+ var filter = filters[column_key];
+ if (filter && cf[column_key] && filter == cf_arg) {
+ tmpl += '<span class="categorical-filter ' + column_key + '-filter current-filter">' + cf_label + '</span>';
+ } else {
+ tmpl += '<span class="categorical-filter ' + column_key + '-filter">' +
+ '<a href="javascript:void(0);" filter_key="' + cf_key + '" filter_val="' + cf_arg + '">' + cf_label + '</a>' +
+ '</span>';
+ }
+ }
+ tmpl += '</span>';
+ }
+ tmpl += '</td>' +
+ '</tr>';
+
+ // return template
+ return tmpl;
+ },
+
+ // template for filter items
+ filter_element: function(filter_key, filter_value) {
+ return '<span class="text-filter-val">' + filter_value +
+ '<a href="javascript:void(0);" filter_key="' + filter_key + '" filter_val="' + filter_value + '">' +
+ '<i class="fa fa-times" style="padding-left: 5px; padding-bottom: 6px;"/>' +
+ '</a>' +
+ '</span>';
+
+ }
+};
+
+});
\ No newline at end of file
This diff is so big that we needed to truncate the remainder.
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.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7637cfbea32e/
Changeset: 7637cfbea32e
Branch: job-search
User: Kyle Ellrott
Date: 2014-01-29 21:51:37
Summary: Default Merge
Affected #: 429 files
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 buildbot_setup.sh
--- a/buildbot_setup.sh
+++ b/buildbot_setup.sh
@@ -4,28 +4,6 @@
: ${HOSTTYPE:=`uname -m`}
-# link to HYPHY is arch-dependent
-case "$OSTYPE" in
- linux-gnu)
- kernel=`uname -r | cut -f1,2 -d.`
- HYPHY="/galaxy/software/linux$kernel-$HOSTTYPE/hyphy"
- ;;
- darwin*)
- this_minor=`uname -r | awk -F. '{print ($1-4)}'`
- machine=`machine`
- for minor in `jot - 3 $this_minor 1`; do
- HYPHY="/galaxy/software/macosx10.$minor-$machine/hyphy"
- [ -d "$HYPHY" ] && break
- done
- [ ! -d "$HYPHY" ] && unset HYPHY
- ;;
- solaris2.10)
- # For the psu-production builder which is Solaris, but jobs run on a
- # Linux cluster
- HYPHY="/galaxy/software/linux2.6-x86_64/hyphy"
- ;;
-esac
-
LINKS="
/galaxy/data/location/add_scores.loc
/galaxy/data/location/all_fasta.loc
@@ -121,12 +99,6 @@
ln -sf $link tool-data
done
- if [ -d "$HYPHY" ]; then
- echo "Linking $HYPHY"
- rm -f tool-data/HYPHY
- ln -sf $HYPHY tool-data/HYPHY
- fi
-
if [ -d "$JARS" ]; then
echo "Linking $JARS"
rm -f tool-data/shared/jars
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -37,17 +37,27 @@
this.chart_view = new ChartView(this);
this.viewport_view = new ViewportView(this);
- // portlet
- this.portlet = new Portlet({icon : 'fa-bar-chart-o', label : 'Charts'});
+ // append view port to charts viewer
+ this.charts_view.append(this.viewport_view.$el);
+
+ // create portlet
+ if (!this.options.config.widget) {
+ this.portlet = new Portlet({icon : 'fa-bar-chart-o', label : 'Charts'});
+ } else {
+ this.portlet = $('<div></div>');
+ }
+
+ // append views
this.portlet.append(this.charts_view.$el);
this.portlet.append(this.group_view.$el);
this.portlet.append(this.chart_view.$el);
- // append main
- this.charts_view.append(this.viewport_view.$el);
-
- // set elements
- this.setElement(this.portlet.$el);
+ // set element
+ if (!this.options.config.widget) {
+ this.setElement(this.portlet.$el);
+ } else {
+ this.setElement(this.portlet);
+ }
// hide views
this.group_view.$el.hide();
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 config/plugins/visualizations/charts/static/library/portlet.js
--- a/config/plugins/visualizations/charts/static/library/portlet.js
+++ b/config/plugins/visualizations/charts/static/library/portlet.js
@@ -116,21 +116,38 @@
showOperation: function(id) {
this.$operations.find('#' + id).show();
},
-
+
+ // set operation
+ setOperation: function(id, callback) {
+ var $el = this.$operations.find('#' + id);
+ $el.off('click');
+ $el.on('click', callback);
+ },
+
+ // label
+ label: function(new_label) {
+ var $el = this.$el.find('#label');
+ if (new_label) {
+ $el.html(new_label);
+ }
+ return $el.html();
+ },
+
// fill regular modal template
template: function(options) {
var tmpl = '<div class="toolForm">';
- if (options.label) {
- tmpl += '<div id="title" class="toolFormTitle" style="padding-bottom: 7px;">' +
+ if (options.label || options.icon) {
+ tmpl += '<div id="title" class="toolFormTitle" style="overflow:hidden;">' +
'<div id="operations" style="float: right;"></div>' +
- '<div>';
+ '<div style="overflow: hidden">';
if (options.icon)
- tmpl += '<i style="font-size: 1.2em" class="icon fa ' + options.icon + '"> </i>';
+ tmpl += '<i style="padding-top: 3px; float: left; font-size: 1.2em" class="icon fa ' + options.icon + '"> </i>';
- tmpl += options.label +
- '</div>' +
+ tmpl += '<div id="label" style="padding-top: 2px; float: left;">' + options.label + '</div>';
+
+ tmpl += '</div>' +
'</div>';
}
tmpl += '<div id="body" class="toolFormBody">';
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 config/plugins/visualizations/charts/static/models/datasets.js
--- a/config/plugins/visualizations/charts/static/models/datasets.js
+++ b/config/plugins/visualizations/charts/static/models/datasets.js
@@ -6,9 +6,9 @@
{
// options
optionsDefault : {
- limit : 20,
+ limit : 500,
pace : 1000,
- max : 5
+ max : 2
},
// list
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 config/plugins/visualizations/charts/static/views/charts.js
--- a/config/plugins/visualizations/charts/static/views/charts.js
+++ b/config/plugins/visualizations/charts/static/views/charts.js
@@ -45,25 +45,6 @@
self.app.chart_view.$el.show();
}
}),
- 'edit' : new Ui.ButtonIcon({
- icon : 'fa-pencil',
- tooltip: 'Edit',
- onclick: function() {
- // check if element has been selected
- var chart_id = self.table.value();
- if (!chart_id) {
- return;
- }
-
- // get chart
- var chart = self.app.charts.get(chart_id);
- self.app.chart.copy(chart);
-
- // show edit
- self.$el.hide();
- self.app.chart_view.$el.show();
- }
- }),
'delete' : new Ui.ButtonIcon({
icon : 'fa-minus',
tooltip: 'Delete',
@@ -100,7 +81,9 @@
this.portlet.append(this.table.$el);
// append to main
- this.$el.append(this.portlet.$el);
+ if (!this.app.options.config.widget) {
+ this.$el.append(this.portlet.$el);
+ }
// events
var self = this;
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 config/plugins/visualizations/charts/static/views/viewport.js
--- a/config/plugins/visualizations/charts/static/views/viewport.js
+++ b/config/plugins/visualizations/charts/static/views/viewport.js
@@ -25,8 +25,16 @@
// add table to portlet
this.portlet = new Portlet({
+ label : '',
+ icon : 'fa-signal',
height : this.options.height,
- overflow : 'hidden'
+ overflow : 'hidden',
+ operations : {
+ 'edit' : new Ui.ButtonIcon({
+ icon : 'fa-gear',
+ tooltip : 'Configure'
+ })
+ }
});
// set this element
@@ -53,15 +61,30 @@
},
// show
- show: function(id) {
+ show: function(chart_id) {
// hide all
this.$el.find('svg').hide();
- var item = this.list[id];
+ // identify selected item from list
+ var item = this.list[chart_id];
if (item) {
// show selected chart
this.$el.find(item.svg_id).show();
+ // get chart
+ var chart = self.app.charts.get(chart_id);
+
+ // update portlet
+ this.portlet.label(chart.get('title'));
+ this.portlet.setOperation('edit', function() {
+ // get chart
+ self.app.chart.copy(chart);
+
+ // show edit
+ self.app.charts_view.$el.hide();
+ self.app.chart_view.$el.show();
+ });
+
// this trigger d3 update events
$(window).trigger('resize');
}
@@ -69,11 +92,17 @@
// add
_addChart: function(chart) {
+ // link this
+ var self = this;
+
+ // backup chart details
+ var chart_id = chart.id;
+
// make sure that svg does not exist already
- this._removeChart(chart.id);
+ this._removeChart(chart_id);
// create id
- var svg_id = '#svg_' + chart.id;
+ var svg_id = '#svg_' + chart_id;
// create element
var chart_el = $(this._template({id: svg_id, height : this.options.height}));
@@ -82,7 +111,7 @@
this.portlet.append(chart_el);
// backup id
- this.list[chart.id] = {
+ this.list[chart_id] = {
svg_id : svg_id
}
@@ -129,8 +158,8 @@
chart_index++;
});
- // add view
- self.list[chart.id].view = view;
+ // show
+ self.show(chart_id);
});
},
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 doc/source/lib/galaxy.tools.util.rst
--- a/doc/source/lib/galaxy.tools.util.rst
+++ b/doc/source/lib/galaxy.tools.util.rst
@@ -9,14 +9,6 @@
:undoc-members:
:show-inheritance:
-:mod:`hyphy_util` Module
-------------------------
-
-.. automodule:: galaxy.tools.util.hyphy_util
- :members:
- :undoc-members:
- :show-inheritance:
-
:mod:`maf_utilities` Module
---------------------------
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 install_and_test_tool_shed_repositories.sh
--- a/install_and_test_tool_shed_repositories.sh
+++ b/install_and_test_tool_shed_repositories.sh
@@ -48,6 +48,14 @@
fi
fi
+if [ -z $GALAXY_INSTALL_TEST_SHED_TOOL_PATH ] ; then
+ export GALAXY_INSTALL_TEST_SHED_TOOL_PATH='/tmp/shed_tools'
+fi
+
+if [ ! -d $GALAXY_INSTALL_TEST_SHED_TOOL_PATH ] ; then
+ mkdir -p $GALAXY_INSTALL_TEST_SHED_TOOL_PATH
+fi
+
test_tool_dependency_definitions () {
# Test installation of repositories of type tool_dependency_definition.
if [ -f $GALAXY_INSTALL_TEST_TOOL_DEPENDENCY_DIR/stage_1_complete ] ; then
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -58,7 +58,7 @@
self.openid_consumer_cache_path = resolve_path( kwargs.get( "openid_consumer_cache_path", "database/openid_consumer_cache" ), self.root )
self.cookie_path = kwargs.get( "cookie_path", "/" )
self.genome_data_path = kwargs.get( "genome_data_path", "tool-data/genome" )
- self.rsync_url = kwargs.get( "rsync_url", "rsync://scofield.bx.psu.edu/indexes" )
+ self.rsync_url = kwargs.get( "rsync_url", "rsync://datacache.galaxyproject.org/indexes" )
# Galaxy OpenID settings
self.enable_openid = string_as_bool( kwargs.get( 'enable_openid', False ) )
self.openid_config = kwargs.get( 'openid_config_file', 'openid_conf.xml' )
@@ -122,6 +122,7 @@
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.use_remote_user = string_as_bool( kwargs.get( "use_remote_user", "False" ) )
+ 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' )
self.remote_user_logout_href = kwargs.get( "remote_user_logout_href", None )
@@ -151,6 +152,7 @@
h, m, s = [ int( v ) for v in self.job_walltime.split( ':' ) ]
self.job_walltime_delta = timedelta( 0, s, 0, 0, m, h )
self.admin_users = kwargs.get( "admin_users", "" )
+ self.reset_password_length = int( kwargs.get('reset_password_length', '15') )
self.mailing_join_addr = kwargs.get('mailing_join_addr',"galaxy-announce-join(a)bx.psu.edu")
self.error_email_to = kwargs.get( 'error_email_to', None )
self.activation_email = kwargs.get( 'activation_email', None )
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/datatypes/converters/bam_to_bai.xml
--- a/lib/galaxy/datatypes/converters/bam_to_bai.xml
+++ b/lib/galaxy/datatypes/converters/bam_to_bai.xml
@@ -1,4 +1,7 @@
<tool id="CONVERTER_Bam_Bai_0" name="Bam to Bai" hidden="true">
+ <requirements>
+ <requirement type="package">samtools</requirement>
+ </requirements><command>samtools index $input1 $output1</command><inputs><page>
@@ -10,4 +13,4 @@
</outputs><help></help>
-</tool>
\ No newline at end of file
+</tool>
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/datatypes/converters/sam_to_bam.xml
--- a/lib/galaxy/datatypes/converters/sam_to_bam.xml
+++ b/lib/galaxy/datatypes/converters/sam_to_bam.xml
@@ -5,6 +5,9 @@
To fix this: (a) merge sam_to_bam tool in tools with this conversion (like fasta_to_len
conversion); and (b) define a datatype-specific way to set converter parameters.
-->
+ <requirements>
+ <requirement type="package">samtools</requirement>
+ </requirements><command interpreter="python">sam_to_bam.py $input1 $output</command><inputs><param name="input1" type="data" format="sam" label="SAM file"/>
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/datatypes/tabular.py
--- a/lib/galaxy/datatypes/tabular.py
+++ b/lib/galaxy/datatypes/tabular.py
@@ -275,7 +275,7 @@
cursor = f.read(1)
return to_json_string( { 'ck_data': util.unicodify( ck_data ), 'ck_index': ck_index + 1 } )
- def display_data(self, trans, dataset, preview=False, filename=None, to_ext=None, chunk=None):
+ def display_data(self, trans, dataset, preview=False, filename=None, to_ext=None, chunk=None, **kwd):
preview = util.string_as_bool( preview )
if chunk:
return self.get_chunk(trans, dataset, chunk)
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -789,8 +789,8 @@
# If the job was deleted, call tool specific fail actions (used for e.g. external metadata) and clean up
if self.tool:
self.tool.job_failed( self, message, exception )
- if self.app.config.cleanup_job == 'always' or (self.app.config.cleanup_job == 'onsuccess' and job.state == job.states.DELETED):
- self.cleanup()
+ delete_files = self.app.config.cleanup_job == 'always' or (self.app.config.cleanup_job == 'onsuccess' and job.state == job.states.DELETED)
+ self.cleanup( delete_files=delete_files )
def pause( self, job=None, message=None ):
if job is None:
@@ -883,11 +883,10 @@
# We set final_job_state to use for dataset management, but *don't* set
# job.state until after dataset collection to prevent history issues
- if job.states.ERROR != job.state:
- if ( self.check_tool_output( stdout, stderr, tool_exit_code, job )):
- final_job_state = job.states.OK
- else:
- final_job_state = job.states.ERROR
+ if ( self.check_tool_output( stdout, stderr, tool_exit_code, job ) ):
+ final_job_state = job.states.OK
+ else:
+ final_job_state = job.states.ERROR
if self.version_string_cmd:
version_filename = self.get_version_string_path()
@@ -1067,22 +1066,26 @@
self.sa_session.flush()
log.debug( 'job %d ended' % self.job_id )
- if self.app.config.cleanup_job == 'always' or ( not stderr and self.app.config.cleanup_job == 'onsuccess' ):
- self.cleanup()
+ delete_files = self.app.config.cleanup_job == 'always' or ( job.state == job.states.OK and self.app.config.cleanup_job == 'onsuccess' )
+ self.cleanup( delete_files=delete_files )
def check_tool_output( self, stdout, stderr, tool_exit_code, job ):
return check_output( self.tool, stdout, stderr, tool_exit_code, job )
- def cleanup( self ):
- # remove temporary files
+ def cleanup( self, delete_files=True ):
+ # At least one of these tool cleanup actions (job import), is needed
+ # for thetool to work properly, that is why one might want to run
+ # cleanup but not delete files.
try:
- for fname in self.extra_filenames:
- os.remove( fname )
- self.external_output_metadata.cleanup_external_metadata( self.sa_session )
+ if delete_files:
+ for fname in self.extra_filenames:
+ os.remove( fname )
+ self.external_output_metadata.cleanup_external_metadata( self.sa_session )
galaxy.tools.imp_exp.JobExportHistoryArchiveWrapper( self.job_id ).cleanup_after_job( self.sa_session )
galaxy.tools.imp_exp.JobImportHistoryArchiveWrapper( self.app, self.job_id ).cleanup_after_job()
galaxy.tools.genome_index.GenomeIndexToolWrapper( self.job_id ).postprocessing( self.sa_session, self.app )
- self.app.object_store.delete(self.get_job(), base_dir='job_work', entire_dir=True, dir_only=True, extra_dir=str(self.job_id))
+ if delete_files:
+ self.app.object_store.delete(self.get_job(), base_dir='job_work', entire_dir=True, dir_only=True, extra_dir=str(self.job_id))
except:
log.exception( "Unable to cleanup job %d" % self.job_id )
@@ -1520,8 +1523,8 @@
# if the job was deleted, don't finish it
if task.state == task.states.DELETED:
# Job was deleted by an administrator
- if self.app.config.cleanup_job in ( 'always', 'onsuccess' ):
- self.cleanup()
+ delete_files = self.app.config.cleanup_job in ( 'always', 'onsuccess' )
+ self.cleanup( delete_files=delete_files )
return
elif task.state == task.states.ERROR:
self.fail( task.info )
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -35,7 +35,9 @@
PasswordField, SelectField, TextArea, TextField, WorkflowField,
WorkflowMappingField)
from sqlalchemy.orm import object_session
+from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import func
+from sqlalchemy import not_
log = logging.getLogger( __name__ )
@@ -898,6 +900,22 @@
rval = galaxy.datatypes.data.nice_size( rval )
return rval
+ @property
+ def active_datasets_children_and_roles( self ):
+ if not hasattr(self, '_active_datasets_children_and_roles'):
+ db_session = object_session( self )
+ query = db_session.query( HistoryDatasetAssociation ).filter( HistoryDatasetAssociation.table.c.history_id == self.id ). \
+ filter( not_( HistoryDatasetAssociation.deleted ) ). \
+ order_by( HistoryDatasetAssociation.table.c.hid.asc() ). \
+ options(
+ joinedload("children"),
+ joinedload("dataset"),
+ joinedload("dataset.actions"),
+ joinedload("dataset.actions.role"),
+ )
+ self._active_datasets_children_and_roles = query.all()
+ return self._active_datasets_children_and_roles
+
def contents_iter( self, **kwds ):
"""
Fetch filtered list of contents of history.
@@ -909,10 +927,10 @@
query = query.order_by( HistoryDatasetAssociation.table.c.hid.asc() )
deleted = galaxy.util.string_as_bool_or_none( kwds.get( 'deleted', None ) )
if deleted is not None:
- query = query.filter( HistoryDatasetAssociation.deleted == bool( kwds['deleted'] ) )
+ query = query.filter( HistoryDatasetAssociation.deleted == deleted )
visible = galaxy.util.string_as_bool_or_none( kwds.get( 'visible', None ) )
if visible is not None:
- query = query.filter( HistoryDatasetAssociation.visible == bool( kwds['visible'] ) )
+ query = query.filter( HistoryDatasetAssociation.visible == visible )
if 'ids' in kwds:
ids = kwds['ids']
max_in_filter_length = kwds.get('max_in_filter_length', MAX_IN_FILTER_LENGTH)
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -213,7 +213,7 @@
db_datasets[ "chromInfo" ] = db_dataset
incoming[ "chromInfo" ] = db_dataset.file_name
else:
- # -- Get chrom_info from either a custom or built-in build. --
+ # -- Get chrom_info (len file) from either a custom or built-in build. --
chrom_info = None
if trans.user and ( 'dbkeys' in trans.user.preferences ) and ( input_dbkey in from_json_string( trans.user.preferences[ 'dbkeys' ] ) ):
@@ -226,9 +226,13 @@
# condition below to avoid getting chrom_info when running the
# fasta-to-len converter.
if 'fasta' in custom_build_dict and tool.id != 'CONVERTER_fasta_to_len':
+ # Build is defined by fasta; get len file, which is obtained from converting fasta.
build_fasta_dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( custom_build_dict[ 'fasta' ] )
chrom_info = build_fasta_dataset.get_converted_dataset( trans, 'len' ).file_name
-
+ elif 'len' in custom_build_dict:
+ # Build is defined by len file, so use it.
+ chrom_info = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( custom_build_dict[ 'len' ] ).file_name
+
if not chrom_info:
# Default to built-in build.
chrom_info = os.path.join( trans.app.config.len_file_path, "%s.len" % input_dbkey )
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/tools/actions/upload_common.py
--- a/lib/galaxy/tools/actions/upload_common.py
+++ b/lib/galaxy/tools/actions/upload_common.py
@@ -332,7 +332,7 @@
is_binary=is_binary,
link_data_only=link_data_only,
uuid=uuid_str,
- to_posix_lines=uploaded_dataset.to_posix_lines,
+ to_posix_lines=getattr(uploaded_dataset, "to_posix_lines", True),
space_to_tab=uploaded_dataset.space_to_tab,
in_place=trans.app.config.external_chown_script is None,
path=uploaded_dataset.path )
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/tools/imp_exp/__init__.py
--- a/lib/galaxy/tools/imp_exp/__init__.py
+++ b/lib/galaxy/tools/imp_exp/__init__.py
@@ -1,4 +1,8 @@
-import os, shutil, logging, tempfile, json
+import os
+import shutil
+import logging
+import tempfile
+import json
from galaxy import model
from galaxy.tools.parameters.basic import UnvalidatedValue
from galaxy.web.framework.helpers import to_unicode
@@ -8,6 +12,7 @@
log = logging.getLogger(__name__)
+
def load_history_imp_exp_tools( toolbox ):
""" Adds tools for importing/exporting histories to archives. """
# Use same process as that used in load_external_metadata_tool; see that
@@ -42,6 +47,7 @@
toolbox.tools_by_id[ history_imp_tool.id ] = history_imp_tool
log.debug( "Loaded history import tool: %s", history_imp_tool.id )
+
class JobImportHistoryArchiveWrapper( object, UsesHistoryMixin, UsesAnnotations ):
"""
Class provides support for performing jobs that import a history from
@@ -144,23 +150,23 @@
metadata = dataset_attrs['metadata']
# Create dataset and HDA.
- hda = model.HistoryDatasetAssociation( name = dataset_attrs['name'].encode( 'utf-8' ),
- extension = dataset_attrs['extension'],
- info = dataset_attrs['info'].encode( 'utf-8' ),
- blurb = dataset_attrs['blurb'],
- peek = dataset_attrs['peek'],
- designation = dataset_attrs['designation'],
- visible = dataset_attrs['visible'],
- dbkey = metadata['dbkey'],
- metadata = metadata,
- history = new_history,
- create_dataset = True,
- sa_session = self.sa_session )
+ hda = model.HistoryDatasetAssociation( name=dataset_attrs['name'].encode( 'utf-8' ),
+ extension=dataset_attrs['extension'],
+ info=dataset_attrs['info'].encode( 'utf-8' ),
+ blurb=dataset_attrs['blurb'],
+ peek=dataset_attrs['peek'],
+ designation=dataset_attrs['designation'],
+ visible=dataset_attrs['visible'],
+ dbkey=metadata['dbkey'],
+ metadata=metadata,
+ history=new_history,
+ create_dataset=True,
+ sa_session=self.sa_session )
hda.state = hda.states.OK
self.sa_session.add( hda )
self.sa_session.flush()
- new_history.add_dataset( hda, genome_build = None )
- hda.hid = dataset_attrs['hid'] # Overwrite default hid set when HDA added to history.
+ new_history.add_dataset( hda, genome_build=None )
+ hda.hid = dataset_attrs['hid'] # Overwrite default hid set when HDA added to history.
# TODO: Is there a way to recover permissions? Is this needed?
#permissions = trans.app.security_agent.history_get_default_permissions( new_history )
#trans.app.security_agent.set_all_dataset_permissions( hda.dataset, permissions )
@@ -273,6 +279,7 @@
jiha.job.stderr += "Error cleaning up history import job: %s" % e
self.sa_session.flush()
+
class JobExportHistoryArchiveWrapper( object, UsesHistoryMixin, UsesAnnotations ):
"""
Class provides support for performing jobs that export a history to an
@@ -317,23 +324,23 @@
""" Encode an HDA, default encoding for everything else. """
if isinstance( obj, trans.app.model.HistoryDatasetAssociation ):
return {
- "__HistoryDatasetAssociation__" : True,
- "create_time" : obj.create_time.__str__(),
- "update_time" : obj.update_time.__str__(),
- "hid" : obj.hid,
- "name" : to_unicode( obj.name ),
- "info" : to_unicode( obj.info ),
- "blurb" : obj.blurb,
- "peek" : obj.peek,
- "extension" : obj.extension,
- "metadata" : prepare_metadata( dict( obj.metadata.items() ) ),
- "parent_id" : obj.parent_id,
- "designation" : obj.designation,
- "deleted" : obj.deleted,
- "visible" : obj.visible,
- "file_name" : obj.file_name,
- "annotation" : to_unicode( getattr( obj, 'annotation', '' ) ),
- "tags" : get_item_tag_dict( obj ),
+ "__HistoryDatasetAssociation__": True,
+ "create_time": obj.create_time.__str__(),
+ "update_time": obj.update_time.__str__(),
+ "hid": obj.hid,
+ "name": to_unicode( obj.name ),
+ "info": to_unicode( obj.info ),
+ "blurb": obj.blurb,
+ "peek": obj.peek,
+ "extension": obj.extension,
+ "metadata": prepare_metadata( dict( obj.metadata.items() ) ),
+ "parent_id": obj.parent_id,
+ "designation": obj.designation,
+ "deleted": obj.deleted,
+ "visible": obj.visible,
+ "file_name": obj.file_name,
+ "annotation": to_unicode( getattr( obj, 'annotation', '' ) ),
+ "tags": get_item_tag_dict( obj ),
}
if isinstance( obj, UnvalidatedValue ):
return obj.__str__()
@@ -347,15 +354,15 @@
# Write history attributes to file.
history = jeha.history
history_attrs = {
- "create_time" : history.create_time.__str__(),
- "update_time" : history.update_time.__str__(),
- "name" : to_unicode( history.name ),
- "hid_counter" : history.hid_counter,
- "genome_build" : history.genome_build,
- "annotation" : to_unicode( self.get_item_annotation_str( trans.sa_session, history.user, history ) ),
- "tags" : get_item_tag_dict( history ),
- "includes_hidden_datasets" : include_hidden,
- "includes_deleted_datasets" : include_deleted
+ "create_time": history.create_time.__str__(),
+ "update_time": history.update_time.__str__(),
+ "name": to_unicode( history.name ),
+ "hid_counter": history.hid_counter,
+ "genome_build": history.genome_build,
+ "annotation": to_unicode( self.get_item_annotation_str( trans.sa_session, history.user, history ) ),
+ "tags": get_item_tag_dict( history ),
+ "includes_hidden_datasets": include_hidden,
+ "includes_deleted_datasets": include_deleted
}
history_attrs_filename = tempfile.NamedTemporaryFile( dir=temp_output_dir ).name
history_attrs_out = open( history_attrs_filename, 'w' )
@@ -391,7 +398,7 @@
# Get the associated job, if any. If this hda was copied from another,
# we need to find the job that created the origial hda
job_hda = hda
- while job_hda.copied_from_history_dataset_association: #should this check library datasets as well?
+ while job_hda.copied_from_history_dataset_association: # should this check library datasets as well?
job_hda = job_hda.copied_from_history_dataset_association
if not job_hda.creating_job_associations:
# No viable HDA found.
@@ -472,4 +479,3 @@
shutil.rmtree( temp_dir )
except Exception, e:
log.debug( 'Error deleting directory containing attribute files (%s): %s' % ( temp_dir, e ) )
-
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
--- a/lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
+++ b/lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
@@ -6,19 +6,25 @@
--[url|file] source type, either a URL or a file.
"""
-import sys, optparse, tarfile, tempfile, urllib2, math
+import sys
+import optparse
+import tarfile
+import tempfile
+import urllib2
+import math
# Set max size of archive/file that will be handled to be 100 GB. This is
# arbitrary and should be adjusted as needed.
MAX_SIZE = 100 * math.pow( 2, 30 )
+
def url_to_file( url, dest_file ):
"""
Transfer a file from a remote URL to a temporary file.
"""
try:
url_reader = urllib2.urlopen( url )
- CHUNK = 10 * 1024 # 10k
+ CHUNK = 10 * 1024 # 10k
total = 0
fp = open( dest_file, 'wb')
while True:
@@ -35,6 +41,7 @@
print "Exception getting file from URL: %s" % e, sys.stderr
return None
+
def unpack_archive( archive_file, dest_dir ):
"""
Unpack a tar and/or gzipped archive into a destination directory.
@@ -63,4 +70,4 @@
# Unpack archive.
unpack_archive( archive_file, dest_dir )
except Exception, e:
- print "Error unpacking tar/gz archive: %s" % e, sys.stderr
\ No newline at end of file
+ print "Error unpacking tar/gz archive: %s" % e, sys.stderr
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1653,7 +1653,7 @@
field.add_option( "%s: (as %s) %s" % ( hid, target_ext, hda_name ), hda.id, selected )
# Also collect children via association object
dataset_collector( hda.children, hid )
- dataset_collector( history.active_datasets, None )
+ dataset_collector( history.active_datasets_children_and_roles, None )
some_data = bool( field.options )
if some_data:
if value is None or len( field.options ) == 1:
@@ -1693,11 +1693,6 @@
pass # no valid options
def dataset_collector( datasets ):
- def is_convertable( dataset ):
- target_ext, converted_dataset = dataset.find_conversion_destination( self.formats )
- if target_ext is not None:
- return True
- return False
for i, data in enumerate( datasets ):
if data.visible and not data.deleted and data.state not in [data.states.ERROR, data.states.DISCARDED]:
is_valid = False
@@ -1714,7 +1709,7 @@
most_recent_dataset.append(data)
# Also collect children via association object
dataset_collector( data.children )
- dataset_collector( history.datasets )
+ dataset_collector( history.active_datasets_children_and_roles )
most_recent_dataset.reverse()
if already_used is not None:
for val in most_recent_dataset:
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/tools/parameters/grouping.py
--- a/lib/galaxy/tools/parameters/grouping.py
+++ b/lib/galaxy/tools/parameters/grouping.py
@@ -361,6 +361,7 @@
'filename' : os.path.basename( ftp_file ) }
file_bunch = get_data_file_filename( ftp_data_file, override_name = name, override_info = info )
if file_bunch.path:
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
rval.append( file_bunch )
return rval
diff -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 lib/galaxy/tools/util/hyphy_util.py
--- a/lib/galaxy/tools/util/hyphy_util.py
+++ /dev/null
@@ -1,1163 +0,0 @@
-#Dan Blankenberg
-#Contains file contents and helper methods for HYPHY configurations
-import tempfile, os
-
-def get_filled_temp_filename(contents):
- fh = tempfile.NamedTemporaryFile('w')
- filename = fh.name
- fh.close()
- fh = open(filename, 'w')
- fh.write(contents)
- fh.close()
- return filename
-
-NJ_tree_shared_ibf = """
-COUNT_GAPS_IN_FREQUENCIES = 0;
-methodIndex = 1;
-
-/*-----------------------------------------------------------------------------------------------------------------------------------------*/
-
-function InferTreeTopology(verbFlag)
-{
- distanceMatrix = {ds.species,ds.species};
-
- MESSAGE_LOGGING = 0;
- ExecuteAFile (HYPHY_BASE_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"chooseDistanceFormula.def");
- InitializeDistances (0);
-
- for (i = 0; i<ds.species; i=i+1)
- {
- for (j = i+1; j<ds.species; j = j+1)
- {
- distanceMatrix[i][j] = ComputeDistanceFormula (i,j);
- }
- }
-
- MESSAGE_LOGGING = 1;
- cladesMade = 1;
-
-
- if (ds.species == 2)
- {
- d1 = distanceMatrix[0][1]/2;
- treeNodes = {{0,1,d1__},
- {1,1,d1__},
- {2,0,0}};
-
- cladesInfo = {{2,0}};
- }
- else
- {
- if (ds.species == 3)
- {
- /* generate least squares estimates here */
-
- d1 = (distanceMatrix[0][1]+distanceMatrix[0][2]-distanceMatrix[1][2])/2;
- d2 = (distanceMatrix[0][1]-distanceMatrix[0][2]+distanceMatrix[1][2])/2;
- d3 = (distanceMatrix[1][2]+distanceMatrix[0][2]-distanceMatrix[0][1])/2;
-
- treeNodes = {{0,1,d1__},
- {1,1,d2__},
- {2,1,d3__}
- {3,0,0}};
-
- cladesInfo = {{3,0}};
- }
- else
- {
- njm = (distanceMatrix > methodIndex)>=ds.species;
-
- treeNodes = {2*(ds.species+1),3};
- cladesInfo = {ds.species-1,2};
-
- for (i=Rows(treeNodes)-1; i>=0; i=i-1)
- {
- treeNodes[i][0] = njm[i][0];
- treeNodes[i][1] = njm[i][1];
- treeNodes[i][2] = njm[i][2];
- }
-
- for (i=Rows(cladesInfo)-1; i>=0; i=i-1)
- {
- cladesInfo[i][0] = njm[i][3];
- cladesInfo[i][1] = njm[i][4];
- }
-
- njm = 0;
- }
- }
- return 1.0;
-}
-
-/*-----------------------------------------------------------------------------------------------------------------------------------------*/
-
-function TreeMatrix2TreeString (doLengths)
-{
- treeString = "";
- p = 0;
- k = 0;
- m = treeNodes[0][1];
- n = treeNodes[0][0];
- treeString*(Rows(treeNodes)*25);
-
- while (m)
- {
- if (m>p)
- {
- if (p)
- {
- treeString*",";
- }
- for (j=p;j<m;j=j+1)
- {
- treeString*"(";
- }
- }
- else
- {
- if (m<p)
- {
- for (j=m;j<p;j=j+1)
- {
- treeString*")";
- }
- }
- else
- {
- treeString*",";
- }
- }
- if (n<ds.species)
- {
- GetString (nodeName, ds, n);
- if (doLengths != 1)
- {
- treeString*nodeName;
- }
- else
- {
- treeString*taxonNameMap[nodeName];
- }
- }
- if (doLengths>.5)
- {
- nodeName = ":"+treeNodes[k][2];
- treeString*nodeName;
- }
- k=k+1;
- p=m;
- n=treeNodes[k][0];
- m=treeNodes[k][1];
- }
-
- for (j=m;j<p;j=j+1)
- {
- treeString*")";
- }
-
- treeString*0;
- return treeString;
-}
-"""
-
-def get_NJ_tree (filename):
- return """
-DISTANCE_PROMPTS = 1;
-ExecuteAFile ("%s");
-
-DataSet ds = ReadDataFile (PROMPT_FOR_FILE);
-DataSetFilter filteredData = CreateFilter (ds,1);
-
-/* do sequence to branch map */
-
-taxonNameMap = {};
-
-for (k=0; k<ds.species; k=k+1)
-{
- GetString (thisName, ds,k);
- shortName = (thisName^{{"\\\\..+",""}})&&1;
- taxonNameMap[shortName] = thisName;
- SetParameter (ds,k,shortName);
-}
-
-DataSetFilter filteredData = CreateFilter (ds,1);
-InferTreeTopology (0);
-treeString = TreeMatrix2TreeString (1);
-
-fprintf (PROMPT_FOR_FILE, CLEAR_FILE, treeString);
-fscanf (stdin, "String", ps_file);
-
-if (Abs(ps_file))
-{
- treeString = TreeMatrix2TreeString (2);
- UseModel (USE_NO_MODEL);
- Tree givenTree = treeString;
- baseHeight = TipCount (givenTree)*28;
- TREE_OUTPUT_OPTIONS = {};
- TREE_OUTPUT_OPTIONS["__FONT_SIZE__"] = 14;
- baseWidth = 0;
- treeAVL = givenTree^0;
- drawLetter = "/drawletter {"+TREE_OUTPUT_OPTIONS["__FONT_SIZE__"]$4+" -"+TREE_OUTPUT_OPTIONS["__FONT_SIZE__"]$2+ " show} def\\n";
- for (k3 = 1; k3 < Abs(treeAVL); k3=k3+1)
- {
- nodeName = (treeAVL[k3])["Name"];
- if(Abs((treeAVL[k3])["Children"]) == 0)
- {
- mySpecs = {};
- mySpecs ["TREE_OUTPUT_BRANCH_LABEL"] = "(" + taxonNameMap[nodeName] + ") drawLetter";
- baseWidth = Max (baseWidth, (treeAVL[k3])["Depth"]);
- }
- }
- baseWidth = 40*baseWidth;
-
- fprintf (ps_file, CLEAR_FILE, drawLetter, PSTreeString (givenTree, "STRING_SUPPLIED_LENGTHS",{{baseWidth,baseHeight}}));
-}
-""" % (filename)
-
-def get_NJ_treeMF (filename):
- return """
-ExecuteAFile ("%s");
-
-VERBOSITY_LEVEL = -1;
-fscanf (PROMPT_FOR_FILE, "Lines", inLines);
-
-_linesIn = Columns (inLines);
-isomorphicTreesBySequenceCount = {};
-
-/*---------------------------------------------------------*/
-
-_currentGene = 1;
-_currentState = 0;
-geneSeqs = "";
-geneSeqs * 128;
-
-fprintf (PROMPT_FOR_FILE, CLEAR_FILE, KEEP_OPEN);
-treeOutFile = LAST_FILE_PATH;
-
-fscanf (stdin,"String", ps_file);
-if (Abs(ps_file))
-{
- fprintf (ps_file, CLEAR_FILE, KEEP_OPEN);
-}
-
-for (l=0; l<_linesIn; l=l+1)
-{
- if (Abs(inLines[l]) == 0)
- {
- if (_currentState == 1)
- {
- geneSeqs * 0;
- DataSet ds = ReadFromString (geneSeqs);
- _processAGene (_currentGene,treeOutFile,ps_file);
- geneSeqs * 128;
- _currentGene = _currentGene + 1;
- }
- }
- else
- {
- if (_currentState == 0)
- {
- _currentState = 1;
- }
- geneSeqs * inLines[l];
- geneSeqs * "\\n";
- }
-}
-
-
-if (_currentState == 1)
-{
- geneSeqs * 0;
- if (Abs(geneSeqs))
- {
- DataSet ds = ReadFromString (geneSeqs);
- _processAGene (_currentGene,treeOutFile,ps_file);
- }
-}
-
-fprintf (treeOutFile,CLOSE_FILE);
-if (Abs(ps_file))
-{
- fprintf (ps_file,CLOSE_FILE);
-}
-/*---------------------------------------------------------*/
-
-function _processAGene (_geneID, nwk_file, ps_file)
-{
- if (ds.species == 1)
- {
- fprintf (nwk_file, _geneID-1, "\\tNone \\tNone\\n");
- return 0;
-
- }
-
- DataSetFilter filteredData = CreateFilter (ds,1);
-
- /* do sequence to branch map */
-
- taxonNameMap = {};
-
- for (k=0; k<ds.species; k=k+1)
- {
- GetString (thisName, ds,k);
- shortName = (thisName^{{"\\\\..+",""}});
- taxonNameMap[shortName] = thisName;
- SetParameter (ds,k,shortName);
- }
-
- DataSetFilter filteredData = CreateFilter (ds,1);
- DISTANCE_PROMPTS = (_geneID==1);
-
- InferTreeTopology (0);
- baseTree = TreeMatrix2TreeString (0);
- UseModel (USE_NO_MODEL);
-
- Tree baseTop = baseTree;
-
- /* standardize this top */
-
- for (k=0; k<Abs(isomorphicTreesBySequenceCount[filteredData.species]); k=k+1)
- {
- testString = (isomorphicTreesBySequenceCount[filteredData.species])[k];
- Tree testTree = testString;
- if (testTree == baseTop)
- {
- baseTree = testString;
- break;
- }
- }
- if (k==Abs(isomorphicTreesBySequenceCount[filteredData.species]))
- {
- if (k==0)
- {
- isomorphicTreesBySequenceCount[filteredData.species] = {};
- }
- (isomorphicTreesBySequenceCount[filteredData.species])[k] = baseTree;
- }
-
- fprintf (nwk_file, _geneID-1, "\\t", baseTree, "\\t", TreeMatrix2TreeString (1), "\\n");
- if (Abs(ps_file))
- {
- treeString = TreeMatrix2TreeString (2);
- UseModel (USE_NO_MODEL);
- Tree givenTree = treeString;
- baseHeight = TipCount (givenTree)*28;
- TREE_OUTPUT_OPTIONS = {};
- TREE_OUTPUT_OPTIONS["__FONT_SIZE__"] = 14;
- baseWidth = 0;
- treeAVL = givenTree^0;
- drawLetter = "/drawletter {"+TREE_OUTPUT_OPTIONS["__FONT_SIZE__"]$4+" -"+TREE_OUTPUT_OPTIONS["__FONT_SIZE__"]$2+ " show} def\\n";
- for (k3 = 1; k3 < Abs(treeAVL); k3=k3+1)
- {
- nodeName = (treeAVL[k3])["Name"];
- if(Abs((treeAVL[k3])["Children"]) == 0)
- {
- mySpecs = {};
- mySpecs ["TREE_OUTPUT_BRANCH_LABEL"] = "(" + taxonNameMap[nodeName] + ") drawLetter";
- baseWidth = Max (baseWidth, (treeAVL[k3])["Depth"]);
- }
- }
- baseWidth = 40*baseWidth;
-
- fprintf (stdout, _geneID, ":", givenTree,"\\n");
- fprintf (ps_file, PSTreeString (givenTree, "STRING_SUPPLIED_LENGTHS",{{baseWidth,baseHeight}}));
- }
- return 0;
-}
-""" % (filename)
-
-BranchLengthsMF = """
-VERBOSITY_LEVEL = -1;
-
-fscanf (PROMPT_FOR_FILE, "Lines", inLines);
-
-
-
-_linesIn = Columns (inLines);
-
-
-
-/*---------------------------------------------------------*/
-
-
-
-_currentGene = 1;
-
-_currentState = 0;
-
-geneSeqs = "";
-
-geneSeqs * 128;
-
-
-
-for (l=0; l<_linesIn; l=l+1)
-
-{
-
- if (Abs(inLines[l]) == 0)
-
- {
-
- if (_currentState == 1)
-
- {
-
- geneSeqs * 0;
-
- DataSet ds = ReadFromString (geneSeqs);
-
- _processAGene (_currentGene);
-
- geneSeqs * 128;
-
- _currentGene = _currentGene + 1;
-
- }
-
- }
-
- else
-
- {
-
- if (_currentState == 0)
-
- {
-
- _currentState = 1;
-
- }
-
- geneSeqs * inLines[l];
-
- geneSeqs * "\\n";
-
- }
-
-}
-
-
-
-if (_currentState == 1)
-
-{
-
- geneSeqs * 0;
-
- if (Abs(geneSeqs))
-
- {
-
- DataSet ds = ReadFromString (geneSeqs);
-
- _processAGene (_currentGene);
-
- }
-
-}
-
-
-
-fprintf (resultFile,CLOSE_FILE);
-
-
-
-/*---------------------------------------------------------*/
-
-
-
-function _processAGene (_geneID)
-
-{
-
- DataSetFilter filteredData = CreateFilter (ds,1);
-
- if (_currentGene == 1)
-
- {
-
- SelectTemplateModel (filteredData);
-
-
-
- SetDialogPrompt ("Tree file");
-
- fscanf (PROMPT_FOR_FILE, "Tree", givenTree);
-
- fscanf (stdin, "String", resultFile);
-
-
-
- /* do sequence to branch map */
-
-
-
- validNames = {};
-
- taxonNameMap = {};
-
-
-
- for (k=0; k<TipCount(givenTree); k=k+1)
-
- {
-
- validNames[TipName(givenTree,k)&&1] = 1;
-
- }
-
-
-
- for (k=0; k<BranchCount(givenTree); k=k+1)
-
- {
-
- thisName = BranchName(givenTree,k);
-
- taxonNameMap[thisName&&1] = thisName;
-
- }
-
-
-
- storeValidNames = validNames;
-
- fprintf (resultFile,CLEAR_FILE,KEEP_OPEN,"Block\\tBranch\\tLength\\tLowerBound\\tUpperBound\\n");
-
- }
-
- else
-
- {
-
- HarvestFrequencies (vectorOfFrequencies, filteredData, 1,1,1);
-
- validNames = storeValidNames;
-
- }
-
-
-
- for (k=0; k<ds.species; k=k+1)
-
- {
-
- GetString (thisName, ds,k);
-
- shortName = (thisName^{{"\\\\..+",""}})&&1;
-
- if (validNames[shortName])
-
- {
-
- taxonNameMap[shortName] = thisName;
-
- validNames - (shortName);
-
- SetParameter (ds,k,shortName);
-
- }
-
- else
-
- {
-
- fprintf (resultFile,"ERROR:", thisName, " could not be matched to any of the leaves in tree ", givenTree,"\\n");
-
- return 0;
-
- }
-
- }
-
-
-
- /* */
-
-
-
- LikelihoodFunction lf = (filteredData,givenTree);
-
- Optimize (res,lf);
-
-
-
- timer = Time(0)-timer;
-
-
-
- branchNames = BranchName (givenTree,-1);
-
- branchLengths = BranchLength (givenTree,-1);
-
-
-
-
-
- for (k=0; k<Columns(branchNames)-1; k=k+1)
-
- {
-
- COVARIANCE_PARAMETER = "givenTree."+branchNames[k]+".t";
-
- COVARIANCE_PRECISION = 0.95;
-
- CovarianceMatrix (cmx,lf);
-
- if (k==0)
-
- {
-
- /* compute a scaling factor */
-
- ExecuteCommands ("givenTree."+branchNames[0]+".t=1");
-
- scaleFactor = BranchLength (givenTree,0);
-
- ExecuteCommands ("givenTree."+branchNames[0]+".t="+cmx[0][1]);
-
- }
-
- fprintf (resultFile,_geneID,"\\t",taxonNameMap[branchNames[k]&&1],"\\t",branchLengths[k],"\\t",scaleFactor*cmx[0][0],"\\t",scaleFactor*cmx[0][2],"\\n");
-
- }
-
-
-
- ttl = (branchLengths*(Transpose(branchLengths["1"])))[0];
-
- global treeScaler = 1;
-
- ReplicateConstraint ("this1.?.t:=treeScaler*this2.?.t__",givenTree,givenTree);
-
- COVARIANCE_PARAMETER = "treeScaler";
-
- COVARIANCE_PRECISION = 0.95;
-
- CovarianceMatrix (cmx,lf);
-
- fprintf (resultFile,_geneID,"\\tTotal Tree\\t",ttl,"\\t",ttl*cmx[0][0],"\\t",ttl*cmx[0][2],"\\n");
-
- ClearConstraints (givenTree);
-
- return 0;
-
-}
-"""
-
-BranchLengths = """
-DataSet ds = ReadDataFile (PROMPT_FOR_FILE);
-DataSetFilter filteredData = CreateFilter (ds,1);
-
-SelectTemplateModel (filteredData);
-
-SetDialogPrompt ("Tree file");
-fscanf (PROMPT_FOR_FILE, "Tree", givenTree);
-fscanf (stdin, "String", resultFile);
-
-/* do sequence to branch map */
-
-validNames = {};
-taxonNameMap = {};
-
-for (k=0; k<TipCount(givenTree); k=k+1)
-{
- validNames[TipName(givenTree,k)&&1] = 1;
-}
-
-for (k=0; k<BranchCount(givenTree); k=k+1)
-{
- thisName = BranchName(givenTree,k);
- taxonNameMap[thisName&&1] = thisName;
-}
-
-for (k=0; k<ds.species; k=k+1)
-{
- GetString (thisName, ds,k);
- shortName = (thisName^{{"\\\\..+",""}})&&1;
- if (validNames[shortName])
- {
- taxonNameMap[shortName] = thisName;
- validNames - (shortName);
- SetParameter (ds,k,shortName);
- }
- else
- {
- fprintf (resultFile,CLEAR_FILE,"ERROR:", thisName, " could not be matched to any of the leaves in tree ", givenTree);
- return 0;
- }
-}
-
-/* */
-
-LikelihoodFunction lf = (filteredData,givenTree);
-
-Optimize (res,lf);
-
-timer = Time(0)-timer;
-
-branchNames = BranchName (givenTree,-1);
-branchLengths = BranchLength (givenTree,-1);
-
-fprintf (resultFile,CLEAR_FILE,KEEP_OPEN,"Branch\\tLength\\tLowerBound\\tUpperBound\\n");
-
-for (k=0; k<Columns(branchNames)-1; k=k+1)
-{
- COVARIANCE_PARAMETER = "givenTree."+branchNames[k]+".t";
- COVARIANCE_PRECISION = 0.95;
- CovarianceMatrix (cmx,lf);
- if (k==0)
- {
- /* compute a scaling factor */
- ExecuteCommands ("givenTree."+branchNames[0]+".t=1");
- scaleFactor = BranchLength (givenTree,0);
- ExecuteCommands ("givenTree."+branchNames[0]+".t="+cmx[0][1]);
- }
- fprintf (resultFile,taxonNameMap[branchNames[k]&&1],"\\t",branchLengths[k],"\\t",scaleFactor*cmx[0][0],"\\t",scaleFactor*cmx[0][2],"\\n");
-}
-
-ttl = (branchLengths*(Transpose(branchLengths["1"])))[0];
-global treeScaler = 1;
-ReplicateConstraint ("this1.?.t:=treeScaler*this2.?.t__",givenTree,givenTree);
-COVARIANCE_PARAMETER = "treeScaler";
-COVARIANCE_PRECISION = 0.95;
-CovarianceMatrix (cmx,lf);
-ClearConstraints (givenTree);
-fprintf (resultFile,"Total Tree\\t",ttl,"\\t",ttl*cmx[0][0],"\\t",ttl*cmx[0][2],"\\n");
-fprintf (resultFile,CLOSE_FILE);
-"""
-
-SimpleLocalFitter = """
-VERBOSITY_LEVEL = -1;
-COUNT_GAPS_IN_FREQUENCIES = 0;
-
-/*---------------------------------------------------------*/
-
-function returnResultHeaders (dummy)
-{
- _analysisHeaders = {};
- _analysisHeaders[0] = "BLOCK";
- _analysisHeaders[1] = "BP";
- _analysisHeaders[2] = "S_sites";
- _analysisHeaders[3] = "NS_sites";
- _analysisHeaders[4] = "Stop_codons";
- _analysisHeaders[5] = "LogL";
- _analysisHeaders[6] = "AC";
- _analysisHeaders[7] = "AT";
- _analysisHeaders[8] = "CG";
- _analysisHeaders[9] = "CT";
- _analysisHeaders[10] = "GT";
- _analysisHeaders[11] = "Tree";
-
- for (_biterator = 0; _biterator < treeBranchCount; _biterator = _biterator + 1)
- {
- branchName = treeBranchNames[_biterator];
-
- _analysisHeaders [Abs(_analysisHeaders)] = "length("+branchName+")";
- _analysisHeaders [Abs(_analysisHeaders)] = "dS("+branchName+")";
- _analysisHeaders [Abs(_analysisHeaders)] = "dN("+branchName+")";
- _analysisHeaders [Abs(_analysisHeaders)] = "omega("+branchName+")";
- }
-
- return _analysisHeaders;
-}
-
-/*---------------------------------------------------------*/
-
-function runAGeneFit (myID)
-{
- DataSetFilter filteredData = CreateFilter (ds,3,"","",GeneticCodeExclusions);
-
- if (_currentGene==1)
- {
- _MG94stdinOverload = {};
- _MG94stdinOverload ["0"] = "Local";
- _MG94stdinOverload ["1"] = modelSpecString;
-
- ExecuteAFile (HYPHY_BASE_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"TemplateModels"+DIRECTORY_SEPARATOR+"MG94custom.mdl",
- _MG94stdinOverload);
-
- Tree codonTree = treeString;
- }
- else
- {
- HarvestFrequencies (observedFreq,filteredData,3,1,1);
- MULTIPLY_BY_FREQS = PopulateModelMatrix ("MG94custom", observedFreq);
- vectorOfFrequencies = BuildCodonFrequencies (observedFreq);
- Model MG94customModel = (MG94custom,vectorOfFrequencies,0);
-
- Tree codonTree = treeString;
- }
-
- LikelihoodFunction lf = (filteredData,codonTree);
-
- Optimize (res,lf);
-
- _snsAVL = _computeSNSSites ("filteredData", _Genetic_Code, vectorOfFrequencies, 0);
- _cL = ReturnVectorsOfCodonLengths (ComputeScalingStencils (0), "codonTree");
-
-
- _returnMe = {};
- _returnMe ["BLOCK"] = myID;
- _returnMe ["LogL"] = res[1][0];
- _returnMe ["BP"] = _snsAVL ["Sites"];
- _returnMe ["S_sites"] = _snsAVL ["SSites"];
- _returnMe ["NS_sites"] = _snsAVL ["NSSites"];
- _returnMe ["AC"] = AC;
- _returnMe ["AT"] = AT;
- _returnMe ["CG"] = CG;
- _returnMe ["CT"] = CT;
- _returnMe ["GT"] = GT;
- _returnMe ["Tree"] = Format(codonTree,0,1);
-
- for (_biterator = 0; _biterator < treeBranchCount; _biterator = _biterator + 1)
- {
- branchName = treeBranchNames[_biterator];
-
- _returnMe ["length("+branchName+")"] = (_cL["Total"])[_biterator];
- _returnMe ["dS("+branchName+")"] = (_cL["Syn"])[_biterator]*(_returnMe ["BP"]/_returnMe ["S_sites"]);
- _returnMe ["dN("+branchName+")"] = (_cL["NonSyn"])[_biterator]*(_returnMe ["BP"]/_returnMe ["NS_sites"]);
-
- ExecuteCommands ("_lom = _standardizeRatio(codonTree."+treeBranchNames[_biterator]+".nonSynRate,codonTree."+treeBranchNames[_biterator]+".synRate);");
- _returnMe ["omega("+branchName+")"] = _lom;
- }
-
- return _returnMe;
-}
-
-"""
-
-SimpleGlobalFitter = """
-VERBOSITY_LEVEL = -1;
-COUNT_GAPS_IN_FREQUENCIES = 0;
-
-/*---------------------------------------------------------*/
-
-function returnResultHeaders (dummy)
-{
- _analysisHeaders = {};
- _analysisHeaders[0] = "BLOCK";
- _analysisHeaders[1] = "BP";
- _analysisHeaders[2] = "S_sites";
- _analysisHeaders[3] = "NS_sites";
- _analysisHeaders[4] = "Stop_codons";
- _analysisHeaders[5] = "LogL";
- _analysisHeaders[6] = "omega";
- _analysisHeaders[7] = "omega_range";
- _analysisHeaders[8] = "AC";
- _analysisHeaders[9] = "AT";
- _analysisHeaders[10] = "CG";
- _analysisHeaders[11] = "CT";
- _analysisHeaders[12] = "GT";
- _analysisHeaders[13] = "Tree";
-
- return _analysisHeaders;
-}
-
-/*---------------------------------------------------------*/
-
-function runAGeneFit (myID)
-{
- fprintf (stdout, "[SimpleGlobalFitter.bf on GENE ", myID, "]\\n");
- taxonNameMap = {};
-
- for (k=0; k<ds.species; k=k+1)
- {
- GetString (thisName, ds,k);
- shortName = (thisName^{{"\\\\..+",""}})&&1;
- taxonNameMap[shortName] = thisName;
- SetParameter (ds,k,shortName);
- }
-
- DataSetFilter filteredData = CreateFilter (ds,1);
- _nucSites = filteredData.sites;
-
- if (Abs(treeString))
- {
- givenTreeString = treeString;
- }
- else
- {
- if (_currentGene==1)
- {
- ExecuteAFile (HYPHY_BASE_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"Utility"+DIRECTORY_SEPARATOR+"NJ.bf");
- }
- givenTreeString = InferTreeTopology (0);
- treeString = "";
- }
-
- DataSetFilter filteredData = CreateFilter (ds,3,"","",GeneticCodeExclusions);
-
- if (_currentGene==1)
- {
- _MG94stdinOverload = {};
- _MG94stdinOverload ["0"] = "Global";
- _MG94stdinOverload ["1"] = modelSpecString;
-
- ExecuteAFile (HYPHY_BASE_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"TemplateModels"+DIRECTORY_SEPARATOR+"MG94custom.mdl",
- _MG94stdinOverload);
-
- Tree codonTree = givenTreeString;
- }
- else
- {
- HarvestFrequencies (observedFreq,filteredData,3,1,1);
- MULTIPLY_BY_FREQS = PopulateModelMatrix ("MG94custom", observedFreq);
- vectorOfFrequencies = BuildCodonFrequencies (observedFreq);
- Model MG94customModel = (MG94custom,vectorOfFrequencies,0);
-
- Tree codonTree = givenTreeString;
- }
-
- LikelihoodFunction lf = (filteredData,codonTree);
-
- Optimize (res,lf);
-
- _snsAVL = _computeSNSSites ("filteredData", _Genetic_Code, vectorOfFrequencies, 0);
- _cL = ReturnVectorsOfCodonLengths (ComputeScalingStencils (0), "codonTree");
-
-
- _returnMe = {};
- _returnMe ["BLOCK"] = myID;
- _returnMe ["LogL"] = res[1][0];
- _returnMe ["BP"] = _snsAVL ["Sites"];
- _returnMe ["S_sites"] = _snsAVL ["SSites"];
- _returnMe ["NS_sites"] = _snsAVL ["NSSites"];
- _returnMe ["Stop_codons"] = (_nucSites-filteredData.sites*3)$3;
- _returnMe ["AC"] = AC;
- _returnMe ["AT"] = AT;
- _returnMe ["CG"] = CG;
- _returnMe ["CT"] = CT;
- _returnMe ["GT"] = GT;
- _returnMe ["omega"] = R;
- COVARIANCE_PARAMETER = "R";
- COVARIANCE_PRECISION = 0.95;
- CovarianceMatrix (cmx,lf);
- _returnMe ["omega_range"] = ""+cmx[0]+"-"+cmx[2];
- _returnMe ["Tree"] = Format(codonTree,0,1);
-
-
- return _returnMe;
-}
-"""
-
-FastaReader = """
-fscanf (stdin, "String", _coreAnalysis);
-fscanf (stdin, "String", _outputDriver);
-
-ExecuteAFile (HYPHY_BASE_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"TemplateModels"+DIRECTORY_SEPARATOR+"chooseGeneticCode.def");
-ExecuteAFile (HYPHY_BASE_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"dSdNTreeTools.ibf");
-ExecuteAFile (HYPHY_BASE_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"Utility"+DIRECTORY_SEPARATOR+"CodonTools.bf");
-ExecuteAFile (HYPHY_BASE_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"Utility"+DIRECTORY_SEPARATOR+"GrabBag.bf");
-
-SetDialogPrompt ("Tree file");
-fscanf (PROMPT_FOR_FILE, "Tree", givenTree);
-
-treeBranchNames = BranchName (givenTree,-1);
-treeBranchCount = Columns (treeBranchNames)-1;
-treeString = Format (givenTree,1,1);
-
-SetDialogPrompt ("Multiple gene FASTA file");
-fscanf (PROMPT_FOR_FILE, "Lines", inLines);
-fscanf (stdin, "String", modelSpecString);
-fscanf (stdin, "String", _outPath);
-
-ExecuteAFile (_outputDriver);
-ExecuteAFile (_coreAnalysis);
-
-/*---------------------------------------------------------*/
-
-_linesIn = Columns (inLines);
-_currentGene = 1;
- _currentState = 0;
-/* 0 - waiting for a non-empty line */
-/* 1 - reading files */
-
-geneSeqs = "";
-geneSeqs * 0;
-
-_prepareFileOutput (_outPath);
-
-for (l=0; l<_linesIn; l=l+1)
-{
- if (Abs(inLines[l]) == 0)
- {
- if (_currentState == 1)
- {
- geneSeqs * 0;
- DataSet ds = ReadFromString (geneSeqs);
- _processAGene (ds.species == treeBranchCount,_currentGene);
- geneSeqs * 128;
- _currentGene = _currentGene + 1;
- }
- }
- else
- {
- if (_currentState == 0)
- {
- _currentState = 1;
- }
- geneSeqs * inLines[l];
- geneSeqs * "\\n";
- }
-}
-
-if (_currentState == 1)
-{
- geneSeqs * 0;
- DataSet ds = ReadFromString (geneSeqs);
- _processAGene (ds.species == treeBranchCount,_currentGene);
-}
-
-_finishFileOutput (0);
-"""
-
-TabWriter = """
-/*---------------------------------------------------------*/
-function _prepareFileOutput (_outPath)
-{
- _outputFilePath = _outPath;
-
- _returnHeaders = returnResultHeaders(0);
-
- fprintf (_outputFilePath, CLEAR_FILE, KEEP_OPEN, _returnHeaders[0]);
- for (_biterator = 1; _biterator < Abs(_returnHeaders); _biterator = _biterator + 1)
- {
- fprintf (_outputFilePath,"\\t",_returnHeaders[_biterator]);
- }
-
-
-
- fprintf (_outputFilePath,"\\n");
- return 0;
-}
-
-/*---------------------------------------------------------*/
-
-function _processAGene (valid, _geneID)
-{
- if (valid)
- {
- returnValue = runAGeneFit (_geneID);
- fprintf (_outputFilePath, returnValue[_returnHeaders[0]]);
- for (_biterator = 1; _biterator < Abs(_returnHeaders); _biterator = _biterator + 1)
- {
- fprintf (_outputFilePath,"\\t",returnValue[_returnHeaders[_biterator]]);
- }
- fprintf (_outputFilePath, "\\n");
- }
- /*
- else
- {
- fprintf (_outputFilePath,
- _geneID, ", Incorrect number of sequences\\n");
- }
- */
- _currentState = 0;
- return 0;
-}
-
-/*---------------------------------------------------------*/
-function _finishFileOutput (dummy)
-{
- return 0;
-}
-"""
-
-def get_dnds_config_filename(Fitter_filename, TabWriter_filename, genetic_code, tree_filename, input_filename, nuc_model, output_filename, FastaReader_filename ):
- contents = """
-_genomeScreenOptions = {};
-
-/* all paths are either absolute or relative
-to the DATA READER */
-
-_genomeScreenOptions ["0"] = "%s";
- /* which analysis to run on each gene; */
-_genomeScreenOptions ["1"] = "%s";
- /* what output to produce; */
-_genomeScreenOptions ["2"] = "%s";
- /* genetic code */
-_genomeScreenOptions ["3"] = "%s";
- /* tree file */
-_genomeScreenOptions ["4"] = "%s";
- /* alignment file */
-_genomeScreenOptions ["5"] = "%s";
- /* nucleotide bias string; can define any of the 203 models */
-_genomeScreenOptions ["6"] = "%s";
- /* output csv file */
-
-ExecuteAFile ("%s", _genomeScreenOptions);
-""" % (Fitter_filename, TabWriter_filename, genetic_code, tree_filename, input_filename, nuc_model, output_filename, FastaReader_filename )
- return get_filled_temp_filename(contents)
-
-
-def get_branch_lengths_config_filename(input_filename, nuc_model, model_options, base_freq, tree_filename, output_filename, BranchLengths_filename):
- contents = """
-_genomeScreenOptions = {};
-
-/* all paths are either absolute or relative
-to the NucDataBranchLengths.bf */
-
-_genomeScreenOptions ["0"] = "%s";
- /* the file to analyze; */
-_genomeScreenOptions ["1"] = "CUSTOM";
- /* use an arbitrary nucleotide model */
-_genomeScreenOptions ["2"] = "%s";
- /* which model to use */
-_genomeScreenOptions ["3"] = "%s";
- /* model options */
-_genomeScreenOptions ["4"] = "Estimated";
- /* rate parameters */
-_genomeScreenOptions ["5"] = "%s";
- /* base frequencies */
-_genomeScreenOptions ["6"] = "%s";
- /* the tree to use; */
-_genomeScreenOptions ["7"] = "%s";
- /* write .csv output to; */
-
-ExecuteAFile ("%s", _genomeScreenOptions);
-""" % (input_filename, nuc_model, model_options, base_freq, tree_filename, output_filename, BranchLengths_filename)
- return get_filled_temp_filename(contents)
-
-
-def get_nj_tree_config_filename(input_filename, distance_metric, output_filename1, output_filename2, NJ_tree_filename):
- contents = """
-_genomeScreenOptions = {};
-
-/* all paths are either absolute or relative
-to the BuildNJTree.bf */
-
-_genomeScreenOptions ["0"] = "%s";
- /* the file to analyze; */
-_genomeScreenOptions ["1"] = "%s";
- /* pick which distance metric to use; TN93 is a good default */
-_genomeScreenOptions ["2"] = "%s";
- /* write Newick tree output to; */
-_genomeScreenOptions ["3"] = "%s";
- /* write a postscript tree file to this file; leave blank to not write a tree */
-
-ExecuteAFile ("%s", _genomeScreenOptions);
-""" % (input_filename, distance_metric, output_filename1, output_filename2, NJ_tree_filename)
- return get_filled_temp_filename(contents)
-
-
-def get_nj_treeMF_config_filename(input_filename, output_filename1, output_filename2, distance_metric, NJ_tree_filename):
- contents = """
-_genomeScreenOptions = {};
-
-/* all paths are either absolute or relative
-to the BuildNJTreeMF.bf */
-
-_genomeScreenOptions ["0"] = "%s";
- /* the multiple alignment file to analyze; */
-_genomeScreenOptions ["1"] = "%s";
- /* write Newick tree output to; */
-_genomeScreenOptions ["2"] = "%s";
- /* write a postscript tree file to this file; leave blank to not write a tree */
-_genomeScreenOptions ["3"] = "%s";
- /* pick which distance metric to use; TN93 is a good default */
-
-ExecuteAFile ("%s", _genomeScreenOptions);
-""" % (input_filename, output_filename1, output_filename2, distance_metric, NJ_tree_filename)
- return get_filled_temp_filename(contents)
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/galaxy/galaxy-central/commits/e0e1dab49f16/
Changeset: e0e1dab49f16
Branch: job-search
User: Kyle Ellrott
Date: 2014-01-29 21:52:46
Summary: Fixing parameter finding for non-string parameters (ints/floats)
Affected #: 1 file
diff -r 7637cfbea32e2a5e4af28400fa88909cbb6bd058 -r e0e1dab49f16eacf6e43c7193129b8371866c2e8 lib/galaxy/webapps/galaxy/api/jobs.py
--- a/lib/galaxy/webapps/galaxy/api/jobs.py
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -131,7 +131,7 @@
raise exceptions.ObjectNotFound( "Dataset %s not found" % ( v[ 'id' ] ) )
input_data[k] = dataset.dataset_id
else:
- input_param[k] = json.dumps( v )
+ input_param[k] = json.dumps( str(v) )
query = trans.sa_session.query( trans.app.model.Job ).filter(
trans.app.model.Job.tool_id == tool_id,
https://bitbucket.org/galaxy/galaxy-central/commits/be7ece945447/
Changeset: be7ece945447
User: jmchilton
Date: 2014-01-31 05:44:58
Summary: Merged in kellrott/galaxy-central/job-search (pull request #316)
Fixing non-string parameter selection for job searches
Affected #: 1 file
diff -r 24753d36e6a60bb446bd961d16cb4b59abf7b13b -r be7ece9454471d655668f3997c29b90c2f6c312d lib/galaxy/webapps/galaxy/api/jobs.py
--- a/lib/galaxy/webapps/galaxy/api/jobs.py
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -131,7 +131,7 @@
raise exceptions.ObjectNotFound( "Dataset %s not found" % ( v[ 'id' ] ) )
input_data[k] = dataset.dataset_id
else:
- input_param[k] = json.dumps( v )
+ input_param[k] = json.dumps( str(v) )
query = trans.sa_session.query( trans.app.model.Job ).filter(
trans.app.model.Job.tool_id == tool_id,
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.
1
0
commit/galaxy-central: jmchilton: Improved jobs testing.
by commits-noreply@bitbucket.org 30 Jan '14
by commits-noreply@bitbucket.org 30 Jan '14
30 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/24753d36e6a6/
Changeset: 24753d36e6a6
User: jmchilton
Date: 2014-01-31 05:44:10
Summary: Improved jobs testing.
Fix bug in buildbot related to differences between local handling of list/tuple parameters and requests handling (I mostly use requests locally, but buildbot doesn't have it available). Add test that fails without @kellrott's pull request #314 (and in turn verifies it fixes a problem).
Affected #: 2 files
diff -r 2ce1ba52c6a7b33676ffebb73053ab3f9e9baa21 -r 24753d36e6a60bb446bd961d16cb4b59abf7b13b test/base/interactor.py
--- a/test/base/interactor.py
+++ b/test/base/interactor.py
@@ -1,6 +1,7 @@
import os
from StringIO import StringIO
from galaxy.tools.parameters import grouping
+from galaxy.util import listify
from galaxy.util.odict import odict
import galaxy.model
from galaxy.model.orm import and_, desc
@@ -440,7 +441,16 @@
argsep = '&'
if '?' not in url:
argsep = '?'
- url = url + argsep + '&'.join( [ '%s=%s' % (k, v) for k, v in params.iteritems() ] )
+ param_pairs = []
+ for key, value in params.iteritems():
+ # Handle single parameters or lists and tuples of them.
+ if isinstance( value, tuple ):
+ value = list( value )
+ elif not isinstance( value, list ):
+ value = [ value ]
+ for val in value:
+ param_pairs.append( "%s=%s" % ( key, val ) )
+ url = url + argsep + '&'.join( param_pairs )
#req = urllib2.Request( url, headers = { 'Content-Type': 'application/json' } )
try:
response = urllib2.urlopen( url )
diff -r 2ce1ba52c6a7b33676ffebb73053ab3f9e9baa21 -r 24753d36e6a60bb446bd961d16cb4b59abf7b13b test/functional/api/test_jobs.py
--- a/test/functional/api/test_jobs.py
+++ b/test/functional/api/test_jobs.py
@@ -82,8 +82,33 @@
self.__run_cat_tool( history_id, dataset_id )
self._wait_for_history( history_id, assert_ok=True )
+ self.__assert_one_search_result( search_payload )
+
+ def test_search_param( self ):
+ history_id, dataset_id = self.__history_with_ok_dataset()
+
+ inputs = json.dumps(
+ dict(
+ input=dict(
+ src='hda',
+ id=dataset_id,
+ ),
+ num_lines=1,
+ )
+ )
+ search_payload = dict(
+ tool_id="random_lines1",
+ inputs=inputs,
+ state="ok",
+ )
+
+ self.__run_randomlines_tool( 1, history_id, dataset_id )
+ self._wait_for_history( history_id, assert_ok=True )
+ self.__assert_one_search_result( search_payload )
+
+ def __assert_one_search_result( self, search_payload ):
search_response = self._post( "jobs/search", data=search_payload )
- self._assert_status_code_is( empty_search_response, 200 )
+ self._assert_status_code_is( search_response, 200 )
assert len( search_response.json() ) == 1, search_response.json()
def __run_cat_tool( self, history_id, dataset_id ):
@@ -100,6 +125,20 @@
)
self._post( "tools", data=payload )
+ def __run_randomlines_tool( self, lines, history_id, dataset_id ):
+ payload = self._run_tool_payload(
+ tool_id="random_lines1",
+ inputs=dict(
+ num_lines=lines,
+ input=dict(
+ src='hda',
+ id=dataset_id,
+ ),
+ ),
+ history_id=history_id,
+ )
+ self._post( "tools", data=payload )
+
def __uploads_with_state( self, *states ):
jobs_response = self._get( "jobs", data=dict( state=states ) )
self._assert_status_code_is( jobs_response, 200 )
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.
1
0
commit/galaxy-central: martenson: reports: addressing stringification bug
by commits-noreply@bitbucket.org 30 Jan '14
by commits-noreply@bitbucket.org 30 Jan '14
30 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2ce1ba52c6a7/
Changeset: 2ce1ba52c6a7
User: martenson
Date: 2014-01-30 22:38:04
Summary: reports: addressing stringification bug
Affected #: 1 file
diff -r 72a210496cda233f28769dac11c116e0e6a71f18 -r 2ce1ba52c6a7b33676ffebb73053ab3f9e9baa21 lib/galaxy/webapps/reports/controllers/jobs.py
--- a/lib/galaxy/webapps/reports/controllers/jobs.py
+++ b/lib/galaxy/webapps/reports/controllers/jobs.py
@@ -29,7 +29,7 @@
return job.tool_id
class CreateTimeColumn( grids.DateTimeColumn ):
def get_value( self, trans, grid, job ):
- return job.create_time
+ return job.create_time.isoformat()
class UserColumn( grids.GridColumn ):
def get_value( self, trans, grid, job ):
if job.user:
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.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c77d83fe4c3e/
Changeset: c77d83fe4c3e
Branch: next-stable
User: jeremy goecks
Date: 2014-01-30 21:54:26
Summary: Fix bug that prevented relative path from being used for len_file_path config option.
Affected #: 2 files
diff -r fd4936ae82193639011ed06b9552ec1a8c8166e5 -r c77d83fe4c3e37d07c241bb1f76064a3d0b7f149 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -67,7 +67,7 @@
self.enable_unique_workflow_defaults = string_as_bool( kwargs.get( 'enable_unique_workflow_defaults', False ) )
self.tool_path = resolve_path( kwargs.get( "tool_path", "tools" ), self.root )
self.tool_data_path = resolve_path( kwargs.get( "tool_data_path", "tool-data" ), os.getcwd() )
- self.len_file_path = kwargs.get( "len_file_path", resolve_path(os.path.join(self.tool_data_path, 'shared','ucsc','chrom'), self.root) )
+ self.len_file_path = resolve_path( kwargs.get( "len_file_path", os.path.join( self.tool_data_path, 'shared','ucsc','chrom') ), self.root )
self.test_conf = resolve_path( kwargs.get( "test_conf", "" ), self.root )
# The value of migrated_tools_config is the file reserved for containing only those tools that have been eliminated from the distribution
# and moved to the tool shed.
diff -r fd4936ae82193639011ed06b9552ec1a8c8166e5 -r c77d83fe4c3e37d07c241bb1f76064a3d0b7f149 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -236,7 +236,7 @@
if not chrom_info:
# Default to built-in build.
chrom_info = os.path.join( trans.app.config.len_file_path, "%s.len" % input_dbkey )
- incoming[ "chromInfo" ] = chrom_info
+ incoming[ "chromInfo" ] = os.path.abspath( chrom_info )
inp_data.update( db_datasets )
# Determine output dataset permission/roles list
https://bitbucket.org/galaxy/galaxy-central/commits/72a210496cda/
Changeset: 72a210496cda
User: jeremy goecks
Date: 2014-01-30 21:54:54
Summary: Automated merge of next-stable to default branch
Affected #: 2 files
diff -r bf7251133a037cda8ca7025a15af4ab9efb326ba -r 72a210496cda233f28769dac11c116e0e6a71f18 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -67,7 +67,7 @@
self.enable_unique_workflow_defaults = string_as_bool( kwargs.get( 'enable_unique_workflow_defaults', False ) )
self.tool_path = resolve_path( kwargs.get( "tool_path", "tools" ), self.root )
self.tool_data_path = resolve_path( kwargs.get( "tool_data_path", "tool-data" ), os.getcwd() )
- self.len_file_path = kwargs.get( "len_file_path", resolve_path(os.path.join(self.tool_data_path, 'shared','ucsc','chrom'), self.root) )
+ self.len_file_path = resolve_path( kwargs.get( "len_file_path", os.path.join( self.tool_data_path, 'shared','ucsc','chrom') ), self.root )
self.test_conf = resolve_path( kwargs.get( "test_conf", "" ), self.root )
# The value of migrated_tools_config is the file reserved for containing only those tools that have been eliminated from the distribution
# and moved to the tool shed.
diff -r bf7251133a037cda8ca7025a15af4ab9efb326ba -r 72a210496cda233f28769dac11c116e0e6a71f18 lib/galaxy/tools/actions/__init__.py
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -236,7 +236,7 @@
if not chrom_info:
# Default to built-in build.
chrom_info = os.path.join( trans.app.config.len_file_path, "%s.len" % input_dbkey )
- incoming[ "chromInfo" ] = chrom_info
+ incoming[ "chromInfo" ] = os.path.abspath( chrom_info )
inp_data.update( db_datasets )
# Determine output dataset permission/roles list
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.
1
0
commit/galaxy-central: carlfeberhard: Visualizations Registry: small fixes
by commits-noreply@bitbucket.org 30 Jan '14
by commits-noreply@bitbucket.org 30 Jan '14
30 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/bf7251133a03/
Changeset: bf7251133a03
User: carlfeberhard
Date: 2014-01-30 19:10:34
Summary: Visualizations Registry: small fixes
Affected #: 4 files
diff -r d9f6f3f2467195397828d452664c68e5e4c104ef -r bf7251133a037cda8ca7025a15af4ab9efb326ba lib/galaxy/datatypes/dataproviders/decorators.py
--- a/lib/galaxy/datatypes/dataproviders/decorators.py
+++ b/lib/galaxy/datatypes/dataproviders/decorators.py
@@ -18,6 +18,7 @@
from functools import wraps
#from types import MethodType
+import urllib2
import copy
import logging
@@ -143,8 +144,9 @@
'int' : int,
'float' : float,
'bool' : bool,
- 'list:str' : lambda s: list_from_query_string( s ),
- 'list:int' : lambda s: [ int( i ) for i in list_from_query_string( s ) ],
+ 'list:str' : lambda s: list_from_query_string( s ),
+ 'list:escaped' : lambda s: [ urllib2.unquote( e ) for e in list_from_query_string( s ) ],
+ 'list:int' : lambda s: [ int( i ) for i in list_from_query_string( s ) ],
}
settings = settings or {}
# yay! yet another set of query string parsers! <-- sarcasm
diff -r d9f6f3f2467195397828d452664c68e5e4c104ef -r bf7251133a037cda8ca7025a15af4ab9efb326ba lib/galaxy/datatypes/dataproviders/line.py
--- a/lib/galaxy/datatypes/dataproviders/line.py
+++ b/lib/galaxy/datatypes/dataproviders/line.py
@@ -78,7 +78,7 @@
line = line.strip( '\n' )
if not self.provide_blank and line == '':
return None
- elif line.startswith( self.comment_char ):
+ elif self.comment_char and line.startswith( self.comment_char ):
return None
return super( FilteredLineDataProvider, self ).filter( line )
@@ -94,7 +94,7 @@
the line it is considered valid and will be provided).
"""
settings = {
- 'regex_list' : 'list:str',
+ 'regex_list' : 'list:escaped',
'invert' : 'bool',
}
diff -r d9f6f3f2467195397828d452664c68e5e4c104ef -r bf7251133a037cda8ca7025a15af4ab9efb326ba lib/galaxy/visualization/registry.py
--- a/lib/galaxy/visualization/registry.py
+++ b/lib/galaxy/visualization/registry.py
@@ -41,23 +41,18 @@
NOTE: also searches dictionaries
"""
- #print '\n\t getattr_recursive:', item, attr_key
using_default = len( args ) >= 1
default = args[0] if using_default else None
- #print '\t defaults:', using_default, default
for attr_key in attr_key.split( '.' ):
try:
- #print '\t\t attr:', attr_key, 'item:', item
if isinstance( item, dict ):
item = item.__getitem__( attr_key )
else:
item = getattr( item, attr_key )
except ( KeyError, AttributeError ), err:
- #print '\t\t error:', err
if using_default:
- #print '\t\t\t default:', default
return default
raise
@@ -77,7 +72,6 @@
attr_key = last_key
try:
- #print '\t\t attr:', attr_key, 'item:', item
if isinstance( item, dict ):
return item.__contains__( attr_key )
else:
@@ -88,6 +82,7 @@
return True
+
# ------------------------------------------------------------------- the registry
class VisualizationsRegistry( pluginframework.PageServingPluginManager ):
"""
@@ -118,7 +113,7 @@
super( VisualizationsRegistry, self ).__init__( app, 'visualizations', **kwargs )
# what to use to parse query strings into resources/vars for the template
self.resource_parser = ResourceParser()
- log.debug( '%s loaded', str( self ) )
+ #log.debug( '%s loaded', str( self ) )
def is_plugin( self, plugin_path ):
"""
@@ -265,8 +260,6 @@
#precondition: the target_object should be usable by the visualization (accrd. to data_sources)
# convert params using vis.data_source.to_params
params = self.get_url_params( trans, target_object, param_data )
- #for param in params:
- # print param
# we want existing visualizations to work as normal but still be part of the registry (without mod'ing)
# so generate their urls differently
@@ -294,12 +287,8 @@
# assign takes precedence (goes last, overwrites)?
#NOTE this is only one level
- #print 'target_object:', target_object
- #print 'target_attr:', target_attr
-
if target_attr and hasattr_recursive( target_object, target_attr ):
params[ to_param_name ] = getattr_recursive( target_object, target_attr )
- #print 'params[ %s ]:' %( to_param_name ), params[ to_param_name ]
if assign:
params[ to_param_name ] = assign
@@ -394,7 +383,6 @@
returned[ 'name' ] = xml_tree.attrib.get( 'name', None )
if not returned[ 'name' ]:
raise ParsingException( 'visualization needs a name attribute' )
- print returned[ 'name' ]
# a (for now) text description of what the visualization does
description = xml_tree.find( 'description' )
@@ -532,7 +520,7 @@
raise ParsingException( 'data_source entry requires a model_class' )
if xml_tree.text not in self.ALLOWED_MODEL_CLASSES:
- log.debug( 'available data_source model_classes: %s' %( str( self.ALLOWED_MODEL_CLASSES ) ) )
+ #log.debug( 'available data_source model_classes: %s' %( str( self.ALLOWED_MODEL_CLASSES ) ) )
raise ParsingException( 'Invalid data_source model_class: %s' %( xml_tree.text ) )
# look up the model from the model module returning an empty data_source if not found
@@ -760,6 +748,7 @@
If param is required and not present, raises a `KeyError`.
"""
+ #log.debug( 'parse_parameter_dictionary, query_params:\n%s', query_params )
# first parse any params from any visualizations that were passed
query_params = self.get_params_from_visualization_param( trans, controller, param_config_dict, query_params )
@@ -842,8 +831,8 @@
return self.parse_parameter( trans, param_config, default )
def get_params_from_visualization_param( self, trans, controller, param_config_dict, query_params ):
- log.debug( 'parse_visualization_params: %s', param_config_dict )
- log.debug( ' : %s', query_params )
+ #log.debug( 'parse_visualization_params: %s', param_config_dict )
+ #log.debug( ' : %s', query_params )
# first, find the visualization in the parameters if any
visualization = None
@@ -854,25 +843,25 @@
if query_val is None:
continue
- log.debug( 'found visualization param: %s, %s', param_name, query_val )
+ #log.debug( 'found visualization param: %s, %s', param_name, query_val )
visualization = self.parse_parameter( trans, controller, param_config, query_val )
if visualization:
break
# if no vis is found, can't get any new params from it: return the original query_params
if not visualization:
- log.debug( 'visualization not found' )
+ #log.debug( 'visualization not found' )
return query_params
- log.debug( 'found visualization: %s', visualization )
+ #log.debug( 'found visualization: %s', visualization )
# next, attempt to copy any params from the visualizations config
visualization_config = visualization.latest_revision.config
- log.debug( '\t config: %s', visualization_config )
+ #log.debug( '\t config: %s', visualization_config )
params_from_visualization = {}
for param_name, param_config in param_config_dict.items():
if param_name in visualization_config:
params_from_visualization[ param_name ] = visualization_config[ param_name ]
- log.debug( 'params_from_visualization: %s', params_from_visualization )
+ #log.debug( 'params_from_visualization: %s', params_from_visualization )
# layer the query_params over the params from the visualization, returning the combined
params_from_visualization.update( query_params )
@@ -926,7 +915,7 @@
#TODO: subclass here?
elif param_type == 'visualization':
encoded_visualization_id = query_param
- log.debug( 'visualization param, id : %s', encoded_visualization_id )
+ #log.debug( 'visualization param, id : %s', encoded_visualization_id )
#TODO:?? some fallback if there's no get_X in controller that's passed?
parsed_param = controller.get_visualization( trans, encoded_visualization_id,
check_ownership=False, check_accessible=True )
@@ -948,5 +937,4 @@
dbkey = query_param
parsed_param = galaxy.util.sanitize_html.sanitize_html( dbkey, 'utf-8' )
- #print ( '%s, %s -> %s, %s' %( param_type, query_param, str( type( parsed_param ) ), parsed_param ) )
return parsed_param
diff -r d9f6f3f2467195397828d452664c68e5e4c104ef -r bf7251133a037cda8ca7025a15af4ab9efb326ba lib/galaxy/web/base/pluginframework.py
--- a/lib/galaxy/web/base/pluginframework.py
+++ b/lib/galaxy/web/base/pluginframework.py
@@ -62,7 +62,7 @@
:param skip_bad_plugins: whether to skip plugins that cause
exceptions when loaded or to raise that exception
"""
- log.debug( 'PluginManager.init: %s, %s', directories_setting, kwargs )
+ #log.debug( 'PluginManager.init: %s, %s', directories_setting, kwargs )
self.directories = []
self.skip_bad_plugins = skip_bad_plugins
self.plugins = odict.odict()
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.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/fd4936ae8219/
Changeset: fd4936ae8219
Branch: next-stable
User: greg
Date: 2014-01-30 17:20:04
Summary: Fixes in the tool shed's install and test framework for handling repositories containing tools that install correctly but with one or more dependencies that do not.
Affected #: 2 files
diff -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 -r fd4936ae82193639011ed06b9552ec1a8c8166e5 test/install_and_test_tool_shed_repositories/base/util.py
--- a/test/install_and_test_tool_shed_repositories/base/util.py
+++ b/test/install_and_test_tool_shed_repositories/base/util.py
@@ -735,6 +735,8 @@
repository_name = str( repository.name )
repository_owner = str( repository.owner )
repository_changeset_revision = str( repository.changeset_revision )
+ print 'Populating dependency install containers for revision %s of repository %s owned by %s.' % \
+ ( repository_changeset_revision, repository_name, repository_owner )
processed_successful_repository_installations = install_and_test_statistics_dict.get( 'successful_repository_installations', [] )
if repository_identifier_tup not in processed_successful_repository_installations:
install_and_test_statistics_dict[ 'successful_repository_installations' ].append( repository_identifier_tup )
@@ -844,12 +846,17 @@
repository_name = str( repository.name )
repository_owner = str( repository.owner )
repository_changeset_revision = str( repository.changeset_revision )
+ print 'Potentially populating install containers for repository dependencies of revision %s of repository %s owned by %s.' % \
+ ( repository_changeset_revision, repository_name, repository_owner )
repository_dependencies_dicts, error_message = get_repository_dependencies_dicts( galaxy_tool_shed_url, repository_metadata_id )
if error_message:
- print 'Cannot check or populate repository dependency install containers for version %s of repository %s owned by %s ' % \
+ print 'Cannot check or populate repository dependency install containers for revision %s of repository %s owned by %s ' % \
( repository_changeset_revision, repository_name, repository_owner )
print 'due to the following error getting repository_dependencies_dicts:\n%s' % str( error_message )
else:
+ if not repository_dependencies_dicts:
+ print 'Revision %s of repository %s owned by %s has no repository dependencies.' % \
+ ( repository_changeset_revision, repository_name, repository_owner )
for repository_dependencies_dict in repository_dependencies_dicts:
if not isinstance( repository_dependencies_dict, dict ):
print 'Skipping invalid repository_dependencies_dict: %s' % str( repository_dependencies_dict )
@@ -951,7 +958,7 @@
can_update_tool_shed )
print 'Result of inserting tool_test_results for revision %s of repository %s owned by %s:\n%s' % \
( changeset_revision, name, owner, str( response_dict ) )
- print'============================================================='
+ print'\n============================================================='
else:
# The required repository's installation failed.
tool_test_results_dict[ 'installation_errors' ][ 'current_repository' ] = str( required_repository.error_message )
@@ -965,7 +972,7 @@
can_update_tool_shed )
print 'Result of inserting tool_test_results for revision %s of repository %s owned by %s:\n%s' % \
( changeset_revision, name, owner, str( response_dict ) )
- print'============================================================='
+ print'\n============================================================='
else:
print 'Cannot retrieve revision %s of required repository %s owned by %s from the database ' % \
( changeset_revision, name, owner )
@@ -1056,7 +1063,7 @@
name = str( name )
owner = str( owner )
changeset_revision = str( changeset_revision )
- print '============================================================='
+ print '\n============================================================='
print 'Inserting the following into tool_test_results for revision %s of repository %s owned by %s:\n%s' % \
( changeset_revision, name, owner, str( tool_test_results_dict ) )
print 'Updating tool_test_results for repository_metadata id %s.' % metadata_revision_id
diff -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 -r fd4936ae82193639011ed06b9552ec1a8c8166e5 test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
--- a/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
+++ b/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
@@ -251,6 +251,19 @@
repository_identifier_tup,
install_and_test_statistics_dict,
tool_test_results_dict )
+ if params.get( 'test_install_error', False ):
+ # The repository was successfully installed, but one or more dependencies had installation errors,
+ # so we'll populate the test result containers since we cannot execute any tests.
+ response_dict = \
+ install_and_test_base_util.save_test_results_for_changeset_revision( install_and_test_base_util.galaxy_tool_shed_url,
+ tool_test_results_dicts,
+ tool_test_results_dict,
+ repository_dict,
+ params,
+ can_update_tool_shed )
+ print 'Result of inserting tool_test_results for revision %s of repository %s owned by %s:\n%s' % \
+ ( changeset_revision, name, owner, str( response_dict ) )
+ print'\n============================================================='
# Populate the installation containers (success or error) for the repository's immediate repository
# dependencies whose containers are not yet populated.
install_and_test_base_util.populate_install_containers_for_repository_dependencies( app,
@@ -266,6 +279,10 @@
print 'Cannot execute tests for tools in revision %s of repository %s owned by %s ' % \
( changeset_revision, name, owner )
print 'because one or more dependencies has installation errors.'
+ # The repository was installed successfully, but one or more dependencies had installation errors. Since
+ # we cannot test the tools due to these errors, we'll remove tests and tools were created during the repository
+ # installation process so nose will not discover them and attempt to execute them.
+ remove_tests( app )
else:
print 'Revision %s of repository %s owned by %s installed successfully, so running tool tests.' % \
( changeset_revision, name, owner )
@@ -279,6 +296,9 @@
from_json_string( file( galaxy_shed_tools_dict, 'r' ).read() ) )
# If the repository has a test-data directory we write the generated shed_tools_dict to a temporary
# file so the functional test framework can find it.
+ # TODO: Eliminate the need for this shed_tools_dict since it grows large over the course of each test run.
+ # If it cannot be eliminated altogether, reinitialize it with each new repository install so at this point
+ # it contains only entries for the current repository dependency hierarchy being tested.
file( galaxy_shed_tools_dict, 'w' ).write( to_json_string( shed_tools_dict ) )
print 'Saved generated shed_tools_dict to %s\nContents: %s' % ( galaxy_shed_tools_dict, shed_tools_dict )
try:
@@ -605,6 +625,7 @@
owner = str( repository.owner )
changeset_revision = str( repository.changeset_revision )
repository_identifier_tup = ( name, owner, changeset_revision )
+ print 'Testing tools contained in revision %s of repository %s owned by %s.' % ( changeset_revision, name, owner )
# Generate the test methods for this installed repository. We need to pass testing_shed_tools=True here
# or twill will look in $GALAXY_HOME/test-data for test data, which may result in missing or invalid test
# files.
https://bitbucket.org/galaxy/galaxy-central/commits/d9f6f3f24671/
Changeset: d9f6f3f24671
User: greg
Date: 2014-01-30 17:20:33
Summary: Merged from next-stable
Affected #: 2 files
diff -r b67a464b8588525e17fd64910b9b9f3bcadb82ae -r d9f6f3f2467195397828d452664c68e5e4c104ef test/install_and_test_tool_shed_repositories/base/util.py
--- a/test/install_and_test_tool_shed_repositories/base/util.py
+++ b/test/install_and_test_tool_shed_repositories/base/util.py
@@ -735,6 +735,8 @@
repository_name = str( repository.name )
repository_owner = str( repository.owner )
repository_changeset_revision = str( repository.changeset_revision )
+ print 'Populating dependency install containers for revision %s of repository %s owned by %s.' % \
+ ( repository_changeset_revision, repository_name, repository_owner )
processed_successful_repository_installations = install_and_test_statistics_dict.get( 'successful_repository_installations', [] )
if repository_identifier_tup not in processed_successful_repository_installations:
install_and_test_statistics_dict[ 'successful_repository_installations' ].append( repository_identifier_tup )
@@ -844,12 +846,17 @@
repository_name = str( repository.name )
repository_owner = str( repository.owner )
repository_changeset_revision = str( repository.changeset_revision )
+ print 'Potentially populating install containers for repository dependencies of revision %s of repository %s owned by %s.' % \
+ ( repository_changeset_revision, repository_name, repository_owner )
repository_dependencies_dicts, error_message = get_repository_dependencies_dicts( galaxy_tool_shed_url, repository_metadata_id )
if error_message:
- print 'Cannot check or populate repository dependency install containers for version %s of repository %s owned by %s ' % \
+ print 'Cannot check or populate repository dependency install containers for revision %s of repository %s owned by %s ' % \
( repository_changeset_revision, repository_name, repository_owner )
print 'due to the following error getting repository_dependencies_dicts:\n%s' % str( error_message )
else:
+ if not repository_dependencies_dicts:
+ print 'Revision %s of repository %s owned by %s has no repository dependencies.' % \
+ ( repository_changeset_revision, repository_name, repository_owner )
for repository_dependencies_dict in repository_dependencies_dicts:
if not isinstance( repository_dependencies_dict, dict ):
print 'Skipping invalid repository_dependencies_dict: %s' % str( repository_dependencies_dict )
@@ -951,7 +958,7 @@
can_update_tool_shed )
print 'Result of inserting tool_test_results for revision %s of repository %s owned by %s:\n%s' % \
( changeset_revision, name, owner, str( response_dict ) )
- print'============================================================='
+ print'\n============================================================='
else:
# The required repository's installation failed.
tool_test_results_dict[ 'installation_errors' ][ 'current_repository' ] = str( required_repository.error_message )
@@ -965,7 +972,7 @@
can_update_tool_shed )
print 'Result of inserting tool_test_results for revision %s of repository %s owned by %s:\n%s' % \
( changeset_revision, name, owner, str( response_dict ) )
- print'============================================================='
+ print'\n============================================================='
else:
print 'Cannot retrieve revision %s of required repository %s owned by %s from the database ' % \
( changeset_revision, name, owner )
@@ -1056,7 +1063,7 @@
name = str( name )
owner = str( owner )
changeset_revision = str( changeset_revision )
- print '============================================================='
+ print '\n============================================================='
print 'Inserting the following into tool_test_results for revision %s of repository %s owned by %s:\n%s' % \
( changeset_revision, name, owner, str( tool_test_results_dict ) )
print 'Updating tool_test_results for repository_metadata id %s.' % metadata_revision_id
diff -r b67a464b8588525e17fd64910b9b9f3bcadb82ae -r d9f6f3f2467195397828d452664c68e5e4c104ef test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
--- a/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
+++ b/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
@@ -251,6 +251,19 @@
repository_identifier_tup,
install_and_test_statistics_dict,
tool_test_results_dict )
+ if params.get( 'test_install_error', False ):
+ # The repository was successfully installed, but one or more dependencies had installation errors,
+ # so we'll populate the test result containers since we cannot execute any tests.
+ response_dict = \
+ install_and_test_base_util.save_test_results_for_changeset_revision( install_and_test_base_util.galaxy_tool_shed_url,
+ tool_test_results_dicts,
+ tool_test_results_dict,
+ repository_dict,
+ params,
+ can_update_tool_shed )
+ print 'Result of inserting tool_test_results for revision %s of repository %s owned by %s:\n%s' % \
+ ( changeset_revision, name, owner, str( response_dict ) )
+ print'\n============================================================='
# Populate the installation containers (success or error) for the repository's immediate repository
# dependencies whose containers are not yet populated.
install_and_test_base_util.populate_install_containers_for_repository_dependencies( app,
@@ -266,6 +279,10 @@
print 'Cannot execute tests for tools in revision %s of repository %s owned by %s ' % \
( changeset_revision, name, owner )
print 'because one or more dependencies has installation errors.'
+ # The repository was installed successfully, but one or more dependencies had installation errors. Since
+ # we cannot test the tools due to these errors, we'll remove tests and tools were created during the repository
+ # installation process so nose will not discover them and attempt to execute them.
+ remove_tests( app )
else:
print 'Revision %s of repository %s owned by %s installed successfully, so running tool tests.' % \
( changeset_revision, name, owner )
@@ -279,6 +296,9 @@
from_json_string( file( galaxy_shed_tools_dict, 'r' ).read() ) )
# If the repository has a test-data directory we write the generated shed_tools_dict to a temporary
# file so the functional test framework can find it.
+ # TODO: Eliminate the need for this shed_tools_dict since it grows large over the course of each test run.
+ # If it cannot be eliminated altogether, reinitialize it with each new repository install so at this point
+ # it contains only entries for the current repository dependency hierarchy being tested.
file( galaxy_shed_tools_dict, 'w' ).write( to_json_string( shed_tools_dict ) )
print 'Saved generated shed_tools_dict to %s\nContents: %s' % ( galaxy_shed_tools_dict, shed_tools_dict )
try:
@@ -605,6 +625,7 @@
owner = str( repository.owner )
changeset_revision = str( repository.changeset_revision )
repository_identifier_tup = ( name, owner, changeset_revision )
+ print 'Testing tools contained in revision %s of repository %s owned by %s.' % ( changeset_revision, name, owner )
# Generate the test methods for this installed repository. We need to pass testing_shed_tools=True here
# or twill will look in $GALAXY_HOME/test-data for test data, which may result in missing or invalid test
# files.
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.
1
0
commit/galaxy-central: jmchilton: Fix division by zero error in quota.
by commits-noreply@bitbucket.org 29 Jan '14
by commits-noreply@bitbucket.org 29 Jan '14
29 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b67a464b8588/
Changeset: b67a464b8588
User: jmchilton
Date: 2014-01-30 01:35:54
Summary: Fix division by zero error in quota.
Affected #: 1 file
diff -r 286b0d3b0485cfd1e5434dda86528662549d4468 -r b67a464b8588525e17fd64910b9b9f3bcadb82ae lib/galaxy/quota/__init__.py
--- a/lib/galaxy/quota/__init__.py
+++ b/lib/galaxy/quota/__init__.py
@@ -138,7 +138,11 @@
# get the usage, if it wasn't passed
if usage is False:
usage = self.get_usage( trans, user, history )
- return min( ( int( float( usage ) / quota * 100 ), 100 ) )
+ try:
+ return min( ( int( float( usage ) / quota * 100 ), 100 ) )
+ except ZeroDivisionError:
+ return 100
+
def set_entity_quota_associations( self, quotas=[], users=[], groups=[], delete_existing_assocs=True ):
for quota in quotas:
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.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e034999e8b1a/
Changeset: e034999e8b1a
User: jmchilton
Date: 2014-01-29 15:36:32
Summary: Bugfix: History import when 'cleanup_job=never'.
Affected #: 1 file
diff -r 6a7cb977238c76359f39c8484b88cdd1daff4b1f -r e034999e8b1a2820f81e6fe64c623b7417e38148 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -789,8 +789,8 @@
# If the job was deleted, call tool specific fail actions (used for e.g. external metadata) and clean up
if self.tool:
self.tool.job_failed( self, message, exception )
- if self.app.config.cleanup_job == 'always' or (self.app.config.cleanup_job == 'onsuccess' and job.state == job.states.DELETED):
- self.cleanup()
+ delete_files = self.app.config.cleanup_job == 'always' or (self.app.config.cleanup_job == 'onsuccess' and job.state == job.states.DELETED)
+ self.cleanup( delete_files=delete_files )
def pause( self, job=None, message=None ):
if job is None:
@@ -1067,22 +1067,27 @@
self.sa_session.flush()
log.debug( 'job %d ended' % self.job_id )
- if self.app.config.cleanup_job == 'always' or ( not stderr and self.app.config.cleanup_job == 'onsuccess' ):
- self.cleanup()
+ # TODO: Also fix "not stderr" below, use final_job_state.
+ delete_files = self.app.config.cleanup_job == 'always' or ( not stderr and self.app.config.cleanup_job == 'onsuccess' )
+ self.cleanup( delete_files=delete_files )
def check_tool_output( self, stdout, stderr, tool_exit_code, job ):
return check_output( self.tool, stdout, stderr, tool_exit_code, job )
- def cleanup( self ):
- # remove temporary files
+ def cleanup( self, delete_files=True ):
+ # At least one of these tool cleanup actions (job import), is needed
+ # for thetool to work properly, that is why one might want to run
+ # cleanup but not delete files.
try:
- for fname in self.extra_filenames:
- os.remove( fname )
- self.external_output_metadata.cleanup_external_metadata( self.sa_session )
+ if delete_files:
+ for fname in self.extra_filenames:
+ os.remove( fname )
+ self.external_output_metadata.cleanup_external_metadata( self.sa_session )
galaxy.tools.imp_exp.JobExportHistoryArchiveWrapper( self.job_id ).cleanup_after_job( self.sa_session )
galaxy.tools.imp_exp.JobImportHistoryArchiveWrapper( self.app, self.job_id ).cleanup_after_job()
galaxy.tools.genome_index.GenomeIndexToolWrapper( self.job_id ).postprocessing( self.sa_session, self.app )
- self.app.object_store.delete(self.get_job(), base_dir='job_work', entire_dir=True, dir_only=True, extra_dir=str(self.job_id))
+ if delete_files:
+ self.app.object_store.delete(self.get_job(), base_dir='job_work', entire_dir=True, dir_only=True, extra_dir=str(self.job_id))
except:
log.exception( "Unable to cleanup job %d" % self.job_id )
@@ -1520,8 +1525,8 @@
# if the job was deleted, don't finish it
if task.state == task.states.DELETED:
# Job was deleted by an administrator
- if self.app.config.cleanup_job in ( 'always', 'onsuccess' ):
- self.cleanup()
+ delete_files = self.app.config.cleanup_job in ( 'always', 'onsuccess' )
+ self.cleanup( delete_files=delete_files )
return
elif task.state == task.states.ERROR:
self.fail( task.info )
https://bitbucket.org/galaxy/galaxy-central/commits/40d94d94900b/
Changeset: 40d94d94900b
User: jmchilton
Date: 2014-01-29 15:36:32
Summary: Bugfix: cleanup_job for newer job error checking logic.
Affected #: 1 file
diff -r e034999e8b1a2820f81e6fe64c623b7417e38148 -r 40d94d94900b82be76e11b778626d09a421e4966 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -1067,8 +1067,7 @@
self.sa_session.flush()
log.debug( 'job %d ended' % self.job_id )
- # TODO: Also fix "not stderr" below, use final_job_state.
- delete_files = self.app.config.cleanup_job == 'always' or ( not stderr and self.app.config.cleanup_job == 'onsuccess' )
+ delete_files = self.app.config.cleanup_job == 'always' or ( job.state == job.states.OK and self.app.config.cleanup_job == 'onsuccess' )
self.cleanup( delete_files=delete_files )
def check_tool_output( self, stdout, stderr, tool_exit_code, job ):
https://bitbucket.org/galaxy/galaxy-central/commits/07dceba219c3/
Changeset: 07dceba219c3
User: jmchilton
Date: 2014-01-29 15:36:32
Summary: Eliminate unneeded if in jobs/__init__.py.
Checking if job.state is ERROR when that cannot be (method returns self.fail above this if that were the case). Even if it were somehow possible, subsequent code would fail badly with final_job_state not being set.
Affected #: 1 file
diff -r 40d94d94900b82be76e11b778626d09a421e4966 -r 07dceba219c315e2857f105abfdaf030efa1f16c lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -883,11 +883,10 @@
# We set final_job_state to use for dataset management, but *don't* set
# job.state until after dataset collection to prevent history issues
- if job.states.ERROR != job.state:
- if ( self.check_tool_output( stdout, stderr, tool_exit_code, job )):
- final_job_state = job.states.OK
- else:
- final_job_state = job.states.ERROR
+ if ( self.check_tool_output( stdout, stderr, tool_exit_code, job ) ):
+ final_job_state = job.states.OK
+ else:
+ final_job_state = job.states.ERROR
if self.version_string_cmd:
version_filename = self.get_version_string_path()
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.
1
0
commit/galaxy-central: jmchilton: Fix for a failing API test in buildbot.
by commits-noreply@bitbucket.org 29 Jan '14
by commits-noreply@bitbucket.org 29 Jan '14
29 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6a7cb977238c/
Changeset: 6a7cb977238c
User: jmchilton
Date: 2014-01-29 07:27:30
Summary: Fix for a failing API test in buildbot.
Just noticed these are actually running tonight, that is good news.
Affected #: 1 file
diff -r 60203bad003cc6b4bc054500248e5a69cbe9b8bc -r 6a7cb977238c76359f39c8484b88cdd1daff4b1f test/functional/api/test_page_revisions.py
--- a/test/functional/api/test_page_revisions.py
+++ b/test/functional/api/test_page_revisions.py
@@ -1,5 +1,5 @@
from galaxy.exceptions import error_codes
-from functional.api.pages import BasePageApiTestCase
+from functional.api.test_pages import BasePageApiTestCase
class PageRevisionsApiTestCase( BasePageApiTestCase ):
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.
1
0
11 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b928679cc4ac/
Changeset: b928679cc4ac
User: jmchilton
Date: 2014-01-28 21:35:14
Summary: PEP-8 and style fixes for various files related to history import/export.
Affected #: 3 files
diff -r 0ab0eb81d9828b0527d68f404a36acc64359f5f8 -r b928679cc4acd843e8a6dcfb24c89f5a0b40d3a6 lib/galaxy/tools/imp_exp/__init__.py
--- a/lib/galaxy/tools/imp_exp/__init__.py
+++ b/lib/galaxy/tools/imp_exp/__init__.py
@@ -1,4 +1,8 @@
-import os, shutil, logging, tempfile, json
+import os
+import shutil
+import logging
+import tempfile
+import json
from galaxy import model
from galaxy.tools.parameters.basic import UnvalidatedValue
from galaxy.web.framework.helpers import to_unicode
@@ -8,6 +12,7 @@
log = logging.getLogger(__name__)
+
def load_history_imp_exp_tools( toolbox ):
""" Adds tools for importing/exporting histories to archives. """
# Use same process as that used in load_external_metadata_tool; see that
@@ -42,6 +47,7 @@
toolbox.tools_by_id[ history_imp_tool.id ] = history_imp_tool
log.debug( "Loaded history import tool: %s", history_imp_tool.id )
+
class JobImportHistoryArchiveWrapper( object, UsesHistoryMixin, UsesAnnotations ):
"""
Class provides support for performing jobs that import a history from
@@ -144,23 +150,23 @@
metadata = dataset_attrs['metadata']
# Create dataset and HDA.
- hda = model.HistoryDatasetAssociation( name = dataset_attrs['name'].encode( 'utf-8' ),
- extension = dataset_attrs['extension'],
- info = dataset_attrs['info'].encode( 'utf-8' ),
- blurb = dataset_attrs['blurb'],
- peek = dataset_attrs['peek'],
- designation = dataset_attrs['designation'],
- visible = dataset_attrs['visible'],
- dbkey = metadata['dbkey'],
- metadata = metadata,
- history = new_history,
- create_dataset = True,
- sa_session = self.sa_session )
+ hda = model.HistoryDatasetAssociation( name=dataset_attrs['name'].encode( 'utf-8' ),
+ extension=dataset_attrs['extension'],
+ info=dataset_attrs['info'].encode( 'utf-8' ),
+ blurb=dataset_attrs['blurb'],
+ peek=dataset_attrs['peek'],
+ designation=dataset_attrs['designation'],
+ visible=dataset_attrs['visible'],
+ dbkey=metadata['dbkey'],
+ metadata=metadata,
+ history=new_history,
+ create_dataset=True,
+ sa_session=self.sa_session )
hda.state = hda.states.OK
self.sa_session.add( hda )
self.sa_session.flush()
- new_history.add_dataset( hda, genome_build = None )
- hda.hid = dataset_attrs['hid'] # Overwrite default hid set when HDA added to history.
+ new_history.add_dataset( hda, genome_build=None )
+ hda.hid = dataset_attrs['hid'] # Overwrite default hid set when HDA added to history.
# TODO: Is there a way to recover permissions? Is this needed?
#permissions = trans.app.security_agent.history_get_default_permissions( new_history )
#trans.app.security_agent.set_all_dataset_permissions( hda.dataset, permissions )
@@ -273,6 +279,7 @@
jiha.job.stderr += "Error cleaning up history import job: %s" % e
self.sa_session.flush()
+
class JobExportHistoryArchiveWrapper( object, UsesHistoryMixin, UsesAnnotations ):
"""
Class provides support for performing jobs that export a history to an
@@ -317,23 +324,23 @@
""" Encode an HDA, default encoding for everything else. """
if isinstance( obj, trans.app.model.HistoryDatasetAssociation ):
return {
- "__HistoryDatasetAssociation__" : True,
- "create_time" : obj.create_time.__str__(),
- "update_time" : obj.update_time.__str__(),
- "hid" : obj.hid,
- "name" : to_unicode( obj.name ),
- "info" : to_unicode( obj.info ),
- "blurb" : obj.blurb,
- "peek" : obj.peek,
- "extension" : obj.extension,
- "metadata" : prepare_metadata( dict( obj.metadata.items() ) ),
- "parent_id" : obj.parent_id,
- "designation" : obj.designation,
- "deleted" : obj.deleted,
- "visible" : obj.visible,
- "file_name" : obj.file_name,
- "annotation" : to_unicode( getattr( obj, 'annotation', '' ) ),
- "tags" : get_item_tag_dict( obj ),
+ "__HistoryDatasetAssociation__": True,
+ "create_time": obj.create_time.__str__(),
+ "update_time": obj.update_time.__str__(),
+ "hid": obj.hid,
+ "name": to_unicode( obj.name ),
+ "info": to_unicode( obj.info ),
+ "blurb": obj.blurb,
+ "peek": obj.peek,
+ "extension": obj.extension,
+ "metadata": prepare_metadata( dict( obj.metadata.items() ) ),
+ "parent_id": obj.parent_id,
+ "designation": obj.designation,
+ "deleted": obj.deleted,
+ "visible": obj.visible,
+ "file_name": obj.file_name,
+ "annotation": to_unicode( getattr( obj, 'annotation', '' ) ),
+ "tags": get_item_tag_dict( obj ),
}
if isinstance( obj, UnvalidatedValue ):
return obj.__str__()
@@ -347,15 +354,15 @@
# Write history attributes to file.
history = jeha.history
history_attrs = {
- "create_time" : history.create_time.__str__(),
- "update_time" : history.update_time.__str__(),
- "name" : to_unicode( history.name ),
- "hid_counter" : history.hid_counter,
- "genome_build" : history.genome_build,
- "annotation" : to_unicode( self.get_item_annotation_str( trans.sa_session, history.user, history ) ),
- "tags" : get_item_tag_dict( history ),
- "includes_hidden_datasets" : include_hidden,
- "includes_deleted_datasets" : include_deleted
+ "create_time": history.create_time.__str__(),
+ "update_time": history.update_time.__str__(),
+ "name": to_unicode( history.name ),
+ "hid_counter": history.hid_counter,
+ "genome_build": history.genome_build,
+ "annotation": to_unicode( self.get_item_annotation_str( trans.sa_session, history.user, history ) ),
+ "tags": get_item_tag_dict( history ),
+ "includes_hidden_datasets": include_hidden,
+ "includes_deleted_datasets": include_deleted
}
history_attrs_filename = tempfile.NamedTemporaryFile( dir=temp_output_dir ).name
history_attrs_out = open( history_attrs_filename, 'w' )
@@ -391,7 +398,7 @@
# Get the associated job, if any. If this hda was copied from another,
# we need to find the job that created the origial hda
job_hda = hda
- while job_hda.copied_from_history_dataset_association: #should this check library datasets as well?
+ while job_hda.copied_from_history_dataset_association: # should this check library datasets as well?
job_hda = job_hda.copied_from_history_dataset_association
if not job_hda.creating_job_associations:
# No viable HDA found.
@@ -472,4 +479,3 @@
shutil.rmtree( temp_dir )
except Exception, e:
log.debug( 'Error deleting directory containing attribute files (%s): %s' % ( temp_dir, e ) )
-
diff -r 0ab0eb81d9828b0527d68f404a36acc64359f5f8 -r b928679cc4acd843e8a6dcfb24c89f5a0b40d3a6 lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
--- a/lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
+++ b/lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
@@ -6,19 +6,25 @@
--[url|file] source type, either a URL or a file.
"""
-import sys, optparse, tarfile, tempfile, urllib2, math
+import sys
+import optparse
+import tarfile
+import tempfile
+import urllib2
+import math
# Set max size of archive/file that will be handled to be 100 GB. This is
# arbitrary and should be adjusted as needed.
MAX_SIZE = 100 * math.pow( 2, 30 )
+
def url_to_file( url, dest_file ):
"""
Transfer a file from a remote URL to a temporary file.
"""
try:
url_reader = urllib2.urlopen( url )
- CHUNK = 10 * 1024 # 10k
+ CHUNK = 10 * 1024 # 10k
total = 0
fp = open( dest_file, 'wb')
while True:
@@ -35,6 +41,7 @@
print "Exception getting file from URL: %s" % e, sys.stderr
return None
+
def unpack_archive( archive_file, dest_dir ):
"""
Unpack a tar and/or gzipped archive into a destination directory.
@@ -63,4 +70,4 @@
# Unpack archive.
unpack_archive( archive_file, dest_dir )
except Exception, e:
- print "Error unpacking tar/gz archive: %s" % e, sys.stderr
\ No newline at end of file
+ print "Error unpacking tar/gz archive: %s" % e, sys.stderr
diff -r 0ab0eb81d9828b0527d68f404a36acc64359f5f8 -r b928679cc4acd843e8a6dcfb24c89f5a0b40d3a6 lib/galaxy/webapps/galaxy/api/histories.py
--- a/lib/galaxy/webapps/galaxy/api/histories.py
+++ b/lib/galaxy/webapps/galaxy/api/histories.py
@@ -11,15 +11,17 @@
from galaxy import web
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
-from galaxy.util import string_as_bool, restore_text
-from galaxy.util.sanitize_html import sanitize_html
-from galaxy.web.base.controller import BaseAPIController, UsesHistoryMixin, UsesTagsMixin
+from galaxy.util import string_as_bool
+from galaxy.util import restore_text
+from galaxy.web.base.controller import BaseAPIController
+from galaxy.web.base.controller import UsesHistoryMixin
+from galaxy.web.base.controller import UsesTagsMixin
from galaxy.web import url_for
-from galaxy.model.orm import desc
import logging
log = logging.getLogger( __name__ )
+
class HistoriesController( BaseAPIController, UsesHistoryMixin, UsesTagsMixin ):
@expose_api_anonymous
@@ -46,14 +48,14 @@
histories = self.get_user_histories( trans, user=trans.user, only_deleted=deleted )
#for history in query:
for history in histories:
- item = history.to_dict(value_mapper={'id':trans.security.encode_id})
+ item = history.to_dict(value_mapper={'id': trans.security.encode_id})
item['url'] = url_for( 'history', id=trans.security.encode_id( history.id ) )
rval.append( item )
elif trans.galaxy_session.current_history:
#No user, this must be session authentication with an anonymous user.
history = trans.galaxy_session.current_history
- item = history.to_dict(value_mapper={'id':trans.security.encode_id})
+ item = history.to_dict(value_mapper={'id': trans.security.encode_id})
item['url'] = url_for( 'history', id=trans.security.encode_id( history.id ) )
rval.append(item)
@@ -257,7 +259,7 @@
log.exception( 'Histories API, delete: uncaught HTTPInternalServerError: %s, %s\n%s',
history_id, str( kwd ), str( http_server_err ) )
raise
- except HTTPException, http_exc:
+ except HTTPException:
raise
except Exception, exc:
log.exception( 'Histories API, delete: uncaught exception: %s, %s\n%s',
https://bitbucket.org/galaxy/galaxy-central/commits/f4485c8dd5f5/
Changeset: f4485c8dd5f5
Branch: job-search
User: Kyle Ellrott
Date: 2014-01-22 02:30:47
Summary: Adding in /api/jobs and refining the Job.to_dict method
Affected #: 4 files
diff -r 54defa390a91ec1db34141f97711e673218cde13 -r f4485c8dd5f5392f1cc8a1ed296fb772064f1e10 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -209,8 +209,8 @@
class Job( object, Dictifiable ):
- dict_collection_visible_keys = [ 'id', 'state', 'exit_code' ]
- dict_element_visible_keys = [ 'id', 'state', 'exit_code' ]
+ dict_collection_visible_keys = [ 'id', 'state', 'exit_code', 'update_time', 'create_time' ]
+ dict_element_visible_keys = [ 'id', 'state', 'exit_code', 'update_time', 'create_time' ]
"""
A job represents a request to run a tool given input datasets, tool
@@ -416,30 +416,31 @@
dataset.info = 'Job output deleted by user before job completed'
def to_dict( self, view='collection' ):
rval = super( Job, self ).to_dict( view=view )
- rval['tool_name'] = self.tool_id
- param_dict = dict( [ ( p.name, p.value ) for p in self.parameters ] )
- rval['params'] = param_dict
+ if view == 'element':
+ rval['tool_name'] = self.tool_id
+ param_dict = dict( [ ( p.name, p.value ) for p in self.parameters ] )
+ rval['params'] = param_dict
- input_dict = {}
- for i in self.input_datasets:
- if i.dataset is not None:
- input_dict[i.name] = {"hda_id" : i.dataset.id}
- for i in self.input_library_datasets:
- if i.dataset is not None:
- input_dict[i.name] = {"ldda_id" : i.dataset.id}
- for k in input_dict:
- if k in param_dict:
- del param_dict[k]
- rval['inputs'] = input_dict
+ input_dict = {}
+ for i in self.input_datasets:
+ if i.dataset is not None:
+ input_dict[i.name] = {"id" : i.dataset.id, "src" : "hda"}
+ for i in self.input_library_datasets:
+ if i.dataset is not None:
+ input_dict[i.name] = {"id" : i.dataset.id, "src" : "ldda"}
+ for k in input_dict:
+ if k in param_dict:
+ del param_dict[k]
+ rval['inputs'] = input_dict
- output_dict = {}
- for i in self.output_datasets:
- if i.dataset is not None:
- output_dict[i.name] = {"hda_id" : i.dataset.id}
- for i in self.output_library_datasets:
- if i.dataset is not None:
- output_dict[i.name] = {"ldda_id" : i.dataset.id}
- rval['outputs'] = output_dict
+ output_dict = {}
+ for i in self.output_datasets:
+ if i.dataset is not None:
+ output_dict[i.name] = {"id" : i.dataset.id, "src" : "hda"}
+ for i in self.output_library_datasets:
+ if i.dataset is not None:
+ output_dict[i.name] = {"id" : i.dataset.id, "src" : "ldda"}
+ rval['outputs'] = output_dict
return rval
diff -r 54defa390a91ec1db34141f97711e673218cde13 -r f4485c8dd5f5392f1cc8a1ed296fb772064f1e10 lib/galaxy/webapps/galaxy/api/jobs.py
--- /dev/null
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -0,0 +1,84 @@
+"""
+API operations on a jobs.
+
+.. seealso:: :class:`galaxy.model.Jobs`
+"""
+
+import pkg_resources
+pkg_resources.require( "Paste" )
+from paste.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPInternalServerError, HTTPException
+
+from sqlalchemy import or_
+
+from galaxy import web
+from galaxy.web import _future_expose_api as expose_api
+from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
+from galaxy.util import string_as_bool, restore_text
+from galaxy.util.sanitize_html import sanitize_html
+from galaxy.web.base.controller import BaseAPIController
+from galaxy.web import url_for
+from galaxy.model.orm import desc
+
+import logging
+log = logging.getLogger( __name__ )
+
+class HistoriesController( BaseAPIController ):
+
+ @web.expose_api
+ def index( self, trans, **kwd ):
+ """
+ index( trans, state=None )
+ * GET /api/jobs:
+ return jobs for current user
+
+ :type state: string or list
+ :param state: limit listing of jobs to those that match one of the included states. If none, all are returned.
+ Valid Galaxy job states include:
+ 'new', 'upload', 'waiting', 'queued', 'running', 'ok', 'error', 'paused', 'deleted', 'deleted_new'
+
+ :rtype: list
+ :returns: list of dictionaries containing summary job information
+ """
+
+ state = kwd.get('state', None)
+ query = trans.sa_session.query(trans.app.model.Job).filter(
+ trans.app.model.Job.user == trans.user )
+ if state is not None:
+ if isinstance(state, basestring):
+ query = query.filter( trans.app.model.Job.state == state )
+ elif isinstance(state, list):
+ t = []
+ for s in state:
+ t.append( trans.app.model.Job.state == s )
+ query = query.filter( or_( *t ) )
+
+ out = []
+ for job in query.order_by(
+ trans.app.model.Job.update_time.desc()
+ ).all():
+ out.append( self.encode_all_ids( trans, job.to_dict('collection'), True) )
+ return out
+
+ @web.expose_api
+ def show( self, trans, id, **kwd ):
+ decoded_job_id = trans.security.decode_id(id)
+ query = trans.sa_session.query(trans.app.model.Job).filter(
+ trans.app.model.Job.user == trans.user,
+ trans.app.model.Job.id == decoded_job_id)
+ job = query.first()
+ if job is None:
+ return None
+ return self.encode_all_ids( trans, job.to_dict('element'), True)
+
+ @expose_api
+ def create( self, trans, payload, **kwd ):
+ error = None
+ if 'tool_id' not in payload:
+ error = "No tool ID"
+
+ tool_id = payload.get('tool_id')
+
+ if error is not None:
+ return { "error" : error }
+
+
diff -r 54defa390a91ec1db34141f97711e673218cde13 -r f4485c8dd5f5392f1cc8a1ed296fb772064f1e10 lib/galaxy/webapps/galaxy/api/tools.py
--- a/lib/galaxy/webapps/galaxy/api/tools.py
+++ b/lib/galaxy/webapps/galaxy/api/tools.py
@@ -78,7 +78,12 @@
# -- Execute tool. --
# Get tool.
- tool = trans.app.toolbox.get_tool( payload[ 'tool_id' ] ) if 'tool_id' in payload else None
+ tool = None
+ if 'tool_id' in payload:
+ tool = trans.app.toolbox.get_tool( payload[ 'tool_id' ] )
+ if 'tool_name' in payload:
+ #in job descriptions it is called 'tool_name' to avoid having the name 'crushed'
+ tool = trans.app.toolbox.get_tool( payload[ 'tool_name' ] )
if not tool:
trans.response.status = 404
return { "message": { "type": "error", "text" : trans.app.model.Dataset.conversion_messages.NO_TOOL } }
diff -r 54defa390a91ec1db34141f97711e673218cde13 -r f4485c8dd5f5392f1cc8a1ed296fb772064f1e10 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -228,6 +228,12 @@
path_prefix='/api/libraries/:library_id',
parent_resources=dict( member_name='library', collection_name='libraries' ) )
+ webapp.mapper.resource( 'job',
+ 'jobs',
+ path_prefix='/api' )
+ #webapp.mapper.connect( 'job_item', '/api/jobs/:job_id', controller='jobs', action='show', conditions=dict( method=['GET'] ) )
+
+
_add_item_extended_metadata_controller( webapp,
name_prefix="library_dataset_",
path_prefix='/api/libraries/:library_id/contents/:library_content_id' )
https://bitbucket.org/galaxy/galaxy-central/commits/f78bab3d44f0/
Changeset: f78bab3d44f0
Branch: job-search
User: Kyle Ellrott
Date: 2014-01-22 23:09:36
Summary: Adding job search method that attempts to find previous tool runs with the same requested inputs and outputs.
Affected #: 2 files
diff -r f4485c8dd5f5392f1cc8a1ed296fb772064f1e10 -r f78bab3d44f00b245beebce45cac2a2287c8f4ce lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -416,8 +416,8 @@
dataset.info = 'Job output deleted by user before job completed'
def to_dict( self, view='collection' ):
rval = super( Job, self ).to_dict( view=view )
+ rval['tool_name'] = self.tool_id
if view == 'element':
- rval['tool_name'] = self.tool_id
param_dict = dict( [ ( p.name, p.value ) for p in self.parameters ] )
rval['params'] = param_dict
diff -r f4485c8dd5f5392f1cc8a1ed296fb772064f1e10 -r f78bab3d44f00b245beebce45cac2a2287c8f4ce lib/galaxy/webapps/galaxy/api/jobs.py
--- a/lib/galaxy/webapps/galaxy/api/jobs.py
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -8,21 +8,22 @@
pkg_resources.require( "Paste" )
from paste.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPInternalServerError, HTTPException
-from sqlalchemy import or_
-
+from sqlalchemy import or_, and_
+from sqlalchemy.orm import aliased
+import json
from galaxy import web
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
from galaxy.util import string_as_bool, restore_text
from galaxy.util.sanitize_html import sanitize_html
-from galaxy.web.base.controller import BaseAPIController
+from galaxy.web.base.controller import BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems
from galaxy.web import url_for
from galaxy.model.orm import desc
import logging
log = logging.getLogger( __name__ )
-class HistoriesController( BaseAPIController ):
+class HistoriesController( BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems ):
@web.expose_api
def index( self, trans, **kwd ):
@@ -61,6 +62,18 @@
@web.expose_api
def show( self, trans, id, **kwd ):
+ """
+ show( trans, id )
+ * GET /api/jobs/{job_id}:
+ return jobs for current user
+
+ :type id: string
+ :param id: Specific job id
+
+ :rtype: dictionary
+ :returns: dictionary containing full description of job data
+ """
+
decoded_job_id = trans.security.decode_id(id)
query = trans.sa_session.query(trans.app.model.Job).filter(
trans.app.model.Job.user == trans.user,
@@ -72,13 +85,100 @@
@expose_api
def create( self, trans, payload, **kwd ):
+ """
+ show( trans, payload )
+ * POST /api/jobs:
+ return jobs for current user
+
+ :type payload: dict
+ :param payload: Dictionary containing description of requested job. This is in the same format as
+ a request to POST /apt/tools would take to initiate a job
+
+ :rtype: list
+ :returns: list of dictionaries containing summary job information of the jobs that match the requested job run
+
+ This method is designed to scan the list of previously run jobs and find records of jobs that had
+ the exact some input parameters and datasets. This can be used to minimize the amount of repeated work, and simply
+ recycle the old results.
+ """
+
error = None
- if 'tool_id' not in payload:
+ tool_id = None
+ if 'tool_id' in payload:
+ tool_id = payload.get('tool_id')
+ if 'tool_name' in payload:
+ tool_id = payload.get('tool_name')
+
+ tool = trans.app.toolbox.get_tool( tool_id )
+ if tool is None:
+ error = "Requested tool not found"
+ if 'inputs' not in payload:
+ error = "No inputs defined"
+ if tool_id is None:
error = "No tool ID"
-
- tool_id = payload.get('tool_id')
-
if error is not None:
return { "error" : error }
+ inputs = payload['inputs']
+ input_data = {}
+ input_param = {}
+ for k, v in inputs.items():
+ if isinstance(v,dict):
+ if 'id' in v:
+ try:
+ if 'src' not in v or v['src'] == 'hda':
+ dataset = self.get_dataset( trans, v['id'], check_ownership=False, check_accessible=True )
+ else:
+ dataset = self.get_library_dataset_dataset_association( trans, v['id'] )
+ except Exception, e:
+ return { "error" : str( e ) }
+ if dataset is None:
+ return { "error" : "Dataset %s not found" % (v['id']) }
+ input_data[k] = dataset.dataset_id
+ else:
+ input_param[k] = json.dumps(v)
+
+ query = trans.sa_session.query( trans.app.model.Job ).filter(
+ trans.app.model.Job.tool_id == tool_id,
+ trans.app.model.Job.user == trans.user
+ ).filter(
+ or_(
+ trans.app.model.Job.state == 'running',
+ trans.app.model.Job.state == 'queued',
+ trans.app.model.Job.state == 'waiting',
+ trans.app.model.Job.state == 'running',
+ trans.app.model.Job.state == 'ok',
+ )
+ )
+
+ for k,v in input_param.items():
+ a = aliased(trans.app.model.JobParameter)
+ query = query.filter( and_(
+ trans.app.model.Job.id == a.job_id,
+ a.name == k,
+ a.value == v
+ ))
+
+ for k,v in input_data.items():
+ """
+ Here we are attempting to link the inputs to the underlying dataset (not the dataset association)
+ This way, if the calulation was done using a copied HDA (copied from the library or another history)
+ the search will still find the job
+ """
+ a = aliased(trans.app.model.JobToInputDatasetAssociation)
+ b = aliased(trans.app.model.HistoryDatasetAssociation)
+ query = query.filter( and_(
+ trans.app.model.Job.id == a.job_id,
+ a.dataset_id == b.id,
+ b.deleted == False,
+ b.dataset_id == v
+ ))
+ out = []
+ for job in query.all():
+ """
+ check to make sure none of the output files have been deleted
+ """
+ if all(list(a.dataset.deleted == False for a in job.output_datasets)):
+ out.append( self.encode_all_ids( trans, job.to_dict('element'), True) )
+ return out
https://bitbucket.org/galaxy/galaxy-central/commits/3284b02d842a/
Changeset: 3284b02d842a
Branch: job-search
User: kellrott
Date: 2014-01-24 21:05:03
Summary: Modified patch behavoir to match comments to pull request
Affected #: 5 files
diff -r f78bab3d44f00b245beebce45cac2a2287c8f4ce -r 3284b02d842a48c92bab4669982231ab0ac3ca98 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -416,7 +416,7 @@
dataset.info = 'Job output deleted by user before job completed'
def to_dict( self, view='collection' ):
rval = super( Job, self ).to_dict( view=view )
- rval['tool_name'] = self.tool_id
+ rval['tool_id'] = self.tool_id
if view == 'element':
param_dict = dict( [ ( p.name, p.value ) for p in self.parameters ] )
rval['params'] = param_dict
diff -r f78bab3d44f00b245beebce45cac2a2287c8f4ce -r 3284b02d842a48c92bab4669982231ab0ac3ca98 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -161,7 +161,7 @@
if type( rval ) != dict:
return rval
for k, v in rval.items():
- if (k == 'id' or k.endswith( '_id' )) and v is not None:
+ if (k == 'id' or k.endswith( '_id' )) and v is not None and k not in ['tool_id']:
try:
rval[k] = trans.security.encode_id( v )
except:
diff -r f78bab3d44f00b245beebce45cac2a2287c8f4ce -r 3284b02d842a48c92bab4669982231ab0ac3ca98 lib/galaxy/webapps/galaxy/api/jobs.py
--- a/lib/galaxy/webapps/galaxy/api/jobs.py
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -23,7 +23,7 @@
import logging
log = logging.getLogger( __name__ )
-class HistoriesController( BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems ):
+class JobController( BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems ):
@web.expose_api
def index( self, trans, **kwd ):
@@ -85,9 +85,13 @@
@expose_api
def create( self, trans, payload, **kwd ):
+ raise NotImplementedError()
+
+ @expose_api
+ def search(self, trans, payload, **kwd):
"""
- show( trans, payload )
- * POST /api/jobs:
+ search( trans, payload )
+ * POST /api/jobs/search:
return jobs for current user
:type payload: dict
@@ -106,8 +110,6 @@
tool_id = None
if 'tool_id' in payload:
tool_id = payload.get('tool_id')
- if 'tool_name' in payload:
- tool_id = payload.get('tool_name')
tool = trans.app.toolbox.get_tool( tool_id )
if tool is None:
@@ -142,15 +144,28 @@
query = trans.sa_session.query( trans.app.model.Job ).filter(
trans.app.model.Job.tool_id == tool_id,
trans.app.model.Job.user == trans.user
- ).filter(
- or_(
- trans.app.model.Job.state == 'running',
- trans.app.model.Job.state == 'queued',
- trans.app.model.Job.state == 'waiting',
- trans.app.model.Job.state == 'running',
- trans.app.model.Job.state == 'ok',
+ )
+
+ if 'state' not in payload:
+ query = query.filter(
+ or_(
+ trans.app.model.Job.state == 'running',
+ trans.app.model.Job.state == 'queued',
+ trans.app.model.Job.state == 'waiting',
+ trans.app.model.Job.state == 'running',
+ trans.app.model.Job.state == 'ok',
+ )
)
- )
+ else:
+ if isinstance(payload['state'], basestring):
+ query = query.filter( trans.app.model.Job.state == payload['state'] )
+ elif isinstance(payload['state'], list):
+ o = []
+ for s in payload['state']:
+ o.append( trans.app.model.Job.state == s )
+ query = query.filter(
+ or_(*o)
+ )
for k,v in input_param.items():
a = aliased(trans.app.model.JobParameter)
diff -r f78bab3d44f00b245beebce45cac2a2287c8f4ce -r 3284b02d842a48c92bab4669982231ab0ac3ca98 lib/galaxy/webapps/galaxy/api/tools.py
--- a/lib/galaxy/webapps/galaxy/api/tools.py
+++ b/lib/galaxy/webapps/galaxy/api/tools.py
@@ -78,12 +78,7 @@
# -- Execute tool. --
# Get tool.
- tool = None
- if 'tool_id' in payload:
- tool = trans.app.toolbox.get_tool( payload[ 'tool_id' ] )
- if 'tool_name' in payload:
- #in job descriptions it is called 'tool_name' to avoid having the name 'crushed'
- tool = trans.app.toolbox.get_tool( payload[ 'tool_name' ] )
+ tool = trans.app.toolbox.get_tool( payload[ 'tool_id' ] ) if 'tool_id' in payload else None
if not tool:
trans.response.status = 404
return { "message": { "type": "error", "text" : trans.app.model.Dataset.conversion_messages.NO_TOOL } }
diff -r f78bab3d44f00b245beebce45cac2a2287c8f4ce -r 3284b02d842a48c92bab4669982231ab0ac3ca98 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -231,7 +231,7 @@
webapp.mapper.resource( 'job',
'jobs',
path_prefix='/api' )
- #webapp.mapper.connect( 'job_item', '/api/jobs/:job_id', controller='jobs', action='show', conditions=dict( method=['GET'] ) )
+ webapp.mapper.connect( 'job_search', '/api/jobs/search', controller='jobs', action='search', conditions=dict( method=['POST'] ) )
_add_item_extended_metadata_controller( webapp,
https://bitbucket.org/galaxy/galaxy-central/commits/558fb7b96b49/
Changeset: 558fb7b96b49
Branch: job-search
User: kellrott
Date: 2014-01-24 22:59:36
Summary: Adding more standard exceptions
Affected #: 1 file
diff -r 3284b02d842a48c92bab4669982231ab0ac3ca98 -r 558fb7b96b49bdcec0321a0c8d50afbf37ff972b lib/galaxy/webapps/galaxy/api/jobs.py
--- a/lib/galaxy/webapps/galaxy/api/jobs.py
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -19,6 +19,7 @@
from galaxy.web.base.controller import BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems
from galaxy.web import url_for
from galaxy.model.orm import desc
+from galaxy import exceptions
import logging
log = logging.getLogger( __name__ )
@@ -73,14 +74,16 @@
:rtype: dictionary
:returns: dictionary containing full description of job data
"""
-
- decoded_job_id = trans.security.decode_id(id)
+ try:
+ decoded_job_id = trans.security.decode_id(id)
+ except:
+ raise exceptions.ObjectAttributeInvalidException()
query = trans.sa_session.query(trans.app.model.Job).filter(
trans.app.model.Job.user == trans.user,
trans.app.model.Job.id == decoded_job_id)
job = query.first()
if job is None:
- return None
+ raise exceptions.ObjectNotFound()
return self.encode_all_ids( trans, job.to_dict('element'), True)
@expose_api
@@ -106,20 +109,17 @@
recycle the old results.
"""
- error = None
tool_id = None
if 'tool_id' in payload:
tool_id = payload.get('tool_id')
+ if tool_id is None:
+ raise exceptions.ObjectAttributeMissingException("No tool id")
tool = trans.app.toolbox.get_tool( tool_id )
if tool is None:
- error = "Requested tool not found"
+ raise exceptions.ObjectNotFound( "Requested tool not found" )
if 'inputs' not in payload:
- error = "No inputs defined"
- if tool_id is None:
- error = "No tool ID"
- if error is not None:
- return { "error" : error }
+ raise exceptions.ObjectAttributeMissingException("No inputs defined")
inputs = payload['inputs']
@@ -136,7 +136,7 @@
except Exception, e:
return { "error" : str( e ) }
if dataset is None:
- return { "error" : "Dataset %s not found" % (v['id']) }
+ raise exceptions.ObjectNotFound("Dataset %s not found" % (v['id']))
input_data[k] = dataset.dataset_id
else:
input_param[k] = json.dumps(v)
https://bitbucket.org/galaxy/galaxy-central/commits/95747eacf09c/
Changeset: 95747eacf09c
Branch: job-search
User: jmchilton
Date: 2014-01-29 06:29:15
Summary: PEP-8 and other style adjustments for new jobs API.
Affected #: 1 file
diff -r 558fb7b96b49bdcec0321a0c8d50afbf37ff972b -r 95747eacf09c21335323131382de433409b86e16 lib/galaxy/webapps/galaxy/api/jobs.py
--- a/lib/galaxy/webapps/galaxy/api/jobs.py
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -4,26 +4,20 @@
.. seealso:: :class:`galaxy.model.Jobs`
"""
-import pkg_resources
-pkg_resources.require( "Paste" )
-from paste.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPInternalServerError, HTTPException
-
from sqlalchemy import or_, and_
from sqlalchemy.orm import aliased
import json
from galaxy import web
from galaxy.web import _future_expose_api as expose_api
-from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
-from galaxy.util import string_as_bool, restore_text
-from galaxy.util.sanitize_html import sanitize_html
-from galaxy.web.base.controller import BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems
-from galaxy.web import url_for
-from galaxy.model.orm import desc
+from galaxy.web.base.controller import BaseAPIController
+from galaxy.web.base.controller import UsesHistoryDatasetAssociationMixin
+from galaxy.web.base.controller import UsesLibraryMixinItems
from galaxy import exceptions
import logging
log = logging.getLogger( __name__ )
+
class JobController( BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems ):
@web.expose_api
@@ -42,13 +36,14 @@
:returns: list of dictionaries containing summary job information
"""
- state = kwd.get('state', None)
- query = trans.sa_session.query(trans.app.model.Job).filter(
- trans.app.model.Job.user == trans.user )
+ state = kwd.get( 'state', None )
+ query = trans.sa_session.query( trans.app.model.Job ).filter(
+ trans.app.model.Job.user == trans.user
+ )
if state is not None:
- if isinstance(state, basestring):
+ if isinstance( state, basestring ):
query = query.filter( trans.app.model.Job.state == state )
- elif isinstance(state, list):
+ elif isinstance( state, list ):
t = []
for s in state:
t.append( trans.app.model.Job.state == s )
@@ -58,7 +53,7 @@
for job in query.order_by(
trans.app.model.Job.update_time.desc()
).all():
- out.append( self.encode_all_ids( trans, job.to_dict('collection'), True) )
+ out.append( self.encode_all_ids( trans, job.to_dict( 'collection' ), True ) )
return out
@web.expose_api
@@ -78,20 +73,21 @@
decoded_job_id = trans.security.decode_id(id)
except:
raise exceptions.ObjectAttributeInvalidException()
- query = trans.sa_session.query(trans.app.model.Job).filter(
+ query = trans.sa_session.query( trans.app.model.Job ).filter(
trans.app.model.Job.user == trans.user,
- trans.app.model.Job.id == decoded_job_id)
+ trans.app.model.Job.id == decoded_job_id
+ )
job = query.first()
if job is None:
raise exceptions.ObjectNotFound()
- return self.encode_all_ids( trans, job.to_dict('element'), True)
+ return self.encode_all_ids( trans, job.to_dict( 'element' ), True )
@expose_api
def create( self, trans, payload, **kwd ):
raise NotImplementedError()
@expose_api
- def search(self, trans, payload, **kwd):
+ def search( self, trans, payload, **kwd ):
"""
search( trans, payload )
* POST /api/jobs/search:
@@ -104,96 +100,97 @@
:rtype: list
:returns: list of dictionaries containing summary job information of the jobs that match the requested job run
- This method is designed to scan the list of previously run jobs and find records of jobs that had
- the exact some input parameters and datasets. This can be used to minimize the amount of repeated work, and simply
+ This method is designed to scan the list of previously run jobs and find records of jobs that had
+ the exact some input parameters and datasets. This can be used to minimize the amount of repeated work, and simply
recycle the old results.
"""
tool_id = None
if 'tool_id' in payload:
- tool_id = payload.get('tool_id')
+ tool_id = payload.get( 'tool_id' )
if tool_id is None:
- raise exceptions.ObjectAttributeMissingException("No tool id")
+ raise exceptions.ObjectAttributeMissingException( "No tool id" )
tool = trans.app.toolbox.get_tool( tool_id )
if tool is None:
raise exceptions.ObjectNotFound( "Requested tool not found" )
if 'inputs' not in payload:
- raise exceptions.ObjectAttributeMissingException("No inputs defined")
+ raise exceptions.ObjectAttributeMissingException( "No inputs defined" )
- inputs = payload['inputs']
+ inputs = payload[ 'inputs' ]
input_data = {}
input_param = {}
for k, v in inputs.items():
- if isinstance(v,dict):
+ if isinstance( v, dict ):
if 'id' in v:
try:
- if 'src' not in v or v['src'] == 'hda':
+ if 'src' not in v or v[ 'src' ] == 'hda':
dataset = self.get_dataset( trans, v['id'], check_ownership=False, check_accessible=True )
else:
dataset = self.get_library_dataset_dataset_association( trans, v['id'] )
except Exception, e:
return { "error" : str( e ) }
if dataset is None:
- raise exceptions.ObjectNotFound("Dataset %s not found" % (v['id']))
+ raise exceptions.ObjectNotFound( "Dataset %s not found" % ( v[ 'id' ] ) )
input_data[k] = dataset.dataset_id
else:
- input_param[k] = json.dumps(v)
+ input_param[k] = json.dumps( v )
- query = trans.sa_session.query( trans.app.model.Job ).filter(
- trans.app.model.Job.tool_id == tool_id,
+ query = trans.sa_session.query( trans.app.model.Job ).filter(
+ trans.app.model.Job.tool_id == tool_id,
trans.app.model.Job.user == trans.user
)
if 'state' not in payload:
query = query.filter(
- or_(
- trans.app.model.Job.state == 'running',
- trans.app.model.Job.state == 'queued',
- trans.app.model.Job.state == 'waiting',
+ or_(
trans.app.model.Job.state == 'running',
- trans.app.model.Job.state == 'ok',
+ trans.app.model.Job.state == 'queued',
+ trans.app.model.Job.state == 'waiting',
+ trans.app.model.Job.state == 'running',
+ trans.app.model.Job.state == 'ok',
)
)
else:
- if isinstance(payload['state'], basestring):
- query = query.filter( trans.app.model.Job.state == payload['state'] )
- elif isinstance(payload['state'], list):
+ if isinstance( payload[ 'state' ], basestring ):
+ query = query.filter( trans.app.model.Job.state == payload[ 'state' ] )
+ elif isinstance( payload[ 'state' ], list ):
o = []
- for s in payload['state']:
+ for s in payload[ 'state' ]:
o.append( trans.app.model.Job.state == s )
query = query.filter(
- or_(*o)
+ or_( *o )
)
- for k,v in input_param.items():
- a = aliased(trans.app.model.JobParameter)
+ for k, v in input_param.items():
+ a = aliased( trans.app.model.JobParameter )
query = query.filter( and_(
trans.app.model.Job.id == a.job_id,
a.name == k,
a.value == v
- ))
+ ) )
- for k,v in input_data.items():
+ for k, v in input_data.items():
"""
Here we are attempting to link the inputs to the underlying dataset (not the dataset association)
This way, if the calulation was done using a copied HDA (copied from the library or another history)
the search will still find the job
"""
- a = aliased(trans.app.model.JobToInputDatasetAssociation)
- b = aliased(trans.app.model.HistoryDatasetAssociation)
+ a = aliased( trans.app.model.JobToInputDatasetAssociation )
+ b = aliased( trans.app.model.HistoryDatasetAssociation )
query = query.filter( and_(
trans.app.model.Job.id == a.job_id,
a.dataset_id == b.id,
b.deleted == False,
b.dataset_id == v
- ))
+ ) )
+
out = []
for job in query.all():
"""
check to make sure none of the output files have been deleted
"""
- if all(list(a.dataset.deleted == False for a in job.output_datasets)):
- out.append( self.encode_all_ids( trans, job.to_dict('element'), True) )
+ if all( list( a.dataset.deleted == False for a in job.output_datasets ) ):
+ out.append( self.encode_all_ids( trans, job.to_dict( 'element' ), True ) )
return out
https://bitbucket.org/galaxy/galaxy-central/commits/e20e9d60eb80/
Changeset: e20e9d60eb80
Branch: job-search
User: jmchilton
Date: 2014-01-29 06:34:04
Summary: Tweak Jobs API to only use new style API decorator, exception handling.
Affected #: 1 file
diff -r 95747eacf09c21335323131382de433409b86e16 -r e20e9d60eb8017a241976912bfceb30dd316b20e lib/galaxy/webapps/galaxy/api/jobs.py
--- a/lib/galaxy/webapps/galaxy/api/jobs.py
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -7,7 +7,6 @@
from sqlalchemy import or_, and_
from sqlalchemy.orm import aliased
import json
-from galaxy import web
from galaxy.web import _future_expose_api as expose_api
from galaxy.web.base.controller import BaseAPIController
from galaxy.web.base.controller import UsesHistoryDatasetAssociationMixin
@@ -20,7 +19,7 @@
class JobController( BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems ):
- @web.expose_api
+ @expose_api
def index( self, trans, **kwd ):
"""
index( trans, state=None )
@@ -56,7 +55,7 @@
out.append( self.encode_all_ids( trans, job.to_dict( 'collection' ), True ) )
return out
- @web.expose_api
+ @expose_api
def show( self, trans, id, **kwd ):
"""
show( trans, id )
@@ -124,13 +123,10 @@
for k, v in inputs.items():
if isinstance( v, dict ):
if 'id' in v:
- try:
- if 'src' not in v or v[ 'src' ] == 'hda':
- dataset = self.get_dataset( trans, v['id'], check_ownership=False, check_accessible=True )
- else:
- dataset = self.get_library_dataset_dataset_association( trans, v['id'] )
- except Exception, e:
- return { "error" : str( e ) }
+ if 'src' not in v or v[ 'src' ] == 'hda':
+ dataset = self.get_dataset( trans, v['id'], check_ownership=False, check_accessible=True )
+ else:
+ dataset = self.get_library_dataset_dataset_association( trans, v['id'] )
if dataset is None:
raise exceptions.ObjectNotFound( "Dataset %s not found" % ( v[ 'id' ] ) )
input_data[k] = dataset.dataset_id
https://bitbucket.org/galaxy/galaxy-central/commits/8d408c81c6c4/
Changeset: 8d408c81c6c4
Branch: job-search
User: jmchilton
Date: 2014-01-29 06:34:29
Summary: Add functional tests for new jobs API.
Affected #: 1 file
diff -r e20e9d60eb8017a241976912bfceb30dd316b20e -r 8d408c81c6c4abafce7461cab6c5e4b677e238d5 test/functional/api/test_jobs.py
--- /dev/null
+++ b/test/functional/api/test_jobs.py
@@ -0,0 +1,118 @@
+import json
+from operator import itemgetter
+
+from base import api
+
+from .helpers import TestsDatasets
+
+
+class JobsApiTestCase( api.ApiTestCase, TestsDatasets ):
+
+ def test_index( self ):
+ # Create HDA to ensure at least one job exists...
+ self.__history_with_new_dataset()
+ jobs_response = self._get( "jobs" )
+
+ self._assert_status_code_is( jobs_response, 200 )
+
+ jobs = jobs_response.json()
+ assert isinstance( jobs, list )
+ assert "upload1" in map( itemgetter( "tool_id" ), jobs )
+
+ def test_index_state_filter( self ):
+ # Initial number of ok jobs
+ original_count = len( self.__uploads_with_state( "ok" ) )
+
+ # Run through dataset upload to ensure num uplaods at least greater
+ # by 1.
+ self.__history_with_ok_dataset()
+
+ # Verify number of ok jobs is actually greater.
+ new_count = len( self.__uploads_with_state( "ok" ) )
+ assert original_count < new_count
+
+ def test_index_multiple_states_filter( self ):
+ # Initial number of ok jobs
+ original_count = len( self.__uploads_with_state( "ok", "new" ) )
+
+ # Run through dataset upload to ensure num uplaods at least greater
+ # by 1.
+ self.__history_with_ok_dataset()
+
+ # Verify number of ok jobs is actually greater.
+ new_count = len( self.__uploads_with_state( "new", "ok" ) )
+ assert original_count < new_count, new_count
+
+ def test_show( self ):
+ # Create HDA to ensure at least one job exists...
+ self.__history_with_new_dataset()
+
+ jobs_response = self._get( "jobs" )
+ first_job = jobs_response.json()[ 0 ]
+ self._assert_has_key( first_job, 'id', 'state', 'exit_code', 'update_time', 'create_time' )
+
+ job_id = first_job[ "id" ]
+ show_jobs_response = self._get( "jobs/%s" % job_id )
+ self._assert_status_code_is( show_jobs_response, 200 )
+
+ job_details = show_jobs_response.json()
+ self._assert_has_key( job_details, 'id', 'state', 'exit_code', 'update_time', 'create_time' )
+
+ def test_search( self ):
+ history_id, dataset_id = self.__history_with_ok_dataset()
+
+ inputs = json.dumps(
+ dict(
+ input1=dict(
+ src='hda',
+ id=dataset_id,
+ )
+ )
+ )
+ search_payload = dict(
+ tool_id="cat1",
+ inputs=inputs,
+ state="ok",
+ )
+
+ empty_search_response = self._post( "jobs/search", data=search_payload )
+ self._assert_status_code_is( empty_search_response, 200 )
+ assert len( empty_search_response.json() ) == 0
+
+ self.__run_cat_tool( history_id, dataset_id )
+ self._wait_for_history( history_id, assert_ok=True )
+
+ search_response = self._post( "jobs/search", data=search_payload )
+ self._assert_status_code_is( empty_search_response, 200 )
+ assert len( search_response.json() ) == 1, search_response.json()
+
+ def __run_cat_tool( self, history_id, dataset_id ):
+ # Code duplication with test_jobs.py, eliminate
+ payload = self._run_tool_payload(
+ tool_id='cat1',
+ inputs=dict(
+ input1=dict(
+ src='hda',
+ id=dataset_id
+ ),
+ ),
+ history_id=history_id,
+ )
+ self._post( "tools", data=payload )
+
+ def __uploads_with_state( self, *states ):
+ jobs_response = self._get( "jobs", data=dict( state=states ) )
+ self._assert_status_code_is( jobs_response, 200 )
+ jobs = jobs_response.json()
+ assert not filter( lambda j: j[ "state" ] not in states, jobs )
+ return filter( lambda j: j[ "tool_id" ] == "upload1", jobs )
+
+ def __history_with_new_dataset( self ):
+ history_id = self._new_history()
+ dataset_id = self._new_dataset( history_id )[ "id" ]
+ return history_id, dataset_id
+
+ def __history_with_ok_dataset( self ):
+ history_id, dataset_id = self.__history_with_new_dataset()
+ self._wait_for_history( history_id, assert_ok=True )
+ return history_id, dataset_id
https://bitbucket.org/galaxy/galaxy-central/commits/6d8959c8866c/
Changeset: 6d8959c8866c
User: jmchilton
Date: 2014-01-29 06:57:46
Summary: Merge job-search branch.
Affected #: 6 files
diff -r d3bc7ea60b05f3025de3dca2684f1bce0be2c0eb -r 6d8959c8866c699ee0e9461db2a1fcc0381bfac2 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -211,8 +211,8 @@
class Job( object, Dictifiable ):
- dict_collection_visible_keys = [ 'id', 'state', 'exit_code' ]
- dict_element_visible_keys = [ 'id', 'state', 'exit_code' ]
+ dict_collection_visible_keys = [ 'id', 'state', 'exit_code', 'update_time', 'create_time' ]
+ dict_element_visible_keys = [ 'id', 'state', 'exit_code', 'update_time', 'create_time' ]
"""
A job represents a request to run a tool given input datasets, tool
@@ -418,30 +418,31 @@
dataset.info = 'Job output deleted by user before job completed'
def to_dict( self, view='collection' ):
rval = super( Job, self ).to_dict( view=view )
- rval['tool_name'] = self.tool_id
- param_dict = dict( [ ( p.name, p.value ) for p in self.parameters ] )
- rval['params'] = param_dict
+ rval['tool_id'] = self.tool_id
+ if view == 'element':
+ param_dict = dict( [ ( p.name, p.value ) for p in self.parameters ] )
+ rval['params'] = param_dict
- input_dict = {}
- for i in self.input_datasets:
- if i.dataset is not None:
- input_dict[i.name] = {"hda_id" : i.dataset.id}
- for i in self.input_library_datasets:
- if i.dataset is not None:
- input_dict[i.name] = {"ldda_id" : i.dataset.id}
- for k in input_dict:
- if k in param_dict:
- del param_dict[k]
- rval['inputs'] = input_dict
+ input_dict = {}
+ for i in self.input_datasets:
+ if i.dataset is not None:
+ input_dict[i.name] = {"id" : i.dataset.id, "src" : "hda"}
+ for i in self.input_library_datasets:
+ if i.dataset is not None:
+ input_dict[i.name] = {"id" : i.dataset.id, "src" : "ldda"}
+ for k in input_dict:
+ if k in param_dict:
+ del param_dict[k]
+ rval['inputs'] = input_dict
- output_dict = {}
- for i in self.output_datasets:
- if i.dataset is not None:
- output_dict[i.name] = {"hda_id" : i.dataset.id}
- for i in self.output_library_datasets:
- if i.dataset is not None:
- output_dict[i.name] = {"ldda_id" : i.dataset.id}
- rval['outputs'] = output_dict
+ output_dict = {}
+ for i in self.output_datasets:
+ if i.dataset is not None:
+ output_dict[i.name] = {"id" : i.dataset.id, "src" : "hda"}
+ for i in self.output_library_datasets:
+ if i.dataset is not None:
+ output_dict[i.name] = {"id" : i.dataset.id, "src" : "ldda"}
+ rval['outputs'] = output_dict
return rval
diff -r d3bc7ea60b05f3025de3dca2684f1bce0be2c0eb -r 6d8959c8866c699ee0e9461db2a1fcc0381bfac2 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -160,7 +160,7 @@
if type( rval ) != dict:
return rval
for k, v in rval.items():
- if (k == 'id' or k.endswith( '_id' )) and v is not None:
+ if (k == 'id' or k.endswith( '_id' )) and v is not None and k not in ['tool_id']:
try:
rval[k] = trans.security.encode_id( v )
except:
diff -r d3bc7ea60b05f3025de3dca2684f1bce0be2c0eb -r 6d8959c8866c699ee0e9461db2a1fcc0381bfac2 lib/galaxy/webapps/galaxy/api/jobs.py
--- /dev/null
+++ b/lib/galaxy/webapps/galaxy/api/jobs.py
@@ -0,0 +1,192 @@
+"""
+API operations on a jobs.
+
+.. seealso:: :class:`galaxy.model.Jobs`
+"""
+
+from sqlalchemy import or_, and_
+from sqlalchemy.orm import aliased
+import json
+from galaxy.web import _future_expose_api as expose_api
+from galaxy.web.base.controller import BaseAPIController
+from galaxy.web.base.controller import UsesHistoryDatasetAssociationMixin
+from galaxy.web.base.controller import UsesLibraryMixinItems
+from galaxy import exceptions
+
+import logging
+log = logging.getLogger( __name__ )
+
+
+class JobController( BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesLibraryMixinItems ):
+
+ @expose_api
+ def index( self, trans, **kwd ):
+ """
+ index( trans, state=None )
+ * GET /api/jobs:
+ return jobs for current user
+
+ :type state: string or list
+ :param state: limit listing of jobs to those that match one of the included states. If none, all are returned.
+ Valid Galaxy job states include:
+ 'new', 'upload', 'waiting', 'queued', 'running', 'ok', 'error', 'paused', 'deleted', 'deleted_new'
+
+ :rtype: list
+ :returns: list of dictionaries containing summary job information
+ """
+
+ state = kwd.get( 'state', None )
+ query = trans.sa_session.query( trans.app.model.Job ).filter(
+ trans.app.model.Job.user == trans.user
+ )
+ if state is not None:
+ if isinstance( state, basestring ):
+ query = query.filter( trans.app.model.Job.state == state )
+ elif isinstance( state, list ):
+ t = []
+ for s in state:
+ t.append( trans.app.model.Job.state == s )
+ query = query.filter( or_( *t ) )
+
+ out = []
+ for job in query.order_by(
+ trans.app.model.Job.update_time.desc()
+ ).all():
+ out.append( self.encode_all_ids( trans, job.to_dict( 'collection' ), True ) )
+ return out
+
+ @expose_api
+ def show( self, trans, id, **kwd ):
+ """
+ show( trans, id )
+ * GET /api/jobs/{job_id}:
+ return jobs for current user
+
+ :type id: string
+ :param id: Specific job id
+
+ :rtype: dictionary
+ :returns: dictionary containing full description of job data
+ """
+ try:
+ decoded_job_id = trans.security.decode_id(id)
+ except:
+ raise exceptions.ObjectAttributeInvalidException()
+ query = trans.sa_session.query( trans.app.model.Job ).filter(
+ trans.app.model.Job.user == trans.user,
+ trans.app.model.Job.id == decoded_job_id
+ )
+ job = query.first()
+ if job is None:
+ raise exceptions.ObjectNotFound()
+ return self.encode_all_ids( trans, job.to_dict( 'element' ), True )
+
+ @expose_api
+ def create( self, trans, payload, **kwd ):
+ raise NotImplementedError()
+
+ @expose_api
+ def search( self, trans, payload, **kwd ):
+ """
+ search( trans, payload )
+ * POST /api/jobs/search:
+ return jobs for current user
+
+ :type payload: dict
+ :param payload: Dictionary containing description of requested job. This is in the same format as
+ a request to POST /apt/tools would take to initiate a job
+
+ :rtype: list
+ :returns: list of dictionaries containing summary job information of the jobs that match the requested job run
+
+ This method is designed to scan the list of previously run jobs and find records of jobs that had
+ the exact some input parameters and datasets. This can be used to minimize the amount of repeated work, and simply
+ recycle the old results.
+ """
+
+ tool_id = None
+ if 'tool_id' in payload:
+ tool_id = payload.get( 'tool_id' )
+ if tool_id is None:
+ raise exceptions.ObjectAttributeMissingException( "No tool id" )
+
+ tool = trans.app.toolbox.get_tool( tool_id )
+ if tool is None:
+ raise exceptions.ObjectNotFound( "Requested tool not found" )
+ if 'inputs' not in payload:
+ raise exceptions.ObjectAttributeMissingException( "No inputs defined" )
+
+ inputs = payload[ 'inputs' ]
+
+ input_data = {}
+ input_param = {}
+ for k, v in inputs.items():
+ if isinstance( v, dict ):
+ if 'id' in v:
+ if 'src' not in v or v[ 'src' ] == 'hda':
+ dataset = self.get_dataset( trans, v['id'], check_ownership=False, check_accessible=True )
+ else:
+ dataset = self.get_library_dataset_dataset_association( trans, v['id'] )
+ if dataset is None:
+ raise exceptions.ObjectNotFound( "Dataset %s not found" % ( v[ 'id' ] ) )
+ input_data[k] = dataset.dataset_id
+ else:
+ input_param[k] = json.dumps( v )
+
+ query = trans.sa_session.query( trans.app.model.Job ).filter(
+ trans.app.model.Job.tool_id == tool_id,
+ trans.app.model.Job.user == trans.user
+ )
+
+ if 'state' not in payload:
+ query = query.filter(
+ or_(
+ trans.app.model.Job.state == 'running',
+ trans.app.model.Job.state == 'queued',
+ trans.app.model.Job.state == 'waiting',
+ trans.app.model.Job.state == 'running',
+ trans.app.model.Job.state == 'ok',
+ )
+ )
+ else:
+ if isinstance( payload[ 'state' ], basestring ):
+ query = query.filter( trans.app.model.Job.state == payload[ 'state' ] )
+ elif isinstance( payload[ 'state' ], list ):
+ o = []
+ for s in payload[ 'state' ]:
+ o.append( trans.app.model.Job.state == s )
+ query = query.filter(
+ or_( *o )
+ )
+
+ for k, v in input_param.items():
+ a = aliased( trans.app.model.JobParameter )
+ query = query.filter( and_(
+ trans.app.model.Job.id == a.job_id,
+ a.name == k,
+ a.value == v
+ ) )
+
+ for k, v in input_data.items():
+ """
+ Here we are attempting to link the inputs to the underlying dataset (not the dataset association)
+ This way, if the calulation was done using a copied HDA (copied from the library or another history)
+ the search will still find the job
+ """
+ a = aliased( trans.app.model.JobToInputDatasetAssociation )
+ b = aliased( trans.app.model.HistoryDatasetAssociation )
+ query = query.filter( and_(
+ trans.app.model.Job.id == a.job_id,
+ a.dataset_id == b.id,
+ b.deleted == False,
+ b.dataset_id == v
+ ) )
+
+ out = []
+ for job in query.all():
+ """
+ check to make sure none of the output files have been deleted
+ """
+ if all( list( a.dataset.deleted == False for a in job.output_datasets ) ):
+ out.append( self.encode_all_ids( trans, job.to_dict( 'element' ), True ) )
+ return out
diff -r d3bc7ea60b05f3025de3dca2684f1bce0be2c0eb -r 6d8959c8866c699ee0e9461db2a1fcc0381bfac2 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -228,6 +228,12 @@
path_prefix='/api/libraries/:library_id',
parent_resources=dict( member_name='library', collection_name='libraries' ) )
+ webapp.mapper.resource( 'job',
+ 'jobs',
+ path_prefix='/api' )
+ webapp.mapper.connect( 'job_search', '/api/jobs/search', controller='jobs', action='search', conditions=dict( method=['POST'] ) )
+
+
_add_item_extended_metadata_controller( webapp,
name_prefix="library_dataset_",
path_prefix='/api/libraries/:library_id/contents/:library_content_id' )
diff -r d3bc7ea60b05f3025de3dca2684f1bce0be2c0eb -r 6d8959c8866c699ee0e9461db2a1fcc0381bfac2 test/functional/api/test_jobs.py
--- /dev/null
+++ b/test/functional/api/test_jobs.py
@@ -0,0 +1,118 @@
+import json
+from operator import itemgetter
+
+from base import api
+
+from .helpers import TestsDatasets
+
+
+class JobsApiTestCase( api.ApiTestCase, TestsDatasets ):
+
+ def test_index( self ):
+ # Create HDA to ensure at least one job exists...
+ self.__history_with_new_dataset()
+ jobs_response = self._get( "jobs" )
+
+ self._assert_status_code_is( jobs_response, 200 )
+
+ jobs = jobs_response.json()
+ assert isinstance( jobs, list )
+ assert "upload1" in map( itemgetter( "tool_id" ), jobs )
+
+ def test_index_state_filter( self ):
+ # Initial number of ok jobs
+ original_count = len( self.__uploads_with_state( "ok" ) )
+
+ # Run through dataset upload to ensure num uplaods at least greater
+ # by 1.
+ self.__history_with_ok_dataset()
+
+ # Verify number of ok jobs is actually greater.
+ new_count = len( self.__uploads_with_state( "ok" ) )
+ assert original_count < new_count
+
+ def test_index_multiple_states_filter( self ):
+ # Initial number of ok jobs
+ original_count = len( self.__uploads_with_state( "ok", "new" ) )
+
+ # Run through dataset upload to ensure num uplaods at least greater
+ # by 1.
+ self.__history_with_ok_dataset()
+
+ # Verify number of ok jobs is actually greater.
+ new_count = len( self.__uploads_with_state( "new", "ok" ) )
+ assert original_count < new_count, new_count
+
+ def test_show( self ):
+ # Create HDA to ensure at least one job exists...
+ self.__history_with_new_dataset()
+
+ jobs_response = self._get( "jobs" )
+ first_job = jobs_response.json()[ 0 ]
+ self._assert_has_key( first_job, 'id', 'state', 'exit_code', 'update_time', 'create_time' )
+
+ job_id = first_job[ "id" ]
+ show_jobs_response = self._get( "jobs/%s" % job_id )
+ self._assert_status_code_is( show_jobs_response, 200 )
+
+ job_details = show_jobs_response.json()
+ self._assert_has_key( job_details, 'id', 'state', 'exit_code', 'update_time', 'create_time' )
+
+ def test_search( self ):
+ history_id, dataset_id = self.__history_with_ok_dataset()
+
+ inputs = json.dumps(
+ dict(
+ input1=dict(
+ src='hda',
+ id=dataset_id,
+ )
+ )
+ )
+ search_payload = dict(
+ tool_id="cat1",
+ inputs=inputs,
+ state="ok",
+ )
+
+ empty_search_response = self._post( "jobs/search", data=search_payload )
+ self._assert_status_code_is( empty_search_response, 200 )
+ assert len( empty_search_response.json() ) == 0
+
+ self.__run_cat_tool( history_id, dataset_id )
+ self._wait_for_history( history_id, assert_ok=True )
+
+ search_response = self._post( "jobs/search", data=search_payload )
+ self._assert_status_code_is( empty_search_response, 200 )
+ assert len( search_response.json() ) == 1, search_response.json()
+
+ def __run_cat_tool( self, history_id, dataset_id ):
+ # Code duplication with test_jobs.py, eliminate
+ payload = self._run_tool_payload(
+ tool_id='cat1',
+ inputs=dict(
+ input1=dict(
+ src='hda',
+ id=dataset_id
+ ),
+ ),
+ history_id=history_id,
+ )
+ self._post( "tools", data=payload )
+
+ def __uploads_with_state( self, *states ):
+ jobs_response = self._get( "jobs", data=dict( state=states ) )
+ self._assert_status_code_is( jobs_response, 200 )
+ jobs = jobs_response.json()
+ assert not filter( lambda j: j[ "state" ] not in states, jobs )
+ return filter( lambda j: j[ "tool_id" ] == "upload1", jobs )
+
+ def __history_with_new_dataset( self ):
+ history_id = self._new_history()
+ dataset_id = self._new_dataset( history_id )[ "id" ]
+ return history_id, dataset_id
+
+ def __history_with_ok_dataset( self ):
+ history_id, dataset_id = self.__history_with_new_dataset()
+ self._wait_for_history( history_id, assert_ok=True )
+ return history_id, dataset_id
https://bitbucket.org/galaxy/galaxy-central/commits/1dd912d65cfb/
Changeset: 1dd912d65cfb
Branch: job-search
User: jmchilton
Date: 2014-01-29 06:58:04
Summary: Close branch job-search.
Affected #: 0 files
https://bitbucket.org/galaxy/galaxy-central/commits/60203bad003c/
Changeset: 60203bad003c
User: jmchilton
Date: 2014-01-29 07:05:15
Summary: Merge.
Affected #: 3 files
diff -r 6d8959c8866c699ee0e9461db2a1fcc0381bfac2 -r 60203bad003cc6b4bc054500248e5a69cbe9b8bc lib/galaxy/tools/imp_exp/__init__.py
--- a/lib/galaxy/tools/imp_exp/__init__.py
+++ b/lib/galaxy/tools/imp_exp/__init__.py
@@ -1,4 +1,8 @@
-import os, shutil, logging, tempfile, json
+import os
+import shutil
+import logging
+import tempfile
+import json
from galaxy import model
from galaxy.tools.parameters.basic import UnvalidatedValue
from galaxy.web.framework.helpers import to_unicode
@@ -8,6 +12,7 @@
log = logging.getLogger(__name__)
+
def load_history_imp_exp_tools( toolbox ):
""" Adds tools for importing/exporting histories to archives. """
# Use same process as that used in load_external_metadata_tool; see that
@@ -42,6 +47,7 @@
toolbox.tools_by_id[ history_imp_tool.id ] = history_imp_tool
log.debug( "Loaded history import tool: %s", history_imp_tool.id )
+
class JobImportHistoryArchiveWrapper( object, UsesHistoryMixin, UsesAnnotations ):
"""
Class provides support for performing jobs that import a history from
@@ -144,23 +150,23 @@
metadata = dataset_attrs['metadata']
# Create dataset and HDA.
- hda = model.HistoryDatasetAssociation( name = dataset_attrs['name'].encode( 'utf-8' ),
- extension = dataset_attrs['extension'],
- info = dataset_attrs['info'].encode( 'utf-8' ),
- blurb = dataset_attrs['blurb'],
- peek = dataset_attrs['peek'],
- designation = dataset_attrs['designation'],
- visible = dataset_attrs['visible'],
- dbkey = metadata['dbkey'],
- metadata = metadata,
- history = new_history,
- create_dataset = True,
- sa_session = self.sa_session )
+ hda = model.HistoryDatasetAssociation( name=dataset_attrs['name'].encode( 'utf-8' ),
+ extension=dataset_attrs['extension'],
+ info=dataset_attrs['info'].encode( 'utf-8' ),
+ blurb=dataset_attrs['blurb'],
+ peek=dataset_attrs['peek'],
+ designation=dataset_attrs['designation'],
+ visible=dataset_attrs['visible'],
+ dbkey=metadata['dbkey'],
+ metadata=metadata,
+ history=new_history,
+ create_dataset=True,
+ sa_session=self.sa_session )
hda.state = hda.states.OK
self.sa_session.add( hda )
self.sa_session.flush()
- new_history.add_dataset( hda, genome_build = None )
- hda.hid = dataset_attrs['hid'] # Overwrite default hid set when HDA added to history.
+ new_history.add_dataset( hda, genome_build=None )
+ hda.hid = dataset_attrs['hid'] # Overwrite default hid set when HDA added to history.
# TODO: Is there a way to recover permissions? Is this needed?
#permissions = trans.app.security_agent.history_get_default_permissions( new_history )
#trans.app.security_agent.set_all_dataset_permissions( hda.dataset, permissions )
@@ -273,6 +279,7 @@
jiha.job.stderr += "Error cleaning up history import job: %s" % e
self.sa_session.flush()
+
class JobExportHistoryArchiveWrapper( object, UsesHistoryMixin, UsesAnnotations ):
"""
Class provides support for performing jobs that export a history to an
@@ -317,23 +324,23 @@
""" Encode an HDA, default encoding for everything else. """
if isinstance( obj, trans.app.model.HistoryDatasetAssociation ):
return {
- "__HistoryDatasetAssociation__" : True,
- "create_time" : obj.create_time.__str__(),
- "update_time" : obj.update_time.__str__(),
- "hid" : obj.hid,
- "name" : to_unicode( obj.name ),
- "info" : to_unicode( obj.info ),
- "blurb" : obj.blurb,
- "peek" : obj.peek,
- "extension" : obj.extension,
- "metadata" : prepare_metadata( dict( obj.metadata.items() ) ),
- "parent_id" : obj.parent_id,
- "designation" : obj.designation,
- "deleted" : obj.deleted,
- "visible" : obj.visible,
- "file_name" : obj.file_name,
- "annotation" : to_unicode( getattr( obj, 'annotation', '' ) ),
- "tags" : get_item_tag_dict( obj ),
+ "__HistoryDatasetAssociation__": True,
+ "create_time": obj.create_time.__str__(),
+ "update_time": obj.update_time.__str__(),
+ "hid": obj.hid,
+ "name": to_unicode( obj.name ),
+ "info": to_unicode( obj.info ),
+ "blurb": obj.blurb,
+ "peek": obj.peek,
+ "extension": obj.extension,
+ "metadata": prepare_metadata( dict( obj.metadata.items() ) ),
+ "parent_id": obj.parent_id,
+ "designation": obj.designation,
+ "deleted": obj.deleted,
+ "visible": obj.visible,
+ "file_name": obj.file_name,
+ "annotation": to_unicode( getattr( obj, 'annotation', '' ) ),
+ "tags": get_item_tag_dict( obj ),
}
if isinstance( obj, UnvalidatedValue ):
return obj.__str__()
@@ -347,15 +354,15 @@
# Write history attributes to file.
history = jeha.history
history_attrs = {
- "create_time" : history.create_time.__str__(),
- "update_time" : history.update_time.__str__(),
- "name" : to_unicode( history.name ),
- "hid_counter" : history.hid_counter,
- "genome_build" : history.genome_build,
- "annotation" : to_unicode( self.get_item_annotation_str( trans.sa_session, history.user, history ) ),
- "tags" : get_item_tag_dict( history ),
- "includes_hidden_datasets" : include_hidden,
- "includes_deleted_datasets" : include_deleted
+ "create_time": history.create_time.__str__(),
+ "update_time": history.update_time.__str__(),
+ "name": to_unicode( history.name ),
+ "hid_counter": history.hid_counter,
+ "genome_build": history.genome_build,
+ "annotation": to_unicode( self.get_item_annotation_str( trans.sa_session, history.user, history ) ),
+ "tags": get_item_tag_dict( history ),
+ "includes_hidden_datasets": include_hidden,
+ "includes_deleted_datasets": include_deleted
}
history_attrs_filename = tempfile.NamedTemporaryFile( dir=temp_output_dir ).name
history_attrs_out = open( history_attrs_filename, 'w' )
@@ -391,7 +398,7 @@
# Get the associated job, if any. If this hda was copied from another,
# we need to find the job that created the origial hda
job_hda = hda
- while job_hda.copied_from_history_dataset_association: #should this check library datasets as well?
+ while job_hda.copied_from_history_dataset_association: # should this check library datasets as well?
job_hda = job_hda.copied_from_history_dataset_association
if not job_hda.creating_job_associations:
# No viable HDA found.
@@ -472,4 +479,3 @@
shutil.rmtree( temp_dir )
except Exception, e:
log.debug( 'Error deleting directory containing attribute files (%s): %s' % ( temp_dir, e ) )
-
diff -r 6d8959c8866c699ee0e9461db2a1fcc0381bfac2 -r 60203bad003cc6b4bc054500248e5a69cbe9b8bc lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
--- a/lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
+++ b/lib/galaxy/tools/imp_exp/unpack_tar_gz_archive.py
@@ -6,19 +6,25 @@
--[url|file] source type, either a URL or a file.
"""
-import sys, optparse, tarfile, tempfile, urllib2, math
+import sys
+import optparse
+import tarfile
+import tempfile
+import urllib2
+import math
# Set max size of archive/file that will be handled to be 100 GB. This is
# arbitrary and should be adjusted as needed.
MAX_SIZE = 100 * math.pow( 2, 30 )
+
def url_to_file( url, dest_file ):
"""
Transfer a file from a remote URL to a temporary file.
"""
try:
url_reader = urllib2.urlopen( url )
- CHUNK = 10 * 1024 # 10k
+ CHUNK = 10 * 1024 # 10k
total = 0
fp = open( dest_file, 'wb')
while True:
@@ -35,6 +41,7 @@
print "Exception getting file from URL: %s" % e, sys.stderr
return None
+
def unpack_archive( archive_file, dest_dir ):
"""
Unpack a tar and/or gzipped archive into a destination directory.
@@ -63,4 +70,4 @@
# Unpack archive.
unpack_archive( archive_file, dest_dir )
except Exception, e:
- print "Error unpacking tar/gz archive: %s" % e, sys.stderr
\ No newline at end of file
+ print "Error unpacking tar/gz archive: %s" % e, sys.stderr
diff -r 6d8959c8866c699ee0e9461db2a1fcc0381bfac2 -r 60203bad003cc6b4bc054500248e5a69cbe9b8bc lib/galaxy/webapps/galaxy/api/histories.py
--- a/lib/galaxy/webapps/galaxy/api/histories.py
+++ b/lib/galaxy/webapps/galaxy/api/histories.py
@@ -11,15 +11,17 @@
from galaxy import web
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
-from galaxy.util import string_as_bool, restore_text
-from galaxy.util.sanitize_html import sanitize_html
-from galaxy.web.base.controller import BaseAPIController, UsesHistoryMixin, UsesTagsMixin
+from galaxy.util import string_as_bool
+from galaxy.util import restore_text
+from galaxy.web.base.controller import BaseAPIController
+from galaxy.web.base.controller import UsesHistoryMixin
+from galaxy.web.base.controller import UsesTagsMixin
from galaxy.web import url_for
-from galaxy.model.orm import desc
import logging
log = logging.getLogger( __name__ )
+
class HistoriesController( BaseAPIController, UsesHistoryMixin, UsesTagsMixin ):
@expose_api_anonymous
@@ -46,14 +48,14 @@
histories = self.get_user_histories( trans, user=trans.user, only_deleted=deleted )
#for history in query:
for history in histories:
- item = history.to_dict(value_mapper={'id':trans.security.encode_id})
+ item = history.to_dict(value_mapper={'id': trans.security.encode_id})
item['url'] = url_for( 'history', id=trans.security.encode_id( history.id ) )
rval.append( item )
elif trans.galaxy_session.current_history:
#No user, this must be session authentication with an anonymous user.
history = trans.galaxy_session.current_history
- item = history.to_dict(value_mapper={'id':trans.security.encode_id})
+ item = history.to_dict(value_mapper={'id': trans.security.encode_id})
item['url'] = url_for( 'history', id=trans.security.encode_id( history.id ) )
rval.append(item)
@@ -257,7 +259,7 @@
log.exception( 'Histories API, delete: uncaught HTTPInternalServerError: %s, %s\n%s',
history_id, str( kwd ), str( http_server_err ) )
raise
- except HTTPException, http_exc:
+ except HTTPException:
raise
except Exception, exc:
log.exception( 'Histories API, delete: uncaught exception: %s, %s\n%s',
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.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d3bc7ea60b05/
Changeset: d3bc7ea60b05
User: guerler
Date: 2014-01-29 00:29:23
Summary: Merge
Affected #: 0 files
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.
1
0
commit/galaxy-central: guerler: Grids: Option to pick between persistent and transient messages
by commits-noreply@bitbucket.org 28 Jan '14
by commits-noreply@bitbucket.org 28 Jan '14
28 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/593be4d22c47/
Changeset: 593be4d22c47
Branch: next-stable
User: guerler
Date: 2014-01-28 18:26:40
Summary: Grids: Option to pick between persistent and transient messages
Affected #: 7 files
diff -r 44538b70d174dd36836a88123a865e1147c016b5 -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 lib/galaxy/web/framework/helpers/grids.py
--- a/lib/galaxy/web/framework/helpers/grids.py
+++ b/lib/galaxy/web/framework/helpers/grids.py
@@ -24,6 +24,7 @@
template = "grid_base.mako"
async_template = "grid_base_async.mako"
use_async = False
+ use_hide_message = True
global_actions = []
columns = []
operations = []
@@ -286,6 +287,7 @@
status = status,
message = message,
use_panels=self.use_panels,
+ use_hide_message=self.use_hide_message,
advanced_search=self.advanced_search,
show_item_checkboxes = ( self.show_item_checkboxes or
kwargs.get( 'show_item_checkboxes', '' ) in [ 'True', 'true' ] ),
diff -r 44538b70d174dd36836a88123a865e1147c016b5 -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 lib/tool_shed/grids/admin_grids.py
--- a/lib/tool_shed/grids/admin_grids.py
+++ b/lib/tool_shed/grids/admin_grids.py
@@ -508,6 +508,7 @@
model_class = model.RepositoryMetadata
template='/webapps/tool_shed/repository/grid.mako'
default_sort_key = "name"
+ use_hide_message = False
columns = [
IdColumn( "Id",
visible=False,
diff -r 44538b70d174dd36836a88123a865e1147c016b5 -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 lib/tool_shed/grids/repository_grids.py
--- a/lib/tool_shed/grids/repository_grids.py
+++ b/lib/tool_shed/grids/repository_grids.py
@@ -236,6 +236,7 @@
model_class = model.Repository
template='/webapps/tool_shed/repository/grid.mako'
default_sort_key = "name"
+ use_hide_message = False
columns = [
NameColumn( "Name",
key="name",
@@ -344,6 +345,7 @@
model_class = model.RepositoryMetadata
template='/webapps/tool_shed/repository/grid.mako'
default_sort_key = "Repository.name"
+ use_hide_message = False
columns = [
NameColumn( "Repository name",
link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
@@ -652,7 +654,7 @@
columns = [ col for col in RepositoriesMissingToolTestComponentsGrid.columns ]
operations = []
use_paging = False
-
+
def build_initial_query( self, trans, **kwd ):
# First get all repositories that the current user is authorized to update.
username = trans.user.username
diff -r 44538b70d174dd36836a88123a865e1147c016b5 -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 lib/tool_shed/grids/repository_review_grids.py
--- a/lib/tool_shed/grids/repository_review_grids.py
+++ b/lib/tool_shed/grids/repository_review_grids.py
@@ -36,6 +36,7 @@
model_class = model.Component
template='/webapps/tool_shed/repository_review/grid.mako'
default_sort_key = "name"
+ use_hide_message = False
columns = [
NameColumn( "Name",
key="Component.name",
@@ -333,6 +334,7 @@
model_class = model.RepositoryReview
template='/webapps/tool_shed/repository_review/grid.mako'
default_sort_key = 'repository_id'
+ use_hide_message = False
columns = [
RepositoryNameColumn( "Repository Name",
model_class=model.Repository,
diff -r 44538b70d174dd36836a88123a865e1147c016b5 -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 static/scripts/galaxy.grids.js
--- a/static/scripts/galaxy.grids.js
+++ b/static/scripts/galaxy.grids.js
@@ -194,7 +194,9 @@
// update message
if (options.message) {
$('#grid-message').html(this.template_message(options));
- setTimeout( function() { $('#grid-message').html(''); }, 5000);
+ if (options.use_hide_message) {
+ setTimeout( function() { $('#grid-message').html(''); }, 5000);
+ }
}
// configure elements
diff -r 44538b70d174dd36836a88123a865e1147c016b5 -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 static/scripts/packed/galaxy.grids.js
--- a/static/scripts/packed/galaxy.grids.js
+++ b/static/scripts/packed/galaxy.grids.js
@@ -1,1 +1,1 @@
-jQuery.ajaxSettings.traditional=true;define(["mvc/ui"],function(){var a=Backbone.Model.extend({defaults:{url_base:"",async:false,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:false,advanced_search:false,cur_page:1,num_pages:1,operation:undefined,item_ids:undefined},can_async_op:function(c){return _.indexOf(this.attributes.async_ops,c)!==-1},add_filter:function(g,h,d){if(d){var e=this.attributes.filters[g],c;if(e===null||e===undefined){c=h}else{if(typeof(e)=="string"){if(e=="All"){c=h}else{var f=[];f[0]=e;f[1]=h;c=f}}else{c=e;c.push(h)}}this.attributes.filters[g]=c}else{this.attributes.filters[g]=h}},remove_filter:function(d,g){var c=this.attributes.filters[d];if(c===null||c===undefined){return false}var f=true;if(typeof(c)==="string"){if(c=="All"){f=false}else{delete this.attributes.filters[d]}}else{var e=_.indexOf(c,g);if(e!==-1){c.splice(e,1)}else{f=false}}return f},get_url_data:function(){var c={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes,advanced_search:this.attributes.advanced_search};if(this.attributes.operation){c.operation=this.attributes.operation}if(this.attributes.item_ids){c.id=this.attributes.item_ids}var d=this;_.each(_.pairs(d.attributes.filters),function(e){c["f-"+e[0]]=e[1]});return c},get_url:function(c){return this.get("url_base")+"?"+$.param(this.get_url_data())+"&"+$.param(c)}});var b=Backbone.View.extend({grid:null,initialize:function(c){this.init_grid(c);this.init_grid_controls();$("input[type=text]").each(function(){$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})})},handle_refresh:function(c){if(c){if($.inArray("history",c)>-1){if(top.Galaxy&&top.Galaxy.currHistoryPanel){top.Galaxy.currHistoryPanel.loadCurrentHistory()}}}},init_grid:function(e){this.grid=new a(e);var d=this.grid.attributes;this.handle_refresh(d.refresh_frames);var c=this.grid.get("url_base");c=c.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",c);$("#grid-table-body").html(this.template_body(d));$("#grid-table-footer").html(this.template_footer(d));if(d.message){$("#grid-message").html(this.template_message(d));setTimeout(function(){$("#grid-message").html("")},5000)}this.init_grid_elements();init_refresh_on_change()},init_grid_controls:function(){$(".submit-image").each(function(){$(this).mousedown(function(){$(this).addClass("gray-background")});$(this).mouseup(function(){$(this).removeClass("gray-background")})});var c=this;$(".sort-link").each(function(){$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});$(".categorical-filter > a").each(function(){$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});$(".text-filter-form").each(function(){$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});var d=$("#input-tags-filter");if(d.length){d.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var e=$("#input-name-filter");if(e.length){e.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}$(".advanced-search-toggle").each(function(){$(this).click(function(){$("#standard-search").slideToggle("fast");$("#advanced-search").slideToggle("fast");return false})})},init_grid_elements:function(){$(".grid").each(function(){var s=$(this).find("input.grid-row-select-checkbox");var r=$(this).find("span.grid-selected-count");var t=function(){r.text($(s).filter(":checked").length)};$(s).each(function(){$(this).change(t)});t()});if($(".community_rating_star").length!==0){$(".community_rating_star").rating({})}var q=this.grid.attributes;var p=this;$(".page-link > a").each(function(){$(this).click(function(){p.set_page($(this).attr("page_num"));return false})});$(".use-inbound").each(function(){$(this).click(function(r){p.execute({href:$(this).attr("href"),inbound:true});return false})});$(".use-outbound").each(function(){$(this).click(function(r){p.execute({href:$(this).attr("href")});return false})});var f=q.items.length;if(f==0){return}for(var k in q.items){var o=q.items[k];var l=$("#grid-"+k+"-popup");l.off();var d=new PopupMenu(l);for(var h in q.operations){var e=q.operations[h];var m=e.label;var c=o.operation_config[m];var g=o.encode_id;if(c.allowed&&e.allow_popup){var n={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};n.func=function(t){t.preventDefault();var s=$(t.target).html();var r=this.findItemByHtml(s);p.execute(r)};d.addItem(n)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$("<span>"+g+"<a href='javascript:void(0);'><span class='delete-search-icon' /></span></a>");f.addClass("text-filter-val");var d=this;f.click(function(){d.grid.remove_filter(e,g);$(this).remove();d.go_page_one();d.execute()});var c=$("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},set_sort_condition:function(h){var g=this.grid.get("sort_key");var f=h;if(g.indexOf(h)!==-1){if(g.substring(0,1)!=="-"){f="-"+h}else{}}$(".sort-arrow").remove();var e=(f.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+e+"</span>").addClass("sort-arrow");var d=$("#"+h+"-header");d.append(c);this.grid.set("sort_key",f);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;$("."+e+"-filter").each(function(){var m=$.trim($(this).text());var k=d[m];var l=k[e];if(l==g){$(this).empty();$(this).addClass("current-filter");$(this).append(m)}else{if(l==f){$(this).empty();var h=$("<a href='#'>"+m+"</a>");h.click(function(){c.set_categorical_filter(e,l)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;$(".page-link").each(function(){var k=$(this).attr("id"),g=parseInt(k.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$("<a href='#'>"+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(f,g){var e=$('input[name="id"]:checked').length;if(!e>0){return false}var d=$(f).val();var c=[];$("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:d,id:c,confirmation_text:g});return true},execute:function(n){var f=null;var e=null;var g=null;var c=null;var m=null;if(n){e=n.href;g=n.operation;f=n.id;c=n.confirmation_text;m=n.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var l=e.split("?");if(l.length>1){var k=l[1];var d=k.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"&&c!="null"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(m,"")}return false}if(e){this.go_to(m,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(m,"")}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=$("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");$(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(e){c.init_grid($.parseJSON(e));$(".loading-elt-overlay").hide()},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}},template_body:function(t){var m="";var u=0;var g=t.items.length;if(g==0){m+='<tr><td colspan="100"><em>No Items</em></td></tr>';u=1}for(var h in t.items){var r=t.items[h];var c=r.encode_id;var k="grid-"+h+"-popup";m+="<tr ";if(t.current_item_id==r.id){m+='class="current"'}m+=">";if(t.show_item_checkboxes){m+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+c+'" id="'+c+'" class="grid-row-select-checkbox" /></td>'}for(j in t.columns){var f=t.columns[j];if(f.visible){var e="";if(f.nowrap){e='style="white-space:nowrap;"'}var s=r.column_config[f.label];var l=s.link;var n=s.value;var q=s.inbound;if(jQuery.type(n)==="string"){n=n.replace(/\/\//g,"/")}var d="";var p="";if(f.attach_popup){d="grid-"+h+"-popup";p="menubutton";if(l!=""){p+=" split"}p+=" popup"}m+="<td "+e+">";if(l){if(t.operations.length!=0){m+='<div id="'+d+'" class="'+p+'" style="float: left;">'}var o="";if(q){o="use-inbound"}else{o="use-outbound"}m+='<a class="label '+o+'" href="'+l+'" onclick="return false;">'+n+"</a>";if(t.operations.length!=0){m+="</div>"}}else{m+='<div id="'+d+'" class="'+p+'"><label id="'+f.label_id_prefix+c+'" for="'+c+'">'+n+"</label></div>"}m+="</td>"}}m+="</tr>";u++}return m},template_footer:function(q){var m="";if(q.use_paging&&q.num_pages>1){var o=q.num_page_links;var c=q.cur_page_num;var p=q.num_pages;var l=o/2;var k=c-l;var g=0;if(k==0){k=1;g=l-(c-k)}var f=l+g;var e=c+f;if(e<=p){max_offset=0}else{e=p;max_offset=f-(e+1-c)}if(max_offset!=0){k-=max_offset;if(k<1){k=1}}m+='<tr id="page-links-row">';if(q.show_item_checkboxes){m+="<td></td>"}m+='<td colspan="100"><span id="page-link-container">Page:';if(k>1){m+='<span class="page-link" id="page-link-1"><a href="'+this.grid.get_url({page:n})+'" page_num="1" onclick="return false;">1</a></span> ...'}for(var n=k;n<e+1;n++){if(n==q.cur_page_num){m+='<span class="page-link inactive-link" id="page-link-'+n+'">'+n+"</span>"}else{m+='<span class="page-link" id="page-link-'+n+'"><a href="'+this.grid.get_url({page:n})+'" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}}if(e<p){m+='...<span class="page-link" id="page-link-'+p+'"><a href="'+this.grid.get_url({page:p})+'" onclick="return false;" page_num="'+p+'">'+p+"</a></span>"}m+="</span>";m+='<span class="page-link" id="show-all-link-span"> | <a href="'+this.grid.get_url({page:"all"})+'" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(q.show_item_checkboxes){m+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+q.get_class_plural+": ";for(i in q.operations){var d=q.operations[i];if(d.allow_multiple){m+='<input type="button" value="'+d.label+'" class="action-button" onclick="gridView.submit_operation(this, \''+d.confirm+"')\"> "}}m+="</td></tr>"}var h=false;for(i in q.operations){if(q.operations[i].global_operation){h=true;break}}if(h){m+='<tr><td colspan="100">';for(i in q.operations){var d=q.operations[i];if(d.global_operation){m+='<a class="action-button" href="'+d.global_operation+'">'+d.label+"</a>"}}m+="</td></tr>"}if(q.legend){m+='<tr><td colspan="100">'+q.legend+"</td></tr>"}return m},template_message:function(c){return'<p><div class="'+c.status+'message transient-message">'+c.message+'</div><div style="clear: both"></div></p>'}});return{Grid:a,GridView:b}});
\ No newline at end of file
+jQuery.ajaxSettings.traditional=true;define(["mvc/ui"],function(){var a=Backbone.Model.extend({defaults:{url_base:"",async:false,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:false,advanced_search:false,cur_page:1,num_pages:1,operation:undefined,item_ids:undefined},can_async_op:function(c){return _.indexOf(this.attributes.async_ops,c)!==-1},add_filter:function(g,h,d){if(d){var e=this.attributes.filters[g],c;if(e===null||e===undefined){c=h}else{if(typeof(e)=="string"){if(e=="All"){c=h}else{var f=[];f[0]=e;f[1]=h;c=f}}else{c=e;c.push(h)}}this.attributes.filters[g]=c}else{this.attributes.filters[g]=h}},remove_filter:function(d,g){var c=this.attributes.filters[d];if(c===null||c===undefined){return false}var f=true;if(typeof(c)==="string"){if(c=="All"){f=false}else{delete this.attributes.filters[d]}}else{var e=_.indexOf(c,g);if(e!==-1){c.splice(e,1)}else{f=false}}return f},get_url_data:function(){var c={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes,advanced_search:this.attributes.advanced_search};if(this.attributes.operation){c.operation=this.attributes.operation}if(this.attributes.item_ids){c.id=this.attributes.item_ids}var d=this;_.each(_.pairs(d.attributes.filters),function(e){c["f-"+e[0]]=e[1]});return c},get_url:function(c){return this.get("url_base")+"?"+$.param(this.get_url_data())+"&"+$.param(c)}});var b=Backbone.View.extend({grid:null,initialize:function(c){this.init_grid(c);this.init_grid_controls();$("input[type=text]").each(function(){$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})})},handle_refresh:function(c){if(c){if($.inArray("history",c)>-1){if(top.Galaxy&&top.Galaxy.currHistoryPanel){top.Galaxy.currHistoryPanel.loadCurrentHistory()}}}},init_grid:function(e){this.grid=new a(e);var d=this.grid.attributes;this.handle_refresh(d.refresh_frames);var c=this.grid.get("url_base");c=c.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",c);$("#grid-table-body").html(this.template_body(d));$("#grid-table-footer").html(this.template_footer(d));if(d.message){$("#grid-message").html(this.template_message(d));if(d.use_hide_message){setTimeout(function(){$("#grid-message").html("")},5000)}}this.init_grid_elements();init_refresh_on_change()},init_grid_controls:function(){$(".submit-image").each(function(){$(this).mousedown(function(){$(this).addClass("gray-background")});$(this).mouseup(function(){$(this).removeClass("gray-background")})});var c=this;$(".sort-link").each(function(){$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});$(".categorical-filter > a").each(function(){$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});$(".text-filter-form").each(function(){$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});var d=$("#input-tags-filter");if(d.length){d.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var e=$("#input-name-filter");if(e.length){e.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}$(".advanced-search-toggle").each(function(){$(this).click(function(){$("#standard-search").slideToggle("fast");$("#advanced-search").slideToggle("fast");return false})})},init_grid_elements:function(){$(".grid").each(function(){var s=$(this).find("input.grid-row-select-checkbox");var r=$(this).find("span.grid-selected-count");var t=function(){r.text($(s).filter(":checked").length)};$(s).each(function(){$(this).change(t)});t()});if($(".community_rating_star").length!==0){$(".community_rating_star").rating({})}var q=this.grid.attributes;var p=this;$(".page-link > a").each(function(){$(this).click(function(){p.set_page($(this).attr("page_num"));return false})});$(".use-inbound").each(function(){$(this).click(function(r){p.execute({href:$(this).attr("href"),inbound:true});return false})});$(".use-outbound").each(function(){$(this).click(function(r){p.execute({href:$(this).attr("href")});return false})});var f=q.items.length;if(f==0){return}for(var k in q.items){var o=q.items[k];var l=$("#grid-"+k+"-popup");l.off();var d=new PopupMenu(l);for(var h in q.operations){var e=q.operations[h];var m=e.label;var c=o.operation_config[m];var g=o.encode_id;if(c.allowed&&e.allow_popup){var n={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};n.func=function(t){t.preventDefault();var s=$(t.target).html();var r=this.findItemByHtml(s);p.execute(r)};d.addItem(n)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$("<span>"+g+"<a href='javascript:void(0);'><span class='delete-search-icon' /></span></a>");f.addClass("text-filter-val");var d=this;f.click(function(){d.grid.remove_filter(e,g);$(this).remove();d.go_page_one();d.execute()});var c=$("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},set_sort_condition:function(h){var g=this.grid.get("sort_key");var f=h;if(g.indexOf(h)!==-1){if(g.substring(0,1)!=="-"){f="-"+h}else{}}$(".sort-arrow").remove();var e=(f.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+e+"</span>").addClass("sort-arrow");var d=$("#"+h+"-header");d.append(c);this.grid.set("sort_key",f);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;$("."+e+"-filter").each(function(){var m=$.trim($(this).text());var k=d[m];var l=k[e];if(l==g){$(this).empty();$(this).addClass("current-filter");$(this).append(m)}else{if(l==f){$(this).empty();var h=$("<a href='#'>"+m+"</a>");h.click(function(){c.set_categorical_filter(e,l)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;$(".page-link").each(function(){var k=$(this).attr("id"),g=parseInt(k.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$("<a href='#'>"+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(f,g){var e=$('input[name="id"]:checked').length;if(!e>0){return false}var d=$(f).val();var c=[];$("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:d,id:c,confirmation_text:g});return true},execute:function(n){var f=null;var e=null;var g=null;var c=null;var m=null;if(n){e=n.href;g=n.operation;f=n.id;c=n.confirmation_text;m=n.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var l=e.split("?");if(l.length>1){var k=l[1];var d=k.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"&&c!="null"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(m,"")}return false}if(e){this.go_to(m,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(m,"")}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=$("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");$(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(e){c.init_grid($.parseJSON(e));$(".loading-elt-overlay").hide()},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}},template_body:function(t){var m="";var u=0;var g=t.items.length;if(g==0){m+='<tr><td colspan="100"><em>No Items</em></td></tr>';u=1}for(var h in t.items){var r=t.items[h];var c=r.encode_id;var k="grid-"+h+"-popup";m+="<tr ";if(t.current_item_id==r.id){m+='class="current"'}m+=">";if(t.show_item_checkboxes){m+='<td style="width: 1.5em;"><input type="checkbox" name="id" value="'+c+'" id="'+c+'" class="grid-row-select-checkbox" /></td>'}for(j in t.columns){var f=t.columns[j];if(f.visible){var e="";if(f.nowrap){e='style="white-space:nowrap;"'}var s=r.column_config[f.label];var l=s.link;var n=s.value;var q=s.inbound;if(jQuery.type(n)==="string"){n=n.replace(/\/\//g,"/")}var d="";var p="";if(f.attach_popup){d="grid-"+h+"-popup";p="menubutton";if(l!=""){p+=" split"}p+=" popup"}m+="<td "+e+">";if(l){if(t.operations.length!=0){m+='<div id="'+d+'" class="'+p+'" style="float: left;">'}var o="";if(q){o="use-inbound"}else{o="use-outbound"}m+='<a class="label '+o+'" href="'+l+'" onclick="return false;">'+n+"</a>";if(t.operations.length!=0){m+="</div>"}}else{m+='<div id="'+d+'" class="'+p+'"><label id="'+f.label_id_prefix+c+'" for="'+c+'">'+n+"</label></div>"}m+="</td>"}}m+="</tr>";u++}return m},template_footer:function(q){var m="";if(q.use_paging&&q.num_pages>1){var o=q.num_page_links;var c=q.cur_page_num;var p=q.num_pages;var l=o/2;var k=c-l;var g=0;if(k==0){k=1;g=l-(c-k)}var f=l+g;var e=c+f;if(e<=p){max_offset=0}else{e=p;max_offset=f-(e+1-c)}if(max_offset!=0){k-=max_offset;if(k<1){k=1}}m+='<tr id="page-links-row">';if(q.show_item_checkboxes){m+="<td></td>"}m+='<td colspan="100"><span id="page-link-container">Page:';if(k>1){m+='<span class="page-link" id="page-link-1"><a href="'+this.grid.get_url({page:n})+'" page_num="1" onclick="return false;">1</a></span> ...'}for(var n=k;n<e+1;n++){if(n==q.cur_page_num){m+='<span class="page-link inactive-link" id="page-link-'+n+'">'+n+"</span>"}else{m+='<span class="page-link" id="page-link-'+n+'"><a href="'+this.grid.get_url({page:n})+'" onclick="return false;" page_num="'+n+'">'+n+"</a></span>"}}if(e<p){m+='...<span class="page-link" id="page-link-'+p+'"><a href="'+this.grid.get_url({page:p})+'" onclick="return false;" page_num="'+p+'">'+p+"</a></span>"}m+="</span>";m+='<span class="page-link" id="show-all-link-span"> | <a href="'+this.grid.get_url({page:"all"})+'" onclick="return false;" page_num="all">Show All</a></span></td></tr>'}if(q.show_item_checkboxes){m+='<tr><input type="hidden" id="operation" name="operation" value=""><td></td><td colspan="100">For <span class="grid-selected-count"></span> selected '+q.get_class_plural+": ";for(i in q.operations){var d=q.operations[i];if(d.allow_multiple){m+='<input type="button" value="'+d.label+'" class="action-button" onclick="gridView.submit_operation(this, \''+d.confirm+"')\"> "}}m+="</td></tr>"}var h=false;for(i in q.operations){if(q.operations[i].global_operation){h=true;break}}if(h){m+='<tr><td colspan="100">';for(i in q.operations){var d=q.operations[i];if(d.global_operation){m+='<a class="action-button" href="'+d.global_operation+'">'+d.label+"</a>"}}m+="</td></tr>"}if(q.legend){m+='<tr><td colspan="100">'+q.legend+"</td></tr>"}return m},template_message:function(c){return'<p><div class="'+c.status+'message transient-message">'+c.message+'</div><div style="clear: both"></div></p>'}});return{Grid:a,GridView:b}});
\ No newline at end of file
diff -r 44538b70d174dd36836a88123a865e1147c016b5 -r 593be4d22c470abe6bdbbfa51f2a8e7ac035de33 templates/grid_base.mako
--- a/templates/grid_base.mako
+++ b/templates/grid_base.mako
@@ -64,6 +64,7 @@
'legend' : grid.legend,
'current_item_id' : False,
'use_panels' : context.get('use_panels'),
+ 'use_hide_message' : grid.use_hide_message,
'insert' : insert,
'default_filter_dict' : default_filter_dict,
'advanced_search' : advanced_search,
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.
1
0