galaxy-commits
Threads by month
- ----- 2026 -----
- 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
commit/galaxy-central: jmchilton: More reworking of job logging.
by commits-noreply@bitbucket.org 19 May '14
by commits-noreply@bitbucket.org 19 May '14
19 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/40c02d5cfc7d/
Changeset: 40c02d5cfc7d
User: jmchilton
Date: 2014-05-19 18:02:59
Summary: More reworking of job logging.
Drop now duplicated log message in drmaa, condor, cli, etc.... Have local job runner report which job script it is running - but log it as a job script. For each job runner log the full command-line which includes dependency resolution and not the base version produced directly by the tool and use the old format from the external runners.
Affected #: 7 files
diff -r f73317a85e5cc38492e0338538ada18484701030 -r 40c02d5cfc7da40d6b844a8120a019d611462e02 lib/galaxy/jobs/command_factory.py
--- a/lib/galaxy/jobs/command_factory.py
+++ b/lib/galaxy/jobs/command_factory.py
@@ -19,8 +19,8 @@
- commands to set metadata (if include_metadata is True)
"""
base_command_line = job_wrapper.get_command_line()
- job_id = job_wrapper.job_id
- log.debug( 'Tool evaluation for job (%s) produced command-line: %s' % ( job_id, base_command_line ) )
+ # job_id = job_wrapper.job_id
+ # log.debug( 'Tool evaluation for job (%s) produced command-line: %s' % ( job_id, base_command_line ) )
commands_builder = CommandsBuilder(base_command_line)
# All job runners currently handle this case which should never occur
diff -r f73317a85e5cc38492e0338538ada18484701030 -r 40c02d5cfc7da40d6b844a8120a019d611462e02 lib/galaxy/jobs/runners/__init__.py
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -268,8 +268,8 @@
)
## Additional logging to enable if debugging from_work_dir handling, metadata
## commands, etc... (or just peak in the job script.)
- # job_id = job_wrapper.job_id
- # log.debug( 'Extended command-line for job (%s) is: %s' % ( job_id, command_line ) )
+ job_id = job_wrapper.job_id
+ log.debug( '(%s) command is: %s' % ( job_id, command_line ) )
options.update(**kwds)
return job_script(**options)
diff -r f73317a85e5cc38492e0338538ada18484701030 -r 40c02d5cfc7da40d6b844a8120a019d611462e02 lib/galaxy/jobs/runners/cli.py
--- a/lib/galaxy/jobs/runners/cli.py
+++ b/lib/galaxy/jobs/runners/cli.py
@@ -91,7 +91,6 @@
return
log.debug( "(%s) submitting file: %s" % ( galaxy_id_tag, ajs.job_file ) )
- log.debug( "(%s) command is: %s" % ( galaxy_id_tag, command_line ) )
cmd_out = shell.execute(job_interface.submit(ajs.job_file))
if cmd_out.returncode != 0:
diff -r f73317a85e5cc38492e0338538ada18484701030 -r 40c02d5cfc7da40d6b844a8120a019d611462e02 lib/galaxy/jobs/runners/condor.py
--- a/lib/galaxy/jobs/runners/condor.py
+++ b/lib/galaxy/jobs/runners/condor.py
@@ -120,7 +120,6 @@
return
log.debug( "(%s) submitting file %s" % ( galaxy_id_tag, executable ) )
- log.debug( "(%s) command is: %s" % ( galaxy_id_tag, command_line ) )
external_job_id, message = condor_submit(submit_file)
if external_job_id is None:
diff -r f73317a85e5cc38492e0338538ada18484701030 -r 40c02d5cfc7da40d6b844a8120a019d611462e02 lib/galaxy/jobs/runners/drmaa.py
--- a/lib/galaxy/jobs/runners/drmaa.py
+++ b/lib/galaxy/jobs/runners/drmaa.py
@@ -114,9 +114,6 @@
if not self.prepare_job( job_wrapper, include_metadata=True ):
return
- # command line has been added to the wrapper by prepare_job()
- command_line = job_wrapper.runner_command_line
-
# get configured job destination
job_destination = job_wrapper.job_destination
@@ -164,7 +161,6 @@
return
log.debug( "(%s) submitting file %s", galaxy_id_tag, ajs.job_file )
- log.debug( "(%s) command is: %s", galaxy_id_tag, command_line )
if native_spec:
log.debug( "(%s) native specification is: %s", galaxy_id_tag, native_spec )
diff -r f73317a85e5cc38492e0338538ada18484701030 -r 40c02d5cfc7da40d6b844a8120a019d611462e02 lib/galaxy/jobs/runners/local.py
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -88,6 +88,7 @@
try:
stdout_file = tempfile.NamedTemporaryFile( suffix='_stdout', dir=job_wrapper.working_directory )
stderr_file = tempfile.NamedTemporaryFile( suffix='_stderr', dir=job_wrapper.working_directory )
+ log.debug( '(%s) executing job script: %s' % ( job_id, command_line ) )
proc = subprocess.Popen( args=command_line,
shell=True,
cwd=job_wrapper.working_directory,
diff -r f73317a85e5cc38492e0338538ada18484701030 -r 40c02d5cfc7da40d6b844a8120a019d611462e02 lib/galaxy/jobs/runners/pbs.py
--- a/lib/galaxy/jobs/runners/pbs.py
+++ b/lib/galaxy/jobs/runners/pbs.py
@@ -317,7 +317,6 @@
# (if a TaskWrapper was passed in):
galaxy_job_id = job_wrapper.get_id_tag()
log.debug("(%s) submitting file %s" % ( galaxy_job_id, job_file ) )
- log.debug("(%s) command is: %s" % ( galaxy_job_id, command_line ) )
tries = 0
while tries < 5:
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
19 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f73317a85e5c/
Changeset: f73317a85e5c
User: jmchilton
Date: 2014-05-19 17:16:12
Summary: Improved job logging.
Remove now less useful local runner command-line log statement (still contend it will be valuable for debugging purposes to be able to tweak and rerun the exact script - but point taken :)) . Remove stray statement added in ff4b5fe. Add new logging statement that logs just the base command-line produced by tools for all job runners. Add little note to runners/__init__.py about how to produce an extended command-line logging (with metadata handling, dependencies, and from_work_dir handling).
Affected #: 4 files
diff -r 42ced7ee518c0035dba9514b255ca1dbb8dd4c1a -r f73317a85e5cc38492e0338538ada18484701030 lib/galaxy/datatypes/metadata.py
--- a/lib/galaxy/datatypes/metadata.py
+++ b/lib/galaxy/datatypes/metadata.py
@@ -658,7 +658,6 @@
__get_filename_override(),
metadata_path_on_compute(metadata_files.filename_override_metadata),
)
- log.info(line)
return line
if not isinstance( datasets, list ):
datasets = [ datasets ]
diff -r 42ced7ee518c0035dba9514b255ca1dbb8dd4c1a -r f73317a85e5cc38492e0338538ada18484701030 lib/galaxy/jobs/command_factory.py
--- a/lib/galaxy/jobs/command_factory.py
+++ b/lib/galaxy/jobs/command_factory.py
@@ -4,6 +4,9 @@
CAPTURE_RETURN_CODE = "return_code=$?"
YIELD_CAPTURED_CODE = 'sh -c "exit $return_code"'
+from logging import getLogger
+log = getLogger( __name__ )
+
def build_command( runner, job_wrapper, include_metadata=False, include_work_dir_outputs=True, remote_command_params={} ):
"""
@@ -15,8 +18,10 @@
- command line taken from job wrapper
- commands to set metadata (if include_metadata is True)
"""
-
- commands_builder = CommandsBuilder(job_wrapper.get_command_line())
+ base_command_line = job_wrapper.get_command_line()
+ job_id = job_wrapper.job_id
+ log.debug( 'Tool evaluation for job (%s) produced command-line: %s' % ( job_id, base_command_line ) )
+ commands_builder = CommandsBuilder(base_command_line)
# All job runners currently handle this case which should never occur
if not commands_builder.commands:
diff -r 42ced7ee518c0035dba9514b255ca1dbb8dd4c1a -r f73317a85e5cc38492e0338538ada18484701030 lib/galaxy/jobs/runners/__init__.py
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -151,7 +151,11 @@
# Prepare the job
try:
job_wrapper.prepare()
- job_wrapper.runner_command_line = self.build_command_line( job_wrapper, include_metadata=include_metadata, include_work_dir_outputs=include_work_dir_outputs )
+ job_wrapper.runner_command_line = self.build_command_line(
+ job_wrapper,
+ include_metadata=include_metadata,
+ include_work_dir_outputs=include_work_dir_outputs
+ )
except:
log.exception("(%s) Failure preparing job" % job_id)
job_wrapper.fail( "failure preparing job", exception=True )
@@ -254,13 +258,18 @@
envs = destination.get( "env", [] )
for env in envs:
env_setup_commands.append( env_to_statement( env ) )
+ command_line = job_wrapper.runner_command_line
options = dict(
job_instrumenter=job_instrumenter,
galaxy_lib=job_wrapper.galaxy_lib_dir,
env_setup_commands=env_setup_commands,
working_directory=os.path.abspath( job_wrapper.working_directory ),
- command=job_wrapper.runner_command_line,
+ command=command_line,
)
+ ## Additional logging to enable if debugging from_work_dir handling, metadata
+ ## commands, etc... (or just peak in the job script.)
+ # job_id = job_wrapper.job_id
+ # log.debug( 'Extended command-line for job (%s) is: %s' % ( job_id, command_line ) )
options.update(**kwds)
return job_script(**options)
diff -r 42ced7ee518c0035dba9514b255ca1dbb8dd4c1a -r f73317a85e5cc38492e0338538ada18484701030 lib/galaxy/jobs/runners/local.py
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -86,7 +86,6 @@
job_id = job_wrapper.get_id_tag()
try:
- log.debug( '(%s) executing: %s' % ( job_id, command_line ) )
stdout_file = tempfile.NamedTemporaryFile( suffix='_stdout', dir=job_wrapper.working_directory )
stderr_file = tempfile.NamedTemporaryFile( suffix='_stderr', dir=job_wrapper.working_directory )
proc = subprocess.Popen( args=command_line,
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: dan: Fixes for genomespace exporter recieving UnvalidatedValue objects.
by commits-noreply@bitbucket.org 19 May '14
by commits-noreply@bitbucket.org 19 May '14
19 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/42ced7ee518c/
Changeset: 42ced7ee518c
User: dan
Date: 2014-05-19 16:17:36
Summary: Fixes for genomespace exporter recieving UnvalidatedValue objects.
Affected #: 1 file
diff -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 -r 42ced7ee518c0035dba9514b255ca1dbb8dd4c1a tools/genomespace/genomespace_exporter.py
--- a/tools/genomespace/genomespace_exporter.py
+++ b/tools/genomespace/genomespace_exporter.py
@@ -120,7 +120,13 @@
def galaxy_code_get_genomespace_folders( genomespace_site='prod', trans=None, value=None, base_url=None, **kwd ):
if value:
- value = value[0]#single select, only 1 value
+ if isinstance( value, list ):
+ value = value[0] #single select, only 1 value
+ elif not isinstance( value, basestring ):
+ #unvalidated value
+ value = value.value
+ if isinstance( value, list ):
+ value = value[0] #single select, only 1 value
def recurse_directory_dict( url_opener, cur_options, url ):
cur_directory = urllib2.Request( url, headers = { 'Content-Type': 'application/json', 'Accept': 'application/json, text/plain' } )
cur_directory.get_method = lambda: 'GET'
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: Merged in jmchilton/galaxy-central-fork-1 (pull request #384)
by commits-noreply@bitbucket.org 19 May '14
by commits-noreply@bitbucket.org 19 May '14
19 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5bf39d99f789/
Changeset: 5bf39d99f789
User: jmchilton
Date: 2014-05-19 04:12:36
Summary: Merged in jmchilton/galaxy-central-fork-1 (pull request #384)
Local Job Runner Enhancements
Affected #: 5 files
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -1163,6 +1163,11 @@
return 'Job ran longer than the maximum allowed execution time (%s), please try different inputs or parameters' % self.app.job_config.limits.walltime
return None
+ def has_limits( self ):
+ has_output_limit = self.app.job_config.limits.output_size > 0
+ has_walltime_limit = self.app.job_config.limits.walltime_delta is not None
+ return has_output_limit or has_walltime_limit
+
def get_command_line( self ):
return self.command_line
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 lib/galaxy/jobs/runners/__init__.py
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -196,7 +196,7 @@
output_pairs = []
# Walk job's output associations to find and use from_work_dir attributes.
job = job_wrapper.get_job()
- job_tool = self.app.toolbox.tools_by_id.get( job.tool_id, None )
+ job_tool = job_wrapper.tool
for dataset_assoc in job.output_datasets + job.output_library_datasets:
for dataset in dataset_assoc.dataset.dataset.history_associations + dataset_assoc.dataset.dataset.library_associations:
if isinstance( dataset, self.app.model.HistoryDatasetAssociation ):
@@ -269,7 +269,36 @@
self.work_queue.put( ( self.finish_job, ajs ) )
-class AsynchronousJobState( object ):
+class JobState( object ):
+ """
+ Encapsulate state of jobs.
+ """
+
+ def set_defaults( self, files_dir ):
+ if self.job_wrapper is not None:
+ id_tag = self.job_wrapper.get_id_tag()
+ if files_dir is not None:
+ self.job_file = JobState.default_job_file( files_dir, id_tag )
+ self.output_file = os.path.join( files_dir, 'galaxy_%s.o' % id_tag )
+ self.error_file = os.path.join( files_dir, 'galaxy_%s.e' % id_tag )
+ self.exit_code_file = os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
+ job_name = 'g%s' % id_tag
+ if self.job_wrapper.tool.old_id:
+ job_name += '_%s' % self.job_wrapper.tool.old_id
+ if self.job_wrapper.user:
+ job_name += '_%s' % self.job_wrapper.user
+ self.job_name = ''.join( map( lambda x: x if x in ( string.letters + string.digits + '_' ) else '_', job_name ) )
+
+ @staticmethod
+ def default_job_file( files_dir, id_tag ):
+ return os.path.join( files_dir, 'galaxy_%s.sh' % id_tag )
+
+ @staticmethod
+ def default_exit_code_file( files_dir, id_tag ):
+ return os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
+
+
+class AsynchronousJobState( JobState ):
"""
Encapsulate the state of an asynchronous job, this should be subclassed as
needed for various job runners to capture additional information needed
@@ -296,21 +325,6 @@
self.cleanup_file_attributes = [ 'job_file', 'output_file', 'error_file', 'exit_code_file' ]
- def set_defaults( self, files_dir ):
- if self.job_wrapper is not None:
- id_tag = self.job_wrapper.get_id_tag()
- if files_dir is not None:
- self.job_file = os.path.join( files_dir, 'galaxy_%s.sh' % id_tag )
- self.output_file = os.path.join( files_dir, 'galaxy_%s.o' % id_tag )
- self.error_file = os.path.join( files_dir, 'galaxy_%s.e' % id_tag )
- self.exit_code_file = os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
- job_name = 'g%s' % id_tag
- if self.job_wrapper.tool.old_id:
- job_name += '_%s' % self.job_wrapper.tool.old_id
- if self.job_wrapper.user:
- job_name += '_%s' % self.job_wrapper.user
- self.job_name = ''.join( map( lambda x: x if x in ( string.letters + string.digits + '_' ) else '_', job_name ) )
-
def cleanup( self ):
for file in [ getattr( self, a ) for a in self.cleanup_file_attributes if hasattr( self, a ) ]:
try:
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 lib/galaxy/jobs/runners/local.py
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -11,13 +11,20 @@
from time import sleep
from galaxy import model
-from galaxy.jobs.runners import BaseJobRunner
+from ..runners import BaseJobRunner
+from ..runners import JobState
from galaxy.util import DATABASE_MAX_STRING_SIZE, shrink_stream_by_size
+from galaxy.util import asbool
log = logging.getLogger( __name__ )
__all__ = [ 'LocalJobRunner' ]
+DEFAULT_POOL_SLEEP_TIME = 1
+# TODO: Set to false and just get rid of this option. It would simplify this
+# class nicely. -John
+DEFAULT_EMBED_METADATA_IN_JOB = False
+
class LocalJobRunner( BaseJobRunner ):
"""
@@ -31,12 +38,6 @@
#create a local copy of os.environ to use as env for subprocess.Popen
self._environ = os.environ.copy()
- # put lib into the PYTHONPATH for subprocesses
- if 'PYTHONPATH' in self._environ:
- self._environ['PYTHONPATH'] = '%s:%s' % ( self._environ['PYTHONPATH'], os.path.abspath( 'lib' ) )
- else:
- self._environ['PYTHONPATH'] = os.path.abspath( 'lib' )
-
#Set TEMP if a valid temp value is not already set
if not ( 'TMPDIR' in self._environ or 'TEMP' in self._environ or 'TMP' in self._environ ):
self._environ[ 'TEMP' ] = os.path.abspath(tempfile.gettempdir())
@@ -52,24 +53,36 @@
## slots would be cleaner name, but don't want deployers to see examples and think it
## is going to work with other job runners.
slots = job_wrapper.job_destination.params.get( "local_slots", None )
- command_line = command_line.lstrip( " ;" )
if slots:
- command_line = 'GALAXY_SLOTS="%d"; export GALAXY_SLOTS; GALAXY_SLOTS_CONFIGURED="1"; export GALAXY_SLOTS_CONFIGURED; %s' % ( int( slots ), command_line )
+ slots_statement = 'GALAXY_SLOTS="%d"; export GALAXY_SLOTS; GALAXY_SLOTS_CONFIGURED="1"; export GALAXY_SLOTS_CONFIGURED;' % ( int( slots ) )
else:
- command_line = 'GALAXY_SLOTS="1"; export GALAXY_SLOTS; %s' % command_line
- return command_line
+ slots_statement = 'GALAXY_SLOTS="1"; export GALAXY_SLOTS;'
+
+ job_id = job_wrapper.get_id_tag()
+ job_file = JobState.default_job_file( job_wrapper.working_directory, job_id )
+ exit_code_path = JobState.default_exit_code_file( job_wrapper.working_directory, job_id )
+ job_script_props = {
+ 'slots_statement': slots_statement,
+ 'command': command_line,
+ 'exit_code_path': exit_code_path,
+ 'working_directory': job_wrapper.working_directory,
+ }
+ job_file_contents = self.get_job_file( job_wrapper, **job_script_props )
+ open( job_file, 'w' ).write( job_file_contents )
+ os.chmod( job_file, 0755 )
+ return job_file, exit_code_path
def queue_job( self, job_wrapper ):
# prepare the job
- if not self.prepare_job( job_wrapper ):
+ include_metadata = asbool( job_wrapper.job_destination.params.get( "embed_metadata_in_job", DEFAULT_EMBED_METADATA_IN_JOB ) )
+ if not self.prepare_job( job_wrapper, include_metadata=include_metadata ):
return
stderr = stdout = ''
exit_code = 0
# command line has been added to the wrapper by prepare_job()
- command_line = self.__command_line( job_wrapper )
-
+ command_line, exit_code_path = self.__command_line( job_wrapper )
job_id = job_wrapper.get_id_tag()
try:
@@ -85,22 +98,18 @@
preexec_fn=os.setpgrp )
job_wrapper.set_job_destination(job_wrapper.job_destination, proc.pid)
job_wrapper.change_state( model.Job.states.RUNNING )
- job_start = datetime.datetime.now()
- i = 0
- # Iterate until the process exits, periodically checking its limits
- while proc.poll() is None:
- i += 1
- if (i % 20) == 0:
- msg = job_wrapper.check_limits(runtime=datetime.datetime.now() - job_start)
- if msg is not None:
- job_wrapper.fail(msg)
- log.debug('(%s) Terminating process group' % job_id)
- self._terminate(proc)
- return
- else:
- sleep(1)
+
+ terminated = self.__poll_if_needed( proc, job_wrapper, job_id )
+ if terminated:
+ return
+
# Reap the process and get the exit code.
exit_code = proc.wait()
+ try:
+ exit_code = int( open( exit_code_path, 'r' ).read() )
+ except Exception:
+ log.warn( "Failed to read exit code from path %s" % exit_code_path )
+ pass
stdout_file.seek( 0 )
stderr_file.seek( 0 )
stdout = shrink_stream_by_size( stdout_file, DATABASE_MAX_STRING_SIZE, join_by="\n..\n", left_larger=True, beginning_on_size_error=True )
@@ -112,7 +121,9 @@
log.exception("failure running job %d" % job_wrapper.job_id)
job_wrapper.fail( "failure running job", exception=True )
return
- self._handle_metadata_externally( job_wrapper, resolve_requirements=True )
+ external_metadata = not asbool( job_wrapper.job_destination.params.get( "embed_metadata_in_job", DEFAULT_EMBED_METADATA_IN_JOB ) )
+ if external_metadata:
+ self._handle_metadata_externally( job_wrapper, resolve_requirements=True )
# Finish the job!
try:
job_wrapper.finish( stdout, stderr, exit_code )
@@ -168,3 +179,23 @@
if proc.poll() is None:
os.killpg( proc.pid, 9 )
return proc.wait() # reap
+
+ def __poll_if_needed( self, proc, job_wrapper, job_id ):
+ # Only poll if needed (i.e. job limits are set)
+ if not job_wrapper.has_limits():
+ return
+
+ job_start = datetime.datetime.now()
+ i = 0
+ # Iterate until the process exits, periodically checking its limits
+ while proc.poll() is None:
+ i += 1
+ if (i % 20) == 0:
+ msg = job_wrapper.check_limits(runtime=datetime.datetime.now() - job_start)
+ if msg is not None:
+ job_wrapper.fail(msg)
+ log.debug('(%s) Terminating process group' % job_id)
+ self._terminate(proc)
+ return True
+ else:
+ sleep( DEFAULT_POOL_SLEEP_TIME )
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 test/unit/jobs/test_runner_local.py
--- /dev/null
+++ b/test/unit/jobs/test_runner_local.py
@@ -0,0 +1,166 @@
+import os
+import threading
+import time
+from unittest import TestCase
+
+from galaxy.util import bunch
+from galaxy.jobs.runners import local
+from galaxy.jobs import metrics
+from galaxy import model
+
+from tools_support import (
+ UsesApp,
+ UsesTools
+)
+
+
+class TestLocalJobRunner( TestCase, UsesApp, UsesTools ):
+
+ def setUp( self ):
+ self.setup_app()
+ self._init_tool()
+ self.app.job_metrics = metrics.JobMetrics()
+ self.job_wrapper = MockJobWrapper( self.app, self.test_directory, self.tool )
+
+ def tearDown( self ):
+ self.tear_down_app()
+
+ def test_run( self ):
+ self.job_wrapper.command_line = "echo HelloWorld"
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "HelloWorld"
+
+ def test_galaxy_lib_on_path( self ):
+ self.job_wrapper.command_line = '''python -c "import galaxy.util"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.exit_code == 0
+
+ def test_default_slots( self ):
+ self.job_wrapper.command_line = '''echo $GALAXY_SLOTS'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "1"
+
+ def test_slots_override( self ):
+ # Set local_slots in job destination to specify slots for
+ # local job runner.
+ self.job_wrapper.job_destination.params[ "local_slots" ] = 3
+ self.job_wrapper.command_line = '''echo $GALAXY_SLOTS'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "3"
+
+ def test_exit_code( self ):
+ self.job_wrapper.command_line = '''sh -c "exit 4"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.exit_code == 4
+
+ def test_metadata_gets_set( self ):
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert os.path.exists( self.job_wrapper.mock_metadata_path )
+
+ def test_metadata_gets_set_if_embedded( self ):
+ self.job_wrapper.job_destination.params[ "embed_metadata_in_job" ] = "True"
+
+ # Kill off cruft for _handle_metadata_externally and make sure job stil works...
+ self.job_wrapper.external_output_metadata = None
+ self.app.datatypes_registry.set_external_metadata_tool = None
+
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert os.path.exists( self.job_wrapper.mock_metadata_path )
+
+ def test_stopping_job( self ):
+ self.job_wrapper.command_line = '''python -c "import time; time.sleep(15)"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+
+ def queue():
+ runner.queue_job( self.job_wrapper )
+
+ t = threading.Thread(target=queue)
+ t.start()
+ while True:
+ if self.job_wrapper.external_id:
+ break
+ time.sleep( .01 )
+ external_id = self.job_wrapper.external_id
+ mock_job = bunch.Bunch(
+ get_external_output_metadata=lambda: None,
+ get_job_runner_external_id=lambda: str(external_id),
+ get_id=lambda: 1
+ )
+ runner.stop_job( mock_job )
+ t.join(1)
+
+
+class MockJobWrapper( object ):
+
+ def __init__( self, app, test_directory, tool ):
+ working_directory = os.path.join( test_directory, "workdir" )
+ os.makedirs( working_directory )
+ self.app = app
+ self.tool = tool
+ self.state = model.Job.states.QUEUED
+ self.command_line = "echo HelloWorld"
+ self.prepare_called = False
+ self.write_version_cmd = None
+ self.dependency_shell_commands = None
+ self.working_directory = working_directory
+ self.requires_setting_metadata = True
+ self.job_destination = bunch.Bunch( id="default", params={} )
+ self.galaxy_lib_dir = os.path.abspath( "lib" )
+ self.job_id = 1
+ self.external_id = None
+ self.output_paths = [ '/tmp/output1.dat' ]
+ self.mock_metadata_path = os.path.abspath( os.path.join( test_directory, "METADATA_SET" ) )
+ self.metadata_command = "touch %s" % self.mock_metadata_path
+
+ # Cruft for setting metadata externally, axe at some point.
+ self.external_output_metadata = bunch.Bunch(
+ set_job_runner_external_pid=lambda pid, session: None
+ )
+ self.app.datatypes_registry.set_external_metadata_tool = bunch.Bunch(
+ build_dependency_shell_commands=lambda: []
+ )
+
+ def prepare( self ):
+ self.prepare_called = True
+
+ def set_job_destination( self, job_destination, external_id ):
+ self.external_id = external_id
+
+ def get_command_line( self ):
+ return self.command_line
+
+ def get_id_tag( self ):
+ return "1"
+
+ def get_state( self ):
+ return self.state
+
+ def change_state( self, state ):
+ self.state = state
+
+ def get_output_fnames( self ):
+ return []
+
+ def get_job( self ):
+ return model.Job()
+
+ def setup_external_metadata( self, **kwds ):
+ return self.metadata_command
+
+ def get_env_setup_clause( self ):
+ return ""
+
+ def has_limits( self ):
+ return False
+
+ def finish( self, stdout, stderr, exit_code ):
+ self.stdout = stdout
+ self.stderr = stderr
+ self.exit_code = exit_code
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 test/unit/tools_support.py
--- a/test/unit/tools_support.py
+++ b/test/unit/tools_support.py
@@ -58,7 +58,7 @@
class UsesTools( object ):
- def _init_tool( self, tool_contents ):
+ def _init_tool( self, tool_contents=SIMPLE_TOOL_CONTENTS ):
self.tool_file = os.path.join( self.test_directory, "tool.xml" )
self.app.config.drmaa_external_runjob_script = ""
self.app.config.tool_secret = "testsecret"
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/bed23d528080/
Changeset: bed23d528080
User: jmchilton
Date: 2014-05-05 19:35:09
Summary: Simplify command for grabbing tool in get_work_dir_outputs.
Subtlely reduces code duplication and makes runners slightly easier to unit test (fewer dependencies).
Affected #: 1 file
diff -r b94b4da49bfdf4f204d0ad2dce878a37e6e4f3d3 -r bed23d5280808dbc2d6b56ddcfe572e9bedda97a lib/galaxy/jobs/runners/__init__.py
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -196,7 +196,7 @@
output_pairs = []
# Walk job's output associations to find and use from_work_dir attributes.
job = job_wrapper.get_job()
- job_tool = self.app.toolbox.tools_by_id.get( job.tool_id, None )
+ job_tool = job_wrapper.tool
for dataset_assoc in job.output_datasets + job.output_library_datasets:
for dataset in dataset_assoc.dataset.dataset.history_associations + dataset_assoc.dataset.dataset.library_associations:
if isinstance( dataset, self.app.model.HistoryDatasetAssociation ):
https://bitbucket.org/galaxy/galaxy-central/commits/51c248b80e72/
Changeset: 51c248b80e72
User: jmchilton
Date: 2014-05-05 19:35:09
Summary: Unit tests for local job runner.
Test running, capturing standard output and exit code, killing job, setting metadata, adding Galaxy to jobs PYTHONPATH, GALAXY_SLOTS logic (default and overidding).
Affected #: 2 files
diff -r bed23d5280808dbc2d6b56ddcfe572e9bedda97a -r 51c248b80e729ec6a3ef39e851ebdf79ef888476 test/unit/jobs/test_runner_local.py
--- /dev/null
+++ b/test/unit/jobs/test_runner_local.py
@@ -0,0 +1,155 @@
+import os
+import threading
+import time
+from unittest import TestCase
+
+from galaxy.util import bunch
+from galaxy.jobs.runners import local
+from galaxy.jobs import metrics
+from galaxy import model
+
+from tools_support import (
+ UsesApp,
+ UsesTools
+)
+
+
+class TestLocalJobRunner( TestCase, UsesApp, UsesTools ):
+
+ def setUp( self ):
+ self.setup_app()
+ self._init_tool()
+ self.app.job_metrics = metrics.JobMetrics()
+ self.job_wrapper = MockJobWrapper( self.app, self.test_directory, self.tool )
+
+ def tearDown( self ):
+ self.tear_down_app()
+
+ def test_run( self ):
+ self.job_wrapper.command_line = "echo HelloWorld"
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "HelloWorld"
+
+ def test_galaxy_lib_on_path( self ):
+ self.job_wrapper.command_line = '''python -c "import galaxy.util"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.exit_code == 0
+
+ def test_default_slots( self ):
+ self.job_wrapper.command_line = '''echo $GALAXY_SLOTS'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "1"
+
+ def test_slots_override( self ):
+ # Set local_slots in job destination to specify slots for
+ # local job runner.
+ self.job_wrapper.job_destination.params[ "local_slots" ] = 3
+ self.job_wrapper.command_line = '''echo $GALAXY_SLOTS'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "3"
+
+ def test_exit_code( self ):
+ self.job_wrapper.command_line = '''sh -c "exit 4"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.exit_code == 4
+
+ def test_metadata_gets_set( self ):
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert os.path.exists( self.job_wrapper.mock_metadata_path )
+
+ def test_stopping_job( self ):
+ self.job_wrapper.command_line = '''python -c "import time; time.sleep(15)"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+
+ def queue():
+ runner.queue_job( self.job_wrapper )
+
+ t = threading.Thread(target=queue)
+ t.start()
+ while True:
+ if self.job_wrapper.external_id:
+ break
+ time.sleep( .01 )
+ external_id = self.job_wrapper.external_id
+ mock_job = bunch.Bunch(
+ get_external_output_metadata=lambda: None,
+ get_job_runner_external_id=lambda: str(external_id),
+ get_id=lambda: 1
+ )
+ runner.stop_job( mock_job )
+ t.join(1)
+
+
+class MockJobWrapper( object ):
+
+ def __init__( self, app, test_directory, tool ):
+ working_directory = os.path.join( test_directory, "workdir" )
+ os.makedirs( working_directory )
+ self.app = app
+ self.tool = tool
+ self.state = model.Job.states.QUEUED
+ self.command_line = "echo HelloWorld"
+ self.prepare_called = False
+ self.write_version_cmd = None
+ self.dependency_shell_commands = None
+ self.working_directory = working_directory
+ self.requires_setting_metadata = True
+ self.job_destination = bunch.Bunch( id="default", params={} )
+ self.galaxy_lib_dir = os.path.abspath( "lib" )
+ self.job_id = 1
+ self.external_id = None
+ self.output_paths = [ '/tmp/output1.dat' ]
+ self.mock_metadata_path = os.path.abspath( os.path.join( test_directory, "METADATA_SET" ) )
+ self.metadata_command = "touch %s" % self.mock_metadata_path
+
+ # Cruft for setting metadata externally, axe at some point.
+ self.external_output_metadata = bunch.Bunch(
+ set_job_runner_external_pid=lambda pid, session: None
+ )
+ self.app.datatypes_registry.set_external_metadata_tool = bunch.Bunch(
+ build_dependency_shell_commands=lambda: []
+ )
+
+ def prepare( self ):
+ self.prepare_called = True
+
+ def set_job_destination( self, job_destination, external_id ):
+ self.external_id = external_id
+
+ def get_command_line( self ):
+ return self.command_line
+
+ def get_id_tag( self ):
+ return "1"
+
+ def get_state( self ):
+ return self.state
+
+ def change_state( self, state ):
+ self.state = state
+
+ def get_output_fnames( self ):
+ return []
+
+ def get_job( self ):
+ return model.Job()
+
+ def setup_external_metadata( self, **kwds ):
+ return self.metadata_command
+
+ def get_env_setup_clause( self ):
+ return ""
+
+ def has_limits( self ):
+ return False
+
+ def finish( self, stdout, stderr, exit_code ):
+ self.stdout = stdout
+ self.stderr = stderr
+ self.exit_code = exit_code
diff -r bed23d5280808dbc2d6b56ddcfe572e9bedda97a -r 51c248b80e729ec6a3ef39e851ebdf79ef888476 test/unit/tools_support.py
--- a/test/unit/tools_support.py
+++ b/test/unit/tools_support.py
@@ -58,7 +58,7 @@
class UsesTools( object ):
- def _init_tool( self, tool_contents ):
+ def _init_tool( self, tool_contents=SIMPLE_TOOL_CONTENTS ):
self.tool_file = os.path.join( self.test_directory, "tool.xml" )
self.app.config.drmaa_external_runjob_script = ""
self.app.config.tool_secret = "testsecret"
https://bitbucket.org/galaxy/galaxy-central/commits/ff666103459d/
Changeset: ff666103459d
User: jmchilton
Date: 2014-05-05 19:35:09
Summary: Refactor small __poll helper method out of local job runner's queue.
Affected #: 1 file
diff -r 51c248b80e729ec6a3ef39e851ebdf79ef888476 -r ff666103459de3c87595a1d25783d7a3283b4951 lib/galaxy/jobs/runners/local.py
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -18,6 +18,8 @@
__all__ = [ 'LocalJobRunner' ]
+DEFAULT_POOL_SLEEP_TIME = 1
+
class LocalJobRunner( BaseJobRunner ):
"""
@@ -85,20 +87,11 @@
preexec_fn=os.setpgrp )
job_wrapper.set_job_destination(job_wrapper.job_destination, proc.pid)
job_wrapper.change_state( model.Job.states.RUNNING )
- job_start = datetime.datetime.now()
- i = 0
- # Iterate until the process exits, periodically checking its limits
- while proc.poll() is None:
- i += 1
- if (i % 20) == 0:
- msg = job_wrapper.check_limits(runtime=datetime.datetime.now() - job_start)
- if msg is not None:
- job_wrapper.fail(msg)
- log.debug('(%s) Terminating process group' % job_id)
- self._terminate(proc)
- return
- else:
- sleep(1)
+
+ terminated = self.__poll( proc, job_wrapper, job_id )
+ if terminated:
+ return
+
# Reap the process and get the exit code.
exit_code = proc.wait()
stdout_file.seek( 0 )
@@ -168,3 +161,19 @@
if proc.poll() is None:
os.killpg( proc.pid, 9 )
return proc.wait() # reap
+
+ def __poll( self, proc, job_wrapper, job_id ):
+ job_start = datetime.datetime.now()
+ i = 0
+ # Iterate until the process exits, periodically checking its limits
+ while proc.poll() is None:
+ i += 1
+ if (i % 20) == 0:
+ msg = job_wrapper.check_limits(runtime=datetime.datetime.now() - job_start)
+ if msg is not None:
+ job_wrapper.fail(msg)
+ log.debug('(%s) Terminating process group' % job_id)
+ self._terminate(proc)
+ return True
+ else:
+ sleep( DEFAULT_POOL_SLEEP_TIME )
https://bitbucket.org/galaxy/galaxy-central/commits/50de2360e451/
Changeset: 50de2360e451
User: jmchilton
Date: 2014-05-05 19:35:09
Summary: Local job runner - only poll if limits set (so can be set).
Small optimization aimed at speeding up tests - unit and functional.
Affected #: 2 files
diff -r ff666103459de3c87595a1d25783d7a3283b4951 -r 50de2360e4511b91f22ed437c1d1d62826136342 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -1161,6 +1161,11 @@
return 'Job ran longer than the maximum allowed execution time (%s), please try different inputs or parameters' % self.app.job_config.limits.walltime
return None
+ def has_limits( self ):
+ has_output_limit = self.app.job_config.limits.output_size > 0
+ has_walltime_limit = self.app.job_config.limits.walltime_delta is not None
+ return has_output_limit or has_walltime_limit
+
def get_command_line( self ):
return self.command_line
diff -r ff666103459de3c87595a1d25783d7a3283b4951 -r 50de2360e4511b91f22ed437c1d1d62826136342 lib/galaxy/jobs/runners/local.py
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -88,7 +88,7 @@
job_wrapper.set_job_destination(job_wrapper.job_destination, proc.pid)
job_wrapper.change_state( model.Job.states.RUNNING )
- terminated = self.__poll( proc, job_wrapper, job_id )
+ terminated = self.__poll_if_needed( proc, job_wrapper, job_id )
if terminated:
return
@@ -162,7 +162,11 @@
os.killpg( proc.pid, 9 )
return proc.wait() # reap
- def __poll( self, proc, job_wrapper, job_id ):
+ def __poll_if_needed( self, proc, job_wrapper, job_id ):
+ # Only poll if needed (i.e. job limits are set)
+ if not job_wrapper.has_limits():
+ return
+
job_start = datetime.datetime.now()
i = 0
# Iterate until the process exits, periodically checking its limits
https://bitbucket.org/galaxy/galaxy-central/commits/03d912919356/
Changeset: 03d912919356
User: jmchilton
Date: 2014-05-05 19:35:09
Summary: Allow embedding setting of metadata as part of local jobs.
(Like it works for all other runners except the LWR). This is essentially scaffolding toward elimination of extra metadata step in local runner.
Got Dan's blessing to kill this off a while ago but I still don't quite understand why it is separated out - so doing this in two parts. This changeset changes nothing by default but adds an option to local runner destinations (embed_metadata_in_job) to allow them operate in the new fashion (embed the metadata setting step in the job itself). At some later point this option should just be removed and all local jobs should operate this way. Use this new option to speed up the local job runner or to test out how this runner will work in the future.
Affected #: 2 files
diff -r 50de2360e4511b91f22ed437c1d1d62826136342 -r 03d912919356db7ff34d289985c8ee3ac2a67dd1 lib/galaxy/jobs/runners/local.py
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -13,12 +13,16 @@
from galaxy import model
from galaxy.jobs.runners import BaseJobRunner
from galaxy.util import DATABASE_MAX_STRING_SIZE, shrink_stream_by_size
+from galaxy.util import asbool
log = logging.getLogger( __name__ )
__all__ = [ 'LocalJobRunner' ]
DEFAULT_POOL_SLEEP_TIME = 1
+# TODO: Set to false and just get rid of this option. It would simplify this
+# class nicely. -John
+DEFAULT_EMBED_METADATA_IN_JOB = False
class LocalJobRunner( BaseJobRunner ):
@@ -63,7 +67,8 @@
def queue_job( self, job_wrapper ):
# prepare the job
- if not self.prepare_job( job_wrapper ):
+ include_metadata = asbool( job_wrapper.job_destination.params.get( "embed_metadata_in_job", DEFAULT_EMBED_METADATA_IN_JOB ) )
+ if not self.prepare_job( job_wrapper, include_metadata=include_metadata ):
return
stderr = stdout = ''
@@ -105,7 +110,9 @@
log.exception("failure running job %d" % job_wrapper.job_id)
job_wrapper.fail( "failure running job", exception=True )
return
- self._handle_metadata_externally( job_wrapper, resolve_requirements=True )
+ external_metadata = not asbool( job_wrapper.job_destination.params.get( "embed_metadata_in_job", DEFAULT_EMBED_METADATA_IN_JOB ) )
+ if external_metadata:
+ self._handle_metadata_externally( job_wrapper, resolve_requirements=True )
# Finish the job!
try:
job_wrapper.finish( stdout, stderr, exit_code )
diff -r 50de2360e4511b91f22ed437c1d1d62826136342 -r 03d912919356db7ff34d289985c8ee3ac2a67dd1 test/unit/jobs/test_runner_local.py
--- a/test/unit/jobs/test_runner_local.py
+++ b/test/unit/jobs/test_runner_local.py
@@ -63,6 +63,17 @@
runner.queue_job( self.job_wrapper )
assert os.path.exists( self.job_wrapper.mock_metadata_path )
+ def test_metadata_gets_set_if_embedded( self ):
+ self.job_wrapper.job_destination.params[ "embed_metadata_in_job" ] = "True"
+
+ # Kill off cruft for _handle_metadata_externally and make sure job stil works...
+ self.job_wrapper.external_output_metadata = None
+ self.app.datatypes_registry.set_external_metadata_tool = None
+
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert os.path.exists( self.job_wrapper.mock_metadata_path )
+
def test_stopping_job( self ):
self.job_wrapper.command_line = '''python -c "import time; time.sleep(15)"'''
runner = local.LocalJobRunner( self.app, 1 )
https://bitbucket.org/galaxy/galaxy-central/commits/e1db77201a5d/
Changeset: e1db77201a5d
User: jmchilton
Date: 2014-05-05 19:35:09
Summary: Rework local job runner to create job script.
Affected #: 2 files
diff -r 03d912919356db7ff34d289985c8ee3ac2a67dd1 -r e1db77201a5d9e93cf7729c2695c34e98abf5252 lib/galaxy/jobs/runners/__init__.py
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -270,7 +270,36 @@
self.work_queue.put( ( self.finish_job, ajs ) )
-class AsynchronousJobState( object ):
+class JobState( object ):
+ """
+ Encapsulate state of jobs.
+ """
+
+ def set_defaults( self, files_dir ):
+ if self.job_wrapper is not None:
+ id_tag = self.job_wrapper.get_id_tag()
+ if files_dir is not None:
+ self.job_file = JobState.default_job_file( files_dir, id_tag )
+ self.output_file = os.path.join( files_dir, 'galaxy_%s.o' % id_tag )
+ self.error_file = os.path.join( files_dir, 'galaxy_%s.e' % id_tag )
+ self.exit_code_file = os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
+ job_name = 'g%s' % id_tag
+ if self.job_wrapper.tool.old_id:
+ job_name += '_%s' % self.job_wrapper.tool.old_id
+ if self.job_wrapper.user:
+ job_name += '_%s' % self.job_wrapper.user
+ self.job_name = ''.join( map( lambda x: x if x in ( string.letters + string.digits + '_' ) else '_', job_name ) )
+
+ @staticmethod
+ def default_job_file( files_dir, id_tag ):
+ return os.path.join( files_dir, 'galaxy_%s.sh' % id_tag )
+
+ @staticmethod
+ def default_exit_code_file( files_dir, id_tag ):
+ return os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
+
+
+class AsynchronousJobState( JobState ):
"""
Encapsulate the state of an asynchronous job, this should be subclassed as
needed for various job runners to capture additional information needed
@@ -297,21 +326,6 @@
self.cleanup_file_attributes = [ 'job_file', 'output_file', 'error_file', 'exit_code_file' ]
- def set_defaults( self, files_dir ):
- if self.job_wrapper is not None:
- id_tag = self.job_wrapper.get_id_tag()
- if files_dir is not None:
- self.job_file = os.path.join( files_dir, 'galaxy_%s.sh' % id_tag )
- self.output_file = os.path.join( files_dir, 'galaxy_%s.o' % id_tag )
- self.error_file = os.path.join( files_dir, 'galaxy_%s.e' % id_tag )
- self.exit_code_file = os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
- job_name = 'g%s' % id_tag
- if self.job_wrapper.tool.old_id:
- job_name += '_%s' % self.job_wrapper.tool.old_id
- if self.job_wrapper.user:
- job_name += '_%s' % self.job_wrapper.user
- self.job_name = ''.join( map( lambda x: x if x in ( string.letters + string.digits + '_' ) else '_', job_name ) )
-
def cleanup( self ):
for file in [ getattr( self, a ) for a in self.cleanup_file_attributes if hasattr( self, a ) ]:
try:
diff -r 03d912919356db7ff34d289985c8ee3ac2a67dd1 -r e1db77201a5d9e93cf7729c2695c34e98abf5252 lib/galaxy/jobs/runners/local.py
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -11,7 +11,8 @@
from time import sleep
from galaxy import model
-from galaxy.jobs.runners import BaseJobRunner
+from ..runners import BaseJobRunner
+from ..runners import JobState
from galaxy.util import DATABASE_MAX_STRING_SIZE, shrink_stream_by_size
from galaxy.util import asbool
@@ -37,12 +38,6 @@
#create a local copy of os.environ to use as env for subprocess.Popen
self._environ = os.environ.copy()
- # put lib into the PYTHONPATH for subprocesses
- if 'PYTHONPATH' in self._environ:
- self._environ['PYTHONPATH'] = '%s:%s' % ( self._environ['PYTHONPATH'], os.path.abspath( 'lib' ) )
- else:
- self._environ['PYTHONPATH'] = os.path.abspath( 'lib' )
-
#Set TEMP if a valid temp value is not already set
if not ( 'TMPDIR' in self._environ or 'TEMP' in self._environ or 'TMP' in self._environ ):
self._environ[ 'TEMP' ] = tempfile.gettempdir()
@@ -58,12 +53,24 @@
## slots would be cleaner name, but don't want deployers to see examples and think it
## is going to work with other job runners.
slots = job_wrapper.job_destination.params.get( "local_slots", None )
- command_line = command_line.lstrip( " ;" )
if slots:
- command_line = 'GALAXY_SLOTS="%d"; export GALAXY_SLOTS; GALAXY_SLOTS_CONFIGURED="1"; export GALAXY_SLOTS_CONFIGURED; %s' % ( int( slots ), command_line )
+ slots_statement = 'GALAXY_SLOTS="%d"; export GALAXY_SLOTS; GALAXY_SLOTS_CONFIGURED="1"; export GALAXY_SLOTS_CONFIGURED;' % ( int( slots ) )
else:
- command_line = 'GALAXY_SLOTS="1"; export GALAXY_SLOTS; %s' % command_line
- return command_line
+ slots_statement = 'GALAXY_SLOTS="1"; export GALAXY_SLOTS;'
+
+ job_id = job_wrapper.get_id_tag()
+ job_file = JobState.default_job_file( job_wrapper.working_directory, job_id )
+ exit_code_path = JobState.default_exit_code_file( job_wrapper.working_directory, job_id )
+ job_script_props = {
+ 'slots_statement': slots_statement,
+ 'command': command_line,
+ 'exit_code_path': exit_code_path,
+ 'working_directory': job_wrapper.working_directory,
+ }
+ job_file_contents = self.get_job_file( job_wrapper, **job_script_props )
+ open( job_file, 'w' ).write( job_file_contents )
+ os.chmod( job_file, 0755 )
+ return job_file, exit_code_path
def queue_job( self, job_wrapper ):
# prepare the job
@@ -75,8 +82,7 @@
exit_code = 0
# command line has been added to the wrapper by prepare_job()
- command_line = self.__command_line( job_wrapper )
-
+ command_line, exit_code_path = self.__command_line( job_wrapper )
job_id = job_wrapper.get_id_tag()
try:
@@ -99,6 +105,11 @@
# Reap the process and get the exit code.
exit_code = proc.wait()
+ try:
+ exit_code = int( open( exit_code_path, 'r' ).read() )
+ except Exception:
+ log.warn( "Failed to read exit code from path %s" % exit_code_path )
+ pass
stdout_file.seek( 0 )
stderr_file.seek( 0 )
stdout = shrink_stream_by_size( stdout_file, DATABASE_MAX_STRING_SIZE, join_by="\n..\n", left_larger=True, beginning_on_size_error=True )
https://bitbucket.org/galaxy/galaxy-central/commits/5bf39d99f789/
Changeset: 5bf39d99f789
User: jmchilton
Date: 2014-05-19 04:12:36
Summary: Merged in jmchilton/galaxy-central-fork-1 (pull request #384)
Local Job Runner Enhancements
Affected #: 5 files
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 lib/galaxy/jobs/__init__.py
--- a/lib/galaxy/jobs/__init__.py
+++ b/lib/galaxy/jobs/__init__.py
@@ -1163,6 +1163,11 @@
return 'Job ran longer than the maximum allowed execution time (%s), please try different inputs or parameters' % self.app.job_config.limits.walltime
return None
+ def has_limits( self ):
+ has_output_limit = self.app.job_config.limits.output_size > 0
+ has_walltime_limit = self.app.job_config.limits.walltime_delta is not None
+ return has_output_limit or has_walltime_limit
+
def get_command_line( self ):
return self.command_line
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 lib/galaxy/jobs/runners/__init__.py
--- a/lib/galaxy/jobs/runners/__init__.py
+++ b/lib/galaxy/jobs/runners/__init__.py
@@ -196,7 +196,7 @@
output_pairs = []
# Walk job's output associations to find and use from_work_dir attributes.
job = job_wrapper.get_job()
- job_tool = self.app.toolbox.tools_by_id.get( job.tool_id, None )
+ job_tool = job_wrapper.tool
for dataset_assoc in job.output_datasets + job.output_library_datasets:
for dataset in dataset_assoc.dataset.dataset.history_associations + dataset_assoc.dataset.dataset.library_associations:
if isinstance( dataset, self.app.model.HistoryDatasetAssociation ):
@@ -269,7 +269,36 @@
self.work_queue.put( ( self.finish_job, ajs ) )
-class AsynchronousJobState( object ):
+class JobState( object ):
+ """
+ Encapsulate state of jobs.
+ """
+
+ def set_defaults( self, files_dir ):
+ if self.job_wrapper is not None:
+ id_tag = self.job_wrapper.get_id_tag()
+ if files_dir is not None:
+ self.job_file = JobState.default_job_file( files_dir, id_tag )
+ self.output_file = os.path.join( files_dir, 'galaxy_%s.o' % id_tag )
+ self.error_file = os.path.join( files_dir, 'galaxy_%s.e' % id_tag )
+ self.exit_code_file = os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
+ job_name = 'g%s' % id_tag
+ if self.job_wrapper.tool.old_id:
+ job_name += '_%s' % self.job_wrapper.tool.old_id
+ if self.job_wrapper.user:
+ job_name += '_%s' % self.job_wrapper.user
+ self.job_name = ''.join( map( lambda x: x if x in ( string.letters + string.digits + '_' ) else '_', job_name ) )
+
+ @staticmethod
+ def default_job_file( files_dir, id_tag ):
+ return os.path.join( files_dir, 'galaxy_%s.sh' % id_tag )
+
+ @staticmethod
+ def default_exit_code_file( files_dir, id_tag ):
+ return os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
+
+
+class AsynchronousJobState( JobState ):
"""
Encapsulate the state of an asynchronous job, this should be subclassed as
needed for various job runners to capture additional information needed
@@ -296,21 +325,6 @@
self.cleanup_file_attributes = [ 'job_file', 'output_file', 'error_file', 'exit_code_file' ]
- def set_defaults( self, files_dir ):
- if self.job_wrapper is not None:
- id_tag = self.job_wrapper.get_id_tag()
- if files_dir is not None:
- self.job_file = os.path.join( files_dir, 'galaxy_%s.sh' % id_tag )
- self.output_file = os.path.join( files_dir, 'galaxy_%s.o' % id_tag )
- self.error_file = os.path.join( files_dir, 'galaxy_%s.e' % id_tag )
- self.exit_code_file = os.path.join( files_dir, 'galaxy_%s.ec' % id_tag )
- job_name = 'g%s' % id_tag
- if self.job_wrapper.tool.old_id:
- job_name += '_%s' % self.job_wrapper.tool.old_id
- if self.job_wrapper.user:
- job_name += '_%s' % self.job_wrapper.user
- self.job_name = ''.join( map( lambda x: x if x in ( string.letters + string.digits + '_' ) else '_', job_name ) )
-
def cleanup( self ):
for file in [ getattr( self, a ) for a in self.cleanup_file_attributes if hasattr( self, a ) ]:
try:
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 lib/galaxy/jobs/runners/local.py
--- a/lib/galaxy/jobs/runners/local.py
+++ b/lib/galaxy/jobs/runners/local.py
@@ -11,13 +11,20 @@
from time import sleep
from galaxy import model
-from galaxy.jobs.runners import BaseJobRunner
+from ..runners import BaseJobRunner
+from ..runners import JobState
from galaxy.util import DATABASE_MAX_STRING_SIZE, shrink_stream_by_size
+from galaxy.util import asbool
log = logging.getLogger( __name__ )
__all__ = [ 'LocalJobRunner' ]
+DEFAULT_POOL_SLEEP_TIME = 1
+# TODO: Set to false and just get rid of this option. It would simplify this
+# class nicely. -John
+DEFAULT_EMBED_METADATA_IN_JOB = False
+
class LocalJobRunner( BaseJobRunner ):
"""
@@ -31,12 +38,6 @@
#create a local copy of os.environ to use as env for subprocess.Popen
self._environ = os.environ.copy()
- # put lib into the PYTHONPATH for subprocesses
- if 'PYTHONPATH' in self._environ:
- self._environ['PYTHONPATH'] = '%s:%s' % ( self._environ['PYTHONPATH'], os.path.abspath( 'lib' ) )
- else:
- self._environ['PYTHONPATH'] = os.path.abspath( 'lib' )
-
#Set TEMP if a valid temp value is not already set
if not ( 'TMPDIR' in self._environ or 'TEMP' in self._environ or 'TMP' in self._environ ):
self._environ[ 'TEMP' ] = os.path.abspath(tempfile.gettempdir())
@@ -52,24 +53,36 @@
## slots would be cleaner name, but don't want deployers to see examples and think it
## is going to work with other job runners.
slots = job_wrapper.job_destination.params.get( "local_slots", None )
- command_line = command_line.lstrip( " ;" )
if slots:
- command_line = 'GALAXY_SLOTS="%d"; export GALAXY_SLOTS; GALAXY_SLOTS_CONFIGURED="1"; export GALAXY_SLOTS_CONFIGURED; %s' % ( int( slots ), command_line )
+ slots_statement = 'GALAXY_SLOTS="%d"; export GALAXY_SLOTS; GALAXY_SLOTS_CONFIGURED="1"; export GALAXY_SLOTS_CONFIGURED;' % ( int( slots ) )
else:
- command_line = 'GALAXY_SLOTS="1"; export GALAXY_SLOTS; %s' % command_line
- return command_line
+ slots_statement = 'GALAXY_SLOTS="1"; export GALAXY_SLOTS;'
+
+ job_id = job_wrapper.get_id_tag()
+ job_file = JobState.default_job_file( job_wrapper.working_directory, job_id )
+ exit_code_path = JobState.default_exit_code_file( job_wrapper.working_directory, job_id )
+ job_script_props = {
+ 'slots_statement': slots_statement,
+ 'command': command_line,
+ 'exit_code_path': exit_code_path,
+ 'working_directory': job_wrapper.working_directory,
+ }
+ job_file_contents = self.get_job_file( job_wrapper, **job_script_props )
+ open( job_file, 'w' ).write( job_file_contents )
+ os.chmod( job_file, 0755 )
+ return job_file, exit_code_path
def queue_job( self, job_wrapper ):
# prepare the job
- if not self.prepare_job( job_wrapper ):
+ include_metadata = asbool( job_wrapper.job_destination.params.get( "embed_metadata_in_job", DEFAULT_EMBED_METADATA_IN_JOB ) )
+ if not self.prepare_job( job_wrapper, include_metadata=include_metadata ):
return
stderr = stdout = ''
exit_code = 0
# command line has been added to the wrapper by prepare_job()
- command_line = self.__command_line( job_wrapper )
-
+ command_line, exit_code_path = self.__command_line( job_wrapper )
job_id = job_wrapper.get_id_tag()
try:
@@ -85,22 +98,18 @@
preexec_fn=os.setpgrp )
job_wrapper.set_job_destination(job_wrapper.job_destination, proc.pid)
job_wrapper.change_state( model.Job.states.RUNNING )
- job_start = datetime.datetime.now()
- i = 0
- # Iterate until the process exits, periodically checking its limits
- while proc.poll() is None:
- i += 1
- if (i % 20) == 0:
- msg = job_wrapper.check_limits(runtime=datetime.datetime.now() - job_start)
- if msg is not None:
- job_wrapper.fail(msg)
- log.debug('(%s) Terminating process group' % job_id)
- self._terminate(proc)
- return
- else:
- sleep(1)
+
+ terminated = self.__poll_if_needed( proc, job_wrapper, job_id )
+ if terminated:
+ return
+
# Reap the process and get the exit code.
exit_code = proc.wait()
+ try:
+ exit_code = int( open( exit_code_path, 'r' ).read() )
+ except Exception:
+ log.warn( "Failed to read exit code from path %s" % exit_code_path )
+ pass
stdout_file.seek( 0 )
stderr_file.seek( 0 )
stdout = shrink_stream_by_size( stdout_file, DATABASE_MAX_STRING_SIZE, join_by="\n..\n", left_larger=True, beginning_on_size_error=True )
@@ -112,7 +121,9 @@
log.exception("failure running job %d" % job_wrapper.job_id)
job_wrapper.fail( "failure running job", exception=True )
return
- self._handle_metadata_externally( job_wrapper, resolve_requirements=True )
+ external_metadata = not asbool( job_wrapper.job_destination.params.get( "embed_metadata_in_job", DEFAULT_EMBED_METADATA_IN_JOB ) )
+ if external_metadata:
+ self._handle_metadata_externally( job_wrapper, resolve_requirements=True )
# Finish the job!
try:
job_wrapper.finish( stdout, stderr, exit_code )
@@ -168,3 +179,23 @@
if proc.poll() is None:
os.killpg( proc.pid, 9 )
return proc.wait() # reap
+
+ def __poll_if_needed( self, proc, job_wrapper, job_id ):
+ # Only poll if needed (i.e. job limits are set)
+ if not job_wrapper.has_limits():
+ return
+
+ job_start = datetime.datetime.now()
+ i = 0
+ # Iterate until the process exits, periodically checking its limits
+ while proc.poll() is None:
+ i += 1
+ if (i % 20) == 0:
+ msg = job_wrapper.check_limits(runtime=datetime.datetime.now() - job_start)
+ if msg is not None:
+ job_wrapper.fail(msg)
+ log.debug('(%s) Terminating process group' % job_id)
+ self._terminate(proc)
+ return True
+ else:
+ sleep( DEFAULT_POOL_SLEEP_TIME )
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 test/unit/jobs/test_runner_local.py
--- /dev/null
+++ b/test/unit/jobs/test_runner_local.py
@@ -0,0 +1,166 @@
+import os
+import threading
+import time
+from unittest import TestCase
+
+from galaxy.util import bunch
+from galaxy.jobs.runners import local
+from galaxy.jobs import metrics
+from galaxy import model
+
+from tools_support import (
+ UsesApp,
+ UsesTools
+)
+
+
+class TestLocalJobRunner( TestCase, UsesApp, UsesTools ):
+
+ def setUp( self ):
+ self.setup_app()
+ self._init_tool()
+ self.app.job_metrics = metrics.JobMetrics()
+ self.job_wrapper = MockJobWrapper( self.app, self.test_directory, self.tool )
+
+ def tearDown( self ):
+ self.tear_down_app()
+
+ def test_run( self ):
+ self.job_wrapper.command_line = "echo HelloWorld"
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "HelloWorld"
+
+ def test_galaxy_lib_on_path( self ):
+ self.job_wrapper.command_line = '''python -c "import galaxy.util"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.exit_code == 0
+
+ def test_default_slots( self ):
+ self.job_wrapper.command_line = '''echo $GALAXY_SLOTS'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "1"
+
+ def test_slots_override( self ):
+ # Set local_slots in job destination to specify slots for
+ # local job runner.
+ self.job_wrapper.job_destination.params[ "local_slots" ] = 3
+ self.job_wrapper.command_line = '''echo $GALAXY_SLOTS'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.stdout.strip() == "3"
+
+ def test_exit_code( self ):
+ self.job_wrapper.command_line = '''sh -c "exit 4"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert self.job_wrapper.exit_code == 4
+
+ def test_metadata_gets_set( self ):
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert os.path.exists( self.job_wrapper.mock_metadata_path )
+
+ def test_metadata_gets_set_if_embedded( self ):
+ self.job_wrapper.job_destination.params[ "embed_metadata_in_job" ] = "True"
+
+ # Kill off cruft for _handle_metadata_externally and make sure job stil works...
+ self.job_wrapper.external_output_metadata = None
+ self.app.datatypes_registry.set_external_metadata_tool = None
+
+ runner = local.LocalJobRunner( self.app, 1 )
+ runner.queue_job( self.job_wrapper )
+ assert os.path.exists( self.job_wrapper.mock_metadata_path )
+
+ def test_stopping_job( self ):
+ self.job_wrapper.command_line = '''python -c "import time; time.sleep(15)"'''
+ runner = local.LocalJobRunner( self.app, 1 )
+
+ def queue():
+ runner.queue_job( self.job_wrapper )
+
+ t = threading.Thread(target=queue)
+ t.start()
+ while True:
+ if self.job_wrapper.external_id:
+ break
+ time.sleep( .01 )
+ external_id = self.job_wrapper.external_id
+ mock_job = bunch.Bunch(
+ get_external_output_metadata=lambda: None,
+ get_job_runner_external_id=lambda: str(external_id),
+ get_id=lambda: 1
+ )
+ runner.stop_job( mock_job )
+ t.join(1)
+
+
+class MockJobWrapper( object ):
+
+ def __init__( self, app, test_directory, tool ):
+ working_directory = os.path.join( test_directory, "workdir" )
+ os.makedirs( working_directory )
+ self.app = app
+ self.tool = tool
+ self.state = model.Job.states.QUEUED
+ self.command_line = "echo HelloWorld"
+ self.prepare_called = False
+ self.write_version_cmd = None
+ self.dependency_shell_commands = None
+ self.working_directory = working_directory
+ self.requires_setting_metadata = True
+ self.job_destination = bunch.Bunch( id="default", params={} )
+ self.galaxy_lib_dir = os.path.abspath( "lib" )
+ self.job_id = 1
+ self.external_id = None
+ self.output_paths = [ '/tmp/output1.dat' ]
+ self.mock_metadata_path = os.path.abspath( os.path.join( test_directory, "METADATA_SET" ) )
+ self.metadata_command = "touch %s" % self.mock_metadata_path
+
+ # Cruft for setting metadata externally, axe at some point.
+ self.external_output_metadata = bunch.Bunch(
+ set_job_runner_external_pid=lambda pid, session: None
+ )
+ self.app.datatypes_registry.set_external_metadata_tool = bunch.Bunch(
+ build_dependency_shell_commands=lambda: []
+ )
+
+ def prepare( self ):
+ self.prepare_called = True
+
+ def set_job_destination( self, job_destination, external_id ):
+ self.external_id = external_id
+
+ def get_command_line( self ):
+ return self.command_line
+
+ def get_id_tag( self ):
+ return "1"
+
+ def get_state( self ):
+ return self.state
+
+ def change_state( self, state ):
+ self.state = state
+
+ def get_output_fnames( self ):
+ return []
+
+ def get_job( self ):
+ return model.Job()
+
+ def setup_external_metadata( self, **kwds ):
+ return self.metadata_command
+
+ def get_env_setup_clause( self ):
+ return ""
+
+ def has_limits( self ):
+ return False
+
+ def finish( self, stdout, stderr, exit_code ):
+ self.stdout = stdout
+ self.stderr = stderr
+ self.exit_code = exit_code
diff -r 632087d479859d0a8152267f6c21a623722bc875 -r 5bf39d99f7892bd8d9733f5efd68a8bb356c7bd9 test/unit/tools_support.py
--- a/test/unit/tools_support.py
+++ b/test/unit/tools_support.py
@@ -58,7 +58,7 @@
class UsesTools( object ):
- def _init_tool( self, tool_contents ):
+ def _init_tool( self, tool_contents=SIMPLE_TOOL_CONTENTS ):
self.tool_file = os.path.join( self.test_directory, "tool.xml" )
self.app.config.drmaa_external_runjob_script = ""
self.app.config.tool_secret = "testsecret"
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
17 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/632087d47985/
Changeset: 632087d47985
User: guerler
Date: 2014-05-17 16:45:14
Summary: Charts: Fix resizing
Affected #: 6 files
diff -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 -r 632087d479859d0a8152267f6c21a623722bc875 config/plugins/visualizations/charts/static/app.css
--- a/config/plugins/visualizations/charts/static/app.css
+++ b/config/plugins/visualizations/charts/static/app.css
@@ -54,13 +54,13 @@
display: inline-block;
}
-.charts-viewport .container {
+.charts-viewport .charts-viewport-container {
float: left;
display: block;
height: 100%;
}
-.charts-viewport .canvas {
+.charts-viewport .charts-viewport-canvas {
display: block;
width:100%;
height: inherit;
diff -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 -r 632087d479859d0a8152267f6c21a623722bc875 config/plugins/visualizations/charts/static/build-app.js
--- a/config/plugins/visualizations/charts/static/build-app.js
+++ b/config/plugins/visualizations/charts/static/build-app.js
@@ -3,4 +3,4 @@
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore may be freely distributed under the MIT license.
-define("mvc/ui/ui-modal",[],function(){var e=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1,closing_callback:null},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast"),this.options.closing_callback&&this.options.closing_callback()},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup.ui-modal")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&($(document).on("keyup.ui-modal",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:e}}),function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}.call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{url:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},_template:function(e){return'<img src="'+e.url+'"/>'}}),r=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return'<label class="'+e.cls+'"><b>'+e.title+"</b></label>"},value:function(){return options.title}}),i=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.html(e)},_template:function(e){return'<div class="'+e.cls+'">'+e.title+"</div>"},value:function(){return options.title}}),s=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),o=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),u=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),a=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),f=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),l=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),c=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),h=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),p=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:r,Image:n,Button:s,Icon:u,ButtonIcon:o,Input:p,Anchor:a,Message:f,Searchbox:l,Title:c,Text:i,Select:t,ButtonMenu:h}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(e,t,n,r,i){var s=this;e.state("wait","Requesting job results...");var o=e.get("dataset_id_job");o!=""?s._wait(e,r,i):s._submit(e,t,n,r,i)},cleanup:function(t){var n=this,r=t.get("dataset_id_job");r!=""&&(e.request("PUT",config.root+"api/histories/none/contents/"+r,{deleted:!0},function(){n._refreshHdas()}),t.set("dataset_id_job",""))},_submit:function(t,n,r,i,s){var o=this,u=t.id,a=t.get("type"),f=this.app.types.get(a);data={tool_id:"charts",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:f.execute,columns:r,settings:n}},t.state("wait","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response."),s&&s();else{o._refreshHdas();var n=e.outputs[0];t.state("wait","Your job has been queued. You may close the browser window. The job will run in the background."),t.set("dataset_id_job",n.id),this.app.storage.save(),o._wait(t,i,s)}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the 'charts' tool. Please make sure it is installed. "+n),s&&s()})},_wait:function(t,n,r){var i=this;e.request("GET",config.root+"api/datasets/"+t.get("dataset_id_job"),{},function(e){var s=!1;switch(e.state){case"ok":t.state("wait","Job completed successfully..."),n&&n(e),s=!0;break;case"error":t.state("failed","Job has failed. Please check the history for details."),r&&r(e),s=!0;break;case"running":t.state("wait","Your job is running. You may close the browser window. The job will continue in the background.")}s||setTimeout(function(){i._wait(t,n,r)},i.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshContents()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},cache:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._get(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_block_id:function(e,t){return e.id+"_"+e.start+"_"+e.end+"_"+t},_get:function(e,t){e.start||(e.start=0),e.end||(e.end=this.app.config.get("query_limit"));var n=[],r={},i=0;for(var s in e.groups){var o=e.groups[s];for(var u in o.columns){var a=o.columns[u].index,f=this._block_id(e,a);if(this.cache[f])continue;!r[a]&&a!==undefined&&(r[a]=i,n.push(a),i++)}}if(n.length==0){this._fill_from_cache(e),t(e);return}var l={dataset_id:e.id,start:e.start,end:e.end,columns:n},c=this;this._fetch(l,function(r){for(var i in r){var s=n[i],o=c._block_id(e,s);c.cache[o]=r[i]}c._fill_from_cache(e),t(e)})},_fill_from_cache:function(e){console.debug("Datasets::_fill_from_cache() - Filling request from cache.");for(var t in e.groups){var n=e.groups[t];n.values=[];for(var r in n.columns){var i=n.columns[r],s=this._block_id(e,i.index),o=this.cache[s];for(k in o){var u=n.values[k];u===undefined&&(u={x:parseInt(k)+e.start},n.values[k]=u);var a=o[k];isNaN(a)&&!i.is_label&&(a=0),u[r]=a}}}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o=0;t.columns&&(o=t.columns.length,console.debug("Datasets::_fetch() - Fetching "+o+" column(s)")),o==0&&console.debug("Datasets::_fetch() - No columns requested");var u="";for(var a in t.columns)u+=t.columns[a]+",";u=u.substring(0,u.length-1);var f=this;e.request("GET",config.root+"api/datasets/"+t.dataset_id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:u},function(e){var t=new Array(o);for(var r=0;r<o;r++)t[r]=[];for(var r in e.data){var i=e.data[r];for(var s in i){var u=i[s];u!==undefined&&u!=2147483647&&t[s].push(u)}}console.debug("Datasets::_fetch() - Fetching complete."),n(t)})}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})}),define("plugin/library/deferred",["utils/utils"],function(e){return Backbone.Model.extend({queue:[],process:{},counter:0,initialize:function(){this.on("refresh",function(){if(this.counter==0)for(var e in this.queue)this.queue[e](),this.queue.splice(e,1)})},execute:function(e){this.queue.push(e),this.trigger("refresh")},register:function(){var t=e.uuid();return this.process[t]=!0,this.counter++,console.debug("Deferred:register() - Registering "+t),t},done:function(e){this.process[e]&&(delete this.process[e],this.counter--,console.debug("Deferred:done() - Unregistering "+e),this.trigger("refresh"))},ready:function(){return this.counter==0}})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","plugin/library/deferred","mvc/visualization/visualization-model"],function(e,t){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"",state_info:"",modified:!1,dataset_id:"",dataset_id_job:""},initialize:function(n){this.groups=new e,this.settings=new Backbone.Model,this.deferred=new t},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state",e),this.set("state_info",t),this.trigger("set:state"),console.debug("Chart:state() - "+t+" ("+e+")")}})}),define("plugin/library/storage",["utils/utils","plugin/models/chart","plugin/models/group"],function(e,t,n){return Backbone.Model.extend({vis:null,initialize:function(e){this.app=e,this.chart=this.app.chart,this.options=this.app.options,this.id=this.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.options.config.dataset_id,chart_dict:{}}}),this.id&&(this.vis.id=this.id);var t=this.options.config.chart_dict;t&&(this.vis.get("config").chart_dict=t)},save:function(){var e=this.app.chart;this.vis.get("config").chart_dict={};var t=e.get("title");t!=""&&this.vis.set("title",t);var n={attributes:e.attributes,settings:e.settings.attributes,groups:[]};e.groups.each(function(e){n.groups.push(e.attributes)}),this.vis.get("config").chart_dict=n;var r=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n)}).then(function(e){e&&e.id&&(r.id=e.id)})},load:function(){var e=this.vis.get("config").chart_dict;if(!e.attributes)return!1;this.chart.set(e.attributes),this.chart.state("ok","Loading saved visualization..."),this.chart.settings.set(e.settings);for(var t in e.groups)this.chart.groups.add(new n(e.groups[t]));return this.chart.set("modified",!1),!0}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({container_list:[],canvas_list:[],initialize:function(e,t){this.app=e,this.chart=this.app.chart,this.options=n.merge(t,this.optionsDefault),this.setElement($(this._template())),this._fullscreen(this.$el,80),this._createContainer("div");var r=this;this.chart.on("redraw",function(){r._draw(r.chart)}),this.chart.on("set:state",function(){var e=r.$el.find("#info"),t=r.$el.find("container"),n=e.find("#icon");n.removeClass(),e.show(),e.find("#text").html(r.chart.get("state_info")),t.hide();var i=r.chart.get("state");switch(i){case"ok":e.hide(),t.show();break;case"failed":n.addClass("icon fa fa-warning");break;default:n.addClass("icon fa fa-spinner fa-spin")}})},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_fullscreen:function(e,t){e.css("height",$(window).height()-t),$(window).resize(function(){e.css("height",$(window).height()-t)})},_createContainer:function(e,t){t=t||1;for(var n in this.container_list)this.container_list[n].remove();this.container_list=[],this.canvas_list=[];for(var n=0;n<t;n++){var r=$(this._templateContainer(e,parseInt(100/t)));this.$el.append(r),this.container_list[n]=r,e=="svg"?this.canvas_list[n]=d3.select(r.find("#canvas")[0]):this.canvas_list[n]=r.find("#canvas")}},_draw:function(e){var t=this,n=e.deferred.register(),r=e.get("type");this.chart_settings=this.app.types.get(r);var i=this.chart_settings.use_panels,s=1;i&&(s=e.groups.length),this._createContainer(this.chart_settings.tag,s),e.state("wait","Please wait...");if(!this.chart_settings.execute||this.chart_settings.execute&&e.get("modified"))this.app.jobs.cleanup(e),e.set("modified",!1);var t=this;require(["plugin/charts/"+r+"/wrapper"],function(r){var i=new r(t.app,{canvas:t.canvas_list});t.chart_settings.execute?t.app.jobs.request(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){i.draw(n,e,t._defaultRequestDictionary(e))},function(){e.deferred.done(n)}):i.draw(n,e,t._defaultRequestDictionary(e))})},_defaultRequestString:function(e){var t="",n=0,r=this;return e.groups.each(function(e){n++;for(var i in r.chart_settings.columns)t+=i+"_"+n+":"+(parseInt(e.get(i))+1)+", "}),t.substring(0,t.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t={groups:[]};this.chart_settings.execute?t.id=e.get("dataset_id_job"):t.id=e.get("dataset_id");var n=0,r=this;return e.groups.each(function(e){var i={};for(var s in r.chart_settings.columns){var o=r.chart_settings.columns[s];i[s]={index:e.get(s),is_label:o.is_label}}t.groups.push({key:++n+":"+e.get("key"),columns:i})}),t},_template:function(){return'<div class="charts-viewport"><div id="info" class="info"><span id="icon" class="icon" /><span id="text" class="text" /></div></div>'},_templateContainer:function(e,t){return'<div class="container" style="width:'+t+'%;">'+'<div id="menu"/>'+"<"+e+' id="canvas" class="canvas">'+"</div>"}})}),define("plugin/views/viewer",["utils/utils","plugin/library/ui","mvc/ui/ui-portlet","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i){return Backbone.View.extend({initialize:function(e,r){this.app=e,this.chart=this.app.chart,this.viewport_view=new i(e);var s=this;this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Viewport",operations:{edit_button:new t.ButtonIcon({icon:"fa-edit",tooltip:"Customize this chart",title:"Editor",onclick:function(){s._wait(s.chart,function(){s.app.go("editor")})}})}}),this.portlet.append(this.viewport_view.$el),this.setElement(this.portlet.$el);var s=this;this.chart.on("change:title",function(){s._refreshTitle()})},show:function(){this.$el.show(),$(window).trigger("resize")},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e)},_screenshot:function(){var e=new XMLSerializer,t=e.serializeToString(this.viewport_view.svg.node()),n="data:image/svg+xml;base64,"+btoa(t);window.location.href="data:application/x-download/;charset=utf-8,"+encodeURIComponent(t)},_wait:function(e,t){if(e.deferred.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:"Your chart is currently being processed. Please wait and try again.",buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t,n){var r=$("<td></td>");t&&r.css("width",t),n&&r.css("text-align",n),r.append(e),this.row.append(r)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n!=""&&n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e),r.chart.set("modified",!0)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.chart.state("wait","Loading metadata...");var l=this.chart.deferred.register();this.app.datasets.request({id:e},function(e){for(var t in s){var n=i.columns[t].is_label,o=[],u=e.metadata_column_types;for(var a in u)(!n&&(u[a]=="int"||u[a]=="float")||n)&&o.push({label:"Column: "+(parseInt(a)+1)+" ["+u[a]+"]",value:a});s[t].update(o),s[t].show()}r.chart.state("ok","Metadata initialized..."),r.chart.deferred.done(l)})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({list:[],initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll(),this.list=[];for(var n in e)this._add(n,e[n],t);for(var n in this.list){var r=this.list[n].options.onchange;r&&r()}},_add:function(e,n,r){var i=this,s=null,o=n.type;switch(o){case"text":s=new t.Input({id:e,placeholder:n.placeholder,onchange:function(){r.set(e,s.value())}});break;case"select":s=new t.Select.View({id:e,data:n.data,onchange:function(){var t=s.value();r.set(e,t);var o=_.findWhere(n.data,{value:t});o&&(o.show&&i.$el.find("#"+o.show).fadeIn("fast"),o.hide&&i.$el.find("#"+o.hide).fadeOut("fast"))}});break;case"separator":s=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(o!="separator"){r.get(e)||r.set(e,n.init),s.value(r.get(e)),this.list[e]=s;var u=$("<div/>");u.append(s.$el),u.append('<div class="toolParamHelp" style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(u)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.category+" - "+t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/types",["utils/utils","plugin/library/ui"],function(e,t){return Backbone.View.extend({optionsDefault:{onchange:null,ondblclick:null},events:{click:"_onclick",dblclick:"_ondblclick"},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault);var r=$('<div class="charts-grid"/>');this.setElement(r);var i={},s=t.types.attributes;for(var o in s){var u=s[o],a=u.category;i[a]||(i[a]={}),i[a][o]=u}for(var a in i){var r=$('<div style="clear: both;"/>');r.append(e.wrap(this._template_header({title:a})));for(var o in i[a]){var u=i[a][o];r.append(e.wrap(this._template_item({id:o,title:u.title,url:config.app_root+"charts/"+o+"/logo.png"})))}this.$el.append(e.wrap(r))}},value:function(e){var t=this.$el.find(".current").attr("id");e!==undefined&&(this.$el.find(".current").removeClass("current"),this.$el.find("#"+e).addClass("current"));var n=this.$el.find(".current").attr("id");return n===undefined?null:(n!=t&&this.options.onchange&&this.options.onchange(e),n)},_onclick:function(e){var t=this.value(),n=$(e.target).closest(".item").attr("id");n!=""&&n&&t!=n&&this.value(n)},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_template_header:function(e){return'<div class="header">• '+e.title+"<div>"},_template_item:function(e){return'<div id="'+e.id+'" class="item">'+'<img class="image" src="'+e.url+'">'+'<div class="title">'+e.title+"</div>"+"<div>"}})}),define("plugin/views/editor",["mvc/ui/ui-tabs","plugin/library/ui","mvc/ui/ui-portlet","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings","plugin/views/types"],function(e,t,n,r,i,s,o,u,a){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(i,s){var o=this;this.app=i,this.chart=this.app.chart,this.options=r.merge(s,this.optionsDefault),this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Editor",operations:{save:new t.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){o.app.go("viewer"),o._saveChart()}}),back:new t.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){o.app.go("viewer"),o.app.storage.load()}})}}),this.types=new a(i,{onchange:function(e){o.chart.settings.clear(),o.chart.set({type:e}),o.chart.set("modified",!0)},ondblclick:function(e){o.app.go("viewer"),o._saveChart()}}),this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=o._addGroupModel();o.tabs.show(e.id)}}),this.title=new t.Input({placeholder:"Chart title",onchange:function(){o.chart.set("title",o.title.value())}});var f=$("<div/>");f.append(r.wrap((new t.Label({title:"Provide a chart title:"})).$el)),f.append(r.wrap(this.title.$el)),f.append(r.wrap((new t.Label({title:"Select a chart type:"})).$el)),f.append(r.wrap(this.types.$el)),this.tabs.add({id:"main",title:"Start",$el:f}),this.settings=new u(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.portlet.append(this.tabs.$el),this.setElement(this.portlet.$el),this.tabs.hideOperation("back");var o=this;this.chart.on("change:title",function(e){o._refreshTitle()}),this.chart.on("change:type",function(e){o.types.value(e.get("type"))}),this.chart.on("reset",function(e){o._resetChart()}),this.app.chart.on("redraw",function(e){o.portlet.showOperation("back")}),this.app.chart.groups.on("add",function(e){o._addGroup(e)}),this.app.chart.groups.on("remove",function(e){o._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){o._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){o._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e),this.title.value(e)},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new s({id:r.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new o(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey(),this.chart.set("modified",!0)},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",r.uuid()),this.chart.set("type","nvd3_bar"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart"),this.portlet.hideOperation("back")},_saveChart:function(){this.chart.set({type:this.types.value(),title:this.title.value(),date:r.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this;this.chart.deferred.execute(function(){e.app.storage.save(),e.chart.trigger("redraw")})}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:5e3,query_timeout:500}})}),define("plugin/charts/nvd3/config",[],function(){return{title:"",category:"",library:"nvd3.js",tag:"svg",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"x_axis_tick"},{label:"Auto",value:"auto",hide:"x_axis_tick"},{label:"Float",value:"f",show:"x_axis_tick"},{label:"Exponent",value:"e",show:"x_axis_tick"},{label:"Integer",value:"d",hide:"x_axis_tick"},{label:"Percentage",value:"p",show:"x_axis_tick"},{label:"Rounded",value:"r",show:"x_axis_tick"},{label:"SI-prefix",value:"s",show:"x_axis_tick"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"y_axis_tick"},{label:"Auto",value:"auto",hide:"y_axis_tick"},{label:"Float",value:"f",show:"y_axis_tick"},{label:"Exponent",value:"e",show:"y_axis_tick"},{label:"Integer",value:"d",hide:"y_axis_tick"},{label:"Percentage",value:"p",show:"y_axis_tick"},{label:"Rounded",value:"r",show:"y_axis_tick"},{label:"SI-prefix",value:"s",show:"y_axis_tick"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/nvd3_bar/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Regular",category:"Bar diagrams"})}),define("plugin/charts/nvd3_bar_stacked/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked",category:"Bar diagrams"})}),define("plugin/charts/nvd3_bar_horizontal/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Horizontal",category:"Bar diagrams",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/nvd3_bar_horizontal_stacked/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked horizontal",category:"Bar diagrams",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/nvd3_histogram/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",category:"Data processing (requires 'charts' tool from Toolshed)",execute:"histogram",columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_type:{init:"f"},y_axis_tick:{init:".2"}}})}),define("plugin/charts/nvd3_line/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart",category:"Others"})}),define("plugin/charts/nvd3_line_focus/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus",category:"Others"})}),define("plugin/charts/nvd3_pie/config",[],function(){return{title:"Pie chart",library:"nvd3.js",category:"Area charts",tag:"svg",use_panels:!0,columns:{label:{title:"Labels",is_label:!0},y:{title:"Values"}},settings:{show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]},donut_ratio:{title:"Donut ratio",info:"Determine how large the donut hole will be.",type:"select",init:"0.5",data:[{label:"50%",value:"0.5"},{label:"25%",value:"0.25"},{label:"10%",value:"0.10"},{label:"0%",value:"0"}]},label_separator:{type:"separator",title:"Label settings"},label_type:{title:"Donut label",info:"What would you like to show for each slice?",type:"select",init:"percent",data:[{label:"-- Nothing --",value:"hide",hide:"label_outside"},{label:"Label column",value:"key",show:"label_outside"},{label:"Value column",value:"value",show:"label_outside"},{label:"Percentage",value:"percent",show:"label_outside"}]},label_outside:{title:"Show outside",info:"Would you like to show labels outside the donut?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/nvd3_scatter/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",category:"Others",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/nvd3_stackedarea/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Regular",category:"Area charts"})}),define("plugin/charts/nvd3_stackedarea_full/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Expanded",category:"Area charts"})}),define("plugin/charts/nvd3_stackedarea_stream/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stream",category:"Area charts"})}),define("plugin/charts/highcharts_boxplot/config",[],function(){return{title:"Box plot",category:"Data processing (requires 'charts' tool from Toolshed)",library:"highcharts.js",tag:"div",execute:"boxplot",columns:{y:{title:"Observations"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"}}}}),define("plugin/charts/heatmap/config",[],function(){return{title:"Heatmap",category:"Data processing (requires 'charts' tool from Toolshed)",library:"",tag:"div",use_panels:!0,execute:"heatmap",columns:{row_label:{title:"Row labels",is_label:!0},col_label:{title:"Column labels",is_label:!0},value:{title:"Observations"}},settings:{color_set:{title:"Color scheme",info:"Select a color scheme for your heatmap",type:"select",init:"ocean",data:[{label:"Cold-to-Hot",value:"hot"},{label:"Cool",value:"cool"},{label:"Copper",value:"copper"},{label:"Gebco",value:"gebco"},{label:"Globe",value:"globe"},{label:"Gray scale",value:"gray"},{label:"Haxby",value:"haxby"},{label:"Jet",value:"jet"},{label:"No-Green",value:"no_green"},{label:"Ocean",value:"ocean"},{label:"Polar",value:"polar"},{label:"Rainbow",value:"rainbow"},{label:"Red-to-Green",value:"redgreen"},{label:"Red-to-green (saturated)",value:"red2green"},{label:"Relief",value:"relief"},{label:"Seismograph",value:"seis"},{label:"Sealand",value:"sealand"},{label:"Split",value:"split"},{label:"Topo",value:"topo"},{label:"Wysiwyg",value:"wysiwyg"}]},sorting:{title:"Sorting",info:"How should the columns be clustered?",type:"select",init:"hclust",data:[{label:"Read from dataset",value:"hclust"},{label:"Sort column and row labels",value:"byboth"},{label:"Sort column labels",value:"bycolumns"},{label:"Sort by rows",value:"byrow"}]}},menu:function(){return{color_set:this.settings.color_set}}}}),define("plugin/charts/types",["plugin/charts/nvd3_bar/config","plugin/charts/nvd3_bar_stacked/config","plugin/charts/nvd3_bar_horizontal/config","plugin/charts/nvd3_bar_horizontal_stacked/config","plugin/charts/nvd3_histogram/config","plugin/charts/nvd3_line/config","plugin/charts/nvd3_line_focus/config","plugin/charts/nvd3_pie/config","plugin/charts/nvd3_scatter/config","plugin/charts/nvd3_stackedarea/config","plugin/charts/nvd3_stackedarea_full/config","plugin/charts/nvd3_stackedarea_stream/config","plugin/charts/highcharts_boxplot/config","plugin/charts/heatmap/config"],function(e,t,n,r,i,s,o,u,a,f,l,c,h,p){return Backbone.Model.extend({defaults:{nvd3_bar:e,nvd3_bar_stacked:t,nvd3_bar_horizontal:n,nvd3_bar_horizontal_stacked:r,nvd3_stackedarea:f,nvd3_stackedarea_full:l,nvd3_stackedarea_stream:c,nvd3_line:s,nvd3_line_focus:o,nvd3_scatter:a,nvd3_pie:u,nvd3_histogram:i,highcharts_boxplot:h,heatmap:p}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/library/storage","plugin/views/viewer","plugin/views/editor","plugin/models/config","plugin/models/chart","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(t){this.options=t,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new f,this.types=new c,this.chart=new l,this.jobs=new i(this),this.datasets=new s(this),this.storage=new o(this),this.viewer_view=new u(this),this.editor_view=new a(this),this.$el.append(this.viewer_view.$el),this.$el.append(this.editor_view.$el);if(!this.storage.load())this.go("editor");else{this.go("viewer");var n=this;this.chart.deferred.execute(function(){n.chart.trigger("redraw")})}},go:function(e){$(".tooltip").hide();switch(e){case"editor":this.editor_view.show(),this.viewer_view.hide();break;case"viewer":this.editor_view.hide(),this.viewer_view.show()}},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
+define("mvc/ui/ui-modal",[],function(){var e=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1,closing_callback:null},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast"),this.options.closing_callback&&this.options.closing_callback()},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup.ui-modal")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&($(document).on("keyup.ui-modal",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:e}}),function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}.call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{url:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},_template:function(e){return'<img src="'+e.url+'"/>'}}),r=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return'<label class="'+e.cls+'"><b>'+e.title+"</b></label>"},value:function(){return options.title}}),i=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.html(e)},_template:function(e){return'<div class="'+e.cls+'">'+e.title+"</div>"},value:function(){return options.title}}),s=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),o=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),u=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),a=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),f=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),l=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),c=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),h=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),p=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:r,Image:n,Button:s,Icon:u,ButtonIcon:o,Input:p,Anchor:a,Message:f,Searchbox:l,Title:c,Text:i,Select:t,ButtonMenu:h}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(e,t,n,r,i){var s=this;e.state("wait","Requesting job results...");var o=e.get("dataset_id_job");o!=""?s._wait(e,r,i):s._submit(e,t,n,r,i)},cleanup:function(t){var n=this,r=t.get("dataset_id_job");r!=""&&(e.request("PUT",config.root+"api/histories/none/contents/"+r,{deleted:!0},function(){n._refreshHdas()}),t.set("dataset_id_job",""))},_submit:function(t,n,r,i,s){var o=this,u=t.id,a=t.get("type"),f=this.app.types.get(a);data={tool_id:"charts",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:f.execute,columns:r,settings:n}},t.state("wait","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response."),s&&s();else{o._refreshHdas();var n=e.outputs[0];t.state("wait","Your job has been queued. You may close the browser window. The job will run in the background."),t.set("dataset_id_job",n.id),this.app.storage.save(),o._wait(t,i,s)}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the 'charts' tool. Please make sure it is installed. "+n),s&&s()})},_wait:function(t,n,r){var i=this;e.request("GET",config.root+"api/datasets/"+t.get("dataset_id_job"),{},function(e){var s=!1;switch(e.state){case"ok":t.state("wait","Job completed successfully..."),n&&n(e),s=!0;break;case"error":t.state("failed","Job has failed. Please check the history for details."),r&&r(e),s=!0;break;case"running":t.state("wait","Your job is running. You may close the browser window. The job will continue in the background.")}s||setTimeout(function(){i._wait(t,n,r)},i.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshContents()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},cache:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._get(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_block_id:function(e,t){return e.id+"_"+e.start+"_"+e.end+"_"+t},_get:function(e,t){e.start||(e.start=0),e.end||(e.end=this.app.config.get("query_limit"));var n=[],r={},i=0;for(var s in e.groups){var o=e.groups[s];for(var u in o.columns){var a=o.columns[u].index,f=this._block_id(e,a);if(this.cache[f])continue;!r[a]&&a!==undefined&&(r[a]=i,n.push(a),i++)}}if(n.length==0){this._fill_from_cache(e),t(e);return}var l={dataset_id:e.id,start:e.start,end:e.end,columns:n},c=this;this._fetch(l,function(r){for(var i in r){var s=n[i],o=c._block_id(e,s);c.cache[o]=r[i]}c._fill_from_cache(e),t(e)})},_fill_from_cache:function(e){console.debug("Datasets::_fill_from_cache() - Filling request from cache.");for(var t in e.groups){var n=e.groups[t];n.values=[];for(var r in n.columns){var i=n.columns[r],s=this._block_id(e,i.index),o=this.cache[s];for(k in o){var u=n.values[k];u===undefined&&(u={x:parseInt(k)+e.start},n.values[k]=u);var a=o[k];isNaN(a)&&!i.is_label&&(a=0),u[r]=a}}}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o=0;t.columns&&(o=t.columns.length,console.debug("Datasets::_fetch() - Fetching "+o+" column(s)")),o==0&&console.debug("Datasets::_fetch() - No columns requested");var u="";for(var a in t.columns)u+=t.columns[a]+",";u=u.substring(0,u.length-1);var f=this;e.request("GET",config.root+"api/datasets/"+t.dataset_id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:u},function(e){var t=new Array(o);for(var r=0;r<o;r++)t[r]=[];for(var r in e.data){var i=e.data[r];for(var s in i){var u=i[s];u!==undefined&&u!=2147483647&&t[s].push(u)}}console.debug("Datasets::_fetch() - Fetching complete."),n(t)})}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})}),define("plugin/library/deferred",["utils/utils"],function(e){return Backbone.Model.extend({queue:[],process:{},counter:0,initialize:function(){this.on("refresh",function(){if(this.counter==0)for(var e in this.queue)this.queue[e](),this.queue.splice(e,1)})},execute:function(e){this.queue.push(e),this.trigger("refresh")},register:function(){var t=e.uuid();return this.process[t]=!0,this.counter++,console.debug("Deferred:register() - Registering "+t),t},done:function(e){this.process[e]&&(delete this.process[e],this.counter--,console.debug("Deferred:done() - Unregistering "+e),this.trigger("refresh"))},ready:function(){return this.counter==0}})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","plugin/library/deferred","mvc/visualization/visualization-model"],function(e,t){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"",state_info:"",modified:!1,dataset_id:"",dataset_id_job:""},initialize:function(n){this.groups=new e,this.settings=new Backbone.Model,this.deferred=new t},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state",e),this.set("state_info",t),this.trigger("set:state"),console.debug("Chart:state() - "+t+" ("+e+")")}})}),define("plugin/library/storage",["utils/utils","plugin/models/chart","plugin/models/group"],function(e,t,n){return Backbone.Model.extend({vis:null,initialize:function(e){this.app=e,this.chart=this.app.chart,this.options=this.app.options,this.id=this.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.options.config.dataset_id,chart_dict:{}}}),this.id&&(this.vis.id=this.id);var t=this.options.config.chart_dict;t&&(this.vis.get("config").chart_dict=t)},save:function(){var e=this.app.chart;this.vis.get("config").chart_dict={};var t=e.get("title");t!=""&&this.vis.set("title",t);var n={attributes:e.attributes,settings:e.settings.attributes,groups:[]};e.groups.each(function(e){n.groups.push(e.attributes)}),this.vis.get("config").chart_dict=n;var r=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n)}).then(function(e){e&&e.id&&(r.id=e.id)})},load:function(){var e=this.vis.get("config").chart_dict;if(!e.attributes)return!1;this.chart.set(e.attributes),this.chart.state("ok","Loading saved visualization..."),this.chart.settings.set(e.settings);for(var t in e.groups)this.chart.groups.add(new n(e.groups[t]));return this.chart.set("modified",!1),!0}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({container_list:[],canvas_list:[],initialize:function(e,t){this.app=e,this.chart=this.app.chart,this.options=n.merge(t,this.optionsDefault),this.setElement($(this._template())),this._fullscreen(this.$el,80),this._createContainer("div");var r=this;this.chart.on("redraw",function(){r._draw(r.chart)}),this.chart.on("set:state",function(){var e=r.$el.find("#info"),t=r.$el.find("container"),n=e.find("#icon");n.removeClass(),e.show(),e.find("#text").html(r.chart.get("state_info")),t.hide();var i=r.chart.get("state");switch(i){case"ok":e.hide(),t.show();break;case"failed":n.addClass("icon fa fa-warning");break;default:n.addClass("icon fa fa-spinner fa-spin")}})},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_fullscreen:function(e,t){e.css("height",$(window).height()-t),$(window).resize(function(){e.css("height",$(window).height()-t)})},_createContainer:function(e,t){t=t||1;for(var n in this.container_list)this.container_list[n].remove();this.container_list=[],this.canvas_list=[];for(var n=0;n<t;n++){var r=$(this._templateContainer(e,parseInt(100/t)));this.$el.append(r),this.container_list[n]=r,e=="svg"?this.canvas_list[n]=d3.select(r.find("#canvas")[0]):this.canvas_list[n]=r.find("#canvas")}},_draw:function(e){var t=this,n=e.deferred.register(),r=e.get("type");this.chart_settings=this.app.types.get(r);var i=this.chart_settings.use_panels,s=1;i&&(s=e.groups.length),this._createContainer(this.chart_settings.tag,s),e.state("wait","Please wait...");if(!this.chart_settings.execute||this.chart_settings.execute&&e.get("modified"))this.app.jobs.cleanup(e),e.set("modified",!1);var t=this;require(["plugin/charts/"+r+"/wrapper"],function(r){var i=new r(t.app,{canvas:t.canvas_list});t.chart_settings.execute?t.app.jobs.request(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){i.draw(n,e,t._defaultRequestDictionary(e))},function(){e.deferred.done(n)}):i.draw(n,e,t._defaultRequestDictionary(e))})},_defaultRequestString:function(e){var t="",n=0,r=this;return e.groups.each(function(e){n++;for(var i in r.chart_settings.columns)t+=i+"_"+n+":"+(parseInt(e.get(i))+1)+", "}),t.substring(0,t.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t={groups:[]};this.chart_settings.execute?t.id=e.get("dataset_id_job"):t.id=e.get("dataset_id");var n=0,r=this;return e.groups.each(function(e){var i={};for(var s in r.chart_settings.columns){var o=r.chart_settings.columns[s];i[s]={index:e.get(s),is_label:o.is_label}}t.groups.push({key:++n+":"+e.get("key"),columns:i})}),t},_template:function(){return'<div class="charts-viewport"><div id="info" class="info"><span id="icon" class="icon" /><span id="text" class="text" /></div></div>'},_templateContainer:function(e,t){return'<div class="charts-viewport-container" style="width:'+t+'%;">'+'<div id="menu"/>'+"<"+e+' id="canvas" class="charts-viewport-canvas">'+"</div>"}})}),define("plugin/views/viewer",["utils/utils","plugin/library/ui","mvc/ui/ui-portlet","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i){return Backbone.View.extend({initialize:function(e,r){this.app=e,this.chart=this.app.chart,this.viewport_view=new i(e);var s=this;this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Viewport",operations:{edit_button:new t.ButtonIcon({icon:"fa-edit",tooltip:"Customize this chart",title:"Editor",onclick:function(){s._wait(s.chart,function(){s.app.go("editor")})}})}}),this.portlet.append(this.viewport_view.$el),this.setElement(this.portlet.$el);var s=this;this.chart.on("change:title",function(){s._refreshTitle()})},show:function(){this.$el.show(),$(window).trigger("resize")},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e)},_screenshot:function(){var e=new XMLSerializer,t=e.serializeToString(this.viewport_view.svg.node()),n="data:image/svg+xml;base64,"+btoa(t);window.location.href="data:application/x-download/;charset=utf-8,"+encodeURIComponent(t)},_wait:function(e,t){if(e.deferred.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:"Your chart is currently being processed. Please wait and try again.",buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t,n){var r=$("<td></td>");t&&r.css("width",t),n&&r.css("text-align",n),r.append(e),this.row.append(r)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n!=""&&n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e),r.chart.set("modified",!0)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.chart.state("wait","Loading metadata...");var l=this.chart.deferred.register();this.app.datasets.request({id:e},function(e){for(var t in s){var n=i.columns[t].is_label,o=[],u=e.metadata_column_types;for(var a in u)(!n&&(u[a]=="int"||u[a]=="float")||n)&&o.push({label:"Column: "+(parseInt(a)+1)+" ["+u[a]+"]",value:a});s[t].update(o),s[t].show()}r.chart.state("ok","Metadata initialized..."),r.chart.deferred.done(l)})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({list:[],initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll(),this.list=[];for(var n in e)this._add(n,e[n],t);for(var n in this.list){var r=this.list[n].options.onchange;r&&r()}},_add:function(e,n,r){var i=this,s=null,o=n.type;switch(o){case"text":s=new t.Input({id:e,placeholder:n.placeholder,onchange:function(){r.set(e,s.value())}});break;case"select":s=new t.Select.View({id:e,data:n.data,onchange:function(){var t=s.value();r.set(e,t);var o=_.findWhere(n.data,{value:t});o&&(o.show&&i.$el.find("#"+o.show).fadeIn("fast"),o.hide&&i.$el.find("#"+o.hide).fadeOut("fast"))}});break;case"separator":s=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(o!="separator"){r.get(e)||r.set(e,n.init),s.value(r.get(e)),this.list[e]=s;var u=$("<div/>");u.append(s.$el),u.append('<div class="toolParamHelp" style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(u)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.category+" - "+t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/types",["utils/utils","plugin/library/ui"],function(e,t){return Backbone.View.extend({optionsDefault:{onchange:null,ondblclick:null},events:{click:"_onclick",dblclick:"_ondblclick"},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault);var r=$('<div class="charts-grid"/>');this.setElement(r);var i={},s=t.types.attributes;for(var o in s){var u=s[o],a=u.category;i[a]||(i[a]={}),i[a][o]=u}for(var a in i){var r=$('<div style="clear: both;"/>');r.append(e.wrap(this._template_header({title:a})));for(var o in i[a]){var u=i[a][o];r.append(e.wrap(this._template_item({id:o,title:u.title,url:config.app_root+"charts/"+o+"/logo.png"})))}this.$el.append(e.wrap(r))}},value:function(e){var t=this.$el.find(".current").attr("id");e!==undefined&&(this.$el.find(".current").removeClass("current"),this.$el.find("#"+e).addClass("current"));var n=this.$el.find(".current").attr("id");return n===undefined?null:(n!=t&&this.options.onchange&&this.options.onchange(e),n)},_onclick:function(e){var t=this.value(),n=$(e.target).closest(".item").attr("id");n!=""&&n&&t!=n&&this.value(n)},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_template_header:function(e){return'<div class="header">• '+e.title+"<div>"},_template_item:function(e){return'<div id="'+e.id+'" class="item">'+'<img class="image" src="'+e.url+'">'+'<div class="title">'+e.title+"</div>"+"<div>"}})}),define("plugin/views/editor",["mvc/ui/ui-tabs","plugin/library/ui","mvc/ui/ui-portlet","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings","plugin/views/types"],function(e,t,n,r,i,s,o,u,a){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(i,s){var o=this;this.app=i,this.chart=this.app.chart,this.options=r.merge(s,this.optionsDefault),this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Editor",operations:{save:new t.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){o.app.go("viewer"),o._saveChart()}}),back:new t.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){o.app.go("viewer"),o.app.storage.load()}})}}),this.types=new a(i,{onchange:function(e){o.chart.settings.clear(),o.chart.set({type:e}),o.chart.set("modified",!0)},ondblclick:function(e){o.app.go("viewer"),o._saveChart()}}),this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=o._addGroupModel();o.tabs.show(e.id)}}),this.title=new t.Input({placeholder:"Chart title",onchange:function(){o.chart.set("title",o.title.value())}});var f=$("<div/>");f.append(r.wrap((new t.Label({title:"Provide a chart title:"})).$el)),f.append(r.wrap(this.title.$el)),f.append(r.wrap((new t.Label({title:"Select a chart type:"})).$el)),f.append(r.wrap(this.types.$el)),this.tabs.add({id:"main",title:"Start",$el:f}),this.settings=new u(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.portlet.append(this.tabs.$el),this.setElement(this.portlet.$el),this.tabs.hideOperation("back");var o=this;this.chart.on("change:title",function(e){o._refreshTitle()}),this.chart.on("change:type",function(e){o.types.value(e.get("type"))}),this.chart.on("reset",function(e){o._resetChart()}),this.app.chart.on("redraw",function(e){o.portlet.showOperation("back")}),this.app.chart.groups.on("add",function(e){o._addGroup(e)}),this.app.chart.groups.on("remove",function(e){o._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){o._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){o._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e),this.title.value(e)},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new s({id:r.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new o(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey(),this.chart.set("modified",!0)},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",r.uuid()),this.chart.set("type","nvd3_bar"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart"),this.portlet.hideOperation("back")},_saveChart:function(){this.chart.set({type:this.types.value(),title:this.title.value(),date:r.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this;this.chart.deferred.execute(function(){e.app.storage.save(),e.chart.trigger("redraw")})}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:5e3,query_timeout:500}})}),define("plugin/charts/nvd3/config",[],function(){return{title:"",category:"",library:"nvd3.js",tag:"svg",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"x_axis_tick"},{label:"Auto",value:"auto",hide:"x_axis_tick"},{label:"Float",value:"f",show:"x_axis_tick"},{label:"Exponent",value:"e",show:"x_axis_tick"},{label:"Integer",value:"d",hide:"x_axis_tick"},{label:"Percentage",value:"p",show:"x_axis_tick"},{label:"Rounded",value:"r",show:"x_axis_tick"},{label:"SI-prefix",value:"s",show:"x_axis_tick"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"y_axis_tick"},{label:"Auto",value:"auto",hide:"y_axis_tick"},{label:"Float",value:"f",show:"y_axis_tick"},{label:"Exponent",value:"e",show:"y_axis_tick"},{label:"Integer",value:"d",hide:"y_axis_tick"},{label:"Percentage",value:"p",show:"y_axis_tick"},{label:"Rounded",value:"r",show:"y_axis_tick"},{label:"SI-prefix",value:"s",show:"y_axis_tick"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/nvd3_bar/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Regular",category:"Bar diagrams"})}),define("plugin/charts/nvd3_bar_stacked/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked",category:"Bar diagrams"})}),define("plugin/charts/nvd3_bar_horizontal/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Horizontal",category:"Bar diagrams",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/nvd3_bar_horizontal_stacked/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked horizontal",category:"Bar diagrams",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/nvd3_histogram/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",category:"Data processing (requires 'charts' tool from Toolshed)",execute:"histogram",columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_type:{init:"f"},y_axis_tick:{init:".2"}}})}),define("plugin/charts/nvd3_histogram_discrete/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram (discrete)",category:"Data processing (requires 'charts' tool from Toolshed)",execute:"histogramdiscrete",columns:{y:{title:"Observations",is_label:!0}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_type:{init:"f"},y_axis_tick:{init:".2"}}})}),define("plugin/charts/nvd3_line/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart",category:"Others"})}),define("plugin/charts/nvd3_line_focus/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus",category:"Others"})}),define("plugin/charts/nvd3_pie/config",[],function(){return{title:"Pie chart",library:"nvd3.js",category:"Area charts",tag:"svg",use_panels:!0,columns:{label:{title:"Labels",is_label:!0},y:{title:"Values"}},settings:{show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]},donut_ratio:{title:"Donut ratio",info:"Determine how large the donut hole will be.",type:"select",init:"0.5",data:[{label:"50%",value:"0.5"},{label:"25%",value:"0.25"},{label:"10%",value:"0.10"},{label:"0%",value:"0"}]},label_separator:{type:"separator",title:"Label settings"},label_type:{title:"Donut label",info:"What would you like to show for each slice?",type:"select",init:"percent",data:[{label:"-- Nothing --",value:"hide",hide:"label_outside"},{label:"Label column",value:"key",show:"label_outside"},{label:"Value column",value:"value",show:"label_outside"},{label:"Percentage",value:"percent",show:"label_outside"}]},label_outside:{title:"Show outside",info:"Would you like to show labels outside the donut?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/nvd3_scatter/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",category:"Others",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/nvd3_stackedarea/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Regular",category:"Area charts"})}),define("plugin/charts/nvd3_stackedarea_full/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Expanded",category:"Area charts"})}),define("plugin/charts/nvd3_stackedarea_stream/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stream",category:"Area charts"})}),define("plugin/charts/highcharts_boxplot/config",[],function(){return{title:"Box plot",category:"Data processing (requires 'charts' tool from Toolshed)",library:"highcharts.js",tag:"div",execute:"boxplot",columns:{y:{title:"Observations"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"}}}}),define("plugin/charts/heatmap/config",[],function(){return{title:"Heatmap",category:"Data processing (requires 'charts' tool from Toolshed)",library:"",tag:"div",use_panels:!0,execute:"heatmap",columns:{row_label:{title:"Row labels",is_label:!0},col_label:{title:"Column labels",is_label:!0},value:{title:"Observations"}},settings:{color_set:{title:"Color scheme",info:"Select a color scheme for your heatmap",type:"select",init:"ocean",data:[{label:"Cold-to-Hot",value:"hot"},{label:"Cool",value:"cool"},{label:"Copper",value:"copper"},{label:"Gebco",value:"gebco"},{label:"Globe",value:"globe"},{label:"Gray scale",value:"gray"},{label:"Haxby",value:"haxby"},{label:"Jet",value:"jet"},{label:"No-Green",value:"no_green"},{label:"Ocean",value:"ocean"},{label:"Polar",value:"polar"},{label:"Rainbow",value:"rainbow"},{label:"Red-to-Green",value:"redgreen"},{label:"Red-to-green (saturated)",value:"red2green"},{label:"Relief",value:"relief"},{label:"Seismograph",value:"seis"},{label:"Sealand",value:"sealand"},{label:"Split",value:"split"},{label:"Topo",value:"topo"},{label:"Wysiwyg",value:"wysiwyg"}]},sorting:{title:"Sorting",info:"How should the columns be clustered?",type:"select",init:"hclust",data:[{label:"Read from dataset",value:"hclust"},{label:"Sort column and row labels",value:"byboth"},{label:"Sort column labels",value:"bycolumns"},{label:"Sort by rows",value:"byrow"}]}},menu:function(){return{color_set:this.settings.color_set}}}}),define("plugin/charts/types",["plugin/charts/nvd3_bar/config","plugin/charts/nvd3_bar_stacked/config","plugin/charts/nvd3_bar_horizontal/config","plugin/charts/nvd3_bar_horizontal_stacked/config","plugin/charts/nvd3_histogram/config","plugin/charts/nvd3_histogram_discrete/config","plugin/charts/nvd3_line/config","plugin/charts/nvd3_line_focus/config","plugin/charts/nvd3_pie/config","plugin/charts/nvd3_scatter/config","plugin/charts/nvd3_stackedarea/config","plugin/charts/nvd3_stackedarea_full/config","plugin/charts/nvd3_stackedarea_stream/config","plugin/charts/highcharts_boxplot/config","plugin/charts/heatmap/config"],function(e,t,n,r,i,s,o,u,a,f,l,c,h,p,d){return Backbone.Model.extend({defaults:{nvd3_bar:e,nvd3_bar_stacked:t,nvd3_bar_horizontal:n,nvd3_bar_horizontal_stacked:r,nvd3_stackedarea:l,nvd3_stackedarea_full:c,nvd3_stackedarea_stream:h,nvd3_line:o,nvd3_line_focus:u,nvd3_scatter:f,nvd3_pie:a,nvd3_histogram:i,highcharts_boxplot:p,heatmap:d}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/library/storage","plugin/views/viewer","plugin/views/editor","plugin/models/config","plugin/models/chart","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(t){this.options=t,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new f,this.types=new c,this.chart=new l,this.jobs=new i(this),this.datasets=new s(this),this.storage=new o(this),this.viewer_view=new u(this),this.editor_view=new a(this),this.$el.append(this.viewer_view.$el),this.$el.append(this.editor_view.$el);if(!this.storage.load())this.go("editor");else{this.go("viewer");var n=this;this.chart.deferred.execute(function(){n.chart.trigger("redraw")})}},go:function(e){$(".tooltip").hide();switch(e){case"editor":this.editor_view.show(),this.viewer_view.hide();break;case"viewer":this.editor_view.hide(),this.viewer_view.show()}},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
diff -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 -r 632087d479859d0a8152267f6c21a623722bc875 config/plugins/visualizations/charts/static/charts/nvd3_histogram/wrapper.js
--- a/config/plugins/visualizations/charts/static/charts/nvd3_histogram/wrapper.js
+++ b/config/plugins/visualizations/charts/static/charts/nvd3_histogram/wrapper.js
@@ -23,7 +23,7 @@
},
y: {
index: index++
- },
+ }
}
}
diff -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 -r 632087d479859d0a8152267f6c21a623722bc875 config/plugins/visualizations/charts/static/charts/nvd3_histogram_discrete/config.js
--- a/config/plugins/visualizations/charts/static/charts/nvd3_histogram_discrete/config.js
+++ b/config/plugins/visualizations/charts/static/charts/nvd3_histogram_discrete/config.js
@@ -1,12 +1,13 @@
define(['plugin/charts/nvd3/config'], function(nvd3_config) {
return $.extend(true, {}, nvd3_config, {
- title : 'Histogram',
- category : 'Histograms',
- execute : 'histogram_discrete',
+ title : 'Histogram (discrete)',
+ category : 'Data processing (requires \'charts\' tool from Toolshed)',
+ execute : 'histogramdiscrete',
columns : {
y : {
- title : 'Observations'
+ title : 'Observations',
+ is_label : true
}
},
settings : {
diff -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 -r 632087d479859d0a8152267f6c21a623722bc875 config/plugins/visualizations/charts/static/charts/types.js
--- a/config/plugins/visualizations/charts/static/charts/types.js
+++ b/config/plugins/visualizations/charts/static/charts/types.js
@@ -4,6 +4,7 @@
'plugin/charts/nvd3_bar_horizontal/config',
'plugin/charts/nvd3_bar_horizontal_stacked/config',
'plugin/charts/nvd3_histogram/config',
+ 'plugin/charts/nvd3_histogram_discrete/config',
'plugin/charts/nvd3_line/config',
'plugin/charts/nvd3_line_focus/config',
'plugin/charts/nvd3_pie/config',
@@ -18,6 +19,7 @@
nvd3_bar_horizontal,
nvd3_bar_horizontal_stacked,
nvd3_histogram,
+ nvd3_histogram_discrete,
nvd3_line,
nvd3_line_focus,
nvd3_pie,
@@ -46,6 +48,7 @@
'nvd3_scatter' : nvd3_scatter,
'nvd3_pie' : nvd3_pie,
'nvd3_histogram' : nvd3_histogram,
+ //'nvd3_histogram_discrete' : nvd3_histogram_discrete,
'highcharts_boxplot' : highcharts_boxplot,
'heatmap' : heatmap
}
diff -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 -r 632087d479859d0a8152267f6c21a623722bc875 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
@@ -282,9 +282,9 @@
// template svg/div element
_templateContainer: function(tag, width) {
- return '<div class="container" style="width:' + width + '%;">' +
+ return '<div class="charts-viewport-container" style="width:' + width + '%;">' +
'<div id="menu"/>' +
- '<' + tag + ' id="canvas" class="canvas">' +
+ '<' + tag + ' id="canvas" class="charts-viewport-canvas">' +
'</div>';
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: I meant to make this file a .sample file.
by commits-noreply@bitbucket.org 17 May '14
by commits-noreply@bitbucket.org 17 May '14
17 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3bdd01eda31d/
Changeset: 3bdd01eda31d
User: greg
Date: 2014-05-17 16:10:23
Summary: I meant to make this file a .sample file.
Affected #: 3 files
diff -r 2e6e51179f7177b743bd970095be7e261ae62700 -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 lib/tool_shed/scripts/bootstrap_tool_shed/user_info.xml
--- a/lib/tool_shed/scripts/bootstrap_tool_shed/user_info.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<user>
- <email>admin(a)test.org</email>
- <password>testuser</password>
- <username>admin</username>
-</user>
diff -r 2e6e51179f7177b743bd970095be7e261ae62700 -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 lib/tool_shed/scripts/bootstrap_tool_shed/user_info.xml.sample
--- /dev/null
+++ b/lib/tool_shed/scripts/bootstrap_tool_shed/user_info.xml.sample
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+If you are planning to use the export / import repository capsule process for development in your
+local Tool Shed, make sure to change the following to be the account you'll use for development.
+When you export your developed repositories for importing into another Tool Shed, this account
+must be available in that Tool Shed..
+-->
+<user>
+ <email>admin(a)test.org</email>
+ <password>testuser</password>
+ <username>admin</username>
+</user>
diff -r 2e6e51179f7177b743bd970095be7e261ae62700 -r 3bdd01eda31d3f9b195b11982b31c58bc37254e8 run_tool_shed.sh
--- a/run_tool_shed.sh
+++ b/run_tool_shed.sh
@@ -15,6 +15,7 @@
tool_sheds_conf.xml.sample
openid_conf.xml.sample
universe_wsgi.ini.sample
+ lib/tool_shed/scripts/bootstrap_tool_shed/user_info.xml.sample
tool-data/shared/ncbi/builds.txt.sample
tool-data/shared/ensembl/builds.txt.sample
tool-data/shared/ucsc/builds.txt.sample
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: data libraries: permissions UI and API work, library router fixes, security addition for retrieving paginated roles for given dataset
by commits-noreply@bitbucket.org 16 May '14
by commits-noreply@bitbucket.org 16 May '14
16 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2e6e51179f71/
Changeset: 2e6e51179f71
User: martenson
Date: 2014-05-17 00:13:26
Summary: data libraries: permissions UI and API work, library router fixes, security addition for retrieving paginated roles for given dataset
Affected #: 14 files
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 lib/galaxy/security/__init__.py
--- a/lib/galaxy/security/__init__.py
+++ b/lib/galaxy/security/__init__.py
@@ -208,6 +208,75 @@
roles.add( role )
return self.sort_by_attr( [ role for role in roles ], 'name' )
+ def get_valid_dataset_roles( self, trans, dataset, query, page, page_limit ):
+ """
+ This method retrieves the list of possible roles that user can select
+ in the dataset permissions form. Admins can select any role so the
+ results are paginated in order to save the bandwidth and to speed
+ things up.
+ Standard users can select their own private role, any fo their
+ sharing roles and any public role (not private and not sharing).
+ """
+ roles = []
+ if query is not None:
+ query = query.replace( '_', '/_' ).replace( '%', '/%' ).replace( '/', '//' )
+ search_query = query + '%'
+ # Limit the query only to get the page needed
+ limit = page * page_limit
+
+ # Admins see it all
+ if trans.user_is_admin():
+ # Add all roles that fit the query
+ db_query = trans.sa_session.query( trans.app.model.Role ).filter( self.model.Role.table.c.deleted == False )
+ if query is not None:
+ db_query = db_query.filter( self.model.Role.table.c.name.like( search_query, escape='/' ) )
+ for role in ( db_query.order_by( self.model.Role.table.c.name ).limit( limit ) ):
+ roles.append( role )
+ # Take last page of the selection
+ roles = roles[ ( -page_limit ): ]
+
+ # Non-admins see the list of relevant roles
+ else:
+ if self.dataset_is_public( dataset ):
+ # Add the current user's private role
+ roles.append( self.get_private_user_role( trans.user ) )
+ # Add the current user's sharing roles
+ for role in self.get_sharing_roles( trans.user ):
+ roles.append( role )
+ # Add all remaining non-private, non-sharing roles
+ for role in trans.sa_session.query( trans.app.model.Role ) \
+ .filter( and_( self.model.Role.table.c.deleted == False,
+ self.model.Role.table.c.type != self.model.Role.types.PRIVATE,
+ self.model.Role.table.c.type != self.model.Role.types.SHARING ) ) \
+ .order_by( self.model.Role.table.c.name ):
+ roles.append( role )
+
+ else:
+ # If item has roles associated with the access permission, we need to start with them.
+ access_roles = dataset.get_access_roles( trans )
+ for role in access_roles:
+ if trans.user_is_admin() or self.ok_to_display( trans.user, role ):
+ roles.append( role )
+ # Each role potentially has users. We need to find all roles that each of those users have.
+ for ura in role.users:
+ user = ura.user
+ for ura2 in user.roles:
+ if trans.user_is_admin() or self.ok_to_display( trans.user, ura2.role ):
+ roles.append( ura2.role )
+ # Each role also potentially has groups which, in turn, have members ( users ). We need to
+ # find all roles that each group's members have.
+ for gra in role.groups:
+ group = gra.group
+ for uga in group.users:
+ user = uga.user
+ for ura in user.roles:
+ if trans.user_is_admin() or self.ok_to_display( trans.user, ura.role ):
+ roles.append( ura.role )
+
+ # Omit duplicated roles by converting to set
+ return_roles = set( roles )
+ return self.sort_by_attr( [ role for role in return_roles ], 'name' )
+
def get_legitimate_roles( self, trans, item, cntrller ):
"""
Return a sorted list of legitimate roles that can be associated with a permission on
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -75,9 +75,16 @@
for a given dataset permission.
"""
current_user_roles = trans.get_current_user_roles()
- page = int( kwd.get( 'page', None ) )
- page_limit = int( kwd.get( 'page_limit', None ) )
- query = kwd.get ( 'q', None )
+
+ page = kwd.get( 'page', None )
+ if page is not None:
+ page = int( page )
+
+ page_limit = kwd.get( 'page_limit', None )
+ if page_limit is not None:
+ page_limit = int( page_limit )
+
+ query = kwd.get( 'q', None )
if page is None:
page = 1
@@ -96,11 +103,8 @@
if not can_manage:
raise exceptions.InsufficientPermissionsException( 'You do not have proper permissions to access permissions.' )
- cntrller = 'standard_user'
- if trans.user_is_admin():
- cntrller = 'library_admin'
+ roles = trans.app.security_agent.get_valid_dataset_roles( trans, dataset, query, page, page_limit )
- roles = trans.app.security_agent.get_legitimate_roles( trans, library, cntrller )
total_roles = len( roles )
return_roles = []
for role in roles:
@@ -109,6 +113,23 @@
return dict( roles=return_roles, page=page, page_limit=page_limit, total=total_roles )
@expose_api
+ def get_roles( self, trans, encoded_dataset_id, **kwd ):
+ try:
+ library_dataset = self.get_library_dataset( trans, id=encoded_dataset_id, check_ownership=False, check_accessible=False )
+ except Exception, e:
+ raise exceptions.ObjectNotFound( 'Requested dataset was not found.' + str(e) )
+ dataset = library_dataset.library_dataset_dataset_association.dataset
+
+ roles = dataset.get_access_roles( trans )
+
+ # roles = dataset.get_manage_permissions_roles( trans )
+
+ # roles = trans.app.security_agent.get_current_dataset_roles( trans, dataset, trans.app.security_agent.permitted_actions.DATASET_ACCESS )
+ # Omit duplicated roles by converting to set
+ roles = set( roles )
+ return [ role.name for role in roles ]
+
+ @expose_api
def delete( self, trans, encoded_dataset_id, **kwd ):
"""
delete( self, trans, encoded_dataset_id, **kwd ):
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -224,6 +224,12 @@
action='show_roles',
conditions=dict( method=[ "GET" ] ) )
+ webapp.mapper.connect( 'show_legitimate_lda_roles',
+ '/api/libraries/datasets/:encoded_dataset_id/permissions/current',
+ controller='lda_datasets',
+ action='get_roles',
+ conditions=dict( method=[ "GET" ] ) )
+
webapp.mapper.connect( 'delete_lda_item',
'/api/libraries/datasets/:encoded_dataset_id',
controller='lda_datasets',
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/galaxy.library.js
--- a/static/scripts/galaxy.library.js
+++ b/static/scripts/galaxy.library.js
@@ -74,6 +74,7 @@
library_router: null,
folderToolbarView: null,
folderListView: null,
+ datasetView: null,
initialize : function(){
Galaxy.libraries = this;
@@ -106,10 +107,17 @@
});
this.library_router.on('route:dataset_detail', function(folder_id, dataset_id){
- new mod_library_dataset_view.LibraryDatasetView({id: dataset_id})
+ if (Galaxy.libraries.datasetView){
+ Galaxy.libraries.datasetView.$el.unbind('click');
+ }
+ Galaxy.libraries.datasetView = new mod_library_dataset_view.LibraryDatasetView({id: dataset_id});
});
+
this.library_router.on('route:dataset_permissions', function(folder_id, dataset_id){
- new mod_library_dataset_view.LibraryDatasetView({id: dataset_id, show_permissions: true})
+ if (Galaxy.libraries.datasetView){
+ Galaxy.libraries.datasetView.$el.unbind('click');
+ }
+ Galaxy.libraries.datasetView = new mod_library_dataset_view.LibraryDatasetView({id: dataset_id, show_permissions: true});
});
Backbone.history.start({pushState: false});
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/mvc/library/library-dataset-view.js
--- a/static/scripts/mvc/library/library-dataset-view.js
+++ b/static/scripts/mvc/library/library-dataset-view.js
@@ -20,10 +20,15 @@
events: {
"click .toolbtn_modify_dataset" : "enableModification",
"click .toolbtn_cancel_modifications" : "render",
- "click .toolbtn_change_permissions" : "showPermissions",
"click .toolbtn-download-dataset" : "downloadDataset",
"click .toolbtn-import-dataset" : "importIntoHistory",
- "click .toolbtn-share-dataset" : "shareDataset"
+ "click .toolbtn-share-dataset" : "shareDataset",
+
+ // missing features below
+ "click .toolbtn_save_modifications" : "comingSoon",
+ "click .btn-remove-restrictions" : "comingSoon",
+ "click .btn-make-private" : "comingSoon",
+ "click .btn-share-dataset" : "comingSoon"
},
@@ -132,7 +137,7 @@
},
importCurrentIntoHistory: function(){
- var self = this;
+ // var self = this;
var history_id = $(this.modal.elMain).find('select[name=dataset_import_single] option:selected').val();
var historyItem = new mod_library_model.HistoryItem();
historyItem.url = historyItem.urlRoot + history_id + '/contents';
@@ -165,88 +170,102 @@
mod_toastr.info('Feature coming soon.');
},
+ goBack: function(){
+ Galaxy.libraries.library_router.back();
+ },
+
showPermissions: function(){
$(".tooltip").remove();
var template = this.templateDatasetPermissions();
this.$el.html(template({item: this.model}));
+ // Select works different for admins
+ var is_admin = false;
+ if (Galaxy.currUser){
+ is_admin = Galaxy.currUser.isAdmin();
+ }
+
var self = this;
- this.access_perm = new mod_select.View({
- css: 'access_perm',
- multiple:true,
- placeholder: 'Click to select a role',
- container: self.$el.find('#access_perm'),
- ajax: {
- url: "/api/libraries/datasets/5969b1f7201f12ae/permissions",
- dataType: 'json',
- quietMillis: 100,
- data: function (term, page) { // page is the one-based page number tracked by Select2
- return {
- q: term, //search term
- page_limit: 10, // page size
- page: page // page number
- };
- },
- results: function (data, page) {
- var more = (page * 10) < data.total; // whether or not there are more results available
- // notice we return the value of more so Select2 knows if more results can be loaded
- return {results: data.roles, more: more};
- }
- },
- formatResult : function roleFormatResult(role) {
- return role.name;
- },
+ // load all current permissions
+ $.get( "/api/libraries/datasets/" + self.id + "/permissions/current").done(function(fetched_permissions) {
+ var selected_roles = [];
+ for (var i = 0; i < fetched_permissions.length; i++) {
+ selected_roles.push(fetched_permissions[i] + ':' + fetched_permissions[i]);
+ }
+ // ACCESS PERMISSIONS
+ if (is_admin){ // Admin has a special select that allows remote searching
+ var access_select_options = {
+ minimumInputLength: 1,
+ css: 'access_perm',
+ multiple:true,
+ placeholder: 'Click to select a role',
+ container: self.$el.find('#access_perm'),
+ ajax: {
+ url: "/api/libraries/datasets/" + self.id + "/permissions",
+ dataType: 'json',
+ quietMillis: 100,
+ data: function (term, page) { // page is the one-based page number tracked by Select2
+ return {
+ q: term, //search term
+ page_limit: 10, // page size
+ page: page // page number
+ };
+ },
+ results: function (data, page) {
+ var more = (page * 10) < data.total; // whether or not there are more results available
+ // notice we return the value of more so Select2 knows if more results can be loaded
+ return {results: data.roles, more: more};
+ }
+ },
+ formatResult : function roleFormatResult(role) {
+ return role.name + ' type: ' + role.type;
+ },
- formatSelection: function roleFormatSelection(role) {
- return role.name;
- },
- initSelection: function(element, callback) {
- // the input tag has a value attribute preloaded that points to a preselected role's id
- // this function resolves that id attribute to an object that select2 can render
- // using its formatResult renderer - that way the role name is shown preselected
- var data = [];
- $(element.val().split(",")).each(function(i) {
- var item = this.split(':');
- data.push({
- id: item[1],
- name: item[1]
- });
+ formatSelection: function roleFormatSelection(role) {
+ return role.name;
+ },
+ initSelection: function(element, callback) {
+ // the input tag has a value attribute preloaded that points to a preselected role's id
+ // this function resolves that id attribute to an object that select2 can render
+ // using its formatResult renderer - that way the role name is shown preselected
+ var data = [];
+ $(element.val().split(",")).each(function() {
+ var item = this.split(':');
+ data.push({
+ id: item[1],
+ name: item[1]
+ });
+ });
+ callback(data);
+ },
+ initialData: selected_roles.join(','),
+ dropdownCssClass: "bigdrop" // apply css that makes the dropdown taller
+ };
+
+ this.accessSelectObject = new mod_select.View(access_select_options);
+ } else { // Non-admins have select with pre-loaded options
+ var template = this.templateAccessSelect();
+ $.get( "/api/libraries/datasets/" + self.id + "/permissions", function( data ) {
+ $('.access_perm').html(template({options:data.roles}));
+ this.accessSelectObject = $('#access_select').select2();
+ }).fail(function() {
+ mod_toastr.error('An error occurred while fetching data with permissions. :(');
});
- callback(data);
- },
- initialData: 'marten@bx.psu.edu:marten@bx.psu.edu',
- dropdownCssClass: "bigdrop" // apply css that makes the dropdown taller
+ }
+ }).fail(function(){
+ mod_toastr.error('An error occurred while fetching data with permissions. :(');
});
- // this.access_perm.$el.append($('<option>', {value:"NEWVAL", text: "New Option Text"}));
- // this.modify_perm = new mod_select.View({
- // css: 'modify_perm',
- // placeholder: 'Select a role',
- // // onchange : function() {
- // // self.model.set('access_perm', self.select_genome.value());
- // // },
- // data: [{id:'test',text:'testik'}, {id:'dududu', text:'dadada'}],
- // container: self.$el.find('#modify_perm'),
- // multiple: true
- // // value: self.model.get('access_perm')
- // });
- // this.modify_perm.$el.append($('<option>', {value:"NEWVAL", text: "New Option Text"}));
-
- // this.manage_perm = new mod_select.View({
- // css: 'manage_perm',
- // placeholder: 'Select a role',
- // // onchange : function() {
- // // self.model.set('access_perm', self.select_genome.value());
- // // },
- // data: [{id:'test',text:'testik'}, {id:'dududu', text:'dadada'}],
- // container: self.$el.find('#manage_perm'),
- // multiple: true
- // // value: self.model.get('access_perm')
- // });
- // this.manage_perm.$el.append($('<option>', {value:"NEWVAL", text: "New Option Text"}));
+ //TODO add permissions for modification and management of datasets
$("#center [data-toggle]").tooltip();
+ //hack to show scrollbars
+ $("#center").css('overflow','auto');
+ },
+
+ comingSoon: function(){
+ mod_toastr.warning('Feature coming soon');
},
@@ -259,7 +278,7 @@
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Modify dataset" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');
- tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Change permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button>');
+ tmpl_array.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Change permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');
tmpl_array.push(' </div>');
@@ -481,8 +500,8 @@
tmpl_array.push('<div class="library_style_container">');
tmpl_array.push(' <div id="library_toolbar">');
- tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');
- tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');
+ tmpl_array.push(' <a href="#folders/<%- item.get("folder_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to folder" class="btn btn-default primary-button" type="button"><span class="fa fa-folder-open-o"></span> go to Folder</span></button></a>');
+ tmpl_array.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go back to dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-file-o"></span> see the Dataset</span></button><a>');
tmpl_array.push(' </div>');
@@ -511,11 +530,16 @@
tmpl_array.push('<button data-toggle="tooltip" data-placement="top" title="Only you will be able to see the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"></span> Make private</span></button>');
tmpl_array.push('</p>');
+ tmpl_array.push('<p>You can share this dataset with another Galaxy user. ');
+ tmpl_array.push('<button data-toggle="tooltip" data-placement="top" title="Only you and the other user will be able to see the dataset." class="btn btn-default btn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');
+ tmpl_array.push('</p>');
+
tmpl_array.push('<h2>Advanced permissions</h2>');
- tmpl_array.push('<p>You can assign any number of roles to any of the following three dataset permissions:</p>');
+ tmpl_array.push('<p>You can assign any number of roles to any of the following three dataset permission types. However please read carefully the implications of such actions.</p>');
tmpl_array.push('<h3>Access Roles</h3>');
tmpl_array.push('<div class="alert alert-info">User has to have <strong>all these roles</strong> in order to see this dataset.</div>');
tmpl_array.push('<div id="access_perm" class="access_perm roles-selection"></div>');
+ tmpl_array.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');
tmpl_array.push('<h3>Modify Roles</h3>');
tmpl_array.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can modify the information about this dataset.</div>');
tmpl_array.push('<div id="modify_perm" class="modify_perm"></div>');
@@ -532,7 +556,7 @@
return _.template(tmpl_array.join(''));
},
-templateBulkImportInModal : function(){
+ templateBulkImportInModal: function(){
var tmpl_array = [];
tmpl_array.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');
@@ -545,8 +569,22 @@
tmpl_array.push('</span>');
return _.template(tmpl_array.join(''));
+ },
+
+ templateAccessSelect: function(){
+ var tmpl_array = [];
+
+ tmpl_array.push('<select id="access_select" multiple>');
+
+ tmpl_array.push(' <% _.each(options, function(option) { %>');
+ tmpl_array.push(' <option value="<%- option.name %>"><%- option.name %></option>');
+ tmpl_array.push(' <% }); %>');
+
+ tmpl_array.push('</select>');
+
+
+ return _.template(tmpl_array.join(''));
}
-
});
return {
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/mvc/library/library-folderrow-view.js
--- a/static/scripts/mvc/library/library-folderrow-view.js
+++ b/static/scripts/mvc/library/library-folderrow-view.js
@@ -46,7 +46,7 @@
},
showDatasetDetails : function(){
- this.dataset_view = new mod_library_dataset_view.LibraryDatasetView({id: this.id});
+ Galaxy.libraries.datasetView = new mod_library_dataset_view.LibraryDatasetView({id: this.id});
},
/**
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/mvc/library/library-foldertoolbar-view.js
@@ -520,7 +520,7 @@
tmpl_array.push('<div class="library_style_container">');
// TOOLBAR
tmpl_array.push('<div id="library_toolbar">');
- tmpl_array.push('<span data-toggle="tooltip" data-placement="top" class="logged-dataset-manipulation" title="Include deleted datasets" style="display:none;"><input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');
+ tmpl_array.push('<span data-toggle="tooltip" data-placement="top" class="logged-dataset-manipulation" title="Include deleted datasets" style="display:none;"><input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"> include deleted</input></span>');
tmpl_array.push('<div class="btn-group add-library-items" style="display:none;">');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');
tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/mvc/library/library-librarytoolbar-view.js
--- a/static/scripts/mvc/library/library-librarytoolbar-view.js
+++ b/static/scripts/mvc/library/library-librarytoolbar-view.js
@@ -118,7 +118,7 @@
tmpl_array.push(' <div id="toolbar_form">');
tmpl_array.push(' <% if(admin_user === true) { %>');
tmpl_array.push(' <div id="library_toolbar">');
- tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Include deleted libraries"><input id="include_deleted_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');
+ tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Include deleted libraries"><input id="include_deleted_chk" style="margin: 0;" type="checkbox"> include deleted</input></span>');
tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Create New Library"><button id="create_new_library_btn" class="primary-button btn-xs" type="button"><span class="fa fa-plus"></span> New Library</button><span>');
tmpl_array.push(' </div>');
tmpl_array.push(' <% } %>');
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/mvc/ui/ui-select.js
--- a/static/scripts/mvc/ui/ui-select.js
+++ b/static/scripts/mvc/ui/ui-select.js
@@ -17,6 +17,7 @@
value : null,
multiple : false,
minimumInputLength : 0,
+ // example format of initial data: "id:name,55:anotherrole@role.com,27:role@role.com"
initialData : ''
},
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/packed/galaxy.library.js
--- a/static/scripts/packed/galaxy.library.js
+++ b/static/scripts/packed/galaxy.library.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/base-mvc","mvc/library/library-model","mvc/library/library-folderlist-view","mvc/library/library-librarylist-view","mvc/library/library-librarytoolbar-view","mvc/library/library-foldertoolbar-view","mvc/library/library-dataset-view"],function(f,c,h,l,i,a,g,e,j,d){var m=Backbone.Router.extend({initialize:function(){this.routesHit=0;Backbone.history.on("route",function(){this.routesHit++},this)},routes:{"":"libraries","folders/:id":"folder_content","folders/:folder_id/datasets/:dataset_id":"dataset_detail","folders/:folder_id/datasets/:dataset_id/permissions":"dataset_permissions","folders/:folder_id/download/:format":"download"},back:function(){if(this.routesHit>1){window.history.back()}else{this.navigate("#",{trigger:true,replace:true})}}});var k=l.SessionStorageModel.extend({defaults:{with_deleted:false,sort_order:"asc",sort_by:"name"}});var b=Backbone.View.extend({libraryToolbarView:null,libraryListView:null,library_router:null,folderToolbarView:null,folderListView:null,initialize:function(){Galaxy.libraries=this;this.preferences=new k({id:"global-lib-prefs"});this.library_router=new m();this.library_router.on("route:libraries",function(){Galaxy.libraries.libraryToolbarView=new e.LibraryToolbarView();Galaxy.libraries.libraryListView=new g.LibraryListView()});this.library_router.on("route:folder_content",function(n){if(Galaxy.libraries.folderToolbarView){Galaxy.libraries.folderToolbarView.$el.unbind("click")}Galaxy.libraries.folderToolbarView=new j.FolderToolbarView({id:n});Galaxy.libraries.folderListView=new a.FolderListView({id:n})});this.library_router.on("route:download",function(n,o){if($("#folder_list_body").find(":checked").length===0){h.info("You have to select some datasets to download");Galaxy.libraries.library_router.navigate("folders/"+n,{trigger:true,replace:true})}else{Galaxy.libraries.folderToolbarView.download(n,o);Galaxy.libraries.library_router.navigate("folders/"+n,{trigger:false,replace:true})}});this.library_router.on("route:dataset_detail",function(o,n){new d.LibraryDatasetView({id:n})});this.library_router.on("route:dataset_permissions",function(o,n){new d.LibraryDatasetView({id:n,show_permissions:true})});Backbone.history.start({pushState:false})}});return{GalaxyApp:b}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/base-mvc","mvc/library/library-model","mvc/library/library-folderlist-view","mvc/library/library-librarylist-view","mvc/library/library-librarytoolbar-view","mvc/library/library-foldertoolbar-view","mvc/library/library-dataset-view"],function(f,c,h,l,i,a,g,e,j,d){var m=Backbone.Router.extend({initialize:function(){this.routesHit=0;Backbone.history.on("route",function(){this.routesHit++},this)},routes:{"":"libraries","folders/:id":"folder_content","folders/:folder_id/datasets/:dataset_id":"dataset_detail","folders/:folder_id/datasets/:dataset_id/permissions":"dataset_permissions","folders/:folder_id/download/:format":"download"},back:function(){if(this.routesHit>1){window.history.back()}else{this.navigate("#",{trigger:true,replace:true})}}});var k=l.SessionStorageModel.extend({defaults:{with_deleted:false,sort_order:"asc",sort_by:"name"}});var b=Backbone.View.extend({libraryToolbarView:null,libraryListView:null,library_router:null,folderToolbarView:null,folderListView:null,datasetView:null,initialize:function(){Galaxy.libraries=this;this.preferences=new k({id:"global-lib-prefs"});this.library_router=new m();this.library_router.on("route:libraries",function(){Galaxy.libraries.libraryToolbarView=new e.LibraryToolbarView();Galaxy.libraries.libraryListView=new g.LibraryListView()});this.library_router.on("route:folder_content",function(n){if(Galaxy.libraries.folderToolbarView){Galaxy.libraries.folderToolbarView.$el.unbind("click")}Galaxy.libraries.folderToolbarView=new j.FolderToolbarView({id:n});Galaxy.libraries.folderListView=new a.FolderListView({id:n})});this.library_router.on("route:download",function(n,o){if($("#folder_list_body").find(":checked").length===0){h.info("You have to select some datasets to download");Galaxy.libraries.library_router.navigate("folders/"+n,{trigger:true,replace:true})}else{Galaxy.libraries.folderToolbarView.download(n,o);Galaxy.libraries.library_router.navigate("folders/"+n,{trigger:false,replace:true})}});this.library_router.on("route:dataset_detail",function(o,n){if(Galaxy.libraries.datasetView){Galaxy.libraries.datasetView.$el.unbind("click")}Galaxy.libraries.datasetView=new d.LibraryDatasetView({id:n})});this.library_router.on("route:dataset_permissions",function(o,n){if(Galaxy.libraries.datasetView){Galaxy.libraries.datasetView.$el.unbind("click")}Galaxy.libraries.datasetView=new d.LibraryDatasetView({id:n,show_permissions:true})});Backbone.history.start({pushState:false})}});return{GalaxyApp:b}});
\ No newline at end of file
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/packed/mvc/library/library-dataset-view.js
--- a/static/scripts/packed/mvc/library/library-dataset-view.js
+++ b/static/scripts/packed/mvc/library/library-dataset-view.js
@@ -1,1 +1,1 @@
-define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,b){var a=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_modify_dataset":"enableModification","click .toolbtn_cancel_modifications":"render","click .toolbtn_change_permissions":"showPermissions","click .toolbtn-download-dataset":"downloadDataset","click .toolbtn-import-dataset":"importIntoHistory","click .toolbtn-share-dataset":"shareDataset"},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchDataset()}},fetchDataset:function(e){this.options=_.extend(this.options,e);this.model=new c.Item({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{f.render()}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred :(. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){$(".tooltip").remove();this.options=_.extend(this.options,e);var f=this.templateDataset();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},enableModification:function(){$(".tooltip").remove();var e=this.templateModifyDataset();this.$el.html(e({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},downloadDataset:function(){var e="/api/libraries/datasets/download/uncompressed";var f={ldda_ids:this.id};this.processDownload(e,f)},processDownload:function(f,g,h){if(f&&g){g=typeof g=="string"?g:$.param(g);var e="";$.each(g.split("&"),function(){var i=this.split("=");e+='<input type="hidden" name="'+i[0]+'" value="'+i[1]+'" />'});$('<form action="'+f+'" method="'+(h||"post")+'">'+e+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon")}},importIntoHistory:function(){this.refreshUserHistoriesList(function(e){var f=e.templateBulkImportInModal();e.modal=Galaxy.modal;e.modal.show({closing_events:true,title:"Import into History",body:f({histories:e.histories.models}),buttons:{Import:function(){e.importCurrentIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})},refreshUserHistoriesList:function(f){var e=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){f(e)},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg)}else{d.error("An error ocurred :(")}}})},importCurrentIntoHistory:function(){var f=this;var g=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();var h=new c.HistoryItem();h.url=h.urlRoot+g+"/contents";var e="/api/histories/"+g+"/set_as_current";$.ajax({url:e,type:"PUT"});h.save({content:this.id,source:"library"},{success:function(){Galaxy.modal.hide();d.success("Dataset imported. Click this to start analysing it.","",{onclick:function(){window.location="/"}})},error:function(j,i){if(typeof i.responseJSON!=="undefined"){d.error("Dataset not imported. "+i.responseJSON.err_msg)}else{d.error("An error occured! Dataset not imported. Please try again.")}}})},shareDataset:function(){d.info("Feature coming soon.")},showPermissions:function(){$(".tooltip").remove();var g=this.templateDatasetPermissions();this.$el.html(g({item:this.model}));var e=this;this.access_perm=new b.View({css:"access_perm",multiple:true,placeholder:"Click to select a role",container:e.$el.find("#access_perm"),ajax:{url:"/api/libraries/datasets/5969b1f7201f12ae/permissions",dataType:"json",quietMillis:100,data:function(i,j){return{q:i,page_limit:10,page:j}},results:function(k,j){var i=(j*10)<k.total;return{results:k.roles,more:i}}},formatResult:function f(i){return i.name},formatSelection:function h(i){return i.name},initSelection:function(i,k){var j=[];$(i.val().split(",")).each(function(l){var m=this.split(":");j.push({id:m[1],name:m[1]})});k(j)},initialData:"marten@bx.psu.edu:marten@bx.psu.edu",dropdownCssClass:"bigdrop"});$("#center [data-toggle]").tooltip()},templateDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify dataset" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Change permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("data_type")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("data_type")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateModifyDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push('<p>For more editing options please import the dataset to history and use "Edit attributes" on it.</p>');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><input class="input_dataset_name form-control" type="text" placeholder="name" value="<%= _.escape(item.get("name")) %>"></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("data_type")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(' <tr scope="row">');e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <% if (item.get("metadata_comment_lines") === "") { %>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" <% } else { %>");e.push(' <td scope="row">unknown</td>');e.push(" <% } %>");e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" </table>");e.push("<div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push("</div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateDatasetPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<h1><%= _.escape(item.get("name")) %></h1>');e.push('<div class="alert alert-success">You have rights to change permissions on this dataset. That means you can control who can access it, who can modify it and also appoint others that can manage permissions on it.</div>');e.push('<div class="dataset_table">');e.push("<h2>Basic permissions</h2>");e.push("<p>You can remove all access restrictions on this dataset. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Everybody will be able to see the dataset." class="btn btn-default btn-remove-restrictions primary-button" type="button"><span class="fa fa-globe"></span> Remove restrictions</span></button>');e.push("</p>");e.push("<p>You can make this dataset private to you. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Only you will be able to see the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"></span> Make private</span></button>');e.push("</p>");e.push("<h2>Advanced permissions</h2>");e.push("<p>You can assign any number of roles to any of the following three dataset permissions:</p>");e.push("<h3>Access Roles</h3>");e.push('<div class="alert alert-info">User has to have <strong>all these roles</strong> in order to see this dataset.</div>');e.push('<div id="access_perm" class="access_perm roles-selection"></div>');e.push("<h3>Modify Roles</h3>");e.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can modify the information about this dataset.</div>');e.push('<div id="modify_perm" class="modify_perm"></div>');e.push("<h3>Manage Roles</h3>");e.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can change permissions of this dataset.</div>');e.push('<div id="manage_perm" class="manage_perm"></div>');e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateBulkImportInModal:function(){var e=[];e.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');e.push("Select history: ");e.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');e.push(" <% _.each(histories, function(history) { %>");e.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');e.push(" <% }); %>");e.push("</select>");e.push("</span>");return _.template(e.join(""))}});return{LibraryDatasetView:a}});
\ No newline at end of file
+define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,b){var a=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_modify_dataset":"enableModification","click .toolbtn_cancel_modifications":"render","click .toolbtn-download-dataset":"downloadDataset","click .toolbtn-import-dataset":"importIntoHistory","click .toolbtn-share-dataset":"shareDataset","click .toolbtn_save_modifications":"comingSoon","click .btn-remove-restrictions":"comingSoon","click .btn-make-private":"comingSoon","click .btn-share-dataset":"comingSoon"},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchDataset()}},fetchDataset:function(e){this.options=_.extend(this.options,e);this.model=new c.Item({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{f.render()}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred :(. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){$(".tooltip").remove();this.options=_.extend(this.options,e);var f=this.templateDataset();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},enableModification:function(){$(".tooltip").remove();var e=this.templateModifyDataset();this.$el.html(e({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},downloadDataset:function(){var e="/api/libraries/datasets/download/uncompressed";var f={ldda_ids:this.id};this.processDownload(e,f)},processDownload:function(f,g,h){if(f&&g){g=typeof g=="string"?g:$.param(g);var e="";$.each(g.split("&"),function(){var i=this.split("=");e+='<input type="hidden" name="'+i[0]+'" value="'+i[1]+'" />'});$('<form action="'+f+'" method="'+(h||"post")+'">'+e+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon")}},importIntoHistory:function(){this.refreshUserHistoriesList(function(e){var f=e.templateBulkImportInModal();e.modal=Galaxy.modal;e.modal.show({closing_events:true,title:"Import into History",body:f({histories:e.histories.models}),buttons:{Import:function(){e.importCurrentIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})},refreshUserHistoriesList:function(f){var e=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){f(e)},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg)}else{d.error("An error ocurred :(")}}})},importCurrentIntoHistory:function(){var f=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();var g=new c.HistoryItem();g.url=g.urlRoot+f+"/contents";var e="/api/histories/"+f+"/set_as_current";$.ajax({url:e,type:"PUT"});g.save({content:this.id,source:"library"},{success:function(){Galaxy.modal.hide();d.success("Dataset imported. Click this to start analysing it.","",{onclick:function(){window.location="/"}})},error:function(i,h){if(typeof h.responseJSON!=="undefined"){d.error("Dataset not imported. "+h.responseJSON.err_msg)}else{d.error("An error occured! Dataset not imported. Please try again.")}}})},shareDataset:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(){$(".tooltip").remove();var f=this.templateDatasetPermissions();this.$el.html(f({item:this.model}));var g=false;if(Galaxy.currUser){g=Galaxy.currUser.isAdmin()}var e=this;$.get("/api/libraries/datasets/"+e.id+"/permissions/current").done(function(j){var k=[];for(var m=0;m<j.length;m++){k.push(j[m]+":"+j[m])}if(g){var h={minimumInputLength:1,css:"access_perm",multiple:true,placeholder:"Click to select a role",container:e.$el.find("#access_perm"),ajax:{url:"/api/libraries/datasets/"+e.id+"/permissions",dataType:"json",quietMillis:100,data:function(i,p){return{q:i,page_limit:10,page:p}},results:function(q,p){var i=(p*10)<q.total;return{results:q.roles,more:i}}},formatResult:function l(i){return i.name+" type: "+i.type},formatSelection:function o(i){return i.name},initSelection:function(i,q){var p=[];$(i.val().split(",")).each(function(){var r=this.split(":");p.push({id:r[1],name:r[1]})});q(p)},initialData:k.join(","),dropdownCssClass:"bigdrop"};this.accessSelectObject=new b.View(h)}else{var n=this.templateAccessSelect();$.get("/api/libraries/datasets/"+e.id+"/permissions",function(i){$(".access_perm").html(n({options:i.roles}));this.accessSelectObject=$("#access_select").select2()}).fail(function(){d.error("An error occurred while fetching data with permissions. :(")})}}).fail(function(){d.error("An error occurred while fetching data with permissions. :(")});$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},comingSoon:function(){d.warning("Feature coming soon")},templateDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify dataset" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Change permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("data_type")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("data_type")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateModifyDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push('<p>For more editing options please import the dataset to history and use "Edit attributes" on it.</p>');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><input class="input_dataset_name form-control" type="text" placeholder="name" value="<%= _.escape(item.get("name")) %>"></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("data_type")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(' <tr scope="row">');e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <% if (item.get("metadata_comment_lines") === "") { %>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" <% } else { %>");e.push(' <td scope="row">unknown</td>');e.push(" <% } %>");e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" </table>");e.push("<div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push("</div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateDatasetPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to folder" class="btn btn-default primary-button" type="button"><span class="fa fa-folder-open-o"></span> go to Folder</span></button></a>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go back to dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-file-o"></span> see the Dataset</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<h1><%= _.escape(item.get("name")) %></h1>');e.push('<div class="alert alert-success">You have rights to change permissions on this dataset. That means you can control who can access it, who can modify it and also appoint others that can manage permissions on it.</div>');e.push('<div class="dataset_table">');e.push("<h2>Basic permissions</h2>");e.push("<p>You can remove all access restrictions on this dataset. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Everybody will be able to see the dataset." class="btn btn-default btn-remove-restrictions primary-button" type="button"><span class="fa fa-globe"></span> Remove restrictions</span></button>');e.push("</p>");e.push("<p>You can make this dataset private to you. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Only you will be able to see the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"></span> Make private</span></button>');e.push("</p>");e.push("<p>You can share this dataset with another Galaxy user. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Only you and the other user will be able to see the dataset." class="btn btn-default btn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push("</p>");e.push("<h2>Advanced permissions</h2>");e.push("<p>You can assign any number of roles to any of the following three dataset permission types. However please read carefully the implications of such actions.</p>");e.push("<h3>Access Roles</h3>");e.push('<div class="alert alert-info">User has to have <strong>all these roles</strong> in order to see this dataset.</div>');e.push('<div id="access_perm" class="access_perm roles-selection"></div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("<h3>Modify Roles</h3>");e.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can modify the information about this dataset.</div>');e.push('<div id="modify_perm" class="modify_perm"></div>');e.push("<h3>Manage Roles</h3>");e.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can change permissions of this dataset.</div>');e.push('<div id="manage_perm" class="manage_perm"></div>');e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateBulkImportInModal:function(){var e=[];e.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');e.push("Select history: ");e.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');e.push(" <% _.each(histories, function(history) { %>");e.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');e.push(" <% }); %>");e.push("</select>");e.push("</span>");return _.template(e.join(""))},templateAccessSelect:function(){var e=[];e.push('<select id="access_select" multiple>');e.push(" <% _.each(options, function(option) { %>");e.push(' <option value="<%- option.name %>"><%- option.name %></option>');e.push(" <% }); %>");e.push("</select>");return _.template(e.join(""))}});return{LibraryDatasetView:a}});
\ No newline at end of file
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/packed/mvc/library/library-folderrow-view.js
--- a/static/scripts/packed/mvc/library/library-folderrow-view.js
+++ b/static/scripts/packed/mvc/library/library-folderrow-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-dataset-view"],function(c,e,f,d,b){var a=Backbone.View.extend({lastSelectedHistory:"",events:{"click .undelete_dataset_btn":"undelete_dataset"},options:{type:null},initialize:function(g){this.render(g)},render:function(g){var h=null;if(g.get("type")==="folder"){this.options.type="folder";h=this.templateRowFolder()}else{this.options.type="file";if(g.get("deleted")){h=this.templateRowDeletedFile()}else{h=this.templateRowFile()}}this.setElement(h({content_item:g}));this.$el.show();return this},showDatasetDetails:function(){this.dataset_view=new b.LibraryDatasetView({id:this.id})},undelete_dataset:function(i){$(".tooltip").hide();var h=this;var g=$(i.target).closest("tr")[0].id;var j=Galaxy.libraries.folderListView.collection.get(g);j.url=j.urlRoot+j.id+"?undelete=true";j.destroy({success:function(l,k){Galaxy.libraries.folderListView.collection.remove(g);var m=new d.Item(k);Galaxy.libraries.folderListView.collection.add(m);f.success("Dataset undeleted. Click this to see it.","",{onclick:function(){h.showDatasetDetails()}})},error:function(l,k){if(typeof k.responseJSON!=="undefined"){f.error("Dataset was not undeleted. "+k.responseJSON.err_msg)}else{f.error("An error occured! Dataset was not undeleted. Please try again.")}}})},templateRowFolder:function(){tmpl_array=[];tmpl_array.push('<tr class="folder_row light" id="<%- content_item.id %>">');tmpl_array.push(" <td>");tmpl_array.push(' <span title="Folder" class="fa fa-folder-o"></span>');tmpl_array.push(" </td>");tmpl_array.push(" <td></td>");tmpl_array.push(" <td>");tmpl_array.push(' <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');tmpl_array.push(" </td>");tmpl_array.push(" <td>folder</td>");tmpl_array.push(" <td></td>");tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>');tmpl_array.push(" <td></td>");tmpl_array.push("</tr>");return _.template(tmpl_array.join(""))},templateRowFile:function(){tmpl_array=[];tmpl_array.push('<tr class="dataset_row light dataset" id="<%- content_item.id %>">');tmpl_array.push(" <td>");tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');tmpl_array.push(" </td>");tmpl_array.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');tmpl_array.push(' <td><a href="#folders/<%- content_item.get("folder_id") %>/datasets/<%- content_item.id %>" class="library-dataset"><%- content_item.get("name") %><a></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("file_size")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>');tmpl_array.push(" <td>");tmpl_array.push(' <% if (content_item.get("is_unrestricted")) { %><span data-toggle="tooltip" data-placement="top" title="Unrestricted dataset" style="color:grey;" class="fa fa-globe fa-lg"></span><% } %>');tmpl_array.push(' <% if (content_item.get("is_private")) { %><span data-toggle="tooltip" data-placement="top" title="Private dataset" style="color:grey;" class="fa fa-key fa-lg"></span><% } %>');tmpl_array.push(' <% if ((content_item.get("is_unrestricted") === false) && (content_item.get("is_private") === false)) { %><span data-toggle="tooltip" data-placement="top" title="Restricted dataset" style="color:grey;" class="fa fa-shield fa-lg"></span><% } %>');tmpl_array.push(' <% if (content_item.get("can_manage")) { %><a href="#folders/<%- content_item.get("folder_id") %>/datasets/<%- content_item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" class="primary-button btn-xs permissions-dataset-btn show_on_hover" title="Manage permissions" style="display:none;"><span class="fa fa-group"></span></button></a><% } %>');tmpl_array.push(" </td>");tmpl_array.push("</tr>");return _.template(tmpl_array.join(""))},templateRowDeletedFile:function(){tmpl_array=[];tmpl_array.push('<tr class="active deleted_dataset dataset" id="<%- content_item.id %>">');tmpl_array.push(" <td>");tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');tmpl_array.push(" </td>");tmpl_array.push(" <td></td>");tmpl_array.push(' <td style="color:grey;"><%- content_item.get("name") %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("file_size")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>');tmpl_array.push(' <td><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg"></span><button data-toggle="tooltip" data-placement="top" title="Undelete <%- content_item.get("name") %>" class="primary-button btn-xs undelete_dataset_btn show_on_hover" type="button" style="display:none; margin-left:1em;"><span class="fa fa-unlock"> Undelete</span></button></td>');tmpl_array.push("</tr>");return _.template(tmpl_array.join(""))}});return{FolderRowView:a}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model","mvc/library/library-dataset-view"],function(c,e,f,d,b){var a=Backbone.View.extend({lastSelectedHistory:"",events:{"click .undelete_dataset_btn":"undelete_dataset"},options:{type:null},initialize:function(g){this.render(g)},render:function(g){var h=null;if(g.get("type")==="folder"){this.options.type="folder";h=this.templateRowFolder()}else{this.options.type="file";if(g.get("deleted")){h=this.templateRowDeletedFile()}else{h=this.templateRowFile()}}this.setElement(h({content_item:g}));this.$el.show();return this},showDatasetDetails:function(){Galaxy.libraries.datasetView=new b.LibraryDatasetView({id:this.id})},undelete_dataset:function(i){$(".tooltip").hide();var h=this;var g=$(i.target).closest("tr")[0].id;var j=Galaxy.libraries.folderListView.collection.get(g);j.url=j.urlRoot+j.id+"?undelete=true";j.destroy({success:function(l,k){Galaxy.libraries.folderListView.collection.remove(g);var m=new d.Item(k);Galaxy.libraries.folderListView.collection.add(m);f.success("Dataset undeleted. Click this to see it.","",{onclick:function(){h.showDatasetDetails()}})},error:function(l,k){if(typeof k.responseJSON!=="undefined"){f.error("Dataset was not undeleted. "+k.responseJSON.err_msg)}else{f.error("An error occured! Dataset was not undeleted. Please try again.")}}})},templateRowFolder:function(){tmpl_array=[];tmpl_array.push('<tr class="folder_row light" id="<%- content_item.id %>">');tmpl_array.push(" <td>");tmpl_array.push(' <span title="Folder" class="fa fa-folder-o"></span>');tmpl_array.push(" </td>");tmpl_array.push(" <td></td>");tmpl_array.push(" <td>");tmpl_array.push(' <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');tmpl_array.push(" </td>");tmpl_array.push(" <td>folder</td>");tmpl_array.push(" <td></td>");tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>');tmpl_array.push(" <td></td>");tmpl_array.push("</tr>");return _.template(tmpl_array.join(""))},templateRowFile:function(){tmpl_array=[];tmpl_array.push('<tr class="dataset_row light dataset" id="<%- content_item.id %>">');tmpl_array.push(" <td>");tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');tmpl_array.push(" </td>");tmpl_array.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');tmpl_array.push(' <td><a href="#folders/<%- content_item.get("folder_id") %>/datasets/<%- content_item.id %>" class="library-dataset"><%- content_item.get("name") %><a></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("file_size")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>');tmpl_array.push(" <td>");tmpl_array.push(' <% if (content_item.get("is_unrestricted")) { %><span data-toggle="tooltip" data-placement="top" title="Unrestricted dataset" style="color:grey;" class="fa fa-globe fa-lg"></span><% } %>');tmpl_array.push(' <% if (content_item.get("is_private")) { %><span data-toggle="tooltip" data-placement="top" title="Private dataset" style="color:grey;" class="fa fa-key fa-lg"></span><% } %>');tmpl_array.push(' <% if ((content_item.get("is_unrestricted") === false) && (content_item.get("is_private") === false)) { %><span data-toggle="tooltip" data-placement="top" title="Restricted dataset" style="color:grey;" class="fa fa-shield fa-lg"></span><% } %>');tmpl_array.push(' <% if (content_item.get("can_manage")) { %><a href="#folders/<%- content_item.get("folder_id") %>/datasets/<%- content_item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" class="primary-button btn-xs permissions-dataset-btn show_on_hover" title="Manage permissions" style="display:none;"><span class="fa fa-group"></span></button></a><% } %>');tmpl_array.push(" </td>");tmpl_array.push("</tr>");return _.template(tmpl_array.join(""))},templateRowDeletedFile:function(){tmpl_array=[];tmpl_array.push('<tr class="active deleted_dataset dataset" id="<%- content_item.id %>">');tmpl_array.push(" <td>");tmpl_array.push(' <span title="Dataset" class="fa fa-file-o"></span>');tmpl_array.push(" </td>");tmpl_array.push(" <td></td>");tmpl_array.push(' <td style="color:grey;"><%- content_item.get("name") %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("file_size")) %></td>');tmpl_array.push(' <td><%= _.escape(content_item.get("update_time")) %></td>');tmpl_array.push(' <td><span data-toggle="tooltip" data-placement="top" title="Marked deleted" style="color:grey;" class="fa fa-ban fa-lg"></span><button data-toggle="tooltip" data-placement="top" title="Undelete <%- content_item.get("name") %>" class="primary-button btn-xs undelete_dataset_btn show_on_hover" type="button" style="display:none; margin-left:1em;"><span class="fa fa-unlock"> Undelete</span></button></td>');tmpl_array.push("</tr>");return _.template(tmpl_array.join(""))}});return{FolderRowView:a}});
\ No newline at end of file
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/packed/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal","click #include_deleted_datasets_chk":"checkIncludeDeleted","click #toolbtn_bulk_delete":"deleteSelectedDatasets"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(g){this.options=_.extend(this.options,g);var i=false;var f=true;if(Galaxy.currUser){i=Galaxy.currUser.isAdmin();f=Galaxy.currUser.isAnonymous()}var h=this.templateToolBar();this.$el.html(h({id:this.options.id,admin_user:i,anonym:f}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$(".add-library-items").show()}else{$(".add-library-items").hide()}if(this.options.contains_file===true){if(Galaxy.currUser){if(!Galaxy.currUser.isAnonymous()){$(".logged-dataset-manipulation").show();$(".dataset-manipulation").show()}else{$(".dataset-manipulation").show();$(".logged-dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var k=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=k;var n=$("select[name=dataset_import_bulk] option:selected").text();var p=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){p.push(this.parentElement.parentElement.id)}});var o=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(o({history_name:n}));var l=100/p.length;this.initProgress(l);var f=[];for(var h=p.length-1;h>=0;h--){var j=p[h];var m=new c.HistoryItem();m.url=m.urlRoot+k+"/contents";m.content=j;m.source="library";f.push(m)}this.options.chain_call_control.total_number=f.length;var g="/api/histories/"+k+"/set_as_current";$.ajax({url:g,type:"PUT"});this.chainCall(f,n)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history. Click this to start analysing it.","",{onclick:function(){window.location="/"}})}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history. Click this to see what was imported.","",{onclick:function(){window.location="/"}})}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();f.modal.show({closing_events:true,title:"Add datasets from history to "+f.options.folder_name,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(h){f.fetchAndDisplayHistoryContents(h.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(){e.error("An error ocurred :(")}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},checkIncludeDeleted:function(f){if(f.target.checked){Galaxy.libraries.folderListView.fetchFolder({include_deleted:true})}else{Galaxy.libraries.folderListView.fetchFolder({include_deleted:false})}},deleteSelectedDatasets:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{var j=this.templateDeletingDatasetsProgressBar();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Deleting selected datasets",body:j({}),buttons:{Close:function(){Galaxy.modal.hide()}}});this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var g=[];f.each(function(){if(this.parentElement.parentElement.id!==""){g.push(this.parentElement.parentElement.id)}});this.progressStep=100/g.length;this.progress=0;var l=[];for(var h=g.length-1;h>=0;h--){var k=new c.Item({id:g[h]});l.push(k)}this.options.chain_call_control.total_number=g.length;this.chainCallDeletingHdas(l)}},chainCallDeletingHdas:function(g){var f=this;this.deleted_lddas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets deleted")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were deleted.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be deleted")}}}Galaxy.modal.hide();return this.deleted_lddas}var i=$.when(h.destroy());i.done(function(k){Galaxy.libraries.folderListView.collection.remove(h.id);f.updateProgress();if(Galaxy.libraries.folderListView.options.include_deleted){var j=new c.Item(k);Galaxy.libraries.folderListView.collection.add(j)}f.chainCallDeletingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallDeletingHdas(g)})},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<div id="library_toolbar">');tmpl_array.push('<span data-toggle="tooltip" data-placement="top" class="logged-dataset-manipulation" title="Include deleted datasets" style="display:none;"><input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');tmpl_array.push('<div class="btn-group add-library-items" style="display:none;">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push("</div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button dataset-manipulation" style="margin-left: 0.5em; display:none;" type="button"><span class="fa fa-book"></span> to History</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group dataset-manipulation" style="margin-left: 0.5em; display:none; ">');tmpl_array.push(' <button title="Download selected datasets as archive" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> Download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button logged-dataset-manipulation" style="margin-left: 0.5em; display:none; " type="button"><span class="fa fa-times"></span> Delete</button>');tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateDeletingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-delete" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal","click #include_deleted_datasets_chk":"checkIncludeDeleted","click #toolbtn_bulk_delete":"deleteSelectedDatasets"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(g){this.options=_.extend(this.options,g);var i=false;var f=true;if(Galaxy.currUser){i=Galaxy.currUser.isAdmin();f=Galaxy.currUser.isAnonymous()}var h=this.templateToolBar();this.$el.html(h({id:this.options.id,admin_user:i,anonym:f}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$(".add-library-items").show()}else{$(".add-library-items").hide()}if(this.options.contains_file===true){if(Galaxy.currUser){if(!Galaxy.currUser.isAnonymous()){$(".logged-dataset-manipulation").show();$(".dataset-manipulation").show()}else{$(".dataset-manipulation").show();$(".logged-dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var k=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=k;var n=$("select[name=dataset_import_bulk] option:selected").text();var p=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){p.push(this.parentElement.parentElement.id)}});var o=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(o({history_name:n}));var l=100/p.length;this.initProgress(l);var f=[];for(var h=p.length-1;h>=0;h--){var j=p[h];var m=new c.HistoryItem();m.url=m.urlRoot+k+"/contents";m.content=j;m.source="library";f.push(m)}this.options.chain_call_control.total_number=f.length;var g="/api/histories/"+k+"/set_as_current";$.ajax({url:g,type:"PUT"});this.chainCall(f,n)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history. Click this to start analysing it.","",{onclick:function(){window.location="/"}})}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history. Click this to see what was imported.","",{onclick:function(){window.location="/"}})}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();f.modal.show({closing_events:true,title:"Add datasets from history to "+f.options.folder_name,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(h){f.fetchAndDisplayHistoryContents(h.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(){e.error("An error ocurred :(")}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},checkIncludeDeleted:function(f){if(f.target.checked){Galaxy.libraries.folderListView.fetchFolder({include_deleted:true})}else{Galaxy.libraries.folderListView.fetchFolder({include_deleted:false})}},deleteSelectedDatasets:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{var j=this.templateDeletingDatasetsProgressBar();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Deleting selected datasets",body:j({}),buttons:{Close:function(){Galaxy.modal.hide()}}});this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var g=[];f.each(function(){if(this.parentElement.parentElement.id!==""){g.push(this.parentElement.parentElement.id)}});this.progressStep=100/g.length;this.progress=0;var l=[];for(var h=g.length-1;h>=0;h--){var k=new c.Item({id:g[h]});l.push(k)}this.options.chain_call_control.total_number=g.length;this.chainCallDeletingHdas(l)}},chainCallDeletingHdas:function(g){var f=this;this.deleted_lddas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets deleted")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were deleted.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be deleted")}}}Galaxy.modal.hide();return this.deleted_lddas}var i=$.when(h.destroy());i.done(function(k){Galaxy.libraries.folderListView.collection.remove(h.id);f.updateProgress();if(Galaxy.libraries.folderListView.options.include_deleted){var j=new c.Item(k);Galaxy.libraries.folderListView.collection.add(j)}f.chainCallDeletingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallDeletingHdas(g)})},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<div id="library_toolbar">');tmpl_array.push('<span data-toggle="tooltip" data-placement="top" class="logged-dataset-manipulation" title="Include deleted datasets" style="display:none;"><input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"> include deleted</input></span>');tmpl_array.push('<div class="btn-group add-library-items" style="display:none;">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push("</div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button dataset-manipulation" style="margin-left: 0.5em; display:none;" type="button"><span class="fa fa-book"></span> to History</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group dataset-manipulation" style="margin-left: 0.5em; display:none; ">');tmpl_array.push(' <button title="Download selected datasets as archive" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> Download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button logged-dataset-manipulation" style="margin-left: 0.5em; display:none; " type="button"><span class="fa fa-times"></span> Delete</button>');tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateDeletingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-delete" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
diff -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e -r 2e6e51179f7177b743bd970095be7e261ae62700 static/scripts/packed/mvc/library/library-librarytoolbar-view.js
--- a/static/scripts/packed/mvc/library/library-librarytoolbar-view.js
+++ b/static/scripts/packed/mvc/library/library-librarytoolbar-view.js
@@ -1,1 +1,1 @@
-define(["libs/toastr","mvc/library/library-model"],function(b,a){var c=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},render:function(){var f=this.templateToolBar();var e=false;var d=true;if(Galaxy.currUser){e=Galaxy.currUser.isAdmin();d=Galaxy.currUser.isAnonymous()}this.$el.html(f({admin_user:e,anon_user:d}));if(e){this.$el.find("#include_deleted_chk")[0].checked=Galaxy.libraries.preferences.get("with_deleted")}},show_library_modal:function(e){e.preventDefault();e.stopPropagation();var d=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){d.create_new_library_event()},Close:function(){d.modal.hide()}}})},create_new_library_event:function(){var f=this.serialize_new_library();if(this.validate_new_library(f)){var e=new a.Library();var d=this;e.save(f,{success:function(g){Galaxy.libraries.libraryListView.collection.add(g);d.modal.hide();d.clear_library_modal();Galaxy.libraries.libraryListView.render();b.success("Library created")},error:function(h,g){if(typeof g.responseJSON!=="undefined"){b.error(g.responseJSON.err_msg)}else{b.error("An error occured :(")}}})}else{b.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(d){return d.name!==""},check_include_deleted:function(d){if(d.target.checked){Galaxy.libraries.preferences.set({with_deleted:true});Galaxy.libraries.libraryListView.render()}else{Galaxy.libraries.preferences.set({with_deleted:false});Galaxy.libraries.libraryListView.render()}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push(' <div id="toolbar_form">');tmpl_array.push(" <% if(admin_user === true) { %>");tmpl_array.push(' <div id="library_toolbar">');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Include deleted libraries"><input id="include_deleted_chk" style="margin: 0;" type="checkbox"><span class="fa fa-trash-o fa-lg"></span></input></span>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Create New Library"><button id="create_new_library_btn" class="primary-button btn-xs" type="button"><span class="fa fa-plus"></span> New Library</button><span>');tmpl_array.push(" </div>");tmpl_array.push(" <% } %>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="libraries_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")}});return{LibraryToolbarView:c}});
\ No newline at end of file
+define(["libs/toastr","mvc/library/library-model"],function(b,a){var c=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},render:function(){var f=this.templateToolBar();var e=false;var d=true;if(Galaxy.currUser){e=Galaxy.currUser.isAdmin();d=Galaxy.currUser.isAnonymous()}this.$el.html(f({admin_user:e,anon_user:d}));if(e){this.$el.find("#include_deleted_chk")[0].checked=Galaxy.libraries.preferences.get("with_deleted")}},show_library_modal:function(e){e.preventDefault();e.stopPropagation();var d=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){d.create_new_library_event()},Close:function(){d.modal.hide()}}})},create_new_library_event:function(){var f=this.serialize_new_library();if(this.validate_new_library(f)){var e=new a.Library();var d=this;e.save(f,{success:function(g){Galaxy.libraries.libraryListView.collection.add(g);d.modal.hide();d.clear_library_modal();Galaxy.libraries.libraryListView.render();b.success("Library created")},error:function(h,g){if(typeof g.responseJSON!=="undefined"){b.error(g.responseJSON.err_msg)}else{b.error("An error occured :(")}}})}else{b.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(d){return d.name!==""},check_include_deleted:function(d){if(d.target.checked){Galaxy.libraries.preferences.set({with_deleted:true});Galaxy.libraries.libraryListView.render()}else{Galaxy.libraries.preferences.set({with_deleted:false});Galaxy.libraries.libraryListView.render()}},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push(' <div id="toolbar_form">');tmpl_array.push(" <% if(admin_user === true) { %>");tmpl_array.push(' <div id="library_toolbar">');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Include deleted libraries"><input id="include_deleted_chk" style="margin: 0;" type="checkbox"> include deleted</input></span>');tmpl_array.push(' <span data-toggle="tooltip" data-placement="top" title="Create New Library"><button id="create_new_library_btn" class="primary-button btn-xs" type="button"><span class="fa fa-plus"></span> New Library</button><span>');tmpl_array.push(" </div>");tmpl_array.push(" <% } %>");tmpl_array.push(" </div>");tmpl_array.push(' <div id="libraries_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")}});return{LibraryToolbarView:c}});
\ 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: jmchilton: Update LWR client through LWR changeset f7d15f0.
by commits-noreply@bitbucket.org 16 May '14
by commits-noreply@bitbucket.org 16 May '14
16 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6d45e4c17643/
Changeset: 6d45e4c17643
User: jmchilton
Date: 2014-05-16 23:17:08
Summary: Update LWR client through LWR changeset f7d15f0.
Adds new LWR file action type - rewrite - that allows paths to be simply rewritten during paramater replacement or command rewriting.
Affected #: 5 files
diff -r f61263482700499fd79238b6468c18e6915aaf08 -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e lib/galaxy/jobs/runners/lwr_client/action_mapper.py
--- a/lib/galaxy/jobs/runners/lwr_client/action_mapper.py
+++ b/lib/galaxy/jobs/runners/lwr_client/action_mapper.py
@@ -132,6 +132,24 @@
self.mappers = mappers_from_dicts(config.get("paths", []))
self.files_endpoint = config.get("files_endpoint", None)
+ def action(self, path, type, mapper=None):
+ mapper = self.__find_mapper(path, type, mapper)
+ action_class = self.__action_class(path, type, mapper)
+ file_lister = DEFAULT_FILE_LISTER
+ action_kwds = {}
+ if mapper:
+ file_lister = mapper.file_lister
+ action_kwds = mapper.action_kwds
+ action = action_class(path, file_lister=file_lister, **action_kwds)
+ self.__process_action(action, type)
+ return action
+
+ def unstructured_mappers(self):
+ """ Return mappers that will map 'unstructured' files (i.e. go beyond
+ mapping inputs, outputs, and config files).
+ """
+ return filter(lambda m: path_type.UNSTRUCTURED in m.path_types, self.mappers)
+
def to_dict(self):
return dict(
default_action=self.default_action,
@@ -153,18 +171,19 @@
config = load(open(path, 'rb'))
self.mappers = mappers_from_dicts(config.get('paths', []))
- def action(self, path, type, mapper=None):
- action_type = self.default_action if type in ACTION_DEFAULT_PATH_TYPES else "none"
- file_lister = DEFAULT_FILE_LISTER
- normalized_path = abspath(path)
+ def __find_mapper(self, path, type, mapper=None):
if not mapper:
+ normalized_path = abspath(path)
for query_mapper in self.mappers:
if query_mapper.matches(normalized_path, type):
mapper = query_mapper
break
+ return mapper
+
+ def __action_class(self, path, type, mapper):
+ action_type = self.default_action if type in ACTION_DEFAULT_PATH_TYPES else "none"
if mapper:
action_type = mapper.action_type
- file_lister = mapper.file_lister
if type in ["workdir", "output_workdir"] and action_type == "none":
# We are changing the working_directory relative to what
# Galaxy would use, these need to be copied over.
@@ -174,15 +193,7 @@
message_template = "Unknown action_type encountered %s while trying to map path %s"
message_args = (action_type, path)
raise Exception(message_template % message_args)
- action = action_class(path, file_lister=file_lister)
- self.__process_action(action, type)
- return action
-
- def unstructured_mappers(self):
- """ Return mappers that will map 'unstructured' files (i.e. go beyond
- mapping inputs, outputs, and config files).
- """
- return filter(lambda m: path_type.UNSTRUCTURED in m.path_types, self.mappers)
+ return action_class
def __process_action(self, action, file_type):
""" Extension point to populate extra action information after an
@@ -198,19 +209,30 @@
url = "%s&path=%s&file_type=%s" % (url_base, action.path, file_type)
action.url = url
+REQUIRED_ACTION_KWD = object()
+
class BaseAction(object):
+ action_spec = {}
def __init__(self, path, file_lister=None):
self.path = path
self.file_lister = file_lister or DEFAULT_FILE_LISTER
- def unstructured_map(self):
+ def unstructured_map(self, path_helper):
unstructured_map = self.file_lister.unstructured_map(self.path)
- # To ensure uniqueness, prepend unique prefix to each name
- prefix = unique_path_prefix(self.path)
- for path, name in unstructured_map.iteritems():
- unstructured_map[path] = join(prefix, name)
+ if self.staging_needed:
+ # To ensure uniqueness, prepend unique prefix to each name
+ prefix = unique_path_prefix(self.path)
+ for path, name in unstructured_map.iteritems():
+ unstructured_map[path] = join(prefix, name)
+ else:
+ path_rewrites = {}
+ for path in unstructured_map:
+ rewrite = self.path_rewrite(path_helper, path)
+ if rewrite:
+ path_rewrites[path] = rewrite
+ unstructured_map = path_rewrites
return unstructured_map
@property
@@ -230,6 +252,56 @@
action_type = "none"
staging = STAGING_ACTION_NONE
+ def to_dict(self):
+ return dict(path=self.path, action_type=self.action_type)
+
+ @classmethod
+ def from_dict(cls, action_dict):
+ return NoneAction(path=action_dict["path"])
+
+ def path_rewrite(self, path_helper, path=None):
+ return None
+
+
+class RewriteAction(BaseAction):
+ """ This actin indicates the LWR server should simply rewrite the path
+ to the specified file.
+ """
+ action_spec = dict(
+ source_directory=REQUIRED_ACTION_KWD,
+ destination_directory=REQUIRED_ACTION_KWD
+ )
+ action_type = "rewrite"
+ staging = STAGING_ACTION_NONE
+
+ def __init__(self, path, file_lister=None, source_directory=None, destination_directory=None):
+ self.path = path
+ self.file_lister = file_lister or DEFAULT_FILE_LISTER
+ self.source_directory = source_directory
+ self.destination_directory = destination_directory
+
+ def to_dict(self):
+ return dict(
+ path=self.path,
+ action_type=self.action_type,
+ source_directory=self.source_directory,
+ destination_directory=self.destination_directory,
+ )
+
+ @classmethod
+ def from_dict(cls, action_dict):
+ return RewriteAction(
+ path=action_dict["path"],
+ source_directory=action_dict["source_directory"],
+ destination_directory=action_dict["destination_directory"],
+ )
+
+ def path_rewrite(self, path_helper, path=None):
+ if not path:
+ path = self.path
+ new_path = path_helper.from_posix_with_new_base(self.path, self.source_directory, self.destination_directory)
+ return None if new_path == self.path else new_path
+
class TransferAction(BaseAction):
""" This actions indicates that the LWR client should initiate an HTTP
@@ -353,7 +425,18 @@
class BasePathMapper(object):
def __init__(self, config):
- self.action_type = config.get('action', DEFAULT_MAPPED_ACTION)
+ action_type = config.get('action', DEFAULT_MAPPED_ACTION)
+ action_class = actions.get(action_type, None)
+ action_kwds = action_class.action_spec.copy()
+ for key, value in action_kwds.items():
+ if key in config:
+ action_kwds[key] = config[key]
+ elif value is REQUIRED_ACTION_KWD:
+ message_template = "action_type %s requires key word argument %s"
+ message = message_template % (action_type, key)
+ raise Exception( message )
+ self.action_type = action_type
+ self.action_kwds = action_kwds
path_types_str = config.get('path_types', "*defaults*")
path_types_str = path_types_str.replace("*defaults*", ",".join(ACTION_DEFAULT_PATH_TYPES))
path_types_str = path_types_str.replace("*any*", ",".join(ALL_PATH_TYPES))
@@ -368,9 +451,10 @@
base_dict = dict(
action=self.action_type,
path_types=",".join(self.path_types),
- match_type=self.match_type,
- **self.file_lister.to_dict()
+ match_type=self.match_type
)
+ base_dict.update(self.file_lister.to_dict())
+ base_dict.update(self.action_kwds)
base_dict.update(**kwds)
return base_dict
@@ -464,10 +548,11 @@
ACTION_CLASSES = [
NoneAction,
+ RewriteAction,
TransferAction,
CopyAction,
RemoteCopyAction,
- RemoteTransferAction
+ RemoteTransferAction,
]
actions = dict([(clazz.action_type, clazz) for clazz in ACTION_CLASSES])
diff -r f61263482700499fd79238b6468c18e6915aaf08 -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e lib/galaxy/jobs/runners/lwr_client/amqp_exchange.py
--- a/lib/galaxy/jobs/runners/lwr_client/amqp_exchange.py
+++ b/lib/galaxy/jobs/runners/lwr_client/amqp_exchange.py
@@ -48,6 +48,7 @@
def consume(self, queue_name, callback, check=True, connection_kwargs={}):
queue = self.__queue(queue_name)
+ log.debug("Consuming queue '%s'", queue)
while check:
try:
with self.connection(self.__url, ssl=self.__connect_ssl, **connection_kwargs) as connection:
diff -r f61263482700499fd79238b6468c18e6915aaf08 -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e lib/galaxy/jobs/runners/lwr_client/path_mapper.py
--- a/lib/galaxy/jobs/runners/lwr_client/path_mapper.py
+++ b/lib/galaxy/jobs/runners/lwr_client/path_mapper.py
@@ -59,7 +59,7 @@
path = str(local_path) # Use false_path if needed.
action = self.action_mapper.action(path, path_type.UNSTRUCTURED)
if not action.staging_needed:
- return None, []
+ return action.path_rewrite(self.path_helper), []
unique_names = action.unstructured_map()
name = unique_names[path]
remote_path = self.path_helper.remote_join(self.unstructured_files_directory, name)
@@ -70,12 +70,16 @@
"""
path = str(dataset_path) # Use false_path if needed.
action = self.action_mapper.action(path, dataset_path_type)
- remote_path_rewrite = None
if action.staging_needed:
if name is None:
name = os.path.basename(path)
remote_directory = self.__remote_directory(dataset_path_type)
remote_path_rewrite = self.path_helper.remote_join(remote_directory, name)
+ else:
+ # Actions which don't require staging MUST define a path_rewrite
+ # method.
+ remote_path_rewrite = action.path_rewrite(self.path_helper)
+
return remote_path_rewrite
def __action(self, dataset_path, dataset_path_type):
diff -r f61263482700499fd79238b6468c18e6915aaf08 -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e lib/galaxy/jobs/runners/lwr_client/staging/up.py
--- a/lib/galaxy/jobs/runners/lwr_client/staging/up.py
+++ b/lib/galaxy/jobs/runners/lwr_client/staging/up.py
@@ -78,9 +78,11 @@
self.job_inputs = JobInputs(self.command_line, self.config_files)
self.action_mapper = FileActionMapper(client)
- self.transfer_tracker = TransferTracker(client, self.action_mapper, self.job_inputs, rewrite_paths=self.rewrite_paths)
self.__handle_setup(job_config)
+
+ self.transfer_tracker = TransferTracker(client, self.path_helper, self.action_mapper, self.job_inputs, rewrite_paths=self.rewrite_paths)
+
self.__initialize_referenced_tool_files()
if self.rewrite_paths:
self.__initialize_referenced_arbitrary_files()
@@ -142,7 +144,7 @@
referenced_arbitrary_path_mappers[path] = mapper
for path, mapper in referenced_arbitrary_path_mappers.iteritems():
action = self.action_mapper.action(path, path_type.UNSTRUCTURED, mapper)
- unstructured_map = action.unstructured_map()
+ unstructured_map = action.unstructured_map(self.path_helper)
self.arbitrary_files.update(unstructured_map)
def __upload_tool_files(self):
@@ -330,8 +332,9 @@
class TransferTracker(object):
- def __init__(self, client, action_mapper, job_inputs, rewrite_paths):
+ def __init__(self, client, path_helper, action_mapper, job_inputs, rewrite_paths):
self.client = client
+ self.path_helper = path_helper
self.action_mapper = action_mapper
self.job_inputs = job_inputs
@@ -357,6 +360,11 @@
register = self.rewrite_paths or type == 'tool' # Even if inputs not rewritten, tool must be.
if register:
self.register_rewrite(path, get_path(), type, force=True)
+ elif self.rewrite_paths:
+ path_rewrite = action.path_rewrite(self.path_helper)
+ if path_rewrite:
+ self.register_rewrite(path, path_rewrite, type, force=True)
+
# else: # No action for this file
def __add_remote_staging_input(self, action, name, type):
diff -r f61263482700499fd79238b6468c18e6915aaf08 -r 6d45e4c17643f86a5b7c572a9bd423ac46fb446e lib/galaxy/jobs/runners/lwr_client/util.py
--- a/lib/galaxy/jobs/runners/lwr_client/util.py
+++ b/lib/galaxy/jobs/runners/lwr_client/util.py
@@ -107,6 +107,12 @@
'moo/cow'
>>> nt_path_helper.local_name("moo\\\\cow")
'moo/cow'
+ >>> posix_path_helper.from_posix_with_new_base("/galaxy/data/bowtie/hg19.fa", "/galaxy/data/", "/work/galaxy/data")
+ '/work/galaxy/data/bowtie/hg19.fa'
+ >>> posix_path_helper.from_posix_with_new_base("/galaxy/data/bowtie/hg19.fa", "/galaxy/data", "/work/galaxy/data")
+ '/work/galaxy/data/bowtie/hg19.fa'
+ >>> posix_path_helper.from_posix_with_new_base("/galaxy/data/bowtie/hg19.fa", "/galaxy/data", "/work/galaxy/data/")
+ '/work/galaxy/data/bowtie/hg19.fa'
'''
def __init__(self, separator, local_path_module=os.path):
@@ -123,6 +129,22 @@
def remote_join(self, *args):
return self.separator.join(args)
+ def from_posix_with_new_base(self, posix_path, old_base, new_base):
+ # TODO: Test with new_base as a windows path against nt_path_helper.
+ if old_base.endswith("/"):
+ old_base = old_base[:-1]
+ if not posix_path.startswith(old_base):
+ message_template = "Cannot compute new path for file %s, does not start with %s."
+ message = message_template % (posix_path, old_base)
+ raise Exception(message)
+ stripped_path = posix_path[ len(old_base): ]
+ while stripped_path.startswith("/"):
+ stripped_path = stripped_path[1:]
+ path_parts = stripped_path.split(self.separator)
+ if new_base.endswith(self.separator):
+ new_base = new_base[:-len(self.separator)]
+ return self.remote_join(new_base, *path_parts)
+
class TransferEventManager(object):
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: greg: Add a script for creating a new user and an associated API key to streamline the process of setting up a new local development tool shed.
by commits-noreply@bitbucket.org 16 May '14
by commits-noreply@bitbucket.org 16 May '14
16 May '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f61263482700/
Changeset: f61263482700
User: greg
Date: 2014-05-16 23:14:24
Summary: Add a script for creating a new user and an associated API key to streamline the process of setting up a new local development tool shed.
Affected #: 2 files
diff -r 9fbe2754793109a1680239131b5507614d431870 -r f61263482700499fd79238b6468c18e6915aaf08 lib/tool_shed/scripts/bootstrap_tool_shed/create_user_with_api_key.py
--- /dev/null
+++ b/lib/tool_shed/scripts/bootstrap_tool_shed/create_user_with_api_key.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python
+
+import ConfigParser
+import logging
+import os
+import re
+import sys
+
+from optparse import OptionParser
+
+new_path = [ os.path.join( os.getcwd(), "lib" ) ]
+new_path.extend( sys.path[1:] )
+sys.path = new_path
+
+from galaxy import eggs
+eggs.require( "SQLAlchemy >= 0.4" )
+eggs.require( 'mercurial' )
+
+from galaxy.web import security
+import galaxy.webapps.tool_shed.config as tool_shed_config
+from galaxy.webapps.tool_shed.model import mapping
+from tool_shed.util import xml_util
+
+log = logging.getLogger( __name__ )
+
+
+VALID_PUBLICNAME_RE = re.compile( "^[a-z0-9\-]+$" )
+VALID_EMAIL_RE = re.compile( "[^@]+@[^@]+\.[^@]+" )
+
+
+class BootstrapApplication( object ):
+ """
+ Creates a basic Tool Shed application in order to discover the database connection and use SQL
+ to create a user and API key.
+ """
+
+ def __init__( self, config ):
+ self.config = config
+ if not self.config.database_connection:
+ self.config.database_connection = "sqlite:///%s?isolation_level=IMMEDIATE" % str( config.database )
+ print 'Using database connection: ', self.config.database_connection
+ # Setup the database engine and ORM
+ self.model = mapping.init( self.config.file_path,
+ self.config.database_connection,
+ engine_options={},
+ create_tables=False )
+ self.security = security.SecurityHelper( id_secret=self.config.id_secret )
+ self.hgweb_config_manager = self.model.hgweb_config_manager
+ self.hgweb_config_manager.hgweb_config_dir = self.config.hgweb_config_dir
+ print 'Using hgweb.config file: ', self.hgweb_config_manager.hgweb_config
+
+ @property
+ def sa_session( self ):
+ """Returns a SQLAlchemy session."""
+ return self.model.context.current
+
+ def shutdown( self ):
+ pass
+
+def create_api_key( app, user ):
+ api_key = app.security.get_new_guid()
+ new_key = app.model.APIKeys()
+ new_key.user_id = user.id
+ new_key.key = api_key
+ app.sa_session.add( new_key )
+ app.sa_session.flush()
+ return api_key
+
+def create_user( app ):
+ user_info_config = os.path.abspath( os.path.join( app.config.root, 'lib/tool_shed/scripts/bootstrap_tool_shed', 'user_info.xml' ) )
+ email = None
+ password = None
+ username = None
+ tree, error_message = xml_util.parse_xml( user_info_config )
+ if tree is None:
+ print "The XML file ", user_info_config, " seems to be invalid, using defaults."
+ email = 'admin(a)test.org'
+ password = 'testuser'
+ username = 'admin'
+ else:
+ root = tree.getroot()
+ for elem in root:
+ if elem.tag == 'email':
+ email = elem.text
+ elif elem.tag == 'password':
+ password = elem.text
+ elif elem.tag == 'username':
+ username = elem.text
+ if email and password and username:
+ invalid_message = validate( email, password, username )
+ if invalid_message:
+ print invalid_message
+ else:
+ user = app.model.User( email=email )
+ user.set_password_cleartext( password )
+ user.username = username
+ app.sa_session.add( user )
+ app.sa_session.flush()
+ app.model.security_agent.create_private_user_role( user )
+ return user
+ else:
+ print "Missing required values for email: ", email, ", password: ", password, ", username: ", username
+ return None
+
+def validate( email, password, username ):
+ message = validate_email( email )
+ if not message:
+ message = validate_password( password )
+ if not message:
+ message = validate_publicname( username )
+ return message
+
+def validate_email( email ):
+ """Validates the email format."""
+ message = ''
+ if not( VALID_EMAIL_RE.match( email ) ):
+ message = "Please enter a real email address."
+ elif len( email ) > 255:
+ message = "Email address exceeds maximum allowable length."
+ return message
+
+def validate_password( password ):
+ if len( password ) < 6:
+ return "Use a password of at least 6 characters"
+ return ''
+
+def validate_publicname( username ):
+ """""Validates the public username."""
+ if len( username ) < 3:
+ return "Public name must be at least 3 characters in length"
+ if len( username ) > 255:
+ return "Public name cannot be more than 255 characters in length"
+ if not( VALID_PUBLICNAME_RE.match( username ) ):
+ return "Public name must contain only lower-case letters, numbers and '-'"
+ return ''
+
+if __name__ == "__main__":
+ parser = OptionParser()
+ ( options, args ) = parser.parse_args()
+ try:
+ ini_file = args[ 0 ]
+ except IndexError:
+ print "Usage: python %s <tool shed .ini file> [options]" % sys.argv[ 0 ]
+ exit( 127 )
+ config_parser = ConfigParser.ConfigParser( { 'here':os.getcwd() } )
+ print "Reading ini file: ", ini_file
+ config_parser.read( ini_file )
+ config_dict = {}
+ for key, value in config_parser.items( "app:main" ):
+ config_dict[ key ] = value
+ config = tool_shed_config.Configuration( **config_dict )
+ app = BootstrapApplication( config )
+ user = create_user( app )
+ if user is not None:
+ api_key = create_api_key( app, user )
+ print "Created new user with public username '", user.username, ". An API key was also created and associated with the user."
+ else:
+ print "Problem creating a new user and an associated API key."
diff -r 9fbe2754793109a1680239131b5507614d431870 -r f61263482700499fd79238b6468c18e6915aaf08 lib/tool_shed/scripts/bootstrap_tool_shed/user_info.xml
--- /dev/null
+++ b/lib/tool_shed/scripts/bootstrap_tool_shed/user_info.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<user>
+ <email>admin(a)test.org</email>
+ <password>testuser</password>
+ <username>admin</username>
+</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