From 9cf21b3469d20eee1c269f02274e83388c4fbbb3 Mon Sep 17 00:00:00 2001 From: Bjoern Gruening Date: Thu, 31 Jul 2014 16:58:30 -0500 Subject: [PATCH 001/120] Copied readme from Bjoern's repo --- README.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000000..a3d7d819b7e --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +Galaxy RStudio Integration +========================== + +This projects integrates [RStudio](http://www.rstudio.com/), a interactive computational environment, with [Galaxy](http://galaxyproject.org). +We hope to make Galaxy more attractive for bioinformaticians and to combine the power of both projects to unlock creativity in data analysis + + +Requirements +============ + +The only requirement is to have [Docker](https://www.docker.com) installed on your system. +For a detailed instruction how to install docker, please look at the [docker website](https://docs.docker.com/installation/). + + +Installation +============ + +Copy the template and config folder in your ``GALAXY_ROOT/config/plugins/visualizations/rstudio`` folder and restart Galaxy. +Alternatively, you can clone the repository with + +```bash +git clone https://github.com/erasche/galaxy-rstudio.git config/plugins/viz/rstudio +```` + +The RStudio visualisation option should be visible next to the usual Charts or Trackster options in your visualisation menue. + + +Authors +======= + + * Björn Grüning + * Eric Rasche + + +History +======= + +- v0.1: Initial public release + + +Licence (MIT) +============= + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From bbc50545072e365664d5176720f3aa9ca9137dc1 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 31 Jul 2014 16:58:49 -0500 Subject: [PATCH 002/120] Added licence/config file --- LICENSE | 21 +++++++++++++++++++++ config/rstudio.xml | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 LICENSE create mode 100644 config/rstudio.xml diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..4687d5857c7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Björn Grüning + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/config/rstudio.xml b/config/rstudio.xml new file mode 100644 index 00000000000..c48d3b1cb44 --- /dev/null +++ b/config/rstudio.xml @@ -0,0 +1,16 @@ + + + + + + HistoryDatasetAssociation + tabular.Tabular + data.Text + dataset_id + + + + dataset_id + + + From 2fb9e013579566679109120561ede41c66e3d100 Mon Sep 17 00:00:00 2001 From: Bjoern Gruening Date: Thu, 31 Jul 2014 16:59:13 -0500 Subject: [PATCH 003/120] Copied from bgruening/galaxy-ipython --- templates/rstudio.mako | 153 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 templates/rstudio.mako diff --git a/templates/rstudio.mako b/templates/rstudio.mako new file mode 100644 index 00000000000..a54da02cb59 --- /dev/null +++ b/templates/rstudio.mako @@ -0,0 +1,153 @@ +<% +import os +import sys +import time +import yaml +import shlex +import random +import shutil +import hashlib +import tempfile +import subprocess +import ConfigParser + +galaxy_root_dir = os.path.abspath(trans.app.config.root) +history_id = trans.security.encode_id( trans.history.id ) +dataset_id = trans.security.encode_id( hda.id ) + +config = ConfigParser.SafeConfigParser({'port': '8080'}) +config.read( os.path.join( galaxy_root_dir, 'universe_wsgi.ini' ) ) + +galaxy_paster_port = config.getint('server:main', 'port') + +# Find out where we are +viz_plugin_dir = config.get('app:main', 'visualization_plugins_directory') +if not os.path.isabs(viz_plugin_dir): + # If it is NOT absolute, i.e. relative, append to galaxy root + viz_plugin_dir = os.path.join(galaxy_root_dir, viz_plugin_dir) +# Get this plugin's directory +viz_plugin_dir = os.path.join(viz_plugin_dir, "ipython") +# Store our template and configuration path +our_config_dir = os.path.join(viz_plugin_dir, "config") +our_template_dir = os.path.join(viz_plugin_dir, "templates") +ipy_viz_config = ConfigParser.SafeConfigParser({'apache_urls': False, 'command': 'docker', 'image': + 'bgruening/docker-ipython-notebook'}) +ipy_viz_config.read( os.path.join( our_config_dir, "ipython.conf" ) ) + +# Ensure generation of notebook id is deterministic for the dataset. Replace with history id +# whenever we figure out how to access that. +random.seed( history_id ) +notebook_id = ''.join(random.choice('0123456789abcdef') for _ in range(64)) + +with open( os.path.join( our_template_dir, 'notebook.ipynb' ), 'r') as nb_handle: + empty_nb = nb_handle.read() +empty_nb = empty_nb % notebook_id + + +# Find all ports that are already occupied +cmd_netstat = shlex.split("netstat -tuln") +p1 = subprocess.Popen(cmd_netstat, stdout=subprocess.PIPE) + +occupied_ports = set() +for line in p1.stdout.read().split('\n'): + if line.startswith('tcp') or line.startswith('tcp6'): + col = line.split() + local_address = col[3] + local_port = local_address.split(':')[-1] + occupied_ports.add( int(local_port) ) + +# Generate random free port number for our docker container +while True: + PORT = random.randrange(10000,15000) + if PORT not in occupied_ports: + break + +HOST = request.host +# Strip out port, we just want the URL this galaxy server was accessed at. +if ':' in HOST: + HOST = HOST[0:HOST.index(':')] + +temp_dir = os.path.abspath( tempfile.mkdtemp() ) + +# Generate a random password + salt +notebook_pw_salt = ''.join(random.choice('0123456789abcdefghijklmnopqrstuvwxyz') for _ in range(12)) +notebook_pw = ''.join(random.choice('0123456789abcdefghijklmnopqrstuvwxyz') for _ in range(24)) +m = hashlib.sha1() +m.update( notebook_pw + notebook_pw_salt ) + +conf_file = { + 'history_id': history_id, + 'galaxy_url': request.application_url.rstrip('/'), + 'api_key': trans.user.api_keys[0].key, + 'remote_host': request.remote_addr, + 'galaxy_paster_port': galaxy_paster_port, + 'docker_port': PORT, + 'notebook_password': 'sha1:%s:%s' % (notebook_pw_salt, m.hexdigest()), +} + +with open( os.path.join( temp_dir, 'conf.yaml' ), 'wb' ) as handle: + handle.write( yaml.dump(conf_file, default_flow_style=False) ) + +empty_nb_path = os.path.join(temp_dir, 'ipython_galaxy_notebook.ipynb') +if hda.datatype.__class__.__name__ != "Ipynb": + with open( empty_nb_path, 'w+' ) as handle: + handle.write( empty_nb ) +else: + shutil.copy( hda.file_name, empty_nb_path ) + +docker_cmd = '%s run -d --sig-proxy=true -p %s:6789 -v "%s:/import/" %s' % \ + (ipy_viz_config.get("docker", "command"), PORT, temp_dir, ipy_viz_config.get("docker", "image")) + +if ipy_viz_config.getboolean("main", "apache_urls"): + notebook_access_url = "http://%s/ipython/%s/notebooks/ipython_galaxy_notebook.ipynb" % ( HOST, PORT ) + notebook_login_url = "http://%s/ipython/%s/login?next=%%2Fipython%%2F%s%%2Fnotebooks%%2Fipython_galaxy_notebook.ipynb" % ( HOST, PORT, PORT ) +else: + notebook_access_url = "http://%s:%s/ipython/%s/notebooks/ipython_galaxy_notebook.ipynb" % ( HOST, PORT, PORT ) + notebook_login_url = "http://%s:%s/ipython/%s/login?next=%%2Fipython%%2F%s%%2Fnotebooks%%2Fipython_galaxy_notebook.ipynb" % ( HOST, PORT, PORT, PORT ) +subprocess.call(docker_cmd, shell=True) + +# We need to wait until the Image and IPython in loaded +# TODO: This can be enhanced later, with some JS spinning if needed. +time.sleep(1) + +%> + + +${h.js( 'libs/jquery/jquery' ) } + + + + + From d3fa742a41c79b9d5900c4209931b237ccadefb4 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 31 Jul 2014 17:10:27 -0500 Subject: [PATCH 004/120] Added empty default Rproject file --- templates/default.Rproj | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 templates/default.Rproj diff --git a/templates/default.Rproj b/templates/default.Rproj new file mode 100644 index 00000000000..109d35996f8 --- /dev/null +++ b/templates/default.Rproj @@ -0,0 +1,15 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RunWeave: Sweave +LaTeX: XeLaTeX + +BuildType: Makefile From e902372eea5c249b5d7b91e381d5aba4ce5320fb Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Mon, 4 Aug 2014 14:15:58 -0500 Subject: [PATCH 005/120] Initial version stuck to port 7777 --- config/rstudio.conf | 6 +++++ templates/rstudio.mako | 60 ++++++++++++------------------------------ 2 files changed, 23 insertions(+), 43 deletions(-) create mode 100644 config/rstudio.conf diff --git a/config/rstudio.conf b/config/rstudio.conf new file mode 100644 index 00000000000..a020b03ae9a --- /dev/null +++ b/config/rstudio.conf @@ -0,0 +1,6 @@ +[main] + +[docker] +command = "docker" +image = "rstudio-notebook" + diff --git a/templates/rstudio.mako b/templates/rstudio.mako index a54da02cb59..55cfd178c33 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -31,7 +31,7 @@ viz_plugin_dir = os.path.join(viz_plugin_dir, "ipython") our_config_dir = os.path.join(viz_plugin_dir, "config") our_template_dir = os.path.join(viz_plugin_dir, "templates") ipy_viz_config = ConfigParser.SafeConfigParser({'apache_urls': False, 'command': 'docker', 'image': - 'bgruening/docker-ipython-notebook'}) + 'erasche/docker-rstudio-notebook'}) ipy_viz_config.read( os.path.join( our_config_dir, "ipython.conf" ) ) # Ensure generation of notebook id is deterministic for the dataset. Replace with history id @@ -67,13 +67,9 @@ HOST = request.host if ':' in HOST: HOST = HOST[0:HOST.index(':')] -temp_dir = os.path.abspath( tempfile.mkdtemp() ) +PORT=7777 -# Generate a random password + salt -notebook_pw_salt = ''.join(random.choice('0123456789abcdefghijklmnopqrstuvwxyz') for _ in range(12)) -notebook_pw = ''.join(random.choice('0123456789abcdefghijklmnopqrstuvwxyz') for _ in range(24)) -m = hashlib.sha1() -m.update( notebook_pw + notebook_pw_salt ) +temp_dir = os.path.abspath( tempfile.mkdtemp() ) conf_file = { 'history_id': history_id, @@ -82,7 +78,6 @@ conf_file = { 'remote_host': request.remote_addr, 'galaxy_paster_port': galaxy_paster_port, 'docker_port': PORT, - 'notebook_password': 'sha1:%s:%s' % (notebook_pw_salt, m.hexdigest()), } with open( os.path.join( temp_dir, 'conf.yaml' ), 'wb' ) as handle: @@ -95,15 +90,17 @@ if hda.datatype.__class__.__name__ != "Ipynb": else: shutil.copy( hda.file_name, empty_nb_path ) -docker_cmd = '%s run -d --sig-proxy=true -p %s:6789 -v "%s:/import/" %s' % \ +docker_cmd = '%s run -d --sig-proxy=true -p %s:8787 -v "%s:/import/" %s' % \ (ipy_viz_config.get("docker", "command"), PORT, temp_dir, ipy_viz_config.get("docker", "image")) if ipy_viz_config.getboolean("main", "apache_urls"): - notebook_access_url = "http://%s/ipython/%s/notebooks/ipython_galaxy_notebook.ipynb" % ( HOST, PORT ) - notebook_login_url = "http://%s/ipython/%s/login?next=%%2Fipython%%2F%s%%2Fnotebooks%%2Fipython_galaxy_notebook.ipynb" % ( HOST, PORT, PORT ) -else: - notebook_access_url = "http://%s:%s/ipython/%s/notebooks/ipython_galaxy_notebook.ipynb" % ( HOST, PORT, PORT ) - notebook_login_url = "http://%s:%s/ipython/%s/login?next=%%2Fipython%%2F%s%%2Fnotebooks%%2Fipython_galaxy_notebook.ipynb" % ( HOST, PORT, PORT, PORT ) + notebook_access_url = "http://%s/rstudio/%s/" % ( HOST, PORT ) + notebook_login_url = "http://%s/rstudio/%s/" % ( HOST, PORT ) + apache_urls_jsvar = "true" +#else: + #notebook_access_url = "http://%s:%s/rstudio/%s/notebooks/rstudio_galaxy_notebook.ipynb" % ( HOST, PORT, PORT ) + #notebook_login_url = "http://%s:%s/rstudio/%s/login?next=%%2Frstudio%%2F%s%%2Fnotebooks%%2Frstudio_galaxy_notebook.ipynb" % ( HOST, PORT, PORT, PORT ) + #apache_urls_jsvar = "false" subprocess.call(docker_cmd, shell=True) # We need to wait until the Image and IPython in loaded @@ -113,40 +110,17 @@ time.sleep(1) %> +${h.css( 'base' ) } ${h.js( 'libs/jquery/jquery' ) } +${h.js( 'libs/toastr' ) } + From 1cf5ac9df755a91c905e26998438eb413f868c1e Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Fri, 8 Aug 2014 14:33:37 -0500 Subject: [PATCH 006/120] More progress Autologin may not be possible but we'll certainly try for it. This has the container come up and copies every dataset into the R container. No magic R/Galaxy sugar yet. --- config/rstudio.conf | 1 + templates/default.Rproj | 15 ------ templates/rstudio.mako | 116 +++++++++++++++++++++++----------------- 3 files changed, 67 insertions(+), 65 deletions(-) delete mode 100644 templates/default.Rproj diff --git a/config/rstudio.conf b/config/rstudio.conf index a020b03ae9a..f0ebd488761 100644 --- a/config/rstudio.conf +++ b/config/rstudio.conf @@ -1,4 +1,5 @@ [main] +apache_urls = False [docker] command = "docker" diff --git a/templates/default.Rproj b/templates/default.Rproj deleted file mode 100644 index 109d35996f8..00000000000 --- a/templates/default.Rproj +++ /dev/null @@ -1,15 +0,0 @@ -Version: 1.0 - -RestoreWorkspace: Default -SaveWorkspace: Default -AlwaysSaveHistory: Default - -EnableCodeIndexing: Yes -UseSpacesForTab: Yes -NumSpacesForTab: 2 -Encoding: UTF-8 - -RunWeave: Sweave -LaTeX: XeLaTeX - -BuildType: Makefile diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 55cfd178c33..db9c8cea0f1 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -6,11 +6,50 @@ import yaml import shlex import random import shutil -import hashlib +import crypt import tempfile import subprocess import ConfigParser + +def gen_hex_str(length=12): + return ''.join(random.choice('0123456789abcdef') for _ in range(length)) + +def generate_password(length=12): + return ''.join(random.choice('0123456789qwertzuiopasdfghjklyxcvbnm') for _ in range(length)) + +def generate_sha512(salt, password): + return crypt.crypt(password, '$6$%s' % salt) + +def find_occupied_ports(): + # Find all ports that are already occupied + cmd_netstat = shlex.split("netstat -tuln") + p1 = subprocess.Popen(cmd_netstat, stdout=subprocess.PIPE) + + occupied_ports = set() + for line in p1.stdout.read().split('\n'): + if line.startswith('tcp') or line.startswith('tcp6'): + col = line.split() + local_address = col[3] + local_port = local_address.split(':')[-1] + occupied_ports.add( int(local_port) ) + return occupied_ports + +def find_free_port(): + # Generate random free port number for our docker container + while True: + PORT = random.randrange(10000,15000) + if PORT not in find_occupied_ports(): + break + return PORT + +def get_host(): + HOST = request.host + # Strip out port, we just want the URL this galaxy server was accessed at. + if ':' in HOST: + HOST = HOST[0:HOST.index(':')] + return HOST + galaxy_root_dir = os.path.abspath(trans.app.config.root) history_id = trans.security.encode_id( trans.history.id ) dataset_id = trans.security.encode_id( hda.id ) @@ -26,80 +65,57 @@ if not os.path.isabs(viz_plugin_dir): # If it is NOT absolute, i.e. relative, append to galaxy root viz_plugin_dir = os.path.join(galaxy_root_dir, viz_plugin_dir) # Get this plugin's directory -viz_plugin_dir = os.path.join(viz_plugin_dir, "ipython") +viz_plugin_dir = os.path.join(viz_plugin_dir, "rstudio") # Store our template and configuration path our_config_dir = os.path.join(viz_plugin_dir, "config") our_template_dir = os.path.join(viz_plugin_dir, "templates") ipy_viz_config = ConfigParser.SafeConfigParser({'apache_urls': False, 'command': 'docker', 'image': 'erasche/docker-rstudio-notebook'}) -ipy_viz_config.read( os.path.join( our_config_dir, "ipython.conf" ) ) - -# Ensure generation of notebook id is deterministic for the dataset. Replace with history id -# whenever we figure out how to access that. -random.seed( history_id ) -notebook_id = ''.join(random.choice('0123456789abcdef') for _ in range(64)) - -with open( os.path.join( our_template_dir, 'notebook.ipynb' ), 'r') as nb_handle: - empty_nb = nb_handle.read() -empty_nb = empty_nb % notebook_id - - -# Find all ports that are already occupied -cmd_netstat = shlex.split("netstat -tuln") -p1 = subprocess.Popen(cmd_netstat, stdout=subprocess.PIPE) - -occupied_ports = set() -for line in p1.stdout.read().split('\n'): - if line.startswith('tcp') or line.startswith('tcp6'): - col = line.split() - local_address = col[3] - local_port = local_address.split(':')[-1] - occupied_ports.add( int(local_port) ) - -# Generate random free port number for our docker container -while True: - PORT = random.randrange(10000,15000) - if PORT not in occupied_ports: - break - -HOST = request.host -# Strip out port, we just want the URL this galaxy server was accessed at. -if ':' in HOST: - HOST = HOST[0:HOST.index(':')] +ipy_viz_config.read( os.path.join( our_config_dir, "rstudio.conf" ) ) +PORT = find_free_port() PORT=7777 +HOST = get_host() + +PASSWORD = generate_password(24) +PASSWORD = "password" +salt = generate_password(12) + temp_dir = os.path.abspath( tempfile.mkdtemp() ) +# Copy a single dataset in +for dataset in trans.history.active_datasets: + shutil.copy( dataset.file_name, os.path.join( temp_dir, str( dataset.hid ) ) ) + conf_file = { 'history_id': history_id, - 'galaxy_url': request.application_url.rstrip('/'), - 'api_key': trans.user.api_keys[0].key, - 'remote_host': request.remote_addr, - 'galaxy_paster_port': galaxy_paster_port, + #'galaxy_url': request.application_url.rstrip('/'), + #'api_key': trans.user.api_keys[0].key, + #'remote_host': request.remote_addr, + #'galaxy_paster_port': galaxy_paster_port, 'docker_port': PORT, + 'use_auth': True, + 'notebook_username': 'galaxy', + 'notebook_password': generate_sha512(salt, PASSWORD) } + with open( os.path.join( temp_dir, 'conf.yaml' ), 'wb' ) as handle: handle.write( yaml.dump(conf_file, default_flow_style=False) ) -empty_nb_path = os.path.join(temp_dir, 'ipython_galaxy_notebook.ipynb') -if hda.datatype.__class__.__name__ != "Ipynb": - with open( empty_nb_path, 'w+' ) as handle: - handle.write( empty_nb ) -else: - shutil.copy( hda.file_name, empty_nb_path ) docker_cmd = '%s run -d --sig-proxy=true -p %s:8787 -v "%s:/import/" %s' % \ (ipy_viz_config.get("docker", "command"), PORT, temp_dir, ipy_viz_config.get("docker", "image")) +print docker_cmd if ipy_viz_config.getboolean("main", "apache_urls"): notebook_access_url = "http://%s/rstudio/%s/" % ( HOST, PORT ) notebook_login_url = "http://%s/rstudio/%s/" % ( HOST, PORT ) apache_urls_jsvar = "true" -#else: - #notebook_access_url = "http://%s:%s/rstudio/%s/notebooks/rstudio_galaxy_notebook.ipynb" % ( HOST, PORT, PORT ) - #notebook_login_url = "http://%s:%s/rstudio/%s/login?next=%%2Frstudio%%2F%s%%2Fnotebooks%%2Frstudio_galaxy_notebook.ipynb" % ( HOST, PORT, PORT, PORT ) +else: + notebook_access_url = "http://%s:%s/" % ( HOST, PORT ) + notebook_login_url = "http://%s:%s/auth-sign-in" % ( HOST, PORT ) #apache_urls_jsvar = "false" subprocess.call(docker_cmd, shell=True) @@ -115,7 +131,7 @@ ${h.js( 'libs/jquery/jquery' ) } ${h.js( 'libs/toastr' ) } - +Password: ${ PASSWORD } +// +// +// +// Password: ${ PASSWORD } From 3d9c8a043ccc883978e6979fce95586804553372 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Wed, 24 Sep 2014 14:35:58 -0500 Subject: [PATCH 010/120] Moved to IE framework --- static/js/ie.js | 52 ++++++++++ static/js/rstudio.js | 82 ++++++++++++++++ templates/ie.mako | 214 +++++++++++++++++++++++++++++++++++++++++ templates/rstudio.mako | 180 ++++++---------------------------- 4 files changed, 379 insertions(+), 149 deletions(-) create mode 100644 static/js/ie.js create mode 100644 static/js/rstudio.js create mode 100644 templates/ie.mako diff --git a/static/js/ie.js b/static/js/ie.js new file mode 100644 index 00000000000..651f71fe83a --- /dev/null +++ b/static/js/ie.js @@ -0,0 +1,52 @@ +/** + * Internal function to remove content from the main area and add the notebook. + * Not idempotent + */ +function append_notebook(url){ + clear_main_area(); + $('#main').append('' + ); +} + +function clear_main_area(){ + $('#spinner').remove(); + $('#main').children().remove(); +} + +function display_spinner(){ + $('#main').append(''); +} + + +/** + * Test availability of a URL, and call a callback when done. + * http://stackoverflow.com/q/25390206/347368 + * @param {String} url: URL to test availability of. Must return a 200 (302->200 is OK). + * @param {String} callback: function to call once successfully connected. + * + */ +function test_ie_availability(url, success_callback){ + var request_count = 0; + display_spinner(); + interval = setInterval(function(){ + $.ajax({ + type: "GET", + success: function(){ + clearInterval(interval); + success_callback(); + }, + error: function(){ + request_count++; + if(request_count > 30){ + clearInterval(interval); + clear_main_area(); + toastr.error( + "Could not connect to IE, contact your administrator", + "Error", + {'closeButton': true, 'timeOut': 20000, 'tapToDismiss': false} + ); + } + } + }); + }, 1000); +} diff --git a/static/js/rstudio.js b/static/js/rstudio.js new file mode 100644 index 00000000000..acfddb5fb9b --- /dev/null +++ b/static/js/rstudio.js @@ -0,0 +1,82 @@ +function message_failed_auth(password){ + toastr.info( + "Automatic authorization failed. You can manually login with:
" + password + "
More details ...", + "Please login manually", + {'closeButton': true, 'timeOut': 100000, 'tapToDismiss': false} + ); +} + +function message_failed_connection(){ + toastr.error( + "Could not connect to IPython Notebook. Please contact your administrator. More details ...", + "Security warning", + {'closeButton': true, 'timeOut': 20000, 'tapToDismiss': true} + ); +} + +function message_no_auth(){ + toastr.warning( + "IPython Notebook was lunched without authentication. This is a security issue. More details ...", + "Security warning", + {'closeButton': true, 'timeOut': 20000, 'tapToDismiss': false} + ); +} + + +/** + * Load an interactive environment (IE) from a remote URL + * @param {String} password: password used to authenticate to the remote resource + * @param {String} notebook_login_url: URL that should be POSTed to for login + * @param {String} notebook_access_url: the URL embeded in the page and loaded + * + */ +function load_notebook(password, notebook_login_url, notebook_access_url){ + $( document ).ready(function() { + // Test notebook_login_url for accessibility, executing the login+load function whenever + // we've successfully connected to the IE. + test_ie_availability(notebook_login_url, function(){ + _handle_notebook_loading(password, notebook_login_url, notebook_access_url); + }); + }); +} + +/** + * Must be implemented by IEs + */ +function _handle_notebook_loading(password, notebook_login_url, notebook_access_url){ + if ( ie_password_auth ) { + // Make an AJAX POST + $.ajax({ + type: "POST", + // to the Login URL + url: notebook_login_url, + // With our password + data: { + 'password': password + }, + xhrFields: { + withCredentials: true + }, + // If that is successful, load the notebook + success: function(){ + append_notebook(notebook_access_url); + }, + error: function(jqxhr, status, error){ + if(ie_password_auth && !ie_apache_urls){ + // Failure happens due to CORS + message_failed_auth(password); + append_notebook(notebook_access_url); + }else{ + message_failed_connection(); + // Do we want to try and load the notebook anyway? Just in case? + append_notebook(notebook_access_url); + } + } + }); + } + else { + // Not using password auth, just embed it to avoid content-origin issues. + message_no_auth(); + append_notebook(notebook_access_url); + } +} diff --git a/templates/ie.mako b/templates/ie.mako new file mode 100644 index 00000000000..841758cdfdb --- /dev/null +++ b/templates/ie.mako @@ -0,0 +1,214 @@ +<%! +import os +import yaml +import shlex +import random +import shutil +import hashlib +import subprocess +import ConfigParser + +%> + +<%def name="set_id(name)"> +<% + """ + IEs must register their name, so it can be used in constructing strings + + Additionally this method stores lots of config options we want to access elsewhere. + """ + self.attr.viz_id = name + self.attr.history_id = trans.security.encode_id( trans.history.id ) + self.attr.galaxy_config = trans.app.config + self.attr.galaxy_root_dir = os.path.abspath(self.attr.galaxy_config.root) + self.attr.root = h.url_for("/") + self.attr.app_root = self.attr.root + "plugins/visualizations/ipython/static/" + + # Store our template and configuration path + self.attr.our_config_dir = os.path.join(plugin_path, "config") + self.attr.our_template_dir = os.path.join(plugin_path, "templates") + self.attr.viz_config = ConfigParser.SafeConfigParser(default_dict) + self.attr.viz_config.read( os.path.join( self.attr.our_config_dir, "ipython.conf" ) ) + # Store some variables we want by default + self.attr.PASSWORD_AUTH = self.attr.viz_config.getboolean("main", "password_auth") + self.attr.APACHE_URLS = self.attr.viz_config.getboolean("main", "apache_urls") + self.attr.SSL_URLS = self.attr.viz_config.getboolean("main", "ssl") + self.attr.PORT = self.proxy_request_port() + + self.attr.HOST = request.host.rsplit(':', 1)[0] +%> + + +<%def name="write_conf_file(output_directory)"> +<% + """ + Build up a configuration file that is standard for ALL IEs. + + TODO: replace hashed password with plaintext. + """ + conf_file = { + 'history_id': self.attr.history_id, + 'galaxy_url': request.application_url.rstrip('/') + '/', + 'api_key': get_api_key(), + 'remote_host': request.remote_addr, + 'galaxy_paster_port': self.get_galaxy_paster_port(self.attr.galaxy_root_dir, + self.attr.galaxy_config), + 'docker_port': self.attr.PORT, + 'cors_origin': request.host_url, + } + + if self.attr.PASSWORD_AUTH: + # Generate a random password + salt + notebook_pw_salt = self.generate_password(length=12) + notebook_pw = self.generate_password(length=24) + m = hashlib.sha1() + m.update( notebook_pw + notebook_pw_salt ) + conf_file['notebook_password'] = 'sha1:%s:%s' % (notebook_pw_salt, m.hexdigest()) + # Should we use password based connection or "default" connection style in galaxy + else: + notebook_pw = "None" + + self.attr.notebook_pw = notebook_pw + # Write conf + with open( os.path.join( output_directory, 'conf.yaml' ), 'wb' ) as handle: + handle.write( yaml.dump(conf_file, default_flow_style=False) ) + +%> + + +<%def name="get_galaxy_paster_port(galaxy_root_dir, galaxy_config)"> + <% + """ + Get port galaxy is running on (if running under paster) + """ + config = ConfigParser.SafeConfigParser({'port': '8080'}) + config.read( os.path.join( galaxy_root_dir, 'universe_wsgi.ini' ) ) + + # uWSGI galaxy installations don't use paster and only speak uWSGI not http + try: + port = config.getint('server:%s' % galaxy_config.server_name, 'port') + except: + port = None + return port + %> + + +<%def name="proxy_request_port()"> +<% + """ + Refactor of our port getting...eventually this will be replaced with an API call instead. + """ + # Find all ports that are already occupied + cmd_netstat = shlex.split("netstat -tuln") + p1 = subprocess.Popen(cmd_netstat, stdout=subprocess.PIPE) + + occupied_ports = set() + for line in p1.stdout.read().split('\n'): + if line.startswith('tcp') or line.startswith('tcp6'): + col = line.split() + local_address = col[3] + local_port = local_address.split(':')[-1] + occupied_ports.add( int(local_port) ) + + # Generate random free port number for our docker container + while True: + port = random.randrange(10000,15000) + if port not in occupied_ports: + break + return port +%> + + +<%def name="generate_hex(length)"> +<% + """ + Generate a hex string + """ + return ''.join(random.choice('0123456789abcdef') for _ in range(length)) +%> + + +<%def name="generate_password(length)"> +<% + """ + Generate a random alphanumeric password + """ + return ''.join(random.choice('0123456789abcdefghijklmnopqrstuvwxyz') for _ in range(length)) +%> + + +<%def name="javascript_boolean(python_boolean)"> +<% + """ + Convenience function to convert boolean for use in JS + """ + if python_boolean: + return "true"; + else: + return "false" +%> + + + +<%def name="url_template(url_template)"> +<% + """ + Process a URL template + + There are several variables accessible to the user: + + - ${PROTO} will be replaced with protocol (http/https) + - ${HOST} will be replaced with the correct hostname + - ${PORT} will be replaced with the port the docker image is attached to + + In the case that `apache_urls = False`, the first instance of HOST has a PORT appeneded to + it, so the user doesn't have to template 2x urls. + """ + # Figure out our substitutions + if self.attr.SSL_URLS: + protocol = 'https' + else: + protocol = 'http' + + if not self.attr.APACHE_URLS: + # If they are not using apache URLs, that implies there's a port attached to the host + # string, thus we replace just the first instance of host that we see. + url_template = url_template.replace('${HOST}', '${HOST}:${PORT}', 1) + + url = url_template.replace('${PROTO}', protocol) \ + .replace('${HOST}', self.attr.HOST) \ + .replace('${PORT}', str(self.attr.PORT)) + return url +%> + + + +<%def name="docker_cmd(temp_dir)"> +<% + """ + Generate and return the docker command to execute + """ + return '%s run -d --sig-proxy=true -p %s:6789 -v "%s:/import/" %s' % \ + (self.attr.viz_config.get("docker", "command"), self.attr.PORT, temp_dir, + self.attr.viz_config.get("docker", "image")) +%> + + + +<%def name="default_javascript_variables()"> +// Globals +ie_password_auth = ${ self.javascript_boolean(self.attr.PASSWORD_AUTH) }; +ie_apache_urls = ${ self.javascript_boolean(self.attr.APACHE_URLS) }; +ie_password = '${ self.attr.notebook_pw }'; +// Do these need to be global as well?? +var galaxy_root = '${ self.attr.root }'; +var app_root = '${ self.attr.app_root }'; + + + +<%def name="load_default_js()"> +${h.css( 'base' ) } +${h.js( 'libs/jquery/jquery', + 'libs/toastr', + 'libs/require')} + diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 476e86d386b..4fd53e84651 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -1,127 +1,25 @@ +<%namespace file="ie.mako" name="ie"/> <% import os -import sys -import time -import yaml -import shlex -import random import shutil -import crypt import tempfile import subprocess -import ConfigParser - - -def gen_hex_str(length=12): - return ''.join(random.choice('0123456789abcdef') for _ in range(length)) - -def generate_password(length=12): - return ''.join(random.choice('0123456789qwertzuiopasdfghjklyxcvbnm') for _ in range(length)) - -def generate_sha512(salt, password): - return crypt.crypt(password, '$6$%s' % salt) - -def find_occupied_ports(): - # Find all ports that are already occupied - cmd_netstat = shlex.split("netstat -tuln") - p1 = subprocess.Popen(cmd_netstat, stdout=subprocess.PIPE) - - occupied_ports = set() - for line in p1.stdout.read().split('\n'): - if line.startswith('tcp') or line.startswith('tcp6'): - col = line.split() - local_address = col[3] - local_port = local_address.split(':')[-1] - occupied_ports.add( int(local_port) ) - return occupied_ports - -def find_free_port(): - # Generate random free port number for our docker container - while True: - PORT = random.randrange(10000,15000) - if PORT not in find_occupied_ports(): - break - return PORT - -def get_host(): - HOST = request.host - # Strip out port, we just want the URL this galaxy server was accessed at. - if ':' in HOST: - HOST = HOST[0:HOST.index(':')] - return HOST - -galaxy_root_dir = os.path.abspath(trans.app.config.root) -history_id = trans.security.encode_id( trans.history.id ) -dataset_id = trans.security.encode_id( hda.id ) - -config = ConfigParser.SafeConfigParser({'port': '8080'}) -config.read( os.path.join( galaxy_root_dir, 'universe_wsgi.ini' ) ) - -galaxy_paster_port = config.getint('server:main', 'port') - -# Find out where we are -viz_plugin_dir = config.get('app:main', 'visualization_plugins_directory') -if not os.path.isabs(viz_plugin_dir): - # If it is NOT absolute, i.e. relative, append to galaxy root - viz_plugin_dir = os.path.join(galaxy_root_dir, viz_plugin_dir) -# Get this plugin's directory -viz_plugin_dir = os.path.join(viz_plugin_dir, "rstudio") -# Store our template and configuration path -our_config_dir = os.path.join(viz_plugin_dir, "config") -our_template_dir = os.path.join(viz_plugin_dir, "templates") -ipy_viz_config = ConfigParser.SafeConfigParser({'apache_urls': False, 'command': 'docker', 'image': - 'rstudio-notebook'}) -ipy_viz_config.read( os.path.join( our_config_dir, "rstudio.conf" ) ) - -PORT = find_free_port() -PORT=7777 -HOST = get_host() - -PASSWORD = generate_password(24) -PASSWORD = "password" -USERNAME = "galaxy" -salt = generate_password(12) - +# Sets ID and sets up a lot of other variables +ie.set_id("ipython") +# Create tempdir in galaxy temp_dir = os.path.abspath( tempfile.mkdtemp() ) +# Write out conf file...needs work +ie.write_conf_file(temp_dir) -# Copy a single dataset in -for dataset in trans.history.active_datasets: - shutil.copy( dataset.file_name, os.path.join( temp_dir, str( dataset.hid ) ) ) +## General IE specific +# Access URLs for the notebook from within galaxy. +notebook_access_url = ie.url_template('${PROTO}://${HOST}:${PORT}/rstudio/') +notebook_login_url = ie.url_template('${PROTO}://${HOST}:${PORT}/auth-sign-in') -conf_file = { - 'history_id': history_id, - #'galaxy_url': request.application_url.rstrip('/'), - #'api_key': trans.user.api_keys[0].key, - #'remote_host': request.remote_addr, - #'galaxy_paster_port': galaxy_paster_port, - 'docker_port': PORT, - 'use_auth': True, - 'notebook_username': USERNAME, - 'notebook_password': generate_sha512(salt, PASSWORD) -} - - -with open( os.path.join( temp_dir, 'conf.yaml' ), 'wb' ) as handle: - handle.write( yaml.dump(conf_file, default_flow_style=False) ) - - -docker_cmd = '%s run -d --sig-proxy=true -p %s:8787 -v "%s:/import/" %s' % \ - (ipy_viz_config.get("docker", "command"), PORT, temp_dir, ipy_viz_config.get("docker", "image")) -print docker_cmd - -if ipy_viz_config.getboolean("main", "apache_urls"): - notebook_access_url = "http://%s/rstudio/%s/" % ( HOST, PORT ) - notebook_login_url = "http://%s/rstudio/%s/" % ( HOST, PORT ) - apache_urls_jsvar = "true" -else: - notebook_access_url = "http://%s:%s/" % ( HOST, PORT ) - notebook_login_url = "http://%s:%s/auth-sign-in" % ( HOST, PORT ) - #apache_urls_jsvar = "false" +docker_cmd = ie.docker_cmd(temp_dir) subprocess.call(docker_cmd, shell=True) -# We need to wait until the Image and IPython in loaded -# TODO: This can be enhanced later, with some JS spinning if needed. time.sleep(5) try: @@ -133,27 +31,24 @@ except: e = 0 pass + %> -${h.css( 'base' ) } -${h.js( 'libs/jquery/jquery' ) } -${h.js( 'libs/toastr' ) } +${ ie.load_default_js() } + + + + // // // // - - -Password: ${ PASSWORD } - +
+
From 30a9022c2265ce1ab3263fb74925781c391f64c9 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Wed, 24 Sep 2014 14:48:38 -0500 Subject: [PATCH 011/120] More progress towards new framework --- config/rstudio.conf | 4 + static/js/crypto/base64.js | 71 +++++ static/js/crypto/jsbn.js | 559 +++++++++++++++++++++++++++++++++++++ static/js/crypto/prng4.js | 45 +++ static/js/crypto/rng.js | 75 +++++ static/js/crypto/rsa.js | 112 ++++++++ templates/ie.mako | 4 +- templates/rstudio.mako | 19 +- 8 files changed, 879 insertions(+), 10 deletions(-) create mode 100644 static/js/crypto/base64.js create mode 100644 static/js/crypto/jsbn.js create mode 100644 static/js/crypto/prng4.js create mode 100644 static/js/crypto/rng.js create mode 100644 static/js/crypto/rsa.js diff --git a/config/rstudio.conf b/config/rstudio.conf index 0b0e97d10cb..d13231a69a3 100644 --- a/config/rstudio.conf +++ b/config/rstudio.conf @@ -1,5 +1,9 @@ [main] +# This cannot be changed +password_auth = True +# Other apache_urls = False +ssl = False [docker] command = docker diff --git a/static/js/crypto/base64.js b/static/js/crypto/base64.js new file mode 100644 index 00000000000..ad53bb8ed06 --- /dev/null +++ b/static/js/crypto/base64.js @@ -0,0 +1,71 @@ +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64padchar="="; + +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64padchar; + return ret; +} + +// convert a base64 string to hex +function b64tohex(s) { + var ret = "" + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64padchar) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} + +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} diff --git a/static/js/crypto/jsbn.js b/static/js/crypto/jsbn.js new file mode 100644 index 00000000000..4ed7c8362da --- /dev/null +++ b/static/js/crypto/jsbn.js @@ -0,0 +1,559 @@ +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); diff --git a/static/js/crypto/prng4.js b/static/js/crypto/prng4.js new file mode 100644 index 00000000000..3034f3f1158 --- /dev/null +++ b/static/js/crypto/prng4.js @@ -0,0 +1,45 @@ +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; diff --git a/static/js/crypto/rng.js b/static/js/crypto/rng.js new file mode 100644 index 00000000000..9db13825fb6 --- /dev/null +++ b/static/js/crypto/rng.js @@ -0,0 +1,75 @@ +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(window.crypto && window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for(t = 0; t < 32; ++t) + rng_pool[rng_pptr++] = ua[t]; + } + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; diff --git a/static/js/crypto/rsa.js b/static/js/crypto/rsa.js new file mode 100644 index 00000000000..9f8664037c4 --- /dev/null +++ b/static/js/crypto/rsa.js @@ -0,0 +1,112 @@ +// Depends on jsbn.js and rng.js + +// Version 1.1: support utf-8 encoding in pkcs1pad2 + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function linebrk(s,n) { + var ret = ""; + var i = 0; + while(i + n < s.length) { + ret += s.substring(i,i+n) + "\n"; + i += n; + } + return ret + s.substring(i,s.length); +} + +function byte2Hex(b) { + if(b < 0x10) + return "0" + b.toString(16); + else + return b.toString(16); +} + +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s,n) { + if(n < s.length + 11) { // TODO: fix for utf-8 + alert("Message too long for RSA"); + return null; + } + var ba = new Array(); + var i = s.length - 1; + while(i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if(c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = new Array(); + while(n > 2) { // random non-zero pad + x[0] = 0; + while(x[0] == 0) rng.nextBytes(x); + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} + +// "empty" RSA key constructor +function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; +} + +// Set the public key fields N and e from hex strings +function RSASetPublic(N,E) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + } + else + alert("Invalid RSA public key"); +} + +// Perform raw public operation on "x": return x^e (mod n) +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} + +// Return the PKCS#1 RSA encryption of "text" as an even-length hex string +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + if(m == null) return null; + var c = this.doPublic(m); + if(c == null) return null; + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} + +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +//function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +//} + +// protected +RSAKey.prototype.doPublic = RSADoPublic; + +// public +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; diff --git a/templates/ie.mako b/templates/ie.mako index 841758cdfdb..9045de1b2e3 100644 --- a/templates/ie.mako +++ b/templates/ie.mako @@ -22,13 +22,13 @@ import ConfigParser self.attr.galaxy_config = trans.app.config self.attr.galaxy_root_dir = os.path.abspath(self.attr.galaxy_config.root) self.attr.root = h.url_for("/") - self.attr.app_root = self.attr.root + "plugins/visualizations/ipython/static/" + self.attr.app_root = self.attr.root + "plugins/visualizations/rstudio/static/" # Store our template and configuration path self.attr.our_config_dir = os.path.join(plugin_path, "config") self.attr.our_template_dir = os.path.join(plugin_path, "templates") self.attr.viz_config = ConfigParser.SafeConfigParser(default_dict) - self.attr.viz_config.read( os.path.join( self.attr.our_config_dir, "ipython.conf" ) ) + self.attr.viz_config.read( os.path.join( self.attr.our_config_dir, self.attr.viz_id + ".conf" ) ) # Store some variables we want by default self.attr.PASSWORD_AUTH = self.attr.viz_config.getboolean("main", "password_auth") self.attr.APACHE_URLS = self.attr.viz_config.getboolean("main", "apache_urls") diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 4fd53e84651..db253f92115 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -3,19 +3,21 @@ import os import shutil import tempfile +import time import subprocess # Sets ID and sets up a lot of other variables -ie.set_id("ipython") +ie.set_id("rstudio") # Create tempdir in galaxy temp_dir = os.path.abspath( tempfile.mkdtemp() ) # Write out conf file...needs work ie.write_conf_file(temp_dir) +USERNAME = "galaxy" ## General IE specific # Access URLs for the notebook from within galaxy. -notebook_access_url = ie.url_template('${PROTO}://${HOST}:${PORT}/rstudio/') -notebook_login_url = ie.url_template('${PROTO}://${HOST}:${PORT}/auth-sign-in') +notebook_access_url = ie.url_template('${PROTO}://${HOST}/rstudio/') +notebook_login_url = ie.url_template('${PROTO}://${HOST}/auth-sign-in') docker_cmd = ie.docker_cmd(temp_dir) subprocess.call(docker_cmd, shell=True) @@ -43,17 +45,18 @@ ${ ie.load_default_js() } ${ ie.default_javascript_variables() } var notebook_login_url = '${ notebook_login_url }'; var notebook_access_url = '${ notebook_access_url }'; +var notebook_username = '${ USERNAME }'; // Load notebook // // // // // -//var payload = "${ USERNAME }" + "\n" + "${ PASSWORD }"; -//var rsa = new RSAKey(); -//rsa.setPublic("${ n }", "${ e }"); -//var res = rsa.encrypt(payload); -//var v = hex2b64(res); +var payload = "${ USERNAME }" + "\n" + ie_password; +var rsa = new RSAKey(); +rsa.setPublic("${ n }", "${ e }"); +var res = rsa.encrypt(payload); +var v = hex2b64(res); // require.config({ From a0a39b43504981f586d3e6bf8af75adc34f41f5d Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Wed, 24 Sep 2014 16:30:50 -0500 Subject: [PATCH 012/120] Mostly working, CORS issues --- static/js/rstudio.js | 9 ++++++--- templates/ie.mako | 19 +++++++++---------- templates/rstudio.mako | 36 ++++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/static/js/rstudio.js b/static/js/rstudio.js index acfddb5fb9b..b7b709339ff 100644 --- a/static/js/rstudio.js +++ b/static/js/rstudio.js @@ -52,7 +52,9 @@ function _handle_notebook_loading(password, notebook_login_url, notebook_access_ url: notebook_login_url, // With our password data: { - 'password': password + 'package': password, + 'persist': 1, + 'clientPath': window.location.pathname, }, xhrFields: { withCredentials: true @@ -63,8 +65,9 @@ function _handle_notebook_loading(password, notebook_login_url, notebook_access_ }, error: function(jqxhr, status, error){ if(ie_password_auth && !ie_apache_urls){ - // Failure happens due to CORS - message_failed_auth(password); + // Failure happens due to CORS, can't use `password` because that's actually + // encrypted for rstudio + message_failed_auth(ie_password); append_notebook(notebook_access_url); }else{ message_failed_connection(); diff --git a/templates/ie.mako b/templates/ie.mako index 9045de1b2e3..7fc02d7ffb3 100644 --- a/templates/ie.mako +++ b/templates/ie.mako @@ -39,7 +39,7 @@ import ConfigParser %> -<%def name="write_conf_file(output_directory)"> +<%def name="write_conf_file(output_directory, extra={})"> <% """ Build up a configuration file that is standard for ALL IEs. @@ -58,16 +58,16 @@ import ConfigParser } if self.attr.PASSWORD_AUTH: - # Generate a random password + salt - notebook_pw_salt = self.generate_password(length=12) notebook_pw = self.generate_password(length=24) - m = hashlib.sha1() - m.update( notebook_pw + notebook_pw_salt ) - conf_file['notebook_password'] = 'sha1:%s:%s' % (notebook_pw_salt, m.hexdigest()) + conf_file['notebook_password'] = notebook_pw # Should we use password based connection or "default" connection style in galaxy else: notebook_pw = "None" + # Some will need to pass extra data + for extra_key in extra: + conf_file[extra_key] = extra[extra_key] + self.attr.notebook_pw = notebook_pw # Write conf with open( os.path.join( output_directory, 'conf.yaml' ), 'wb' ) as handle: @@ -188,9 +188,9 @@ import ConfigParser """ Generate and return the docker command to execute """ - return '%s run -d --sig-proxy=true -p %s:6789 -v "%s:/import/" %s' % \ - (self.attr.viz_config.get("docker", "command"), self.attr.PORT, temp_dir, - self.attr.viz_config.get("docker", "image")) + return '%s run -d --sig-proxy=true -p %s:%s -v "%s:/import/" %s' % \ + (self.attr.viz_config.get("docker", "command"), self.attr.PORT, self.attr.docker_port, + temp_dir, self.attr.viz_config.get("docker", "image")) %> @@ -200,7 +200,6 @@ import ConfigParser ie_password_auth = ${ self.javascript_boolean(self.attr.PASSWORD_AUTH) }; ie_apache_urls = ${ self.javascript_boolean(self.attr.APACHE_URLS) }; ie_password = '${ self.attr.notebook_pw }'; -// Do these need to be global as well?? var galaxy_root = '${ self.attr.root }'; var app_root = '${ self.attr.app_root }'; diff --git a/templates/rstudio.mako b/templates/rstudio.mako index db253f92115..20fcc91c6bd 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -8,19 +8,22 @@ import subprocess # Sets ID and sets up a lot of other variables ie.set_id("rstudio") +# Inform the IE of the remote port on docker's end +ie.attr.docker_port = 8787 # Create tempdir in galaxy temp_dir = os.path.abspath( tempfile.mkdtemp() ) # Write out conf file...needs work -ie.write_conf_file(temp_dir) +ie.write_conf_file(temp_dir, {'notebook_username': 'galaxy'}) USERNAME = "galaxy" ## General IE specific # Access URLs for the notebook from within galaxy. -notebook_access_url = ie.url_template('${PROTO}://${HOST}/rstudio/') +notebook_access_url = ie.url_template('${PROTO}://${HOST}/auth-sign-in') notebook_login_url = ie.url_template('${PROTO}://${HOST}/auth-sign-in') docker_cmd = ie.docker_cmd(temp_dir) subprocess.call(docker_cmd, shell=True) +print docker_cmd time.sleep(5) @@ -46,27 +49,28 @@ ${ ie.default_javascript_variables() } var notebook_login_url = '${ notebook_login_url }'; var notebook_access_url = '${ notebook_access_url }'; var notebook_username = '${ USERNAME }'; -// Load notebook -// -// -// -// -// var payload = "${ USERNAME }" + "\n" + ie_password; -var rsa = new RSAKey(); -rsa.setPublic("${ n }", "${ e }"); -var res = rsa.encrypt(payload); -var v = hex2b64(res); -// - require.config({ baseUrl: app_root, paths: { "plugin" : app_root + "js/", + "crypto" : app_root + "js/crypto/", }, }); -requirejs(['plugin/ie', 'plugin/rstudio'], function(){ - //load_notebook(ie_password, notebook_login_url, notebook_access_url); +requirejs([ + 'plugin/ie', + 'plugin/rstudio', + 'crypto/prng4', + 'crypto/rng', + 'crypto/rsa', + 'crypto/jsbn', + 'crypto/base64' +], function(){ + var rsa = new RSAKey(); + rsa.setPublic("${ e }", "${ n }"); + var res = rsa.encrypt(payload); + var v = hex2b64(res); + load_notebook(v, notebook_login_url, notebook_access_url); });
From b438695abfb3017933b71cf5f124d264b01544ed Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Wed, 24 Sep 2014 17:37:43 -0500 Subject: [PATCH 013/120] Wait on pubkey to exist before launching --- templates/rstudio.mako | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 20fcc91c6bd..49e24e4649d 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -27,13 +27,21 @@ print docker_cmd time.sleep(5) +pub_key = os.path.join(temp_dir, 'rserver_pub_key') + +while True: + if os.path.isfile(pub_key): + print "Pubkey exists!" + break + else: + print "Pubkey doesn't exist yet" + time.sleep(1) + try: # Get n, e from public key file with open(os.path.join(temp_dir, 'rserver_pub_key'), 'r') as pub_key_handle: n, e = pub_key_handle.read().split(':') except: - n = 0 - e = 0 pass From 4e64ce445df2d2fe8111c3711778ceb96b1d302e Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 25 Sep 2014 10:18:13 -0500 Subject: [PATCH 014/120] Corrected AJAX request call --- static/js/ie.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/static/js/ie.js b/static/js/ie.js index 651f71fe83a..170aae961db 100644 --- a/static/js/ie.js +++ b/static/js/ie.js @@ -30,8 +30,10 @@ function test_ie_availability(url, success_callback){ display_spinner(); interval = setInterval(function(){ $.ajax({ + url: url, type: "GET", success: function(){ + console.log("Connected to IE, returning"); clearInterval(interval); success_callback(); }, From 8b1eec92c5c0142a6c63e813b88d217ac59fe6c2 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 25 Sep 2014 10:27:49 -0500 Subject: [PATCH 015/120] Updated port for nginx proxy, added more error catching --- static/js/ie.js | 2 +- templates/rstudio.mako | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/static/js/ie.js b/static/js/ie.js index 170aae961db..6a17e7df1ea 100644 --- a/static/js/ie.js +++ b/static/js/ie.js @@ -37,7 +37,7 @@ function test_ie_availability(url, success_callback){ clearInterval(interval); success_callback(); }, - error: function(){ + error: function(jqxhr, status, error){ request_count++; if(request_count > 30){ clearInterval(interval); diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 49e24e4649d..ca971abf76f 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -9,7 +9,7 @@ import subprocess # Sets ID and sets up a lot of other variables ie.set_id("rstudio") # Inform the IE of the remote port on docker's end -ie.attr.docker_port = 8787 +ie.attr.docker_port = 80 # Create tempdir in galaxy temp_dir = os.path.abspath( tempfile.mkdtemp() ) # Write out conf file...needs work @@ -24,12 +24,14 @@ notebook_login_url = ie.url_template('${PROTO}://${HOST}/auth-sign-in') docker_cmd = ie.docker_cmd(temp_dir) subprocess.call(docker_cmd, shell=True) print docker_cmd - time.sleep(5) pub_key = os.path.join(temp_dir, 'rserver_pub_key') +# Todo, migrate to JS +try_count = 0 while True: + try_count += 1 if os.path.isfile(pub_key): print "Pubkey exists!" break @@ -37,11 +39,18 @@ while True: print "Pubkey doesn't exist yet" time.sleep(1) + if try_count > 30: + # Throw an error? + break + try: # Get n, e from public key file with open(os.path.join(temp_dir, 'rserver_pub_key'), 'r') as pub_key_handle: n, e = pub_key_handle.read().split(':') except: + n = 0 + e = 0 + # Throw an error? pass From e186a9673ce992b5ead3d5e5ad3c26fc7854fca3 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 25 Sep 2014 12:32:10 -0500 Subject: [PATCH 016/120] Updated URLs --- static/js/rstudio.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/static/js/rstudio.js b/static/js/rstudio.js index b7b709339ff..af41367cf67 100644 --- a/static/js/rstudio.js +++ b/static/js/rstudio.js @@ -34,7 +34,7 @@ function load_notebook(password, notebook_login_url, notebook_access_url){ $( document ).ready(function() { // Test notebook_login_url for accessibility, executing the login+load function whenever // we've successfully connected to the IE. - test_ie_availability(notebook_login_url, function(){ + test_ie_availability(notebook_access_url, function(){ _handle_notebook_loading(password, notebook_login_url, notebook_access_url); }); }); @@ -54,7 +54,8 @@ function _handle_notebook_loading(password, notebook_login_url, notebook_access_ data: { 'package': password, 'persist': 1, - 'clientPath': window.location.pathname, + 'clientPath': '/rstudio/auth-sign-in', + 'appUri': '', }, xhrFields: { withCredentials: true From bcee19e71cdaa3e8c98d0b6bbcbe402adc220b6c Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 25 Sep 2014 12:32:28 -0500 Subject: [PATCH 017/120] Moved docker container to subpath --- templates/rstudio.mako | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/templates/rstudio.mako b/templates/rstudio.mako index ca971abf76f..7e125fde1d6 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -8,8 +8,10 @@ import subprocess # Sets ID and sets up a lot of other variables ie.set_id("rstudio") -# Inform the IE of the remote port on docker's end -ie.attr.docker_port = 80 +# In order to keep 302 redirects happy, nginx needs to be aware there's a proxy in front of it, +# which may be using a different port. As a result, we have to start nginx on whichever port it is +# we plan to use. +ie.attr.docker_port = ie.attr.PORT # Create tempdir in galaxy temp_dir = os.path.abspath( tempfile.mkdtemp() ) # Write out conf file...needs work @@ -18,13 +20,12 @@ USERNAME = "galaxy" ## General IE specific # Access URLs for the notebook from within galaxy. -notebook_access_url = ie.url_template('${PROTO}://${HOST}/auth-sign-in') -notebook_login_url = ie.url_template('${PROTO}://${HOST}/auth-sign-in') +notebook_access_url = ie.url_template('${PROTO}://${HOST}/rstudio/auth-sign-in') +notebook_login_url = ie.url_template('${PROTO}://${HOST}/rstudio/auth-do-sign-in') docker_cmd = ie.docker_cmd(temp_dir) subprocess.call(docker_cmd, shell=True) print docker_cmd -time.sleep(5) pub_key = os.path.join(temp_dir, 'rserver_pub_key') @@ -61,6 +62,7 @@ ${ ie.load_default_js() } +${ ie.attr.notebook_pw };
From f1bda976bfbb27f232a8d4fc77486200a46d6fb3 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Fri, 26 Sep 2014 15:11:33 -0500 Subject: [PATCH 021/120] Last ditch JS attempts Also threw in all of the wu/rstudio originals --- static/js/crypto/rstudio.big.js | 861 +++++++++++++++++++++++++++++ static/js/crypto/rstudio.min.js | 24 + static/js/crypto/rstudio/base64.js | 73 +++ static/js/crypto/rstudio/jsbn.js | 562 +++++++++++++++++++ static/js/crypto/rstudio/prng4.js | 47 ++ static/js/crypto/rstudio/rng.js | 70 +++ static/js/crypto/rstudio/rsa.js | 114 ++++ static/js/crypto/wu/base64.js | 71 +++ static/js/crypto/wu/jsbn.js | 559 +++++++++++++++++++ static/js/crypto/wu/prng4.js | 45 ++ static/js/crypto/wu/rng.js | 75 +++ static/js/crypto/wu/rsa.js | 112 ++++ static/js/ie.js | 2 +- static/js/rstudio.js | 1 + 14 files changed, 2615 insertions(+), 1 deletion(-) create mode 100644 static/js/crypto/rstudio.big.js create mode 100644 static/js/crypto/rstudio.min.js create mode 100644 static/js/crypto/rstudio/base64.js create mode 100644 static/js/crypto/rstudio/jsbn.js create mode 100644 static/js/crypto/rstudio/prng4.js create mode 100644 static/js/crypto/rstudio/rng.js create mode 100644 static/js/crypto/rstudio/rsa.js create mode 100644 static/js/crypto/wu/base64.js create mode 100644 static/js/crypto/wu/jsbn.js create mode 100644 static/js/crypto/wu/prng4.js create mode 100644 static/js/crypto/wu/rng.js create mode 100644 static/js/crypto/wu/rsa.js diff --git a/static/js/crypto/rstudio.big.js b/static/js/crypto/rstudio.big.js new file mode 100644 index 00000000000..2389ea47282 --- /dev/null +++ b/static/js/crypto/rstudio.big.js @@ -0,0 +1,861 @@ +// Downloaded from http://www-cs-students.stanford.edu/~tjw/ at Tue Nov 30 00:42:57 PST 2010 +// ==== File: jsbn.js +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); +// ==== File: prng4.js +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; +// ==== File: rng.js +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; +// ==== File: rsa.js +// Depends on jsbn.js and rng.js + +// Version 1.1: support utf-8 encoding in pkcs1pad2 + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function linebrk(s,n) { + var ret = ""; + var i = 0; + while(i + n < s.length) { + ret += s.substring(i,i+n) + "\n"; + i += n; + } + return ret + s.substring(i,s.length); +} + +function byte2Hex(b) { + if(b < 0x10) + return "0" + b.toString(16); + else + return b.toString(16); +} + +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s,n) { + if(n < s.length + 11) { // TODO: fix for utf-8 + alert("Message too long for RSA"); + return null; + } + var ba = new Array(); + var i = s.length - 1; + while(i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if(c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = new Array(); + while(n > 2) { // random non-zero pad + x[0] = 0; + while(x[0] == 0) rng.nextBytes(x); + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} + +// "empty" RSA key constructor +function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; +} + +// Set the public key fields N and e from hex strings +function RSASetPublic(N,E) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + } + else + alert("Invalid RSA public key"); +} + +// Perform raw public operation on "x": return x^e (mod n) +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} + +// Return the PKCS#1 RSA encryption of "text" as an even-length hex string +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + if(m == null) return null; + var c = this.doPublic(m); + if(c == null) return null; + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} + +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +//function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +//} + +// protected +RSAKey.prototype.doPublic = RSADoPublic; + +// public +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; +// ==== File: base64.js +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64pad="="; + +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64pad; + return ret; +} + +// convert a base64 string to hex +function b64tohex(s) { + var ret = "" + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64pad) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} + +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} diff --git a/static/js/crypto/rstudio.min.js b/static/js/crypto/rstudio.min.js new file mode 100644 index 00000000000..f74debec619 --- /dev/null +++ b/static/js/crypto/rstudio.min.js @@ -0,0 +1,24 @@ +var g,j,k=(244837814094590&16777215)==15715070;function l(b,a,c){if(b!=null)if("number"==typeof b)this.ca(b,a,c);else a==null&&"string"!=typeof b?this.z(b,256):this.z(b,a)}function m(){return new l(null)}function o(b,a,c,d,e,f){for(;--f>=0;){var h=a*this[b++]+c[d]+e;e=Math.floor(h/67108864);c[d++]=h&67108863}return e} +function p(b,a,c,d,e,f){var h=a&32767;for(a=a>>15;--f>=0;){var i=this[b]&32767,n=this[b++]>>15,r=a*i+n*h;i=h*i+((r&32767)<<15)+c[d]+(e&1073741823);e=(i>>>30)+(r>>>15)+a*n+(e>>>30);c[d++]=i&1073741823}return e}function s(b,a,c,d,e,f){var h=a&16383;for(a=a>>14;--f>=0;){var i=this[b]&16383,n=this[b++]>>14,r=a*i+n*h;i=h*i+((r&16383)<<14)+c[d]+e;e=(i>>28)+(r>>14)+a*n;c[d++]=i&268435455}return e} +if(k&&navigator.appName=="Microsoft Internet Explorer"){l.prototype.i=p;j=30}else if(k&&navigator.appName!="Netscape"){l.prototype.i=o;j=26}else{l.prototype.i=s;j=28}g=l.prototype;g.c=j;g.g=(1<=0;--a)b[a]=this[a];b.a=this.a;b.b=this.b}function D(b){this.a=1;this.b=b<0?-1:0;if(b>0)this[0]=b;else if(b<-1)this[0]=b+DV;else this.a=0}function E(b){var a=m();a.w(b);return a} +function F(b,a){if(a==16)a=4;else if(a==8)a=3;else if(a==256)a=8;else if(a==2)a=1;else if(a==32)a=5;else if(a==4)a=2;else{this.da(b,a);return}this.b=this.a=0;for(var c=b.length,d=false,e=0;--c>=0;){var f=a==8?b[c]&255:A(b,c);if(f<0){if(b.charAt(c)=="-")d=true}else{d=false;if(e==0)this[this.a++]=f;else if(e+a>this.c){this[this.a-1]|=(f&(1<>this.c-e}else this[this.a-1]|=f<=this.c)e-=this.c}}if(a==8&&(b[0]&128)!=0){this.b=-1;if(e>0)this[this.a-1]|=(1<0&&this[this.a-1]==b;)--this.a} +function I(b){if(this.b<0)return"-"+this.G().toString(b);if(b==16)b=4;else if(b==8)b=3;else if(b==2)b=1;else if(b==32)b=5;else if(b==4)b=2;else return this.ga(b);var a=(1<0){if(h>h)>0){d=true;e=t.charAt(c)}for(;f>=0;){if(h>(h+=this.c-b)}else{c=this[f]>>(h-=b)&a;if(h<=0){h+=this.c;--f}}if(c>0)d=true;if(d)e+=t.charAt(c)}}return d?e:"0"} +function J(){var b=m();G.f(this,b);return b}function K(){return this.b<0?this.G():this}function L(b){var a=this.b-b.b;if(a!=0)return a;var c=this.a;a=c-b.a;if(a!=0)return a;for(;--c>=0;)if((a=this[c]-b[c])!=0)return a;return 0}function M(b){var a=1,c;if((c=b>>>16)!=0){b=c;a+=16}if((c=b>>8)!=0){b=c;a+=8}if((c=b>>4)!=0){b=c;a+=4}if((c=b>>2)!=0){b=c;a+=2}if(b>>1!=0)a+=1;return a}function N(){if(this.a<=0)return 0;return this.c*(this.a-1)+M(this[this.a-1]^this.b&this.g)} +function aa(b,a){var c;for(c=this.a-1;c>=0;--c)a[c+b]=this[c];for(c=b-1;c>=0;--c)a[c]=0;a.a=this.a+b;a.b=this.b}function ba(b,a){for(var c=b;c=0;--h){a[h+b+1]=this[h]>>d|f;f=(this[h]&e)<=0;--h)a[h]=0;a[b]=f;a.a=this.a+b+1;a.b=this.b;a.j()} +function da(b,a){a.b=this.b;var c=Math.floor(b/this.c);if(c>=this.a)a.a=0;else{b=b%this.c;var d=this.c-b,e=(1<>b;for(var f=c+1;f>b}if(b>0)a[this.a-c-1]|=(this.b&e)<>=this.c}if(b.a>=this.c}d+=this.b}else{for(d+=this.b;c>=this.c}d-=b.b}a.b=d<0?-1:0;if(d<-1)a[c++]=this.h+d;else if(d>0)a[c++]=d;a.a=c;a.j()}function fa(b,a){var c=this.abs(),d=b.abs(),e=c.a;for(a.a=e+d.a;--e>=0;)a[e]=0;for(e=0;e=0;)b[c]=0;for(c=0;c=a.h){b[c+a.a]-=a.h;b[c+a.a+1]=1}}if(b.a>0)b[b.a-1]+=a.i(c,a[c],b,2*c,0,1);b.b=0;b.j()} +function ha(b,a,c){var d=b.abs();if(!(d.a<=0)){var e=this.abs();if(e.a0){d.A(i,f);e.A(i,c)}else{d.m(f);e.m(c)}d=f.a;e=f[d-1];if(e!=0){var n=e*(1<1?f[d-2]>>this.s:0),r=this.K/n;n=(1<=0){c[c.a++]=1;c.f(q,c)}O.o(d,q);for(q.f(f,f);f.a=0;){var C=c[--w]==e?this.g:Math.floor(c[w]* +r+(c[w-1]+ia)*n);if((c[w]+=f.i(0,C,c,y,0,d))0&&c.W(i,c);h<0&&G.f(c,c)}}}}function ja(b){var a=m();this.abs().p(b,null,a);this.b<0&&a.l(G)>0&&b.f(a,a);return a}function P(b){this.d=b}function ka(b){return b.b<0||b.l(this.d)>=0?b.R(this.d):b}function la(b){return b}function ma(b){b.p(this.d,null,b)}function na(b,a,c){b.F(a,c);this.reduce(c)}function oa(b,a){b.J(a);this.reduce(a)}g=P.prototype;g.t=ka; +g.H=la;g.reduce=ma;g.D=na;g.I=oa;function pa(){if(this.a<1)return 0;var b=this[0];if((b&1)==0)return 0;var a=b&3;a=a*(2-(b&15)*a)&15;a=a*(2-(b&255)*a)&255;a=a*(2-((b&65535)*a&65535))&65535;a=a*(2-b*a%this.h)%this.h;return a>0?this.h-a:-a}function Q(b){this.d=b;this.B=b.P();this.C=this.B&32767;this.T=this.B>>15;this.Y=(1<0&&this.d.f(a,a);return a} +function ra(b){var a=m();b.m(a);this.reduce(a);return a}function sa(b){for(;b.a<=this.U;)b[b.a++]=0;for(var a=0;a>15)*this.C&this.Y)<<15)&b.g;c=a+this.d.a;for(b[c]+=this.d.i(0,d,b,a,0,this.d.a);b[c]>=b.h;){b[c]-=b.h;b[++c]++}}b.j();b.u(this.d.a,b);b.l(this.d)>=0&&b.f(this.d,b)}function ta(b,a){b.J(a);this.reduce(a)}function ua(b,a,c){b.F(a,c);this.reduce(c)}g=Q.prototype;g.t=qa;g.H=ra;g.reduce=sa;g.D=ua;g.I=ta; +function va(){return(this.a>0?this[0]&1:this.b)==0}function wa(b,a){if(b>4294967295||b<1)return O;var c=m(),d=m(),e=a.t(this),f=M(b)-1;for(e.m(c);--f>=0;){a.I(c,d);if((b&1<0)a.D(d,e,c);else{var h=c;c=d;d=h}}return a.H(c)}function xa(b,a){a=b<256||a.Q()?new P(a):new Q(a);return this.exp(b,a)}g=l.prototype;g.m=B;g.w=D;g.z=F;g.j=H;g.o=aa;g.u=ba;g.A=ca;g.W=da;g.f=ea;g.F=fa;g.J=ga;g.p=ha;g.P=pa;g.Q=va;g.exp=wa;g.toString=I;g.G=J;g.abs=K;g.l=L;g.L=N;g.R=ja;g.S=xa;var G=E(0),O=E(1); +function R(){this.n=this.k=0;this.e=[]}function ya(b){var a,c,d;for(a=0;a<256;++a)this.e[a]=a;for(a=c=0;a<256;++a){c=c+this.e[a]+b[a%b.length]&255;d=this.e[a];this.e[a]=this.e[c];this.e[c]=d}this.n=this.k=0}function za(){var b;this.k=this.k+1&255;this.n=this.n+this.e[this.k]&255;b=this.e[this.k];this.e[this.k]=this.e[this.n];this.e[this.n]=b;return this.e[b+this.e[this.k]&255]}R.prototype.O=ya;R.prototype.next=za;var S=256,T,U,V; +function W(b){U[V++]^=b&255;U[V++]^=b>>8&255;U[V++]^=b>>16&255;U[V++]^=b>>24&255;if(V>=S)V-=S}if(U==null){U=[];V=0;var X;if(navigator.appName=="Netscape"&&navigator.appVersion<"5"&&window.crypto){var Y=window.crypto.random(32);for(X=0;X>>8;U[V++]=X&255}V=0;W((new Date).getTime())}function Aa(){if(T==null){W((new Date).getTime());T=new R;T.O(U);for(V=0;V0&&a.length>0){this.q=new l(b,16);this.v=parseInt(a,16)}else alert("Invalid RSA public key")}function Da(b){return b.S(this.v,this.q)} +function Ea(b){var a;a=this.q.L()+7>>3;if(a=0&&a>0;){var e=b.charCodeAt(d--);if(e<128)c[--a]=e;else if(e>127&&e<2048){c[--a]=e&63|128;c[--a]=e>>6|192}else{c[--a]=e&63|128;c[--a]=e>>6&63|128;c[--a]=e>>12|224}}c[--a]=0;b=new Z;for(d=[];a>2;){for(d[0]=0;d[0]==0;)b.V(d);c[--a]=d[0]}c[--a]=2;c[--a]=0;a=new l(c)}if(a==null)return null;a=this.M(a);if(a==null)return null;a=a.toString(16);return(a.length&1)==0?a:"0"+a} +ZZZ.prototype.M=Da;ZZZ.prototype.X=Ca;ZZZ.prototype.N=Ea;window.encrypt=function(b,a,c){var d=new ZZZ;d.X(c,a);b=d.N(b);d="";for(a=0;a+3<=b.length;a+=3){c=parseInt(b.substring(a,a+3),16);d+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(c>>6)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(c&63)}if(a+1==b.length){c=parseInt(b.substring(a,a+1),16);d+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(c<<2)}else if(a+2==b.length){c=parseInt(b.substring(a,a+2),16);d+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(c>> +2)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt((c&3)<<4)}for(;(d.length&3)>0;)d+="=";return d}; + diff --git a/static/js/crypto/rstudio/base64.js b/static/js/crypto/rstudio/base64.js new file mode 100644 index 00000000000..77b3868abf9 --- /dev/null +++ b/static/js/crypto/rstudio/base64.js @@ -0,0 +1,73 @@ +// ==== File: base64.js +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64pad="="; + +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64pad; + return ret; +} + +// convert a base64 string to hex +function b64tohex(s) { + var ret = "" + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64pad) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} + +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} + diff --git a/static/js/crypto/rstudio/jsbn.js b/static/js/crypto/rstudio/jsbn.js new file mode 100644 index 00000000000..801841d7184 --- /dev/null +++ b/static/js/crypto/rstudio/jsbn.js @@ -0,0 +1,562 @@ +// Downloaded from http://www-cs-students.stanford.edu/~tjw/ at Tue Nov 30 00:42:57 PST 2010 +// ==== File: jsbn.js +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + diff --git a/static/js/crypto/rstudio/prng4.js b/static/js/crypto/rstudio/prng4.js new file mode 100644 index 00000000000..5cd681256c1 --- /dev/null +++ b/static/js/crypto/rstudio/prng4.js @@ -0,0 +1,47 @@ +// ==== File: prng4.js +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; + diff --git a/static/js/crypto/rstudio/rng.js b/static/js/crypto/rstudio/rng.js new file mode 100644 index 00000000000..24bae0f8ec8 --- /dev/null +++ b/static/js/crypto/rstudio/rng.js @@ -0,0 +1,70 @@ +// ==== File: rng.js +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; + diff --git a/static/js/crypto/rstudio/rsa.js b/static/js/crypto/rstudio/rsa.js new file mode 100644 index 00000000000..b2e37c35540 --- /dev/null +++ b/static/js/crypto/rstudio/rsa.js @@ -0,0 +1,114 @@ +// ==== File: rsa.js +// Depends on jsbn.js and rng.js + +// Version 1.1: support utf-8 encoding in pkcs1pad2 + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function linebrk(s,n) { + var ret = ""; + var i = 0; + while(i + n < s.length) { + ret += s.substring(i,i+n) + "\n"; + i += n; + } + return ret + s.substring(i,s.length); +} + +function byte2Hex(b) { + if(b < 0x10) + return "0" + b.toString(16); + else + return b.toString(16); +} + +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s,n) { + if(n < s.length + 11) { // TODO: fix for utf-8 + alert("Message too long for RSA"); + return null; + } + var ba = new Array(); + var i = s.length - 1; + while(i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if(c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = new Array(); + while(n > 2) { // random non-zero pad + x[0] = 0; + while(x[0] == 0) rng.nextBytes(x); + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} + +// "empty" RSA key constructor +function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; +} + +// Set the public key fields N and e from hex strings +function RSASetPublic(N,E) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + } + else + alert("Invalid RSA public key"); +} + +// Perform raw public operation on "x": return x^e (mod n) +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} + +// Return the PKCS#1 RSA encryption of "text" as an even-length hex string +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + if(m == null) return null; + var c = this.doPublic(m); + if(c == null) return null; + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} + +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +//function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +//} + +// protected +RSAKey.prototype.doPublic = RSADoPublic; + +// public +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; + diff --git a/static/js/crypto/wu/base64.js b/static/js/crypto/wu/base64.js new file mode 100644 index 00000000000..ad53bb8ed06 --- /dev/null +++ b/static/js/crypto/wu/base64.js @@ -0,0 +1,71 @@ +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64padchar="="; + +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64padchar; + return ret; +} + +// convert a base64 string to hex +function b64tohex(s) { + var ret = "" + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64padchar) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} + +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} diff --git a/static/js/crypto/wu/jsbn.js b/static/js/crypto/wu/jsbn.js new file mode 100644 index 00000000000..4ed7c8362da --- /dev/null +++ b/static/js/crypto/wu/jsbn.js @@ -0,0 +1,559 @@ +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); diff --git a/static/js/crypto/wu/prng4.js b/static/js/crypto/wu/prng4.js new file mode 100644 index 00000000000..3034f3f1158 --- /dev/null +++ b/static/js/crypto/wu/prng4.js @@ -0,0 +1,45 @@ +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; diff --git a/static/js/crypto/wu/rng.js b/static/js/crypto/wu/rng.js new file mode 100644 index 00000000000..9db13825fb6 --- /dev/null +++ b/static/js/crypto/wu/rng.js @@ -0,0 +1,75 @@ +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(window.crypto && window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for(t = 0; t < 32; ++t) + rng_pool[rng_pptr++] = ua[t]; + } + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; diff --git a/static/js/crypto/wu/rsa.js b/static/js/crypto/wu/rsa.js new file mode 100644 index 00000000000..9f8664037c4 --- /dev/null +++ b/static/js/crypto/wu/rsa.js @@ -0,0 +1,112 @@ +// Depends on jsbn.js and rng.js + +// Version 1.1: support utf-8 encoding in pkcs1pad2 + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function linebrk(s,n) { + var ret = ""; + var i = 0; + while(i + n < s.length) { + ret += s.substring(i,i+n) + "\n"; + i += n; + } + return ret + s.substring(i,s.length); +} + +function byte2Hex(b) { + if(b < 0x10) + return "0" + b.toString(16); + else + return b.toString(16); +} + +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s,n) { + if(n < s.length + 11) { // TODO: fix for utf-8 + alert("Message too long for RSA"); + return null; + } + var ba = new Array(); + var i = s.length - 1; + while(i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if(c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = new Array(); + while(n > 2) { // random non-zero pad + x[0] = 0; + while(x[0] == 0) rng.nextBytes(x); + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} + +// "empty" RSA key constructor +function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; +} + +// Set the public key fields N and e from hex strings +function RSASetPublic(N,E) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + } + else + alert("Invalid RSA public key"); +} + +// Perform raw public operation on "x": return x^e (mod n) +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} + +// Return the PKCS#1 RSA encryption of "text" as an even-length hex string +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + if(m == null) return null; + var c = this.doPublic(m); + if(c == null) return null; + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} + +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +//function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +//} + +// protected +RSAKey.prototype.doPublic = RSADoPublic; + +// public +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; diff --git a/static/js/ie.js b/static/js/ie.js index da55dd544b9..1c49c5e9e28 100644 --- a/static/js/ie.js +++ b/static/js/ie.js @@ -4,7 +4,7 @@ */ function append_notebook(url){ clear_main_area(); - $('#main').append('' + $('#main').append('' ); } diff --git a/static/js/rstudio.js b/static/js/rstudio.js index 754d966db6c..5e06a41388e 100644 --- a/static/js/rstudio.js +++ b/static/js/rstudio.js @@ -67,6 +67,7 @@ function _handle_notebook_loading(password, notebook_login_url, notebook_access_ 'clientPath': '/rstudio/auth-sign-in', 'appUri': '', }, + contentType: "application/x-www-form-urlencoded", xhrFields: { withCredentials: true }, From fdb4b4b99774eac0fcd383476202aee2fd973984 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Fri, 26 Sep 2014 15:12:36 -0500 Subject: [PATCH 022/120] Remove IE specific text --- templates/ie.mako | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/ie.mako b/templates/ie.mako index 7fc02d7ffb3..4a222c25c9c 100644 --- a/templates/ie.mako +++ b/templates/ie.mako @@ -22,7 +22,7 @@ import ConfigParser self.attr.galaxy_config = trans.app.config self.attr.galaxy_root_dir = os.path.abspath(self.attr.galaxy_config.root) self.attr.root = h.url_for("/") - self.attr.app_root = self.attr.root + "plugins/visualizations/rstudio/static/" + self.attr.app_root = self.attr.root + "plugins/visualizations/" + self.attr.viz_id + "/static/" # Store our template and configuration path self.attr.our_config_dir = os.path.join(plugin_path, "config") From bc8191543cea3219d995a1cd4c0c69cee6c7bf87 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Fri, 26 Sep 2014 16:50:28 -0500 Subject: [PATCH 023/120] Updated the readme --- README.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fc0612d6b81..c8d818e2b19 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,65 @@ git clone https://github.com/erasche/galaxy-rstudio.git config/plugins/visualiza The RStudio visualisation option should be visible next to the usual Charts or Trackster options in your visualisation menue. +![Starting RStudio in Galaxy](https://raw.githubusercontent.com/erasche/galaxy-ipython/master/static/images/start_rstudio.png) + + +Features +======== + + * run RStudio directly in your Galaxy main window or in Galaxy Scratchbook + * complete encapsulated R environment + * access to all datasets from your current history via pre-defined RStudio function + * manipulate and plot data as you like and export your new files back into the Galaxy history + * self-closing and cleaning RStudio docker container + +How does it work +================ + +The mako template from the Galaxy visualisation framework renders the interface and builds all files and commands needed to lunch the docker container. A config file is saved under ``/import/`` inside the docker container. The RStudio webpage running in docker will be included in a HTML object and displayed to the user. +Depending on your configuration some JavaScript magic is done to add an object to the DOM, which will be loaded by the browser and conditionally handles login. +Iside of docker TCP connections are monitored using cron. As soon as the user quits using the notebook, the dropping TCP connections are recognised and the cotainer cleans up after itself and kills itself. + + + +Functions and variables +======================= + +For your convience, we have added a few pre-defined functions to the IPython profile. + +### gx_get + + The get function will copy a dataset, identified by the history_id, from your current Galaxy + into the docker container. It will return the file path to the copied file. + + *Example*: + ```R + data <- read.csv(gx_get(44), sep="\t") + View(data) + ``` + +### gx_put + + The put function takes a file path and transfers the file to the current history of your Galaxy session. + + *Example*: + ```R + put('./my_file.tsv') + put('./my_file.tsv', file_type="tabular") + ``` + + +Security +======== + +By default, no security is turned on. + +In production, `apache_urls` variable should be set to `True`, and containers should be secured via Apache+SSL for production usage. Please see the [setup](INSTALL.md) document for more information. Authors ======= - * Björn Grüning + * Björn Grüning * Eric Rasche From 34caec7c8316f851090a09085be3c72bda6862e8 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Fri, 26 Sep 2014 16:52:50 -0500 Subject: [PATCH 024/120] Fixed URLs --- README.md | 2 +- static/images/start_rstudio.png | Bin 0 -> 7396 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 static/images/start_rstudio.png diff --git a/README.md b/README.md index c8d818e2b19..624a7789bce 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ git clone https://github.com/erasche/galaxy-rstudio.git config/plugins/visualiza The RStudio visualisation option should be visible next to the usual Charts or Trackster options in your visualisation menue. -![Starting RStudio in Galaxy](https://raw.githubusercontent.com/erasche/galaxy-ipython/master/static/images/start_rstudio.png) +![Starting RStudio in Galaxy](https://raw.githubusercontent.com/erasche/galaxy-rstudio/master/static/images/start_rstudio.png) Features diff --git a/static/images/start_rstudio.png b/static/images/start_rstudio.png new file mode 100644 index 0000000000000000000000000000000000000000..157571b4932c15ff63c595c275546a7a7f47f63a GIT binary patch literal 7396 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 WzjP=|PXbT?0000 Date: Fri, 26 Sep 2014 16:53:12 -0500 Subject: [PATCH 025/120] Change to enable apache_urls usage --- templates/rstudio.mako | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 0dd3600c941..869257037ff 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -20,9 +20,9 @@ USERNAME = "galaxy" ## General IE specific # Access URLs for the notebook from within galaxy. -notebook_pubkey_url = ie.url_template('${PROTO}://${HOST}/rstudio/auth-public-key') -notebook_access_url = ie.url_template('${PROTO}://${HOST}/rstudio/') -notebook_login_url = ie.url_template('${PROTO}://${HOST}/rstudio/auth-do-sign-in') +notebook_pubkey_url = ie.url_template('${PROTO}://${HOST}/rstudio/${PORT}/auth-public-key') +notebook_access_url = ie.url_template('${PROTO}://${HOST}/rstudio/${PORT}/') +notebook_login_url = ie.url_template('${PROTO}://${HOST}/rstudio/${PORT}/auth-do-sign-in') docker_cmd = ie.docker_cmd(temp_dir) subprocess.call(docker_cmd, shell=True) From 7feac47c3b3dd7840616083a11acbde886586bc1 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Fri, 26 Sep 2014 16:56:44 -0500 Subject: [PATCH 026/120] Added installation instructions --- INSTALL.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 00000000000..5f937fa4200 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,37 @@ +# Installation + +We've developed the templates and containers such that they can be run through an Apache proxy using +SSL. This requires some trivial apache configuration to support. + +## Requirements + + * [mod_proxy](http://httpd.apache.org/docs/2.4/mod/mod_proxy.html) + * [mod_proxy_http](http://httpd.apache.org/docs/2.4/mod/mod_proxy_http.html) + * [mod_rewrite](http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html) + +## Apache Configuration + +Here is the relevant configuration + +```apache +RewriteEngine On +RewriteRule ^/rstudio/([0-9]+)/(.*)$ http://localhost:$1/rstudio/$1/$2 [P,L] +``` + +## Nginx Configuration + +Please submit it if you write it! + +## Template Configuration + +Normally containers are accessed via URLs that look like: + +``` +http://fqdn:11235/rstudio/11235/ +``` + +In order to secure them we want to access them via URLs that look like: + +``` +http://fqdn/rstudio/11235/ +``` From 10d2ddb55e4b4926fbcfa2c06568cf92e61a908f Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Sat, 25 Oct 2014 18:09:16 -0500 Subject: [PATCH 027/120] Fixed login issue Not sure I'm entirely fond of this solution, however it functions perfectly --- static/js/rstudio.js | 36 +++--------------------------------- templates/rstudio.mako | 9 +++++++-- 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/static/js/rstudio.js b/static/js/rstudio.js index 5e06a41388e..65a60feeac1 100644 --- a/static/js/rstudio.js +++ b/static/js/rstudio.js @@ -55,39 +55,9 @@ function load_notebook(notebook_login_url, notebook_access_url, notebook_pubkey_ */ function _handle_notebook_loading(password, notebook_login_url, notebook_access_url){ if ( ie_password_auth ) { - // Make an AJAX POST - $.ajax({ - type: "POST", - // to the Login URL - url: notebook_login_url, - // With our password - data: { - 'v': password, - 'persist': 1, - 'clientPath': '/rstudio/auth-sign-in', - 'appUri': '', - }, - contentType: "application/x-www-form-urlencoded", - xhrFields: { - withCredentials: true - }, - // If that is successful, load the notebook - success: function(){ - append_notebook(notebook_access_url); - }, - error: function(jqxhr, status, error){ - if(ie_password_auth && !ie_apache_urls){ - // Failure happens due to CORS, can't use `password` because that's actually - // encrypted for rstudio - message_failed_auth(ie_password); - append_notebook(notebook_access_url); - }else{ - message_failed_connection(); - // Do we want to try and load the notebook anyway? Just in case? - append_notebook(notebook_access_url); - } - } - }); + $('form[name=realform]').attr('action', notebook_login_url); + $('input[name=v]').val(password); + $('form[name=realform]').submit(); } else { // Not using password auth, just embed it to avoid content-origin issues. diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 869257037ff..609185f36b0 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -33,8 +33,6 @@ print docker_cmd ${ ie.load_default_js() } - -${ ie.attr.notebook_pw } + +
+ + + + +
From 6bd9b9bc2e192a66a5ff4939d3f9e41f70e91b8a Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Sat, 25 Oct 2014 18:15:48 -0500 Subject: [PATCH 028/120] Mostly translated to new framework --- config/{rstudio.conf => rstudio.ini.sample} | 0 static/js/ie.js | 56 ----- templates/ie.mako | 213 -------------------- templates/rstudio.mako | 22 +- 4 files changed, 11 insertions(+), 280 deletions(-) rename config/{rstudio.conf => rstudio.ini.sample} (100%) delete mode 100644 static/js/ie.js delete mode 100644 templates/ie.mako diff --git a/config/rstudio.conf b/config/rstudio.ini.sample similarity index 100% rename from config/rstudio.conf rename to config/rstudio.ini.sample diff --git a/static/js/ie.js b/static/js/ie.js deleted file mode 100644 index 1c49c5e9e28..00000000000 --- a/static/js/ie.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Internal function to remove content from the main area and add the notebook. - * Not idempotent - */ -function append_notebook(url){ - clear_main_area(); - $('#main').append('' - ); -} - -function clear_main_area(){ - $('#spinner').remove(); - $('#main').children().remove(); -} - -function display_spinner(){ - $('#main').append(''); -} - - -/** - * Test availability of a URL, and call a callback when done. - * http://stackoverflow.com/q/25390206/347368 - * @param {String} url: URL to test availability of. Must return a 200 (302->200 is OK). - * @param {String} callback: function to call once successfully connected. - * - */ -function test_ie_availability(url, success_callback){ - var request_count = 0; - display_spinner(); - interval = setInterval(function(){ - $.ajax({ - url: url, - type: "GET", - timeout: 500, - success: function(){ - console.log("Connected to IE, returning"); - clearInterval(interval); - success_callback(); - }, - error: function(jqxhr, status, error){ - request_count++; - console.log("Request " + request_count); - if(request_count > 30){ - clearInterval(interval); - clear_main_area(); - toastr.error( - "Could not connect to IE, contact your administrator", - "Error", - {'closeButton': true, 'timeOut': 20000, 'tapToDismiss': false} - ); - } - } - }); - }, 1000); -} diff --git a/templates/ie.mako b/templates/ie.mako deleted file mode 100644 index 4a222c25c9c..00000000000 --- a/templates/ie.mako +++ /dev/null @@ -1,213 +0,0 @@ -<%! -import os -import yaml -import shlex -import random -import shutil -import hashlib -import subprocess -import ConfigParser - -%> - -<%def name="set_id(name)"> -<% - """ - IEs must register their name, so it can be used in constructing strings - - Additionally this method stores lots of config options we want to access elsewhere. - """ - self.attr.viz_id = name - self.attr.history_id = trans.security.encode_id( trans.history.id ) - self.attr.galaxy_config = trans.app.config - self.attr.galaxy_root_dir = os.path.abspath(self.attr.galaxy_config.root) - self.attr.root = h.url_for("/") - self.attr.app_root = self.attr.root + "plugins/visualizations/" + self.attr.viz_id + "/static/" - - # Store our template and configuration path - self.attr.our_config_dir = os.path.join(plugin_path, "config") - self.attr.our_template_dir = os.path.join(plugin_path, "templates") - self.attr.viz_config = ConfigParser.SafeConfigParser(default_dict) - self.attr.viz_config.read( os.path.join( self.attr.our_config_dir, self.attr.viz_id + ".conf" ) ) - # Store some variables we want by default - self.attr.PASSWORD_AUTH = self.attr.viz_config.getboolean("main", "password_auth") - self.attr.APACHE_URLS = self.attr.viz_config.getboolean("main", "apache_urls") - self.attr.SSL_URLS = self.attr.viz_config.getboolean("main", "ssl") - self.attr.PORT = self.proxy_request_port() - - self.attr.HOST = request.host.rsplit(':', 1)[0] -%> - - -<%def name="write_conf_file(output_directory, extra={})"> -<% - """ - Build up a configuration file that is standard for ALL IEs. - - TODO: replace hashed password with plaintext. - """ - conf_file = { - 'history_id': self.attr.history_id, - 'galaxy_url': request.application_url.rstrip('/') + '/', - 'api_key': get_api_key(), - 'remote_host': request.remote_addr, - 'galaxy_paster_port': self.get_galaxy_paster_port(self.attr.galaxy_root_dir, - self.attr.galaxy_config), - 'docker_port': self.attr.PORT, - 'cors_origin': request.host_url, - } - - if self.attr.PASSWORD_AUTH: - notebook_pw = self.generate_password(length=24) - conf_file['notebook_password'] = notebook_pw - # Should we use password based connection or "default" connection style in galaxy - else: - notebook_pw = "None" - - # Some will need to pass extra data - for extra_key in extra: - conf_file[extra_key] = extra[extra_key] - - self.attr.notebook_pw = notebook_pw - # Write conf - with open( os.path.join( output_directory, 'conf.yaml' ), 'wb' ) as handle: - handle.write( yaml.dump(conf_file, default_flow_style=False) ) - -%> - - -<%def name="get_galaxy_paster_port(galaxy_root_dir, galaxy_config)"> - <% - """ - Get port galaxy is running on (if running under paster) - """ - config = ConfigParser.SafeConfigParser({'port': '8080'}) - config.read( os.path.join( galaxy_root_dir, 'universe_wsgi.ini' ) ) - - # uWSGI galaxy installations don't use paster and only speak uWSGI not http - try: - port = config.getint('server:%s' % galaxy_config.server_name, 'port') - except: - port = None - return port - %> - - -<%def name="proxy_request_port()"> -<% - """ - Refactor of our port getting...eventually this will be replaced with an API call instead. - """ - # Find all ports that are already occupied - cmd_netstat = shlex.split("netstat -tuln") - p1 = subprocess.Popen(cmd_netstat, stdout=subprocess.PIPE) - - occupied_ports = set() - for line in p1.stdout.read().split('\n'): - if line.startswith('tcp') or line.startswith('tcp6'): - col = line.split() - local_address = col[3] - local_port = local_address.split(':')[-1] - occupied_ports.add( int(local_port) ) - - # Generate random free port number for our docker container - while True: - port = random.randrange(10000,15000) - if port not in occupied_ports: - break - return port -%> - - -<%def name="generate_hex(length)"> -<% - """ - Generate a hex string - """ - return ''.join(random.choice('0123456789abcdef') for _ in range(length)) -%> - - -<%def name="generate_password(length)"> -<% - """ - Generate a random alphanumeric password - """ - return ''.join(random.choice('0123456789abcdefghijklmnopqrstuvwxyz') for _ in range(length)) -%> - - -<%def name="javascript_boolean(python_boolean)"> -<% - """ - Convenience function to convert boolean for use in JS - """ - if python_boolean: - return "true"; - else: - return "false" -%> - - - -<%def name="url_template(url_template)"> -<% - """ - Process a URL template - - There are several variables accessible to the user: - - - ${PROTO} will be replaced with protocol (http/https) - - ${HOST} will be replaced with the correct hostname - - ${PORT} will be replaced with the port the docker image is attached to - - In the case that `apache_urls = False`, the first instance of HOST has a PORT appeneded to - it, so the user doesn't have to template 2x urls. - """ - # Figure out our substitutions - if self.attr.SSL_URLS: - protocol = 'https' - else: - protocol = 'http' - - if not self.attr.APACHE_URLS: - # If they are not using apache URLs, that implies there's a port attached to the host - # string, thus we replace just the first instance of host that we see. - url_template = url_template.replace('${HOST}', '${HOST}:${PORT}', 1) - - url = url_template.replace('${PROTO}', protocol) \ - .replace('${HOST}', self.attr.HOST) \ - .replace('${PORT}', str(self.attr.PORT)) - return url -%> - - - -<%def name="docker_cmd(temp_dir)"> -<% - """ - Generate and return the docker command to execute - """ - return '%s run -d --sig-proxy=true -p %s:%s -v "%s:/import/" %s' % \ - (self.attr.viz_config.get("docker", "command"), self.attr.PORT, self.attr.docker_port, - temp_dir, self.attr.viz_config.get("docker", "image")) -%> - - - -<%def name="default_javascript_variables()"> -// Globals -ie_password_auth = ${ self.javascript_boolean(self.attr.PASSWORD_AUTH) }; -ie_apache_urls = ${ self.javascript_boolean(self.attr.APACHE_URLS) }; -ie_password = '${ self.attr.notebook_pw }'; -var galaxy_root = '${ self.attr.root }'; -var app_root = '${ self.attr.app_root }'; - - - -<%def name="load_default_js()"> -${h.css( 'base' ) } -${h.js( 'libs/jquery/jquery', - 'libs/toastr', - 'libs/require')} - diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 609185f36b0..e40fe26693a 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -7,30 +7,30 @@ import time import subprocess # Sets ID and sets up a lot of other variables -ie.set_id("rstudio") -# In order to keep 302 redirects happy, nginx needs to be aware there's a proxy in front of it, -# which may be using a different port. As a result, we have to start nginx on whichever port it is -# we plan to use. -ie.attr.docker_port = ie.attr.PORT +ie_request.load_deploy_config() +# In order to keep 302 redirects happy, nginx needs to be aware there's a proxy +# in front of it, which may be using a different port. As a result, we have to +# start nginx on whichever port it is we plan to use. +ie_request.attr.docker_port = ie_request.attr.PORT # Create tempdir in galaxy temp_dir = os.path.abspath( tempfile.mkdtemp() ) # Write out conf file...needs work -ie.write_conf_file(temp_dir, {'notebook_username': 'galaxy'}) +ie_request.write_conf_file(temp_dir, {'notebook_username': 'galaxy'}) USERNAME = "galaxy" ## General IE specific # Access URLs for the notebook from within galaxy. -notebook_pubkey_url = ie.url_template('${PROTO}://${HOST}/rstudio/${PORT}/auth-public-key') -notebook_access_url = ie.url_template('${PROTO}://${HOST}/rstudio/${PORT}/') -notebook_login_url = ie.url_template('${PROTO}://${HOST}/rstudio/${PORT}/auth-do-sign-in') +notebook_pubkey_url = ie_request.url_template('${PROXY_URL}/rstudio/${PORT}/auth-public-key') +notebook_access_url = ie_request('${PROXY_URL}/rstudio/${PORT}/') +notebook_login_url = ie_request.url_template('${PROXY_URL}/rstudio/${PORT}/auth-do-sign-in') -docker_cmd = ie.docker_cmd(temp_dir) +docker_cmd = ie_request.docker_cmd(temp_dir) subprocess.call(docker_cmd, shell=True) print docker_cmd %> -${ ie.load_default_js() } +${ ie_request.load_default_js() } +
From 778f97ba1575349596058038b5c20f0ca33f74ab Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 6 Nov 2014 09:37:35 -0600 Subject: [PATCH 035/120] Updated doctype --- config/rstudio.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rstudio.xml b/config/rstudio.xml index 004006f81df..7a9f7f333f7 100644 --- a/config/rstudio.xml +++ b/config/rstudio.xml @@ -1,5 +1,5 @@ - + From bc63d84182e0c73313f564d23aedb144e50ccab1 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 6 Nov 2014 09:38:27 -0600 Subject: [PATCH 036/120] Proxy seems to be working now? --- templates/rstudio.mako | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/rstudio.mako b/templates/rstudio.mako index cb48c41af34..59c75b920c3 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -33,9 +33,9 @@ ie_request.attr.notebook_pw = PASSWORD # Access URLs for the notebook from within galaxy. # TODO: Make this work without pointing directly to IE. Currently does not work # through proxy. -notebook_pubkey_url = ie_request.url_template('http://localhost:${PORT}/rstudio/${PORT}/auth-public-key') -notebook_access_url = ie_request.url_template('http://localhost:${PORT}/rstudio/${PORT}/') -notebook_login_url = ie_request.url_template('http://localhost:${PORT}/rstudio/${PORT}/auth-do-sign-in') +notebook_pubkey_url = ie_request.url_template('http://localhost/rstudio/${PORT}/auth-public-key') +notebook_access_url = ie_request.url_template('http://localhost/rstudio/${PORT}/') +notebook_login_url = ie_request.url_template('http://localhost/rstudio/${PORT}/auth-do-sign-in') import re docker_cmd = ie_request.docker_cmd(temp_dir) From 549d321d2550008f250a03b299be127913073d41 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 6 Nov 2014 09:51:02 -0600 Subject: [PATCH 037/120] Removed warning --- static/js/rstudio.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/static/js/rstudio.js b/static/js/rstudio.js index fb77f88b286..7229a2b5bed 100644 --- a/static/js/rstudio.js +++ b/static/js/rstudio.js @@ -79,9 +79,16 @@ function _handle_notebook_loading(password, notebook_login_url, notebook_access_ }, error: function(jqxhr, status, error){ if(ie_password_auth && !ie_apache_urls){ - // Failure happens due to CORS, can't use `password` because that's actually - // encrypted for rstudio - message_failed_auth(ie_password); + // Failure now happens because the redirect that RStudio gives us includes the + // port internal to nginx. (E.g. localhost:NNNN/rstudio/NNNN/) + // so disabling the message here makes sense as long as it's working correctly + // + // Additionally: + // XMLHttpRequest cannot load http://localhost:46725/rstudio/46725/. The + // 'Access-Control-Allow-Origin' header has a value 'http://localhost:8081' that + // is not equal to the supplied origin. Origin 'null' is therefore not allowed + // access. + // message_failed_auth(ie_password); append_notebook(notebook_access_url); }else{ message_failed_connection(); From d1d4cb9f4f78da0f791a13268c74c2254fd45832 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 6 Nov 2014 09:51:17 -0600 Subject: [PATCH 038/120] Body was inheriting CSS from galaxy and havinga margin --- templates/rstudio.mako | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 59c75b920c3..fbb2d8d068b 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -49,7 +49,7 @@ print docker_cmd ${ ie.load_default_js() } - + - - -
+
From 0e5da3fc2753f5562f69ff3e0af73b4ba47fc0f8 Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Thu, 6 Nov 2014 10:51:00 -0600 Subject: [PATCH 039/120] Automatically restore .RData files from history --- config/rstudio.xml | 1 + templates/rstudio.mako | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/config/rstudio.xml b/config/rstudio.xml index 7a9f7f333f7..ad42cd92f01 100644 --- a/config/rstudio.xml +++ b/config/rstudio.xml @@ -6,6 +6,7 @@ HistoryDatasetAssociation tabular.Tabular data.Text + binary.RData dataset_id diff --git a/templates/rstudio.mako b/templates/rstudio.mako index fbb2d8d068b..6ba37e12e98 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -37,6 +37,10 @@ notebook_pubkey_url = ie_request.url_template('http://localhost/rstudio/${PORT}/ notebook_access_url = ie_request.url_template('http://localhost/rstudio/${PORT}/') notebook_login_url = ie_request.url_template('http://localhost/rstudio/${PORT}/auth-do-sign-in') +# Did the user give us an RData file? +if hda.datatype.__class__.__name__ == "RData": + shutil.copy( hda.file_name, os.path.join(temp_dir, '.RData') ) + import re docker_cmd = ie_request.docker_cmd(temp_dir) # Hack out the -u galaxy_id statement because the RStudio IE isn't ready to run From 703ed2d2bbb15514843a300aa65145e6aa1964fa Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Sun, 16 Nov 2014 15:31:53 -0600 Subject: [PATCH 040/120] Pass CORS_ORIGIN to NB, make sure URLs are correct --- templates/rstudio.mako | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 6ba37e12e98..0713f68b3d9 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -25,7 +25,8 @@ temp_dir = os.path.abspath( tempfile.mkdtemp() ) PASSWORD = ie_request.generate_password(length=36) USERNAME = "galaxy" # Write out conf file...needs work -ie_request.write_conf_file(temp_dir, {'notebook_username': 'galaxy', 'notebook_password': PASSWORD}) +ie_request.write_conf_file(temp_dir, {'notebook_username': 'galaxy', 'notebook_password': PASSWORD, + 'cors_origin': ie_request.attr.proxy_url}) # This is overwritten at the end of the above function call, so we need to re-overwrite it. ie_request.attr.notebook_pw = PASSWORD @@ -33,9 +34,9 @@ ie_request.attr.notebook_pw = PASSWORD # Access URLs for the notebook from within galaxy. # TODO: Make this work without pointing directly to IE. Currently does not work # through proxy. -notebook_pubkey_url = ie_request.url_template('http://localhost/rstudio/${PORT}/auth-public-key') -notebook_access_url = ie_request.url_template('http://localhost/rstudio/${PORT}/') -notebook_login_url = ie_request.url_template('http://localhost/rstudio/${PORT}/auth-do-sign-in') +notebook_pubkey_url = ie_request.url_template('${PROXY_URL}/rstudio/${PORT}/auth-public-key') +notebook_access_url = ie_request.url_template('${PROXY_URL}/rstudio/${PORT}/') +notebook_login_url = ie_request.url_template('${PROXY_URL}/rstudio/${PORT}/auth-do-sign-in') # Did the user give us an RData file? if hda.datatype.__class__.__name__ == "RData": From 77b5df720d5262bec6f171eed5add750466139fd Mon Sep 17 00:00:00 2001 From: Eric Rasche Date: Mon, 17 Nov 2014 12:22:38 -0600 Subject: [PATCH 041/120] Set to port 80 for nginx --- templates/rstudio.mako | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/templates/rstudio.mako b/templates/rstudio.mako index 0713f68b3d9..76b84dd1fe3 100644 --- a/templates/rstudio.mako +++ b/templates/rstudio.mako @@ -8,10 +8,7 @@ import subprocess # Sets ID and sets up a lot of other variables ie_request.load_deploy_config() -# In order to keep 302 redirects happy, nginx needs to be aware there's a proxy -# in front of it, which may be using a different port. As a result, we have to -# start nginx on whichever port it is we plan to use. -ie_request.attr.docker_port = ie_request.attr.PORT +ie_request.attr.docker_port = 80 # Create tempdir in galaxy temp_dir = os.path.abspath( tempfile.mkdtemp() ) # We have to do some special things with the password here. Currently there's From 5c8ad19ddba639ea4bc09b67aaa3dde9c0fd2bae Mon Sep 17 00:00:00 2001 From: guerler Date: Tue, 14 Apr 2015 02:27:38 -0400 Subject: [PATCH 042/120] New library data selector for tool form --- .../galaxy/scripts/mvc/form/form-section.js | 5 + client/galaxy/scripts/mvc/form/form-view.js | 3 + client/galaxy/scripts/mvc/ui/ui-list.js | 140 ++++++++++++++++++ client/galaxy/scripts/mvc/ui/ui-misc.js | 3 +- client/galaxy/scripts/mvc/ui/ui-portlet.js | 7 +- .../scripts/mvc/ui/ui-select-library.js | 33 ++--- lib/galaxy/tools/__init__.py | 6 + lib/galaxy/tools/parameters/basic.py | 83 ++++++++--- static/maps/mvc/form/form-section.js.map | 2 +- static/maps/mvc/form/form-view.js.map | 2 +- static/maps/mvc/ui/ui-misc.js.map | 2 +- static/maps/mvc/ui/ui-portlet.js.map | 2 +- static/maps/mvc/ui/ui-select-library.js.map | 2 +- static/scripts/mvc/form/form-section.js | 2 +- static/scripts/mvc/form/form-view.js | 2 +- static/scripts/mvc/ui/ui-list.js | 2 + static/scripts/mvc/ui/ui-misc.js | 2 +- static/scripts/mvc/ui/ui-portlet.js | 2 +- static/scripts/mvc/ui/ui-select-library.js | 2 +- static/style/blue/base.css | 5 + static/style/src/less/ui.less | 27 ++++ 21 files changed, 281 insertions(+), 53 deletions(-) create mode 100644 client/galaxy/scripts/mvc/ui/ui-list.js create mode 100644 static/scripts/mvc/ui/ui-list.js diff --git a/client/galaxy/scripts/mvc/form/form-section.js b/client/galaxy/scripts/mvc/form/form-section.js index 3c1c2092451..298f6e94aee 100644 --- a/client/galaxy/scripts/mvc/form/form-section.js +++ b/client/galaxy/scripts/mvc/form/form-section.js @@ -285,6 +285,11 @@ define(['utils/utils', } }); + // add expansion event handler + this.app.on('expand', function(input_id) { + (portlet.$el.find('#' + input_id).length > 0) && !visible && portlet.$header.trigger('click'); + }); + // show sub section if requested if (input_def.expanded) { portlet.$header.trigger('click'); diff --git a/client/galaxy/scripts/mvc/form/form-view.js b/client/galaxy/scripts/mvc/form/form-view.js index 312d9e8c2b7..d74bff73e4f 100644 --- a/client/galaxy/scripts/mvc/form/form-view.js +++ b/client/galaxy/scripts/mvc/form/form-view.js @@ -111,6 +111,9 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', // mark error input_element.error(message || 'Please verify this parameter.'); + // trigger expand event for parent containers + this.trigger('expand', input_id); + // scroll to first input element if (!silent) { $('html, body').animate({ diff --git a/client/galaxy/scripts/mvc/ui/ui-list.js b/client/galaxy/scripts/mvc/ui/ui-list.js new file mode 100644 index 00000000000..d3f045312d9 --- /dev/null +++ b/client/galaxy/scripts/mvc/ui/ui-list.js @@ -0,0 +1,140 @@ +// dependencies +define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc'], function(Utils, Portlet, Ui) { + +// ui list element +var View = Backbone.View.extend({ + // create portlet to keep track of selected list elements + initialize : function(options) { + // link this + var self = this; + + // initialize options + this.options = options; + this.name = options.name || 'element'; + + // create message handler + this.message = new Ui.Message({ cls: 'ui-margin-top' }); + + // create portlet + this.portlet = new Portlet.View({ cls: 'ui-portlet-section' }); + + // create select field containing the options which can be inserted into the list + this.select = new Ui.Select.View(); + + // create insert new list element button + this.button = new Ui.ButtonIcon({ + icon : 'fa fa-sign-in', + floating : 'left', + tooltip : 'Insert new ' + this.name, + onclick : function() { + self.add({ + id : self.select.value(), + name : self.select.text() + }); + } + }); + + // build main element + this.setElement(this._template(options)); + this.$('.ui-list-message').append(this.message.$el); + this.$('.ui-list-portlet').append(this.portlet.$el); + this.$('.ui-list-button').append(this.button.$el); + this.$('.ui-list-select').append(this.select.$el); + }, + + /** Return/Set currently selected list elements */ + value: function(val) { + // set new value + if (val !== undefined) { + this.portlet.empty(); + if ($.isArray(val)) { + for (var i in val) { + this.add({ + id : val[i].id, + name : val[i].name + }); + } + } + this._refresh(); + } + // get current value + var lst = []; + this.$('.ui-list-id').each(function() { + lst.push({ + id : $(this).prop('id'), + name : $(this).find('.ui-list-name').html() + }); + }); + return lst; + }, + + /** Add row */ + add: function(options) { + var self = this; + if (this.$('#' + options.id).length === 0) { + if (Utils.validate(options.id)) { + var $el = $(this._templateRow({ + id : options.id, + name : options.name + })); + $el.on('click', function() { + $el.remove(); + self._refresh(); + }); + $el.on('mouseover', function() { + $el.addClass('portlet-highlight'); + }); + $el.on('mouseout', function() { + $el.removeClass('portlet-highlight'); + }); + this.portlet.append($el); + this._refresh(); + } else { + this.message.update({ message: 'Please select a valid ' + this.name + '.', status: 'danger' }); + } + } else { + this.message.update({ message: 'This ' + this.name + ' is already in the list.' }); + } + }, + + /** Update available options */ + update: function(options) { + this.select.update(options); + }, + + /** Refresh view */ + _refresh: function() { + if (this.$('.ui-list-id').length > 0) { + this.$('.ui-list-portlet').show(); + } else { + this.$('.ui-list-portlet').hide(); + } + this.options.onchange && this.options.onchange(); + }, + + /** Main Template */ + _template: function(options) { + return '
' + + '
' + + '' + + '' + + '
' + + '
' + + '
' + + '
'; + }, + + /** Row Template */ + _templateRow: function(options) { + return '
' + + '' + + '' + options.name + '' + + '
'; + } +}); + +return { + View: View +} + +}); diff --git a/client/galaxy/scripts/mvc/ui/ui-misc.js b/client/galaxy/scripts/mvc/ui/ui-misc.js index 920bdb87b1a..69eaa7e8a34 100644 --- a/client/galaxy/scripts/mvc/ui/ui-misc.js +++ b/client/galaxy/scripts/mvc/ui/ui-misc.js @@ -277,6 +277,7 @@ var Message = Backbone.View.extend({ optionsDefault: { message : null, status : 'info', + cls : '', persistent : false }, @@ -286,7 +287,7 @@ var Message = Backbone.View.extend({ this.options = Utils.merge(options, this.optionsDefault); // create new element - this.setElement('
'); + this.setElement('
'); // show initial message if (this.options.message) { diff --git a/client/galaxy/scripts/mvc/ui/ui-portlet.js b/client/galaxy/scripts/mvc/ui/ui-portlet.js index d427f7dc1bb..e2c3ac311fe 100644 --- a/client/galaxy/scripts/mvc/ui/ui-portlet.js +++ b/client/galaxy/scripts/mvc/ui/ui-portlet.js @@ -88,7 +88,12 @@ var View = Backbone.View.extend({ append: function($el) { this.$content.append($el); }, - + + // remove all content + empty: function() { + this.$content.empty(); + }, + // content content: function() { return this.$content; diff --git a/client/galaxy/scripts/mvc/ui/ui-select-library.js b/client/galaxy/scripts/mvc/ui/ui-select-library.js index aaa105def18..f41aa9cc26a 100644 --- a/client/galaxy/scripts/mvc/ui/ui-select-library.js +++ b/client/galaxy/scripts/mvc/ui/ui-select-library.js @@ -1,6 +1,6 @@ // dependencies -define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-tabs', 'mvc/tools/tools-template'], - function(Utils, Ui, Tabs, ToolTemplate) { +define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-table', 'mvc/ui/ui-list'], + function(Utils, Ui, Table, List) { // collection of libraries var Libraries = Backbone.Collection.extend({ @@ -13,7 +13,7 @@ var LibraryDatasets = Backbone.Collection.extend({ var self = this; this.config = new Backbone.Model({ library_id: null }); this.config.on('change', function() { - self.fetch({reset: true}); + self.fetch({ reset: true }); }); }, url: function() { @@ -36,17 +36,16 @@ var View = Backbone.View.extend({ this.options = options; // select field for the library + // TODO: Remove this once the library API supports searching for library datasets this.library_select = new Ui.Select.View({ - optional : options.optional, onchange : function(value) { self.datasets.config.set('library_id', value); } }); - // select field for the library dataset - this.dataset_select = new Ui.Select.View({ - optional : options.optional, - multiple : options.multiple, + // create ui-list view to keep track of selected data libraries + this.dataset_list = new List.View({ + name : 'dataset', onchange : function() { self.trigger('change'); } @@ -62,7 +61,6 @@ var View = Backbone.View.extend({ }); }); self.library_select.update(data); - self.trigger('change'); }); // add reset handler for fetched library datasets @@ -74,13 +72,12 @@ var View = Backbone.View.extend({ if (model.get('type') === 'file') { data.push({ value : model.id, - label : library_current + model.get('name') + label : model.get('name') }); } }); } - self.dataset_select.update(data); - self.trigger('change'); + self.dataset_list.update(data); }); // add change event. fires on trigger @@ -88,10 +85,10 @@ var View = Backbone.View.extend({ options.onchange && options.onchange(self.value()); }); - // create element + // create elements this.setElement(this._template()); this.$('.library-select').append(this.library_select.$el); - this.$('.dataset-select').append(this.dataset_select.$el); + this.$el.append(this.dataset_list.$el); // initial fetch of libraries this.libraries.fetch({ @@ -106,8 +103,8 @@ var View = Backbone.View.extend({ }, /** Return/Set currently selected library datasets */ - value: function(new_val) { - return this.dataset_select.value(); + value: function(val) { + return this.dataset_list.value(val); }, /** Template */ @@ -117,10 +114,6 @@ var View = Backbone.View.extend({ 'Select Library' + '' + '
' + - '
' + - 'Select Dataset' + - '' + - '
' + '
'; } }); diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py index 473910129ed..c934a453246 100755 --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -2330,6 +2330,12 @@ class Tool( object, Dictifiable ): 'id' : trans.security.encode_id(v.id), 'src' : 'hdca' } + elif isinstance(v, trans.app.model.LibraryDatasetDatasetAssociation): + return { + 'id' : trans.security.encode_id(v.id), + 'name': v.name, + 'src' : 'ldda' + } elif isinstance(v, bool): if v is True: return 'true' diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 31ee1b4152f..cd936357481 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -2379,8 +2379,8 @@ class LibraryDatasetToolParameter( ToolParameter ): Parameter that lets users select a LDDA from a modal window, then use it within the wrapper. """ - def __init__( self, tool, elem ): - ToolParameter.__init__( self, tool, elem ) + def __init__( self, tool, input_source, context=None ): + ToolParameter.__init__( self, tool, input_source ) def get_html_field( self, trans=None, value=None, other_values={} ): return form_builder.LibraryField( self.name, value=value, trans=trans ) @@ -2389,28 +2389,69 @@ class LibraryDatasetToolParameter( ToolParameter ): return None def from_html( self, value, trans, other_values={} ): - if not value: - return None - elif isinstance( value, list ): - return value - else: - decoded_lst = [] - for encoded_id in value.split("||"): - decoded_lst.append( trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( encoded_id ) ) ) - return decoded_lst + return self.to_python( value, trans.app, other_values=other_values, validate=True ) + # converts values to json representation: + # { id: LibraryDatasetDatasetAssociation.id, name: LibraryDatasetDatasetAssociation.name, src: 'lda' } def to_string( self, value, app ): - if not value: - return value - return [ldda.id for ldda in value] + if not isinstance( value, list ): + value = [value] + lst = [] + for item in value: + encoded_id = encoded_name = None + if isinstance (item, app.model.LibraryDatasetDatasetAssociation): + encoded_id = app.security.encode_id( item.id ) + encoded_name = item.name + elif isinstance (item, dict): + encoded_id = item.get('id') + encoded_name = item.get('name') + else: + lst = [] + break + if encoded_id is not None: + lst.append( { + 'id' : encoded_id, + 'name' : encoded_name, + 'src' : 'ldda' + } ) + if len( lst ) == 0: + return None + else: + return lst - def to_python( self, value, app ): - if not value: - return value - lddas = [] - for ldda_id in value: - lddas.append( app.model.context.query( app.model.LibraryDatasetDatasetAssociation ).get( ldda_id ) ) - return lddas + # converts values into python representation: + # LibraryDatasetDatasetAssociation + # valid input values (incl. arrays of mixed sets) are: + # 1. LibraryDatasetDatasetAssociation + # 2. LibraryDatasetDatasetAssociation.id + # 3. { id: LibraryDatasetDatasetAssociation.id, ... } + def to_python( self, value, app, other_values={}, validate=False ): + if not isinstance( value, list ): + value = [value] + lst = [] + for item in value: + if isinstance (item, app.model.LibraryDatasetDatasetAssociation): + lst.append(item) + else: + encoded_id = None + if isinstance (item, dict): + encoded_id = item.get('id') + elif isinstance (item, basestring): + encoded_id = item + else: + lst = [] + break + lda = app.model.context.query( app.model.LibraryDatasetDatasetAssociation ).get( app.security.decode_id( encoded_id ) ) + if lda is not None: + lst.append( lda ) + elif validate: + raise ValueError( "One of the selected library datasets is invalid or not available anymore." ) + if len( lst ) == 0: + if not self.optional and validate: + raise ValueError( "Please select a valid library dataset." ) + return None + else: + return lst # class RawToolParameter( ToolParameter ): # """ diff --git a/static/maps/mvc/form/form-section.js.map b/static/maps/mvc/form/form-section.js.map index d1aaf3aeb6e..fe8973ee02d 100644 --- a/static/maps/mvc/form/form-section.js.map +++ b/static/maps/mvc/form/form-section.js.map @@ -1 +1 @@ -{"version":3,"file":"form-section.js","sources":["../../../src/mvc/form/form-section.js"],"names":["define","Utils","Table","Ui","Portlet","Repeat","InputElement","Parameters","View","Backbone","extend","initialize","app","options","this","inputs","cls","cls_tr","table","parameters","setElement","$el","render","delAll","i","add","input","input_def","jQuery","id","uid","input_list","type","_addConditional","_addRepeat","_addSection","_addRow","self","test_param","field","onchange","value","selectedCase","data","matchCase","cases","case_def","section_id","section_row","get","nonhidden","j","hidden","fadeIn","hide","trigger","sub_section_id","sub_section","addClass","append","create","block_index","repeat","ondel","del","title","title_new","min","max","onnew","n_min","n_cache","_","size","cache","Math","input_element","label","help","button_visible","ButtonIcon","icon","tooltip","portlet","operations","$","html","visible","$content","$header","css","on","setIcon","expanded","field_list","default_value","optional","element_list"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"form-section.js","sources":["../../../src/mvc/form/form-section.js"],"names":["define","Utils","Table","Ui","Portlet","Repeat","InputElement","Parameters","View","Backbone","extend","initialize","app","options","this","inputs","cls","cls_tr","table","parameters","setElement","$el","render","delAll","i","add","input","input_def","jQuery","id","uid","input_list","type","_addConditional","_addRepeat","_addSection","_addRow","self","test_param","field","onchange","value","selectedCase","data","matchCase","cases","case_def","section_id","section_row","get","nonhidden","j","hidden","fadeIn","hide","trigger","sub_section_id","sub_section","addClass","append","create","block_index","repeat","ondel","del","title","title_new","min","max","onnew","n_min","n_cache","_","size","cache","Math","input_element","label","help","button_visible","ButtonIcon","icon","tooltip","portlet","operations","$","html","visible","$content","$header","css","on","setIcon","input_id","find","length","expanded","field_list","default_value","optional","element_list"],"mappings":"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"} \ No newline at end of file diff --git a/static/maps/mvc/form/form-view.js.map b/static/maps/mvc/form/form-view.js.map index 0945822af38..1da92f4bfbe 100644 --- a/static/maps/mvc/form/form-view.js.map +++ b/static/maps/mvc/form/form-view.js.map @@ -1 +1 @@ -{"version":3,"file":"form-view.js","sources":["../../../src/mvc/form/form-view.js"],"names":["define","Utils","Portlet","Ui","FormSection","FormData","Backbone","View","extend","initialize","options","this","optionsDefault","is_workflow","narrow","initial_errors","cls","merge","console","debug","galaxy","parent","Galaxy","modal","Modal","setElement","_build","update","new_model","self","data","matchModel","input_id","node","input","input_list","_","isEqual","field","field_list","new_options","indexOf","type","i","opt","length","push","label","value","trigger","wait","active","is_dynamic","unwait","reciept","$el","empty","append","highlight","message","silent","input_element","element_list","error","$","animate","scrollTop","offset","top","errors","error_messages","matchResponse","off","_renderForm","create","current_check","checksum","on","new_check","onchange","reset","Message","section","inputs","incompatible","hide","show","portlet","icon","title","operations","buttons","addClass","persistent","status"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"form-view.js","sources":["../../../src/mvc/form/form-view.js"],"names":["define","Utils","Portlet","Ui","FormSection","FormData","Backbone","View","extend","initialize","options","this","optionsDefault","is_workflow","narrow","initial_errors","cls","merge","console","debug","galaxy","parent","Galaxy","modal","Modal","setElement","_build","update","new_model","self","data","matchModel","input_id","node","input","input_list","_","isEqual","field","field_list","new_options","indexOf","type","i","opt","length","push","label","value","trigger","wait","active","is_dynamic","unwait","reciept","$el","empty","append","highlight","message","silent","input_element","element_list","error","$","animate","scrollTop","offset","top","errors","error_messages","matchResponse","off","_renderForm","create","current_check","checksum","on","new_check","onchange","reset","Message","section","inputs","incompatible","hide","show","portlet","icon","title","operations","buttons","addClass","persistent","status"],"mappings":"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"} \ No newline at end of file diff --git a/static/maps/mvc/ui/ui-misc.js.map b/static/maps/mvc/ui/ui-misc.js.map index 959d74386da..5bb060fa8e2 100644 --- a/static/maps/mvc/ui/ui-misc.js.map +++ b/static/maps/mvc/ui/ui-misc.js.map @@ -1 +1 @@ -{"version":3,"file":"ui-misc.js","sources":["../../../src/mvc/ui/ui-misc.js"],"names":["define","Utils","Select","Slider","Options","Drilldown","ButtonMenu","ButtonCheck","Modal","Image","Backbone","View","extend","optionsDefault","url","cls","initialize","options","this","merge","setElement","_template","Label","title","new_title","$el","html","value","Icon","floating","icon","tooltip","placement","$","el","Button","id","uid","on","hide","onclick","wait","removeClass","addClass","prop","unwait","str","ButtonIcon","$button","find","self","disabled","disable","enable","setIcon","icon_cls","width","Anchor","Message","message","status","persistent","update","append","fadeIn","timeout","window","clearTimeout","setTimeout","is","fadeOut","Searchbox","searchword","search_field","val","Input","type","placeholder","visible","area","undefined","onchange","new_val","Hidden","tmpl","info","RadioButton","Checkbox","Radio"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"ui-misc.js","sources":["../../../src/mvc/ui/ui-misc.js"],"names":["define","Utils","Select","Slider","Options","Drilldown","ButtonMenu","ButtonCheck","Modal","Image","Backbone","View","extend","optionsDefault","url","cls","initialize","options","this","merge","setElement","_template","Label","title","new_title","$el","html","value","Icon","floating","icon","tooltip","placement","$","el","Button","id","uid","on","hide","onclick","wait","removeClass","addClass","prop","unwait","str","ButtonIcon","$button","find","self","disabled","disable","enable","setIcon","icon_cls","width","Anchor","Message","message","status","persistent","update","append","fadeIn","timeout","window","clearTimeout","setTimeout","is","fadeOut","Searchbox","searchword","search_field","val","Input","type","placeholder","visible","area","undefined","onchange","new_val","Hidden","tmpl","info","RadioButton","Checkbox","Radio"],"mappings":"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"} \ No newline at end of file diff --git a/static/maps/mvc/ui/ui-portlet.js.map b/static/maps/mvc/ui/ui-portlet.js.map index 3aac2c81c61..a305cd5003e 100644 --- a/static/maps/mvc/ui/ui-portlet.js.map +++ b/static/maps/mvc/ui/ui-portlet.js.map @@ -1 +1 @@ -{"version":3,"file":"ui-portlet.js","sources":["../../../src/mvc/ui/ui-portlet.js"],"names":["define","Utils","View","Backbone","extend","visible","optionsDefault","id","uid","title","icon","buttons","body","scrollable","nopadding","operations","placement","cls","operations_flt","$title","$content","$buttons","$operations","$header","initialize","options","this","merge","setElement","_template","$el","find","$portlet_content","css","$","el","self","each","name","item","prop","append","remove","content","show","fadeIn","hide","fadeOut","enableButton","disableButton","hideOperation","showOperation","setOperation","callback","off","on","new_title","html","disable","enable","tmpl"],"mappings":"AACAA,QAAQ,eAAgB,SAASC,GAGjC,GAAIC,GAAOC,SAASD,KAAKE,QAErBC,SAAS,EAGTC,gBACIC,GAAkBN,EAAMO,MACxBC,MAAkB,GAClBC,KAAkB,GAClBC,QAAkB,KAClBC,KAAkB,KAClBC,YAAkB,EAClBC,WAAkB,EAClBC,WAAkB,KAClBC,UAAkB,SAClBC,IAAkB,aAClBC,eAAkB,SAItBC,OAAS,KACTC,SAAW,KACXC,SAAW,KACXC,YAAc,KACdC,QAAU,KAGVC,WAAa,SAASC,GAElBC,KAAKD,QAAUxB,EAAM0B,MAAMF,EAASC,KAAKpB,gBAGzCoB,KAAKE,WAAWF,KAAKG,UAAUH,KAAKD,UAGpCC,KAAKN,SAAWM,KAAKI,IAAIC,KAAK,YAG9BL,KAAKP,OAASO,KAAKI,IAAIC,KAAK,uBAG5BL,KAAKH,QAAUG,KAAKI,IAAIC,KAAK,kBAG7B,IAAIC,GAAmBN,KAAKI,IAAIC,KAAK,mBAUrC,IAPIL,KAAKD,QAAQX,YACbkB,EAAiBC,IAAI,UAAW,OAChCP,KAAKN,SAASa,IAAI,UAAW,QAIjCP,KAAKL,SAAWa,EAAER,KAAKS,IAAIJ,KAAK,YAC5BL,KAAKD,QAAQd,QAAS,CAEtB,GAAIyB,GAAOV,IACXQ,GAAEG,KAAKX,KAAKD,QAAQd,QAAS,SAAS2B,EAAMC,GACxCA,EAAKT,IAAIU,KAAK,KAAMF,GACpBF,EAAKf,SAASoB,OAAOF,EAAKT,WAG9BJ,MAAKL,SAASqB,QAKlB,IADAhB,KAAKJ,YAAcY,EAAER,KAAKS,IAAIJ,KAAK,uBAC/BL,KAAKD,QAAQV,WAAY,CAEzB,GAAIqB,GAAOV,IACXQ,GAAEG,KAAKX,KAAKD,QAAQV,WAAY,SAASuB,EAAMC,GAC3CA,EAAKT,IAAIU,KAAK,KAAMF,GACpBF,EAAKd,YAAYmB,OAAOF,EAAKT,OAKlCJ,KAAKD,QAAQb,MACZc,KAAKe,OAAOf,KAAKD,QAAQb,OAKjC6B,OAAQ,SAASX,GACbJ,KAAKN,SAASqB,OAAOX,IAIzBa,QAAS,WACL,MAAOjB,MAAKN,UAIhBwB,KAAM,WAEFlB,KAAKI,IAAIe,OAAO,QAGhBnB,KAAKrB,SAAU,GAInByC,KAAM,WAEFpB,KAAKI,IAAIiB,QAAQ,QAGjBrB,KAAKrB,SAAU,GAInB2C,aAAc,SAASzC,GACnBmB,KAAKL,SAASU,KAAK,IAAMxB,GAAIiC,KAAK,YAAY,IAIlDS,cAAe,SAAS1C,GACpBmB,KAAKL,SAASU,KAAK,IAAMxB,GAAIiC,KAAK,YAAY,IAIlDU,cAAe,SAAS3C,GACpBmB,KAAKJ,YAAYS,KAAK,IAAMxB,GAAIuC,QAIpCK,cAAe,SAAS5C,GACpBmB,KAAKJ,YAAYS,KAAK,IAAMxB,GAAIqC,QAIpCQ,aAAc,SAAS7C,EAAI8C,GACvB,GAAIvB,GAAMJ,KAAKJ,YAAYS,KAAK,IAAMxB,EACtCuB,GAAIwB,IAAI,SACRxB,EAAIyB,GAAG,QAASF,IAIpB5C,MAAO,SAAS+C,GACZ,GAAI1B,GAAMJ,KAAKP,MAIf,OAHIqC,IACA1B,EAAI2B,KAAKD,GAEN1B,EAAI2B,QAIfC,QAAS,WACLhC,KAAKQ,EAAE,qBAAqBU,QAIhCe,OAAQ,WACJjC,KAAKQ,EAAE,qBAAqBY,QAIhCjB,UAAW,SAASJ,GAChB,GAAImC,GAAQ,YAAcnC,EAAQlB,GAAK,YAAckB,EAAQR,IAAM,IA6BnE,OA3BIQ,GAAQhB,QACRmD,GAAY,6EACuDnC,EAAQP,eAAiB,uCAGxFO,EAAQf,OACRkD,GAAgB,qBAAuBnC,EAAQf,KAAO,gBAE1DkD,GAAoB,oCAAsCnC,EAAQhB,MAAQ,uBAI9EmD,GAAgB,gCAES,OAArBnC,EAAQT,YACR4C,GAAgB,+BAGpBA,GAAoB,8BAEK,UAArBnC,EAAQT,YACR4C,GAAgB,+BAGpBA,GAAgB,gDAOxB,QACI1D,KAAOA"} \ No newline at end of file +{"version":3,"file":"ui-portlet.js","sources":["../../../src/mvc/ui/ui-portlet.js"],"names":["define","Utils","View","Backbone","extend","visible","optionsDefault","id","uid","title","icon","buttons","body","scrollable","nopadding","operations","placement","cls","operations_flt","$title","$content","$buttons","$operations","$header","initialize","options","this","merge","setElement","_template","$el","find","$portlet_content","css","$","el","self","each","name","item","prop","append","remove","empty","content","show","fadeIn","hide","fadeOut","enableButton","disableButton","hideOperation","showOperation","setOperation","callback","off","on","new_title","html","disable","enable","tmpl"],"mappings":"AACAA,QAAQ,eAAgB,SAASC,GAGjC,GAAIC,GAAOC,SAASD,KAAKE,QAErBC,SAAS,EAGTC,gBACIC,GAAkBN,EAAMO,MACxBC,MAAkB,GAClBC,KAAkB,GAClBC,QAAkB,KAClBC,KAAkB,KAClBC,YAAkB,EAClBC,WAAkB,EAClBC,WAAkB,KAClBC,UAAkB,SAClBC,IAAkB,aAClBC,eAAkB,SAItBC,OAAS,KACTC,SAAW,KACXC,SAAW,KACXC,YAAc,KACdC,QAAU,KAGVC,WAAa,SAASC,GAElBC,KAAKD,QAAUxB,EAAM0B,MAAMF,EAASC,KAAKpB,gBAGzCoB,KAAKE,WAAWF,KAAKG,UAAUH,KAAKD,UAGpCC,KAAKN,SAAWM,KAAKI,IAAIC,KAAK,YAG9BL,KAAKP,OAASO,KAAKI,IAAIC,KAAK,uBAG5BL,KAAKH,QAAUG,KAAKI,IAAIC,KAAK,kBAG7B,IAAIC,GAAmBN,KAAKI,IAAIC,KAAK,mBAUrC,IAPIL,KAAKD,QAAQX,YACbkB,EAAiBC,IAAI,UAAW,OAChCP,KAAKN,SAASa,IAAI,UAAW,QAIjCP,KAAKL,SAAWa,EAAER,KAAKS,IAAIJ,KAAK,YAC5BL,KAAKD,QAAQd,QAAS,CAEtB,GAAIyB,GAAOV,IACXQ,GAAEG,KAAKX,KAAKD,QAAQd,QAAS,SAAS2B,EAAMC,GACxCA,EAAKT,IAAIU,KAAK,KAAMF,GACpBF,EAAKf,SAASoB,OAAOF,EAAKT,WAG9BJ,MAAKL,SAASqB,QAKlB,IADAhB,KAAKJ,YAAcY,EAAER,KAAKS,IAAIJ,KAAK,uBAC/BL,KAAKD,QAAQV,WAAY,CAEzB,GAAIqB,GAAOV,IACXQ,GAAEG,KAAKX,KAAKD,QAAQV,WAAY,SAASuB,EAAMC,GAC3CA,EAAKT,IAAIU,KAAK,KAAMF,GACpBF,EAAKd,YAAYmB,OAAOF,EAAKT,OAKlCJ,KAAKD,QAAQb,MACZc,KAAKe,OAAOf,KAAKD,QAAQb,OAKjC6B,OAAQ,SAASX,GACbJ,KAAKN,SAASqB,OAAOX,IAIzBa,MAAO,WACHjB,KAAKN,SAASuB,SAIlBC,QAAS,WACL,MAAOlB,MAAKN,UAIhByB,KAAM,WAEFnB,KAAKI,IAAIgB,OAAO,QAGhBpB,KAAKrB,SAAU,GAInB0C,KAAM,WAEFrB,KAAKI,IAAIkB,QAAQ,QAGjBtB,KAAKrB,SAAU,GAInB4C,aAAc,SAAS1C,GACnBmB,KAAKL,SAASU,KAAK,IAAMxB,GAAIiC,KAAK,YAAY,IAIlDU,cAAe,SAAS3C,GACpBmB,KAAKL,SAASU,KAAK,IAAMxB,GAAIiC,KAAK,YAAY,IAIlDW,cAAe,SAAS5C,GACpBmB,KAAKJ,YAAYS,KAAK,IAAMxB,GAAIwC,QAIpCK,cAAe,SAAS7C,GACpBmB,KAAKJ,YAAYS,KAAK,IAAMxB,GAAIsC,QAIpCQ,aAAc,SAAS9C,EAAI+C,GACvB,GAAIxB,GAAMJ,KAAKJ,YAAYS,KAAK,IAAMxB,EACtCuB,GAAIyB,IAAI,SACRzB,EAAI0B,GAAG,QAASF,IAIpB7C,MAAO,SAASgD,GACZ,GAAI3B,GAAMJ,KAAKP,MAIf,OAHIsC,IACA3B,EAAI4B,KAAKD,GAEN3B,EAAI4B,QAIfC,QAAS,WACLjC,KAAKQ,EAAE,qBAAqBW,QAIhCe,OAAQ,WACJlC,KAAKQ,EAAE,qBAAqBa,QAIhClB,UAAW,SAASJ,GAChB,GAAIoC,GAAQ,YAAcpC,EAAQlB,GAAK,YAAckB,EAAQR,IAAM,IA6BnE,OA3BIQ,GAAQhB,QACRoD,GAAY,6EACuDpC,EAAQP,eAAiB,uCAGxFO,EAAQf,OACRmD,GAAgB,qBAAuBpC,EAAQf,KAAO,gBAE1DmD,GAAoB,oCAAsCpC,EAAQhB,MAAQ,uBAI9EoD,GAAgB,gCAES,OAArBpC,EAAQT,YACR6C,GAAgB,+BAGpBA,GAAoB,8BAEK,UAArBpC,EAAQT,YACR6C,GAAgB,+BAGpBA,GAAgB,gDAOxB,QACI3D,KAAOA"} \ No newline at end of file diff --git a/static/maps/mvc/ui/ui-select-library.js.map b/static/maps/mvc/ui/ui-select-library.js.map index d1b53742e32..955d3fe6a4a 100644 --- a/static/maps/mvc/ui/ui-select-library.js.map +++ b/static/maps/mvc/ui/ui-select-library.js.map @@ -1 +1 @@ -{"version":3,"file":"ui-select-library.js","sources":["../../../src/mvc/ui/ui-select-library.js"],"names":["define","Utils","Ui","Libraries","Backbone","Collection","extend","url","galaxy_config","root","LibraryDatasets","initialize","self","this","config","Model","library_id","on","fetch","reset","get","View","options","libraries","datasets","library_select","Select","optional","onchange","value","set","dataset_select","multiple","trigger","data","each","model","push","id","label","update","library_current","text","setElement","_template","$","append","$el","success","undefined"],"mappings":"AACAA,QAAQ,cAAe,iBAAkB,iBAAkB,4BACnD,SAASC,EAAOC,GAGxB,GAAIC,GAAYC,SAASC,WAAWC,QAChCC,IAAKC,cAAcC,KAAO,kBAI1BC,EAAkBN,SAASC,WAAWC,QACtCK,WAAY,WACR,GAAIC,GAAOC,IACXA,MAAKC,OAAS,GAAIV,UAASW,OAAQC,WAAY,OAC/CH,KAAKC,OAAOG,GAAG,SAAU,WACrBL,EAAKM,OAAOC,OAAO,OAG3BZ,IAAK,WACD,MAAOC,eAAcC,KAAO,iBAAmBI,KAAKC,OAAOM,IAAI,cAAgB,eAKnFC,EAAOjB,SAASiB,KAAKf,QAErBK,WAAa,SAASW,GAElB,GAAIV,GAAOC,IAGXA,MAAKU,UAAa,GAAIpB,GACtBU,KAAKW,SAAa,GAAId,GAGtBG,KAAKS,QAAUA,EAGfT,KAAKY,eAAiB,GAAIvB,GAAGwB,OAAOL,MAChCM,SAAcL,EAAQK,SACtBC,SAAc,SAASC,GACnBjB,EAAKY,SAASV,OAAOgB,IAAI,aAAcD,MAK/ChB,KAAKkB,eAAiB,GAAI7B,GAAGwB,OAAOL,MAChCM,SAAcL,EAAQK,SACtBK,SAAcV,EAAQU,SACtBJ,SAAc,WACVhB,EAAKqB,QAAQ,aAKrBpB,KAAKU,UAAUN,GAAG,QAAS,WACvB,GAAIiB,KACJtB,GAAKW,UAAUY,KAAK,SAASC,GACzBF,EAAKG,MACDR,MAAUO,EAAME,GAChBC,MAAUH,EAAMhB,IAAI,YAG5BR,EAAKa,eAAee,OAAON,GAC3BtB,EAAKqB,QAAQ,YAIjBpB,KAAKW,SAASP,GAAG,QAAS,WACtB,GAAIiB,MACAO,EAAkB7B,EAAKa,eAAeiB,MAClB,QAApBD,GACA7B,EAAKY,SAASW,KAAK,SAASC,GACE,SAAtBA,EAAMhB,IAAI,SACVc,EAAKG,MACDR,MAAUO,EAAME,GAChBC,MAAUE,EAAkBL,EAAMhB,IAAI,YAKtDR,EAAKmB,eAAeS,OAAON,GAC3BtB,EAAKqB,QAAQ,YAIjBpB,KAAKI,GAAG,SAAU,WACdK,EAAQM,UAAYN,EAAQM,SAAShB,EAAKiB,WAI9ChB,KAAK8B,WAAW9B,KAAK+B,aACrB/B,KAAKgC,EAAE,mBAAmBC,OAAOjC,KAAKY,eAAesB,KACrDlC,KAAKgC,EAAE,mBAAmBC,OAAOjC,KAAKkB,eAAegB,KAGrDlC,KAAKU,UAAUL,OACXC,OAAO,EACP6B,QAAS,WACLpC,EAAKa,eAAeQ,QAAQ,UACDgB,SAAvBrC,EAAKU,QAAQO,OACbjB,EAAKiB,MAAMjB,EAAKU,QAAQO,WAOxCA,MAAO,WACH,MAAOhB,MAAKkB,eAAeF,SAI/Be,UAAW,WACP,MAAQ,+QAahB,QACIvB,KAAMA"} \ No newline at end of file +{"version":3,"file":"ui-select-library.js","sources":["../../../src/mvc/ui/ui-select-library.js"],"names":["define","Utils","Ui","Table","List","Libraries","Backbone","Collection","extend","url","galaxy_config","root","LibraryDatasets","initialize","self","this","config","Model","library_id","on","fetch","reset","get","View","options","libraries","datasets","library_select","Select","onchange","value","set","dataset_list","name","trigger","data","each","model","push","id","label","update","library_current","text","setElement","_template","$","append","$el","success","undefined","val"],"mappings":"AACAA,QAAQ,cAAe,iBAAkB,kBAAmB,kBACpD,SAASC,EAAOC,EAAIC,EAAOC,GAGnC,GAAIC,GAAYC,SAASC,WAAWC,QAChCC,IAAKC,cAAcC,KAAO,kBAI1BC,EAAkBN,SAASC,WAAWC,QACtCK,WAAY,WACR,GAAIC,GAAOC,IACXA,MAAKC,OAAS,GAAIV,UAASW,OAAQC,WAAY,OAC/CH,KAAKC,OAAOG,GAAG,SAAU,WACrBL,EAAKM,OAAQC,OAAO,OAG5BZ,IAAK,WACD,MAAOC,eAAcC,KAAO,iBAAmBI,KAAKC,OAAOM,IAAI,cAAgB,eAKnFC,EAAOjB,SAASiB,KAAKf,QAErBK,WAAa,SAASW,GAElB,GAAIV,GAAOC,IAGXA,MAAKU,UAAa,GAAIpB,GACtBU,KAAKW,SAAa,GAAId,GAGtBG,KAAKS,QAAUA,EAIfT,KAAKY,eAAiB,GAAIzB,GAAG0B,OAAOL,MAChCM,SAAc,SAASC,GACnBhB,EAAKY,SAASV,OAAOe,IAAI,aAAcD,MAK/Cf,KAAKiB,aAAe,GAAI5B,GAAKmB,MACzBU,KAAc,UACdJ,SAAc,WACVf,EAAKoB,QAAQ,aAKrBnB,KAAKU,UAAUN,GAAG,QAAS,WACvB,GAAIgB,KACJrB,GAAKW,UAAUW,KAAK,SAASC,GACzBF,EAAKG,MACDR,MAAUO,EAAME,GAChBC,MAAUH,EAAMf,IAAI,YAG5BR,EAAKa,eAAec,OAAON,KAI/BpB,KAAKW,SAASP,GAAG,QAAS,WACtB,GAAIgB,MACAO,EAAkB5B,EAAKa,eAAegB,MAClB,QAApBD,GACA5B,EAAKY,SAASU,KAAK,SAASC,GACE,SAAtBA,EAAMf,IAAI,SACVa,EAAKG,MACDR,MAAUO,EAAME,GAChBC,MAAUH,EAAMf,IAAI,YAKpCR,EAAKkB,aAAaS,OAAON,KAI7BpB,KAAKI,GAAG,SAAU,WACdK,EAAQK,UAAYL,EAAQK,SAASf,EAAKgB,WAI9Cf,KAAK6B,WAAW7B,KAAK8B,aACrB9B,KAAK+B,EAAE,mBAAmBC,OAAOhC,KAAKY,eAAeqB,KACrDjC,KAAKiC,IAAID,OAAOhC,KAAKiB,aAAagB,KAGlCjC,KAAKU,UAAUL,OACXC,OAAO,EACP4B,QAAS,WACLnC,EAAKa,eAAeO,QAAQ,UACDgB,SAAvBpC,EAAKU,QAAQM,OACbhB,EAAKgB,MAAMhB,EAAKU,QAAQM,WAOxCA,MAAO,SAASqB,GACZ,MAAOpC,MAAKiB,aAAaF,MAAMqB,IAInCN,UAAW,WACP,MAAQ,qKAShB,QACItB,KAAMA"} \ No newline at end of file diff --git a/static/scripts/mvc/form/form-section.js b/static/scripts/mvc/form/form-section.js index befc9ba0519..9cbbd80eac1 100644 --- a/static/scripts/mvc/form/form-section.js +++ b/static/scripts/mvc/form/form-section.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-portlet","mvc/form/form-repeat","mvc/form/form-input","mvc/form/form-parameters"],function(a,b,c,d,e,f,g){var h=Backbone.View.extend({initialize:function(a,c){this.app=a,this.inputs=c.inputs,c.cls="ui-table-plain",c.cls_tr="section-row",this.table=new b.View(c),this.parameters=new g(a,c),this.setElement(this.table.$el),this.render()},render:function(){this.table.delAll();for(var a in this.inputs)this.add(this.inputs[a])},add:function(b){var c=jQuery.extend(!0,{},b);c.id=b.id=a.uid(),this.app.input_list[c.id]=c;var d=c.type;switch(d){case"conditional":this._addConditional(c);break;case"repeat":this._addRepeat(c);break;case"section":this._addSection(c);break;default:this._addRow(c)}},_addConditional:function(a){var b=this;a.test_param.id=a.id;var c=this._addRow(a.test_param);c.options.onchange=function(c){var d=b.app.data.matchCase(a,c);for(var e in a.cases){var f=a.cases[e],g=a.id+"-section-"+e,h=b.table.get(g),i=!1;for(var j in f.inputs)if(!f.inputs[j].hidden){i=!0;break}e==d&&i?h.fadeIn("fast"):h.hide()}b.app.trigger("change")};for(var d in a.cases){var e=a.id+"-section-"+d,f=new h(this.app,{inputs:a.cases[d].inputs});f.$el.addClass("ui-table-section"),this.table.add(f.$el),this.table.append(e)}c.trigger("change")},_addRepeat:function(a){function b(b){var e=a.id+"-section-"+d++,f=new h(c.app,{inputs:b});g.add({id:e,$el:f.$el,ondel:function(){g.del(e),c.app.trigger("change")}})}for(var c=this,d=0,g=new e.View({title:a.title,title_new:a.title,min:a.min,max:a.max,onnew:function(){b(a.inputs),c.app.trigger("change")}}),i=a.min,j=_.size(a.cache),k=0;kk?a.cache[k]:a.inputs,b(l)}var m=new f(this.app,{label:a.title,help:a.help,field:g});this.table.add(m.$el),this.table.append(a.id)},_addSection:function(a){var b=this,e=new h(b.app,{inputs:a.inputs}),f=new c.ButtonIcon({icon:"fa-eye-slash",tooltip:"Show/hide section",cls:"ui-button-icon-plain"}),g=new d.View({title:a.title,cls:"ui-portlet-section",operations:{button_visible:f}});g.append(e.$el),g.append($("
").addClass("ui-table-form-info").html(a.help));var i=!1;g.$content.hide(),g.$header.css("cursor","pointer"),g.$header.on("click",function(){i?(i=!1,g.$content.hide(),f.setIcon("fa-eye-slash")):(i=!0,g.$content.fadeIn("fast"),f.setIcon("fa-eye"))}),a.expanded&&g.$header.trigger("click"),this.table.add(g.$el),this.table.append(a.id)},_addRow:function(a){var b=a.id,c=this.parameters.create(a);this.app.field_list[b]=c;var d=new f(this.app,{label:a.label,default_value:a.default_value,optional:a.optional,help:a.help,field:c});return this.app.element_list[b]=d,this.table.add(d.$el),this.table.append(b),a.hidden&&this.table.get(b).hide(),c}});return{View:h}}); +define(["utils/utils","mvc/ui/ui-table","mvc/ui/ui-misc","mvc/ui/ui-portlet","mvc/form/form-repeat","mvc/form/form-input","mvc/form/form-parameters"],function(a,b,c,d,e,f,g){var h=Backbone.View.extend({initialize:function(a,c){this.app=a,this.inputs=c.inputs,c.cls="ui-table-plain",c.cls_tr="section-row",this.table=new b.View(c),this.parameters=new g(a,c),this.setElement(this.table.$el),this.render()},render:function(){this.table.delAll();for(var a in this.inputs)this.add(this.inputs[a])},add:function(b){var c=jQuery.extend(!0,{},b);c.id=b.id=a.uid(),this.app.input_list[c.id]=c;var d=c.type;switch(d){case"conditional":this._addConditional(c);break;case"repeat":this._addRepeat(c);break;case"section":this._addSection(c);break;default:this._addRow(c)}},_addConditional:function(a){var b=this;a.test_param.id=a.id;var c=this._addRow(a.test_param);c.options.onchange=function(c){var d=b.app.data.matchCase(a,c);for(var e in a.cases){var f=a.cases[e],g=a.id+"-section-"+e,h=b.table.get(g),i=!1;for(var j in f.inputs)if(!f.inputs[j].hidden){i=!0;break}e==d&&i?h.fadeIn("fast"):h.hide()}b.app.trigger("change")};for(var d in a.cases){var e=a.id+"-section-"+d,f=new h(this.app,{inputs:a.cases[d].inputs});f.$el.addClass("ui-table-section"),this.table.add(f.$el),this.table.append(e)}c.trigger("change")},_addRepeat:function(a){function b(b){var e=a.id+"-section-"+d++,f=new h(c.app,{inputs:b});g.add({id:e,$el:f.$el,ondel:function(){g.del(e),c.app.trigger("change")}})}for(var c=this,d=0,g=new e.View({title:a.title,title_new:a.title,min:a.min,max:a.max,onnew:function(){b(a.inputs),c.app.trigger("change")}}),i=a.min,j=_.size(a.cache),k=0;kk?a.cache[k]:a.inputs,b(l)}var m=new f(this.app,{label:a.title,help:a.help,field:g});this.table.add(m.$el),this.table.append(a.id)},_addSection:function(a){var b=this,e=new h(b.app,{inputs:a.inputs}),f=new c.ButtonIcon({icon:"fa-eye-slash",tooltip:"Show/hide section",cls:"ui-button-icon-plain"}),g=new d.View({title:a.title,cls:"ui-portlet-section",operations:{button_visible:f}});g.append(e.$el),g.append($("
").addClass("ui-table-form-info").html(a.help));var i=!1;g.$content.hide(),g.$header.css("cursor","pointer"),g.$header.on("click",function(){i?(i=!1,g.$content.hide(),f.setIcon("fa-eye-slash")):(i=!0,g.$content.fadeIn("fast"),f.setIcon("fa-eye"))}),this.app.on("expand",function(a){g.$el.find("#"+a).length>0&&!i&&g.$header.trigger("click")}),a.expanded&&g.$header.trigger("click"),this.table.add(g.$el),this.table.append(a.id)},_addRow:function(a){var b=a.id,c=this.parameters.create(a);this.app.field_list[b]=c;var d=new f(this.app,{label:a.label,default_value:a.default_value,optional:a.optional,help:a.help,field:c});return this.app.element_list[b]=d,this.table.add(d.$el),this.table.append(b),a.hidden&&this.table.get(b).hide(),c}});return{View:h}}); //# sourceMappingURL=../../../maps/mvc/form/form-section.js.map \ No newline at end of file diff --git a/static/scripts/mvc/form/form-view.js b/static/scripts/mvc/form/form-view.js index e145f2683e2..f9194281381 100644 --- a/static/scripts/mvc/form/form-view.js +++ b/static/scripts/mvc/form/form-view.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/form/form-section","mvc/form/form-data"],function(a,b,c,d,e){return Backbone.View.extend({initialize:function(b){this.optionsDefault={is_workflow:!1,narrow:!1,initial_errors:!1,cls:"ui-portlet-limited"},this.options=a.merge(b,this.optionsDefault),console.debug(this.options);var d=parent.Galaxy;this.modal=d&&d.modal?d.modal:new c.Modal.View,this.setElement("
"),this._build()},update:function(a){var b=this;this.data.matchModel(a,function(a,c){var d=b.input_list[a];if(d&&d.options&&!_.isEqual(d.options,c.options)){d.options=c.options;var e=b.field_list[a];if(e.update){var f=[];if(-1!=["data","data_collection","drill_down"].indexOf(d.type))f=d.options;else for(var g in c.options){var h=c.options[g];h.length>2&&f.push({label:h[0],value:h[1]})}e.update(f),e.trigger("change"),console.debug("Updating options for "+a)}}})},wait:function(a){for(var b in this.input_list){var c=this.field_list[b],d=this.input_list[b];d.is_dynamic&&c.wait&&c.unwait&&(a?c.wait():c.unwait())}},reciept:function(a){this.$el.empty(),this.$el.append(a)},highlight:function(a,b,c){var d=this.element_list[a];d&&(d.error(b||"Please verify this parameter."),c||$("html, body").animate({scrollTop:d.$el.offset().top-20},500))},errors:function(a){if(this.trigger("reset"),a&&a.errors){var b=this.data.matchResponse(a.errors);for(var c in this.element_list){{this.element_list[c]}b[c]&&this.highlight(c,b[c],!0)}}},_build:function(){var a=this;this.off("change"),this.off("reset"),this.field_list={},this.input_list={},this.element_list={},this.data=new e(this),this._renderForm(),this.data.create(),this.options.initial_errors&&this.errors(this.options);var b=this.data.checksum();this.on("change",function(){var c=a.data.checksum();c!=b&&(b=c,a.options.onchange&&a.options.onchange())}),this.on("reset",function(){for(var a in this.element_list)this.element_list[a].reset()})},_renderForm:function(){return this.message=new c.Message,this.section=new d.View(this,{inputs:this.options.inputs}),this.incompatible?(this.$el.hide(),void $("#tool-form-classic").show()):(this.portlet=new b.View({icon:"fa-wrench",title:this.options.title,cls:this.options.cls,operations:this.options.operations,buttons:this.options.buttons}),this.portlet.append(this.message.$el.addClass("ui-margin-top")),this.portlet.append(this.section.$el),this.$el.empty(),this.$el.append(this.portlet.$el),this.options.message&&this.message.update({persistent:!0,status:"warning",message:this.options.message}),void console.debug("tools-form-base::initialize() - Completed."))}})}); +define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/form/form-section","mvc/form/form-data"],function(a,b,c,d,e){return Backbone.View.extend({initialize:function(b){this.optionsDefault={is_workflow:!1,narrow:!1,initial_errors:!1,cls:"ui-portlet-limited"},this.options=a.merge(b,this.optionsDefault),console.debug(this.options);var d=parent.Galaxy;this.modal=d&&d.modal?d.modal:new c.Modal.View,this.setElement("
"),this._build()},update:function(a){var b=this;this.data.matchModel(a,function(a,c){var d=b.input_list[a];if(d&&d.options&&!_.isEqual(d.options,c.options)){d.options=c.options;var e=b.field_list[a];if(e.update){var f=[];if(-1!=["data","data_collection","drill_down"].indexOf(d.type))f=d.options;else for(var g in c.options){var h=c.options[g];h.length>2&&f.push({label:h[0],value:h[1]})}e.update(f),e.trigger("change"),console.debug("Updating options for "+a)}}})},wait:function(a){for(var b in this.input_list){var c=this.field_list[b],d=this.input_list[b];d.is_dynamic&&c.wait&&c.unwait&&(a?c.wait():c.unwait())}},reciept:function(a){this.$el.empty(),this.$el.append(a)},highlight:function(a,b,c){var d=this.element_list[a];d&&(d.error(b||"Please verify this parameter."),this.trigger("expand",a),c||$("html, body").animate({scrollTop:d.$el.offset().top-20},500))},errors:function(a){if(this.trigger("reset"),a&&a.errors){var b=this.data.matchResponse(a.errors);for(var c in this.element_list){{this.element_list[c]}b[c]&&this.highlight(c,b[c],!0)}}},_build:function(){var a=this;this.off("change"),this.off("reset"),this.field_list={},this.input_list={},this.element_list={},this.data=new e(this),this._renderForm(),this.data.create(),this.options.initial_errors&&this.errors(this.options);var b=this.data.checksum();this.on("change",function(){var c=a.data.checksum();c!=b&&(b=c,a.options.onchange&&a.options.onchange())}),this.on("reset",function(){for(var a in this.element_list)this.element_list[a].reset()})},_renderForm:function(){return this.message=new c.Message,this.section=new d.View(this,{inputs:this.options.inputs}),this.incompatible?(this.$el.hide(),void $("#tool-form-classic").show()):(this.portlet=new b.View({icon:"fa-wrench",title:this.options.title,cls:this.options.cls,operations:this.options.operations,buttons:this.options.buttons}),this.portlet.append(this.message.$el.addClass("ui-margin-top")),this.portlet.append(this.section.$el),this.$el.empty(),this.$el.append(this.portlet.$el),this.options.message&&this.message.update({persistent:!0,status:"warning",message:this.options.message}),void console.debug("tools-form-base::initialize() - Completed."))}})}); //# sourceMappingURL=../../../maps/mvc/form/form-view.js.map \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-list.js b/static/scripts/mvc/ui/ui-list.js new file mode 100644 index 00000000000..d59044e0000 --- /dev/null +++ b/static/scripts/mvc/ui/ui-list.js @@ -0,0 +1,2 @@ +define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc"],function(a,b,c){var d=Backbone.View.extend({initialize:function(a){var d=this;this.options=a,this.name=a.name||"element",this.message=new c.Message({cls:"ui-margin-top"}),this.portlet=new b.View({cls:"ui-portlet-section"}),this.select=new c.Select.View,this.button=new c.ButtonIcon({icon:"fa fa-sign-in",floating:"left",tooltip:"Insert new "+this.name,onclick:function(){d.add({id:d.select.value(),name:d.select.text()})}}),this.setElement(this._template(a)),this.$(".ui-list-message").append(this.message.$el),this.$(".ui-list-portlet").append(this.portlet.$el),this.$(".ui-list-button").append(this.button.$el),this.$(".ui-list-select").append(this.select.$el)},value:function(a){if(void 0!==a){if(this.portlet.empty(),$.isArray(a))for(var b in a)this.add({id:a[b].id,name:a[b].name});this._refresh()}var c=[];return this.$(".ui-list-id").each(function(){c.push({id:$(this).prop("id"),name:$(this).find(".ui-list-name").html()})}),c},add:function(b){var c=this;if(0===this.$("#"+b.id).length)if(a.validate(b.id)){var d=$(this._templateRow({id:b.id,name:b.name}));d.on("click",function(){d.remove(),c._refresh()}),d.on("mouseover",function(){d.addClass("portlet-highlight")}),d.on("mouseout",function(){d.removeClass("portlet-highlight")}),this.portlet.append(d),this._refresh()}else this.message.update({message:"Please select a valid "+this.name+".",status:"danger"});else this.message.update({message:"This "+this.name+" is already in the list."})},update:function(a){this.select.update(a)},_refresh:function(){this.$(".ui-list-id").length>0?this.$(".ui-list-portlet").show():this.$(".ui-list-portlet").hide(),this.options.onchange&&this.options.onchange()},_template:function(){return'
'},_templateRow:function(a){return'
'+a.name+"
"}});return{View:d}}); +//# sourceMappingURL=../../../maps/mvc/ui/ui-list.js.map \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-misc.js b/static/scripts/mvc/ui/ui-misc.js index 29dce28f607..85c88678e86 100644 --- a/static/scripts/mvc/ui/ui-misc.js +++ b/static/scripts/mvc/ui/ui-misc.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-options","mvc/ui/ui-drilldown","mvc/ui/ui-button-menu","mvc/ui/ui-button-check","mvc/ui/ui-modal"],function(a,b,c,d,e,f,g,h){var i=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options))},_template:function(a){return''}}),j=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options))},title:function(a){this.$el.html(a)},_template:function(a){return'"},value:function(){return options.title}}),k=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},_template:function(a){return'
 '+a.title+"
"}}),l=Backbone.View.extend({optionsDefault:{id:a.uid(),title:"",floating:"right",cls:"ui-button btn btn-default",icon:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",function(){$(".tooltip").hide(),b.onclick&&b.onclick()}),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},wait:function(){this.$el.removeClass(this.options.cls).addClass("btn btn-info").prop("disabled",!0),this.$(".icon").removeClass(this.options.icon).addClass("fa-spinner fa-spin"),this.$(".title").html("Sending...")},unwait:function(){this.$el.removeClass("btn btn-info").addClass(this.options.cls).prop("disabled",!1),this.$(".icon").removeClass("fa-spinner fa-spin").addClass(this.options.icon),this.$(".title").html(this.options.title)},_template:function(a){var b='"}}),m=Backbone.View.extend({optionsDefault:{id:a.uid(),title:"",floating:"right",cls:"ui-button-icon",icon:"",tooltip:"",onclick:null},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),this.$button=this.$el.find(".button");var c=this;$(this.el).on("click",function(){$(".tooltip").hide(),b.onclick&&!c.disabled&&b.onclick()}),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},disable:function(){this.$button.addClass("disabled"),this.disabled=!0},enable:function(){this.$button.removeClass("disabled"),this.disabled=!1},setIcon:function(a){this.$("i").removeClass(this.options.icon).addClass(a),this.options.icon=a},_template:function(a){var b="";a.title&&(b="width: auto;");var c='
';return c+=a.title?'
 '+a.title+"
":'',c+="
"}}),n=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",b.onclick)},_template:function(a){return'"}}),o=Backbone.View.extend({optionsDefault:{message:null,status:"info",persistent:!1},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement("
"),this.options.message&&this.update(this.options)},update:function(b){if(this.options=a.merge(b,this.optionsDefault),""!=b.message){if(this.$el.html(this._template(this.options)),this.$el.find(".alert").append(b.message),this.$el.fadeIn(),this.timeout&&window.clearTimeout(this.timeout),!b.persistent){var c=this;this.timeout=window.setTimeout(function(){c.$el.is(":visible")?c.$el.fadeOut():c.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(a){return'
'}}),p=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options));var c=this;this.options.onclick&&this.$el.on("submit",function(){var a=c.$el.find("#search");c.options.onclick(a.val())})},_template:function(a){return''}}),q=Backbone.View.extend({optionsDefault:{type:"text",placeholder:"",disabled:!1,visible:!0,cls:"",area:!1},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),void 0!==this.options.value&&this.value(this.options.value),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var c=this;this.$el.on("input",function(){c.options.onchange&&c.options.onchange(c.$el.val())})},value:function(a){return void 0!==a&&this.$el.val(a),this.$el.val()},_template:function(a){return a.area?'':''}}),r=Backbone.View.extend({initialize:function(a){this.options=a,this.setElement(this._template(this.options)),void 0!==this.options.value&&this.value(this.options.value)},value:function(a){return void 0!==a&&this.$("hidden").val(a),this.$("hidden").val()},_template:function(a){var b='
';return a.info&&(b+="
"+a.info+"
"),b+='
'}});return{Anchor:n,Button:l,ButtonIcon:m,ButtonCheck:g,ButtonMenu:f,Icon:k,Image:i,Input:q,Label:j,Message:o,Modal:h,RadioButton:d.RadioButton,Checkbox:d.Checkbox,Radio:d.Radio,Searchbox:p,Select:b,Hidden:r,Slider:c,Drilldown:e}}); +define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-options","mvc/ui/ui-drilldown","mvc/ui/ui-button-menu","mvc/ui/ui-button-check","mvc/ui/ui-modal"],function(a,b,c,d,e,f,g,h){var i=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options))},_template:function(a){return''}}),j=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options))},title:function(a){this.$el.html(a)},_template:function(a){return'"},value:function(){return options.title}}),k=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},_template:function(a){return'
 '+a.title+"
"}}),l=Backbone.View.extend({optionsDefault:{id:a.uid(),title:"",floating:"right",cls:"ui-button btn btn-default",icon:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",function(){$(".tooltip").hide(),b.onclick&&b.onclick()}),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},wait:function(){this.$el.removeClass(this.options.cls).addClass("btn btn-info").prop("disabled",!0),this.$(".icon").removeClass(this.options.icon).addClass("fa-spinner fa-spin"),this.$(".title").html("Sending...")},unwait:function(){this.$el.removeClass("btn btn-info").addClass(this.options.cls).prop("disabled",!1),this.$(".icon").removeClass("fa-spinner fa-spin").addClass(this.options.icon),this.$(".title").html(this.options.title)},_template:function(a){var b='"}}),m=Backbone.View.extend({optionsDefault:{id:a.uid(),title:"",floating:"right",cls:"ui-button-icon",icon:"",tooltip:"",onclick:null},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),this.$button=this.$el.find(".button");var c=this;$(this.el).on("click",function(){$(".tooltip").hide(),b.onclick&&!c.disabled&&b.onclick()}),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},disable:function(){this.$button.addClass("disabled"),this.disabled=!0},enable:function(){this.$button.removeClass("disabled"),this.disabled=!1},setIcon:function(a){this.$("i").removeClass(this.options.icon).addClass(a),this.options.icon=a},_template:function(a){var b="";a.title&&(b="width: auto;");var c='
';return c+=a.title?'
 '+a.title+"
":'',c+="
"}}),n=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",b.onclick)},_template:function(a){return'"}}),o=Backbone.View.extend({optionsDefault:{message:null,status:"info",cls:"",persistent:!1},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement('
'),this.options.message&&this.update(this.options)},update:function(b){if(this.options=a.merge(b,this.optionsDefault),""!=b.message){if(this.$el.html(this._template(this.options)),this.$el.find(".alert").append(b.message),this.$el.fadeIn(),this.timeout&&window.clearTimeout(this.timeout),!b.persistent){var c=this;this.timeout=window.setTimeout(function(){c.$el.is(":visible")?c.$el.fadeOut():c.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(a){return'
'}}),p=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options));var c=this;this.options.onclick&&this.$el.on("submit",function(){var a=c.$el.find("#search");c.options.onclick(a.val())})},_template:function(a){return''}}),q=Backbone.View.extend({optionsDefault:{type:"text",placeholder:"",disabled:!1,visible:!0,cls:"",area:!1},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),void 0!==this.options.value&&this.value(this.options.value),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var c=this;this.$el.on("input",function(){c.options.onchange&&c.options.onchange(c.$el.val())})},value:function(a){return void 0!==a&&this.$el.val(a),this.$el.val()},_template:function(a){return a.area?'':''}}),r=Backbone.View.extend({initialize:function(a){this.options=a,this.setElement(this._template(this.options)),void 0!==this.options.value&&this.value(this.options.value)},value:function(a){return void 0!==a&&this.$("hidden").val(a),this.$("hidden").val()},_template:function(a){var b='
';return a.info&&(b+="
"+a.info+"
"),b+='
'}});return{Anchor:n,Button:l,ButtonIcon:m,ButtonCheck:g,ButtonMenu:f,Icon:k,Image:i,Input:q,Label:j,Message:o,Modal:h,RadioButton:d.RadioButton,Checkbox:d.Checkbox,Radio:d.Radio,Searchbox:p,Select:b,Hidden:r,Slider:c,Drilldown:e}}); //# sourceMappingURL=../../../maps/mvc/ui/ui-misc.js.map \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-portlet.js b/static/scripts/mvc/ui/ui-portlet.js index 5e4adafdcee..616881a6c84 100644 --- a/static/scripts/mvc/ui/ui-portlet.js +++ b/static/scripts/mvc/ui/ui-portlet.js @@ -1,2 +1,2 @@ -define(["utils/utils"],function(a){var b=Backbone.View.extend({visible:!1,optionsDefault:{id:a.uid(),title:"",icon:"",buttons:null,body:null,scrollable:!0,nopadding:!1,operations:null,placement:"bottom",cls:"ui-portlet",operations_flt:"right"},$title:null,$content:null,$buttons:null,$operations:null,$header:null,initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find(".content"),this.$title=this.$el.find(".portlet-title-text"),this.$header=this.$el.find(".portlet-header");var c=this.$el.find(".portlet-content");if(this.options.nopadding&&(c.css("padding","0px"),this.$content.css("padding","0px")),this.$buttons=$(this.el).find(".buttons"),this.options.buttons){var d=this;$.each(this.options.buttons,function(a,b){b.$el.prop("id",a),d.$buttons.append(b.$el)})}else this.$buttons.remove();if(this.$operations=$(this.el).find(".portlet-operations"),this.options.operations){var d=this;$.each(this.options.operations,function(a,b){b.$el.prop("id",a),d.$operations.append(b.$el)})}this.options.body&&this.append(this.options.body)},append:function(a){this.$content.append(a)},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(a){this.$buttons.find("#"+a).prop("disabled",!1)},disableButton:function(a){this.$buttons.find("#"+a).prop("disabled",!0)},hideOperation:function(a){this.$operations.find("#"+a).hide()},showOperation:function(a){this.$operations.find("#"+a).show()},setOperation:function(a,b){var c=this.$operations.find("#"+a);c.off("click"),c.on("click",b)},title:function(a){var b=this.$title;return a&&b.html(a),b.html()},disable:function(){this.$(".portlet-backdrop").show()},enable:function(){this.$(".portlet-backdrop").hide()},_template:function(a){var b='
';return a.title&&(b+='
',a.icon&&(b+=' '),b+=''+a.title+"
"),b+='
',"top"==a.placement&&(b+='
'),b+='
',"bottom"==a.placement&&(b+='
'),b+='
'}});return{View:b}}); +define(["utils/utils"],function(a){var b=Backbone.View.extend({visible:!1,optionsDefault:{id:a.uid(),title:"",icon:"",buttons:null,body:null,scrollable:!0,nopadding:!1,operations:null,placement:"bottom",cls:"ui-portlet",operations_flt:"right"},$title:null,$content:null,$buttons:null,$operations:null,$header:null,initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find(".content"),this.$title=this.$el.find(".portlet-title-text"),this.$header=this.$el.find(".portlet-header");var c=this.$el.find(".portlet-content");if(this.options.nopadding&&(c.css("padding","0px"),this.$content.css("padding","0px")),this.$buttons=$(this.el).find(".buttons"),this.options.buttons){var d=this;$.each(this.options.buttons,function(a,b){b.$el.prop("id",a),d.$buttons.append(b.$el)})}else this.$buttons.remove();if(this.$operations=$(this.el).find(".portlet-operations"),this.options.operations){var d=this;$.each(this.options.operations,function(a,b){b.$el.prop("id",a),d.$operations.append(b.$el)})}this.options.body&&this.append(this.options.body)},append:function(a){this.$content.append(a)},empty:function(){this.$content.empty()},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(a){this.$buttons.find("#"+a).prop("disabled",!1)},disableButton:function(a){this.$buttons.find("#"+a).prop("disabled",!0)},hideOperation:function(a){this.$operations.find("#"+a).hide()},showOperation:function(a){this.$operations.find("#"+a).show()},setOperation:function(a,b){var c=this.$operations.find("#"+a);c.off("click"),c.on("click",b)},title:function(a){var b=this.$title;return a&&b.html(a),b.html()},disable:function(){this.$(".portlet-backdrop").show()},enable:function(){this.$(".portlet-backdrop").hide()},_template:function(a){var b='
';return a.title&&(b+='
',a.icon&&(b+=' '),b+=''+a.title+"
"),b+='
',"top"==a.placement&&(b+='
'),b+='
',"bottom"==a.placement&&(b+='
'),b+='
'}});return{View:b}}); //# sourceMappingURL=../../../maps/mvc/ui/ui-portlet.js.map \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-select-library.js b/static/scripts/mvc/ui/ui-select-library.js index 888e1d6cb54..7304af18f6a 100644 --- a/static/scripts/mvc/ui/ui-select-library.js +++ b/static/scripts/mvc/ui/ui-select-library.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(a,b){var c=Backbone.Collection.extend({url:galaxy_config.root+"api/libraries"}),d=Backbone.Collection.extend({initialize:function(){var a=this;this.config=new Backbone.Model({library_id:null}),this.config.on("change",function(){a.fetch({reset:!0})})},url:function(){return galaxy_config.root+"api/libraries/"+this.config.get("library_id")+"/contents"}}),e=Backbone.View.extend({initialize:function(a){var e=this;this.libraries=new c,this.datasets=new d,this.options=a,this.library_select=new b.Select.View({optional:a.optional,onchange:function(a){e.datasets.config.set("library_id",a)}}),this.dataset_select=new b.Select.View({optional:a.optional,multiple:a.multiple,onchange:function(){e.trigger("change")}}),this.libraries.on("reset",function(){var a=[];e.libraries.each(function(b){a.push({value:b.id,label:b.get("name")})}),e.library_select.update(a),e.trigger("change")}),this.datasets.on("reset",function(){var a=[],b=e.library_select.text();null!==b&&e.datasets.each(function(c){"file"===c.get("type")&&a.push({value:c.id,label:b+c.get("name")})}),e.dataset_select.update(a),e.trigger("change")}),this.on("change",function(){a.onchange&&a.onchange(e.value())}),this.setElement(this._template()),this.$(".library-select").append(this.library_select.$el),this.$(".dataset-select").append(this.dataset_select.$el),this.libraries.fetch({reset:!0,success:function(){e.library_select.trigger("change"),void 0!==e.options.value&&e.value(e.options.value)}})},value:function(){return this.dataset_select.value()},_template:function(){return'
Select Library
Select Dataset
'}});return{View:e}}); +define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-table","mvc/ui/ui-list"],function(a,b,c,d){var e=Backbone.Collection.extend({url:galaxy_config.root+"api/libraries"}),f=Backbone.Collection.extend({initialize:function(){var a=this;this.config=new Backbone.Model({library_id:null}),this.config.on("change",function(){a.fetch({reset:!0})})},url:function(){return galaxy_config.root+"api/libraries/"+this.config.get("library_id")+"/contents"}}),g=Backbone.View.extend({initialize:function(a){var c=this;this.libraries=new e,this.datasets=new f,this.options=a,this.library_select=new b.Select.View({onchange:function(a){c.datasets.config.set("library_id",a)}}),this.dataset_list=new d.View({name:"dataset",onchange:function(){c.trigger("change")}}),this.libraries.on("reset",function(){var a=[];c.libraries.each(function(b){a.push({value:b.id,label:b.get("name")})}),c.library_select.update(a)}),this.datasets.on("reset",function(){var a=[],b=c.library_select.text();null!==b&&c.datasets.each(function(b){"file"===b.get("type")&&a.push({value:b.id,label:b.get("name")})}),c.dataset_list.update(a)}),this.on("change",function(){a.onchange&&a.onchange(c.value())}),this.setElement(this._template()),this.$(".library-select").append(this.library_select.$el),this.$el.append(this.dataset_list.$el),this.libraries.fetch({reset:!0,success:function(){c.library_select.trigger("change"),void 0!==c.options.value&&c.value(c.options.value)}})},value:function(a){return this.dataset_list.value(a)},_template:function(){return'
Select Library
'}});return{View:g}}); //# sourceMappingURL=../../../maps/mvc/ui/ui-select-library.js.map \ No newline at end of file diff --git a/static/style/blue/base.css b/static/style/blue/base.css index 27c0ed68afc..6cfb75d57c4 100644 --- a/static/style/blue/base.css +++ b/static/style/blue/base.css @@ -1443,6 +1443,7 @@ html[dir="rtl"] .select2-container-multi .select2-search-choice-close{left:auto; .ui-portlet-repeat,.ui-portlet-section,.ui-portlet-section{border:none;border-left:solid 3px #ebd9b2;border-radius:5px;margin-bottom:5px}.ui-portlet-repeat .portlet-header,.ui-portlet-section .portlet-header{background:#ebd9b2;border-radius:5px;border-bottom-left-radius:0px;border-top-left-radius:0px;padding:0px 2px}.ui-portlet-repeat .portlet-header .portlet-title-text,.ui-portlet-section .portlet-header .portlet-title-text{vertical-align:middle;line-height:20px !important} .ui-portlet-repeat .portlet-content,.ui-portlet-section .portlet-content{padding-right:0px} .ui-portlet-section{margin-top:5px;border-left:solid 3px #dfe5f9}.ui-portlet-section .portlet-header{background:#dfe5f9;border-bottom:solid #b4c2f1 1px} +.ui-portlet-section .portlet-highlight{text-decoration:underline} .ui-portlet-narrow{border:none}.ui-portlet-narrow .portlet-header{border-radius:3px}.ui-portlet-narrow .portlet-header .portlet-operations .ui-button-icon{margin-left:3px} .ui-portlet-narrow .ui-portlet-repeat .portlet-header,.ui-portlet-narrow .ui-portlet-section .portlet-header{border-radius:5px;border-bottom-left-radius:0px;border-top-left-radius:0px} .ui-portlet-narrow .portlet-content{padding:0px} @@ -1470,6 +1471,10 @@ html[dir="rtl"] .select2-container-multi .select2-search-choice-close{left:auto; .ui-color-picker .ui-color-picker-label{float:left;line-height:1.2em} .ui-color-picker .ui-color-picker-view{height:100%;overflow:auto;display:none;float:left;margin-top:5px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel{width:210px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content{margin-bottom:15px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content .label{padding-bottom:2px} .ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content .line .ui-color-picker-box{cursor:pointer;float:left;margin-right:5px;border:solid 1px #c0c0c0;width:15px;height:15px;border-radius:2px}.ui-color-picker .ui-color-picker-view .ui-color-picker-panel .ui-color-picker-content .line .ui-color-picker-box .ui-color-picker-check{color:black;font-size:1.2em;position:relative;left:1px} +.ui-list .ui-list-select{float:left;width:calc(100% - 27px)} +.ui-list .ui-list-button .ui-button-icon{margin-top:3px;margin-right:5px} +.ui-list .ui-list-message,.ui-list .ui-list-portlet{clear:both} +.ui-list .ui-list-id{cursor:pointer;margin-top:5px}.ui-list .ui-list-id .ui-list-delete{font-size:1.2em;margin-right:5px} .ui-select{position:relative}.ui-select .button{position:absolute;top:5px;right:5px} .ui-select select{position:relative;top:0px;height:27px;width:100%;padding-right:20px;cursor:pointer;padding-left:5px} .ui-select .select2-container{width:100%}.ui-select .select2-container .select2-choice{height:27px;padding-left:5px}.ui-select .select2-container .select2-choice .select2-arrow{display:none} diff --git a/static/style/src/less/ui.less b/static/style/src/less/ui.less index adf9a0fe5b2..53b9c914c48 100644 --- a/static/style/src/less/ui.less +++ b/static/style/src/less/ui.less @@ -278,6 +278,9 @@ background: @side-panel-bg; border-bottom: solid darken(@side-panel-bg, 10%) 1px; } + .portlet-highlight { + text-decoration: underline; + } } .ui-portlet-narrow { @@ -501,6 +504,30 @@ } } +.ui-list { + .ui-list-select { + float: left; + width: ~'calc(100% - 27px)'; + } + .ui-list-button { + .ui-button-icon { + margin-top: 3px; + margin-right: 5px; + } + } + .ui-list-message, .ui-list-portlet { + clear: both; + } + .ui-list-id { + cursor: pointer; + margin-top: 5px; + .ui-list-delete { + font-size: 1.2em; + margin-right: 5px; + } + } +} + .ui-select { position: relative; .button { From b1d3552be432d505ce0d862db0c294784e3f061e Mon Sep 17 00:00:00 2001 From: John Chilton Date: Fri, 17 Apr 2015 14:23:38 -0400 Subject: [PATCH 043/120] Add a library_data input test case and small fix. --- lib/galaxy/tools/parameters/wrapped.py | 5 +++++ test/api/test_tools.py | 13 +++++++++++++ test/functional/tools/library_data.xml | 16 ++++++++++++++++ test/functional/tools/samples_tool_conf.xml | 1 + 4 files changed, 35 insertions(+) create mode 100644 test/functional/tools/library_data.xml diff --git a/lib/galaxy/tools/parameters/wrapped.py b/lib/galaxy/tools/parameters/wrapped.py index ea610b06976..2380c6b3dbe 100644 --- a/lib/galaxy/tools/parameters/wrapped.py +++ b/lib/galaxy/tools/parameters/wrapped.py @@ -3,6 +3,7 @@ import galaxy.tools from galaxy.tools.parameters.basic import ( DataToolParameter, DataCollectionToolParameter, + LibraryDatasetToolParameter, SelectToolParameter, ) from galaxy.tools.parameters.grouping import ( @@ -69,6 +70,10 @@ class WrappedParameters( object ): tool=tool, name=input.name, ) + elif isinstance( input, LibraryDatasetToolParameter ): + input_values[ input.name ] = galaxy.tools.LibraryDatasetValueWrapper( + input, input_values[ input.name ], incoming + ) else: input_values[ input.name ] = galaxy.tools.InputValueWrapper( input, input_values[ input.name ], incoming ) diff --git a/test/api/test_tools.py b/test/api/test_tools.py index fe93e6cd436..767cb6e6b5f 100644 --- a/test/api/test_tools.py +++ b/test/api/test_tools.py @@ -3,6 +3,7 @@ from base import api from operator import itemgetter from .helpers import DatasetPopulator from .helpers import DatasetCollectionPopulator +from .helpers import LibraryPopulator from .helpers import skip_without_tool @@ -120,6 +121,18 @@ class ToolsTestCase( api.ApiTestCase ): assert output1_content.strip() == "--ex1" assert output2_content.strip() == "None", output2_content + @skip_without_tool( "library_data" ) + def test_library_data_param( self ): + history_id = self.dataset_populator.new_history() + ld = LibraryPopulator( self ).new_library_dataset( "lda_test_library" ) + inputs = { + "library_datasets": [ld[ "ldda_id" ]], + } + response = self._run( "library_data", history_id, inputs, assert_ok=True ) + output = response[ "outputs" ] + output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output[ 0 ] ) + assert output1_content == "TestData", output1_content + @skip_without_tool( "multi_data_param" ) def test_multidata_param( self ): history_id = self.dataset_populator.new_history() diff --git a/test/functional/tools/library_data.xml b/test/functional/tools/library_data.xml new file mode 100644 index 00000000000..156414a4b0a --- /dev/null +++ b/test/functional/tools/library_data.xml @@ -0,0 +1,16 @@ + + + #for $input in $library_datasets + cat $input.get_file_name() >> $output + #end for + + + + + + + + + + + diff --git a/test/functional/tools/samples_tool_conf.xml b/test/functional/tools/samples_tool_conf.xml index 22fbd8290b7..0a806d00688 100644 --- a/test/functional/tools/samples_tool_conf.xml +++ b/test/functional/tools/samples_tool_conf.xml @@ -9,6 +9,7 @@ + From 27424139a01d80df0ba85a795844d920dd75470e Mon Sep 17 00:00:00 2001 From: guerler Date: Sun, 19 Apr 2015 22:46:45 -0400 Subject: [PATCH 044/120] Add generic list value wrapper and use it for the library data tool parameter, move wrapper import into parameters --- lib/galaxy/tools/__init__.py | 10 --------- lib/galaxy/tools/evaluation.py | 8 +++----- lib/galaxy/tools/parameters/basic.py | 3 +++ lib/galaxy/tools/parameters/wrapped.py | 28 ++++++++++++++++---------- lib/galaxy/tools/wrappers.py | 17 +++++----------- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py index 86e3eeb72fa..e38191efa78 100755 --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -60,16 +60,6 @@ from galaxy.model.item_attrs import Dictifiable from tool_shed.util import shed_util_common as suc from .loader import template_macro_params, raw_tool_xml_tree, imported_macro_paths from .execute import execute as execute_job -from .wrappers import ( - ToolParameterValueWrapper, - RawObjectWrapper, - LibraryDatasetValueWrapper, - InputValueWrapper, - SelectToolParameterWrapper, - DatasetFilenameWrapper, - DatasetListWrapper, - DatasetCollectionWrapper, -) import galaxy.jobs diff --git a/lib/galaxy/tools/evaluation.py b/lib/galaxy/tools/evaluation.py index 05760d60a76..0909c39ed0b 100644 --- a/lib/galaxy/tools/evaluation.py +++ b/lib/galaxy/tools/evaluation.py @@ -11,15 +11,14 @@ from galaxy.tools.wrappers import ( DatasetFilenameWrapper, DatasetListWrapper, DatasetCollectionWrapper, - LibraryDatasetValueWrapper, SelectToolParameterWrapper, InputValueWrapper, + ListValueWrapper, RawObjectWrapper ) from galaxy.tools.parameters.basic import ( DataToolParameter, DataCollectionToolParameter, - LibraryDatasetToolParameter, SelectToolParameter, ) from galaxy.tools.parameters.grouping import Conditional, Repeat, Section @@ -228,9 +227,8 @@ class ToolEvaluator( object ): elif isinstance( input, SelectToolParameter ): input_values[ input.name ] = SelectToolParameterWrapper( input, input_values[ input.name ], self.app, other_values=param_dict, path_rewriter=self.unstructured_path_rewriter ) - elif isinstance( input, LibraryDatasetToolParameter ): - # TODO: Handle input rewrites in here? How to test LibraryDatasetToolParameters? - input_values[ input.name ] = LibraryDatasetValueWrapper( + elif isinstance( input_values[ input.name ], list ): + input_values[ input.name ] = ListValueWrapper( input, input_values[ input.name ], param_dict ) else: input_values[ input.name ] = InputValueWrapper( diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 51d9203f62b..ee8d9a5a3a5 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -2390,6 +2390,9 @@ class LibraryDatasetToolParameter( ToolParameter ): def from_html( self, value, trans, other_values={} ): return self.to_python( value, trans.app, other_values=other_values, validate=True ) + def to_param_dict_string( self, value, other_values={} ): + return [ dataset.get_file_name() for dataset in value ] + # converts values to json representation: # { id: LibraryDatasetDatasetAssociation.id, name: LibraryDatasetDatasetAssociation.name, src: 'lda' } def to_string( self, value, app ): diff --git a/lib/galaxy/tools/parameters/wrapped.py b/lib/galaxy/tools/parameters/wrapped.py index 2380c6b3dbe..e8fc7aadf68 100644 --- a/lib/galaxy/tools/parameters/wrapped.py +++ b/lib/galaxy/tools/parameters/wrapped.py @@ -3,8 +3,15 @@ import galaxy.tools from galaxy.tools.parameters.basic import ( DataToolParameter, DataCollectionToolParameter, - LibraryDatasetToolParameter, - SelectToolParameter, + SelectToolParameter +) +from galaxy.tools.wrappers import ( + InputValueWrapper, + ListValueWrapper, + SelectToolParameterWrapper, + DatasetFilenameWrapper, + DatasetListWrapper, + DatasetCollectionWrapper ) from galaxy.tools.parameters.grouping import ( Repeat, @@ -39,6 +46,7 @@ class WrappedParameters( object ): for input in inputs.itervalues(): if input.name not in input_values and skip_missing_values: continue + value = input_values[ input.name ] if isinstance( input, Repeat ): for d in input_values[ input.name ]: self.wrap_values( input.inputs, d, skip_missing_values=skip_missing_values ) @@ -51,31 +59,29 @@ class WrappedParameters( object ): self.wrap_values( input.inputs, values, skip_missing_values=skip_missing_values ) elif isinstance( input, DataToolParameter ) and input.multiple: input_values[ input.name ] = \ - galaxy.tools.DatasetListWrapper( input_values[ input.name ], + DatasetListWrapper( input_values[ input.name ], datatypes_registry=trans.app.datatypes_registry, tool=tool, name=input.name ) elif isinstance( input, DataToolParameter ): input_values[ input.name ] = \ - galaxy.tools.DatasetFilenameWrapper( input_values[ input.name ], + DatasetFilenameWrapper( input_values[ input.name ], datatypes_registry=trans.app.datatypes_registry, tool=tool, name=input.name ) elif isinstance( input, SelectToolParameter ): - input_values[ input.name ] = galaxy.tools.SelectToolParameterWrapper( input, input_values[ input.name ], tool.app, other_values=incoming ) + input_values[ input.name ] = SelectToolParameterWrapper( input, input_values[ input.name ], tool.app, other_values=incoming ) elif isinstance( input, DataCollectionToolParameter ): - input_values[ input.name ] = galaxy.tools.DatasetCollectionWrapper( + input_values[ input.name ] = DatasetCollectionWrapper( input_values[ input.name ], datatypes_registry=trans.app.datatypes_registry, tool=tool, name=input.name, ) - elif isinstance( input, LibraryDatasetToolParameter ): - input_values[ input.name ] = galaxy.tools.LibraryDatasetValueWrapper( - input, input_values[ input.name ], incoming - ) + elif isinstance( value, list ): + input_values[ input.name ] = ListValueWrapper( input, value, incoming ) else: - input_values[ input.name ] = galaxy.tools.InputValueWrapper( input, input_values[ input.name ], incoming ) + input_values[ input.name ] = InputValueWrapper( input, value, incoming ) def make_dict_copy( from_dict ): diff --git a/lib/galaxy/tools/wrappers.py b/lib/galaxy/tools/wrappers.py index 1a483b66e74..555354c7245 100644 --- a/lib/galaxy/tools/wrappers.py +++ b/lib/galaxy/tools/wrappers.py @@ -57,27 +57,20 @@ class RawObjectWrapper( ToolParameterValueWrapper ): return getattr( self.obj, key ) -class LibraryDatasetValueWrapper( ToolParameterValueWrapper ): +class ListValueWrapper( ToolParameterValueWrapper ): """ - Wraps an input so that __str__ gives the "param_dict" representation. + Wraps an input so that __str__ gives the "param_dict" representation for list values. """ def __init__( self, input, value, other_values={} ): self.input = input self.value = value - self._other_values = other_values - self.counter = 0 + self.to_param_dict_string = self.input.to_param_dict_string( self.value, other_values ) def __str__( self ): - return self.value + return ','.join( self.to_param_dict_string ) def __iter__( self ): - return self - - def next( self ): - if self.counter >= len(self.value): - raise StopIteration - self.counter += 1 - return self.value[ self.counter - 1 ] + return iter( self.to_param_dict_string ) def __getattr__( self, key ): return getattr( self.value, key ) From f026690d2710d32644f6724398857e83f93f8c65 Mon Sep 17 00:00:00 2001 From: guerler Date: Sun, 19 Apr 2015 23:48:20 -0400 Subject: [PATCH 045/120] Add optional feature to list input element --- client/galaxy/scripts/mvc/ui/ui-list.js | 2 +- client/galaxy/scripts/mvc/ui/ui-select-library.js | 1 + static/maps/mvc/ui/ui-select-library.js.map | 2 +- static/scripts/mvc/ui/ui-list.js | 2 +- static/scripts/mvc/ui/ui-select-library.js | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/client/galaxy/scripts/mvc/ui/ui-list.js b/client/galaxy/scripts/mvc/ui/ui-list.js index d3f045312d9..8f3f3342218 100644 --- a/client/galaxy/scripts/mvc/ui/ui-list.js +++ b/client/galaxy/scripts/mvc/ui/ui-list.js @@ -19,7 +19,7 @@ var View = Backbone.View.extend({ this.portlet = new Portlet.View({ cls: 'ui-portlet-section' }); // create select field containing the options which can be inserted into the list - this.select = new Ui.Select.View(); + this.select = new Ui.Select.View({ optional : options.optional }); // create insert new list element button this.button = new Ui.ButtonIcon({ diff --git a/client/galaxy/scripts/mvc/ui/ui-select-library.js b/client/galaxy/scripts/mvc/ui/ui-select-library.js index f41aa9cc26a..0f920ec3173 100644 --- a/client/galaxy/scripts/mvc/ui/ui-select-library.js +++ b/client/galaxy/scripts/mvc/ui/ui-select-library.js @@ -46,6 +46,7 @@ var View = Backbone.View.extend({ // create ui-list view to keep track of selected data libraries this.dataset_list = new List.View({ name : 'dataset', + optional : options.optional, onchange : function() { self.trigger('change'); } diff --git a/static/maps/mvc/ui/ui-select-library.js.map b/static/maps/mvc/ui/ui-select-library.js.map index 955d3fe6a4a..cb1a9bce43d 100644 --- a/static/maps/mvc/ui/ui-select-library.js.map +++ b/static/maps/mvc/ui/ui-select-library.js.map @@ -1 +1 @@ -{"version":3,"file":"ui-select-library.js","sources":["../../../src/mvc/ui/ui-select-library.js"],"names":["define","Utils","Ui","Table","List","Libraries","Backbone","Collection","extend","url","galaxy_config","root","LibraryDatasets","initialize","self","this","config","Model","library_id","on","fetch","reset","get","View","options","libraries","datasets","library_select","Select","onchange","value","set","dataset_list","name","trigger","data","each","model","push","id","label","update","library_current","text","setElement","_template","$","append","$el","success","undefined","val"],"mappings":"AACAA,QAAQ,cAAe,iBAAkB,kBAAmB,kBACpD,SAASC,EAAOC,EAAIC,EAAOC,GAGnC,GAAIC,GAAYC,SAASC,WAAWC,QAChCC,IAAKC,cAAcC,KAAO,kBAI1BC,EAAkBN,SAASC,WAAWC,QACtCK,WAAY,WACR,GAAIC,GAAOC,IACXA,MAAKC,OAAS,GAAIV,UAASW,OAAQC,WAAY,OAC/CH,KAAKC,OAAOG,GAAG,SAAU,WACrBL,EAAKM,OAAQC,OAAO,OAG5BZ,IAAK,WACD,MAAOC,eAAcC,KAAO,iBAAmBI,KAAKC,OAAOM,IAAI,cAAgB,eAKnFC,EAAOjB,SAASiB,KAAKf,QAErBK,WAAa,SAASW,GAElB,GAAIV,GAAOC,IAGXA,MAAKU,UAAa,GAAIpB,GACtBU,KAAKW,SAAa,GAAId,GAGtBG,KAAKS,QAAUA,EAIfT,KAAKY,eAAiB,GAAIzB,GAAG0B,OAAOL,MAChCM,SAAc,SAASC,GACnBhB,EAAKY,SAASV,OAAOe,IAAI,aAAcD,MAK/Cf,KAAKiB,aAAe,GAAI5B,GAAKmB,MACzBU,KAAc,UACdJ,SAAc,WACVf,EAAKoB,QAAQ,aAKrBnB,KAAKU,UAAUN,GAAG,QAAS,WACvB,GAAIgB,KACJrB,GAAKW,UAAUW,KAAK,SAASC,GACzBF,EAAKG,MACDR,MAAUO,EAAME,GAChBC,MAAUH,EAAMf,IAAI,YAG5BR,EAAKa,eAAec,OAAON,KAI/BpB,KAAKW,SAASP,GAAG,QAAS,WACtB,GAAIgB,MACAO,EAAkB5B,EAAKa,eAAegB,MAClB,QAApBD,GACA5B,EAAKY,SAASU,KAAK,SAASC,GACE,SAAtBA,EAAMf,IAAI,SACVa,EAAKG,MACDR,MAAUO,EAAME,GAChBC,MAAUH,EAAMf,IAAI,YAKpCR,EAAKkB,aAAaS,OAAON,KAI7BpB,KAAKI,GAAG,SAAU,WACdK,EAAQK,UAAYL,EAAQK,SAASf,EAAKgB,WAI9Cf,KAAK6B,WAAW7B,KAAK8B,aACrB9B,KAAK+B,EAAE,mBAAmBC,OAAOhC,KAAKY,eAAeqB,KACrDjC,KAAKiC,IAAID,OAAOhC,KAAKiB,aAAagB,KAGlCjC,KAAKU,UAAUL,OACXC,OAAO,EACP4B,QAAS,WACLnC,EAAKa,eAAeO,QAAQ,UACDgB,SAAvBpC,EAAKU,QAAQM,OACbhB,EAAKgB,MAAMhB,EAAKU,QAAQM,WAOxCA,MAAO,SAASqB,GACZ,MAAOpC,MAAKiB,aAAaF,MAAMqB,IAInCN,UAAW,WACP,MAAQ,qKAShB,QACItB,KAAMA"} \ No newline at end of file +{"version":3,"file":"ui-select-library.js","sources":["../../../src/mvc/ui/ui-select-library.js"],"names":["define","Utils","Ui","Table","List","Libraries","Backbone","Collection","extend","url","galaxy_config","root","LibraryDatasets","initialize","self","this","config","Model","library_id","on","fetch","reset","get","View","options","libraries","datasets","library_select","Select","onchange","value","set","dataset_list","name","optional","trigger","data","each","model","push","id","label","update","library_current","text","setElement","_template","$","append","$el","success","undefined","val"],"mappings":"AACAA,QAAQ,cAAe,iBAAkB,kBAAmB,kBACpD,SAASC,EAAOC,EAAIC,EAAOC,GAGnC,GAAIC,GAAYC,SAASC,WAAWC,QAChCC,IAAKC,cAAcC,KAAO,kBAI1BC,EAAkBN,SAASC,WAAWC,QACtCK,WAAY,WACR,GAAIC,GAAOC,IACXA,MAAKC,OAAS,GAAIV,UAASW,OAAQC,WAAY,OAC/CH,KAAKC,OAAOG,GAAG,SAAU,WACrBL,EAAKM,OAAQC,OAAO,OAG5BZ,IAAK,WACD,MAAOC,eAAcC,KAAO,iBAAmBI,KAAKC,OAAOM,IAAI,cAAgB,eAKnFC,EAAOjB,SAASiB,KAAKf,QAErBK,WAAa,SAASW,GAElB,GAAIV,GAAOC,IAGXA,MAAKU,UAAa,GAAIpB,GACtBU,KAAKW,SAAa,GAAId,GAGtBG,KAAKS,QAAUA,EAIfT,KAAKY,eAAiB,GAAIzB,GAAG0B,OAAOL,MAChCM,SAAc,SAASC,GACnBhB,EAAKY,SAASV,OAAOe,IAAI,aAAcD,MAK/Cf,KAAKiB,aAAe,GAAI5B,GAAKmB,MACzBU,KAAc,UACdC,SAAcV,EAAQU,SACtBL,SAAc,WACVf,EAAKqB,QAAQ,aAKrBpB,KAAKU,UAAUN,GAAG,QAAS,WACvB,GAAIiB,KACJtB,GAAKW,UAAUY,KAAK,SAASC,GACzBF,EAAKG,MACDT,MAAUQ,EAAME,GAChBC,MAAUH,EAAMhB,IAAI,YAG5BR,EAAKa,eAAee,OAAON,KAI/BrB,KAAKW,SAASP,GAAG,QAAS,WACtB,GAAIiB,MACAO,EAAkB7B,EAAKa,eAAeiB,MAClB,QAApBD,GACA7B,EAAKY,SAASW,KAAK,SAASC,GACE,SAAtBA,EAAMhB,IAAI,SACVc,EAAKG,MACDT,MAAUQ,EAAME,GAChBC,MAAUH,EAAMhB,IAAI,YAKpCR,EAAKkB,aAAaU,OAAON,KAI7BrB,KAAKI,GAAG,SAAU,WACdK,EAAQK,UAAYL,EAAQK,SAASf,EAAKgB,WAI9Cf,KAAK8B,WAAW9B,KAAK+B,aACrB/B,KAAKgC,EAAE,mBAAmBC,OAAOjC,KAAKY,eAAesB,KACrDlC,KAAKkC,IAAID,OAAOjC,KAAKiB,aAAaiB,KAGlClC,KAAKU,UAAUL,OACXC,OAAO,EACP6B,QAAS,WACLpC,EAAKa,eAAeQ,QAAQ,UACDgB,SAAvBrC,EAAKU,QAAQM,OACbhB,EAAKgB,MAAMhB,EAAKU,QAAQM,WAOxCA,MAAO,SAASsB,GACZ,MAAOrC,MAAKiB,aAAaF,MAAMsB,IAInCN,UAAW,WACP,MAAQ,qKAShB,QACIvB,KAAMA"} \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-list.js b/static/scripts/mvc/ui/ui-list.js index d59044e0000..a47f5e7b4c1 100644 --- a/static/scripts/mvc/ui/ui-list.js +++ b/static/scripts/mvc/ui/ui-list.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc"],function(a,b,c){var d=Backbone.View.extend({initialize:function(a){var d=this;this.options=a,this.name=a.name||"element",this.message=new c.Message({cls:"ui-margin-top"}),this.portlet=new b.View({cls:"ui-portlet-section"}),this.select=new c.Select.View,this.button=new c.ButtonIcon({icon:"fa fa-sign-in",floating:"left",tooltip:"Insert new "+this.name,onclick:function(){d.add({id:d.select.value(),name:d.select.text()})}}),this.setElement(this._template(a)),this.$(".ui-list-message").append(this.message.$el),this.$(".ui-list-portlet").append(this.portlet.$el),this.$(".ui-list-button").append(this.button.$el),this.$(".ui-list-select").append(this.select.$el)},value:function(a){if(void 0!==a){if(this.portlet.empty(),$.isArray(a))for(var b in a)this.add({id:a[b].id,name:a[b].name});this._refresh()}var c=[];return this.$(".ui-list-id").each(function(){c.push({id:$(this).prop("id"),name:$(this).find(".ui-list-name").html()})}),c},add:function(b){var c=this;if(0===this.$("#"+b.id).length)if(a.validate(b.id)){var d=$(this._templateRow({id:b.id,name:b.name}));d.on("click",function(){d.remove(),c._refresh()}),d.on("mouseover",function(){d.addClass("portlet-highlight")}),d.on("mouseout",function(){d.removeClass("portlet-highlight")}),this.portlet.append(d),this._refresh()}else this.message.update({message:"Please select a valid "+this.name+".",status:"danger"});else this.message.update({message:"This "+this.name+" is already in the list."})},update:function(a){this.select.update(a)},_refresh:function(){this.$(".ui-list-id").length>0?this.$(".ui-list-portlet").show():this.$(".ui-list-portlet").hide(),this.options.onchange&&this.options.onchange()},_template:function(){return'
'},_templateRow:function(a){return'
'+a.name+"
"}});return{View:d}}); +define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc"],function(a,b,c){var d=Backbone.View.extend({initialize:function(a){var d=this;this.options=a,this.name=a.name||"element",this.message=new c.Message({cls:"ui-margin-top"}),this.portlet=new b.View({cls:"ui-portlet-section"}),this.select=new c.Select.View({optional:a.optional}),this.button=new c.ButtonIcon({icon:"fa fa-sign-in",floating:"left",tooltip:"Insert new "+this.name,onclick:function(){d.add({id:d.select.value(),name:d.select.text()})}}),this.setElement(this._template(a)),this.$(".ui-list-message").append(this.message.$el),this.$(".ui-list-portlet").append(this.portlet.$el),this.$(".ui-list-button").append(this.button.$el),this.$(".ui-list-select").append(this.select.$el)},value:function(a){if(void 0!==a){if(this.portlet.empty(),$.isArray(a))for(var b in a)this.add({id:a[b].id,name:a[b].name});this._refresh()}var c=[];return this.$(".ui-list-id").each(function(){c.push({id:$(this).prop("id"),name:$(this).find(".ui-list-name").html()})}),c},add:function(b){var c=this;if(0===this.$("#"+b.id).length)if(a.validate(b.id)){var d=$(this._templateRow({id:b.id,name:b.name}));d.on("click",function(){d.remove(),c._refresh()}),d.on("mouseover",function(){d.addClass("portlet-highlight")}),d.on("mouseout",function(){d.removeClass("portlet-highlight")}),this.portlet.append(d),this._refresh()}else this.message.update({message:"Please select a valid "+this.name+".",status:"danger"});else this.message.update({message:"This "+this.name+" is already in the list."})},update:function(a){this.select.update(a)},_refresh:function(){this.$(".ui-list-id").length>0?this.$(".ui-list-portlet").show():this.$(".ui-list-portlet").hide(),this.options.onchange&&this.options.onchange()},_template:function(){return'
'},_templateRow:function(a){return'
'+a.name+"
"}});return{View:d}}); //# sourceMappingURL=../../../maps/mvc/ui/ui-list.js.map \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-select-library.js b/static/scripts/mvc/ui/ui-select-library.js index 7304af18f6a..7551263dc19 100644 --- a/static/scripts/mvc/ui/ui-select-library.js +++ b/static/scripts/mvc/ui/ui-select-library.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-table","mvc/ui/ui-list"],function(a,b,c,d){var e=Backbone.Collection.extend({url:galaxy_config.root+"api/libraries"}),f=Backbone.Collection.extend({initialize:function(){var a=this;this.config=new Backbone.Model({library_id:null}),this.config.on("change",function(){a.fetch({reset:!0})})},url:function(){return galaxy_config.root+"api/libraries/"+this.config.get("library_id")+"/contents"}}),g=Backbone.View.extend({initialize:function(a){var c=this;this.libraries=new e,this.datasets=new f,this.options=a,this.library_select=new b.Select.View({onchange:function(a){c.datasets.config.set("library_id",a)}}),this.dataset_list=new d.View({name:"dataset",onchange:function(){c.trigger("change")}}),this.libraries.on("reset",function(){var a=[];c.libraries.each(function(b){a.push({value:b.id,label:b.get("name")})}),c.library_select.update(a)}),this.datasets.on("reset",function(){var a=[],b=c.library_select.text();null!==b&&c.datasets.each(function(b){"file"===b.get("type")&&a.push({value:b.id,label:b.get("name")})}),c.dataset_list.update(a)}),this.on("change",function(){a.onchange&&a.onchange(c.value())}),this.setElement(this._template()),this.$(".library-select").append(this.library_select.$el),this.$el.append(this.dataset_list.$el),this.libraries.fetch({reset:!0,success:function(){c.library_select.trigger("change"),void 0!==c.options.value&&c.value(c.options.value)}})},value:function(a){return this.dataset_list.value(a)},_template:function(){return'
Select Library
'}});return{View:g}}); +define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-table","mvc/ui/ui-list"],function(a,b,c,d){var e=Backbone.Collection.extend({url:galaxy_config.root+"api/libraries"}),f=Backbone.Collection.extend({initialize:function(){var a=this;this.config=new Backbone.Model({library_id:null}),this.config.on("change",function(){a.fetch({reset:!0})})},url:function(){return galaxy_config.root+"api/libraries/"+this.config.get("library_id")+"/contents"}}),g=Backbone.View.extend({initialize:function(a){var c=this;this.libraries=new e,this.datasets=new f,this.options=a,this.library_select=new b.Select.View({onchange:function(a){c.datasets.config.set("library_id",a)}}),this.dataset_list=new d.View({name:"dataset",optional:a.optional,onchange:function(){c.trigger("change")}}),this.libraries.on("reset",function(){var a=[];c.libraries.each(function(b){a.push({value:b.id,label:b.get("name")})}),c.library_select.update(a)}),this.datasets.on("reset",function(){var a=[],b=c.library_select.text();null!==b&&c.datasets.each(function(b){"file"===b.get("type")&&a.push({value:b.id,label:b.get("name")})}),c.dataset_list.update(a)}),this.on("change",function(){a.onchange&&a.onchange(c.value())}),this.setElement(this._template()),this.$(".library-select").append(this.library_select.$el),this.$el.append(this.dataset_list.$el),this.libraries.fetch({reset:!0,success:function(){c.library_select.trigger("change"),void 0!==c.options.value&&c.value(c.options.value)}})},value:function(a){return this.dataset_list.value(a)},_template:function(){return'
Select Library
'}});return{View:g}}); //# sourceMappingURL=../../../maps/mvc/ui/ui-select-library.js.map \ No newline at end of file From 8b478c1005c2468278149ce271e8a96bf698f421 Mon Sep 17 00:00:00 2001 From: guerler Date: Sun, 19 Apr 2015 23:55:10 -0400 Subject: [PATCH 046/120] Fix import for DatasetFilenameWrapper --- lib/galaxy/tools/parameters/dynamic_options.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/tools/parameters/dynamic_options.py b/lib/galaxy/tools/parameters/dynamic_options.py index 5ec40230e23..b6f1b1b6974 100644 --- a/lib/galaxy/tools/parameters/dynamic_options.py +++ b/lib/galaxy/tools/parameters/dynamic_options.py @@ -116,7 +116,7 @@ class DataMetaFilter( Filter ): return file_value == dataset_value assert self.ref_name in other_values or ( trans is not None and trans.workflow_building_mode), "Required dependency '%s' not found in incoming values" % self.ref_name ref = other_values.get( self.ref_name, None ) - if not isinstance( ref, self.dynamic_option.tool_param.tool.app.model.HistoryDatasetAssociation ) and not ( isinstance( ref, galaxy.tools.DatasetFilenameWrapper ) ): + if not isinstance( ref, self.dynamic_option.tool_param.tool.app.model.HistoryDatasetAssociation ) and not ( isinstance( ref, galaxy.tools.wrappers.DatasetFilenameWrapper ) ): return [] #not a valid dataset meta_value = ref.metadata.get( self.key, None ) if meta_value is None: #assert meta_value is not None, "Required metadata value '%s' not found in referenced dataset" % self.key @@ -358,7 +358,7 @@ class RemoveValueFilter( Filter ): value = other_values.get( self.ref_name ) else: data_ref = other_values.get( self.meta_ref ) - if not isinstance( data_ref, self.dynamic_option.tool_param.tool.app.model.HistoryDatasetAssociation ) and not ( isinstance( data_ref, galaxy.tools.DatasetFilenameWrapper ) ): + if not isinstance( data_ref, self.dynamic_option.tool_param.tool.app.model.HistoryDatasetAssociation ) and not ( isinstance( data_ref, galaxy.tools.wrappers.DatasetFilenameWrapper ) ): return options #cannot modify options value = data_ref.metadata.get( self.metadata_key, None ) return [ ( disp_name, optval, selected ) for disp_name, optval, selected in options if not compare_value( optval, value ) ] From 3832de63b869946b58dcb064621c595964c17dc5 Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 20 Apr 2015 01:43:27 -0400 Subject: [PATCH 047/120] Add multiple option to library dataset parameter --- client/galaxy/scripts/mvc/ui/ui-list.js | 3 +++ client/galaxy/scripts/mvc/ui/ui-misc.js | 18 ++++++++---------- .../galaxy/scripts/mvc/ui/ui-select-library.js | 1 + lib/galaxy/tools/parameters/basic.py | 13 ++++++++++++- lib/galaxy/tools/wrappers.py | 10 ++++++++-- static/maps/mvc/ui/ui-misc.js.map | 2 +- static/maps/mvc/ui/ui-select-library.js.map | 2 +- static/scripts/mvc/ui/ui-list.js | 2 +- static/scripts/mvc/ui/ui-misc.js | 2 +- static/scripts/mvc/ui/ui-select-library.js | 2 +- 10 files changed, 37 insertions(+), 18 deletions(-) diff --git a/client/galaxy/scripts/mvc/ui/ui-list.js b/client/galaxy/scripts/mvc/ui/ui-list.js index 8f3f3342218..4a15dd99aec 100644 --- a/client/galaxy/scripts/mvc/ui/ui-list.js +++ b/client/galaxy/scripts/mvc/ui/ui-list.js @@ -11,6 +11,7 @@ var View = Backbone.View.extend({ // initialize options this.options = options; this.name = options.name || 'element'; + this.multiple = options.multiple || false; // create message handler this.message = new Ui.Message({ cls: 'ui-margin-top' }); @@ -105,8 +106,10 @@ var View = Backbone.View.extend({ /** Refresh view */ _refresh: function() { if (this.$('.ui-list-id').length > 0) { + !this.multiple && this.button.disable(); this.$('.ui-list-portlet').show(); } else { + this.button.enable(); this.$('.ui-list-portlet').hide(); } this.options.onchange && this.options.onchange(); diff --git a/client/galaxy/scripts/mvc/ui/ui-misc.js b/client/galaxy/scripts/mvc/ui/ui-misc.js index 69eaa7e8a34..ae36a02c9ef 100644 --- a/client/galaxy/scripts/mvc/ui/ui-misc.js +++ b/client/galaxy/scripts/mvc/ui/ui-misc.js @@ -199,7 +199,7 @@ var ButtonIcon = Backbone.View.extend({ }); // add tooltip - $(this.el).tooltip({title: options.tooltip, placement: 'bottom'}); + this.$button.tooltip({title: options.tooltip, placement: 'bottom'}); }, // disable @@ -229,18 +229,16 @@ var ButtonIcon = Backbone.View.extend({ } // string - var str = '
'; - - // title + var str = '
' + + '
'; if (options.title) { - str += '
' + - ' ' + - '' + options.title + '' + - '
'; + str += ' ' + + '' + options.title + ''; } else { - str += ''; + str += ''; } - str += '
'; + str += '
' + + '
'; return str; } }); diff --git a/client/galaxy/scripts/mvc/ui/ui-select-library.js b/client/galaxy/scripts/mvc/ui/ui-select-library.js index 0f920ec3173..fdffa445625 100644 --- a/client/galaxy/scripts/mvc/ui/ui-select-library.js +++ b/client/galaxy/scripts/mvc/ui/ui-select-library.js @@ -47,6 +47,7 @@ var View = Backbone.View.extend({ this.dataset_list = new List.View({ name : 'dataset', optional : options.optional, + multiple : options.multiple, onchange : function() { self.trigger('change'); } diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index ee8d9a5a3a5..146720785ee 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -2380,6 +2380,7 @@ class LibraryDatasetToolParameter( ToolParameter ): def __init__( self, tool, input_source, context=None ): ToolParameter.__init__( self, tool, input_source ) + self.multiple = input_source.get_bool( 'multiple', False ) def get_html_field( self, trans=None, value=None, other_values={} ): return form_builder.LibraryField( self.name, value=value, trans=trans ) @@ -2391,7 +2392,12 @@ class LibraryDatasetToolParameter( ToolParameter ): return self.to_python( value, trans.app, other_values=other_values, validate=True ) def to_param_dict_string( self, value, other_values={} ): - return [ dataset.get_file_name() for dataset in value ] + if value is None: + return 'None' + elif self.multiple: + return [ dataset.get_file_name() for dataset in value ] + else: + return value[ 0 ].get_file_name() # converts values to json representation: # { id: LibraryDatasetDatasetAssociation.id, name: LibraryDatasetDatasetAssociation.name, src: 'lda' } @@ -2455,6 +2461,11 @@ class LibraryDatasetToolParameter( ToolParameter ): else: return lst + def to_dict( self, trans, view='collection', value_mapper=None, other_values=None ): + d = super( LibraryDatasetToolParameter, self ).to_dict( trans ) + d['multiple'] = self.multiple + return d + # class RawToolParameter( ToolParameter ): # """ # Completely nondescript parameter, HTML representation is provided as text diff --git a/lib/galaxy/tools/wrappers.py b/lib/galaxy/tools/wrappers.py index 570d022389f..a51049d29be 100644 --- a/lib/galaxy/tools/wrappers.py +++ b/lib/galaxy/tools/wrappers.py @@ -67,10 +67,16 @@ class ListValueWrapper( ToolParameterValueWrapper ): self.to_param_dict_string = self.input.to_param_dict_string( self.value, other_values ) def __str__( self ): - return ','.join( self.to_param_dict_string ) + if isinstance( self.to_param_dict_string, list): + return ','.join( self.to_param_dict_string ) + else: + return self.to_param_dict_string def __iter__( self ): - return iter( self.to_param_dict_string ) + if not isinstance( self.to_param_dict_string, list): + return iter( [self.to_param_dict_string] ) + else: + return iter( self.to_param_dict_string ) def __getattr__( self, key ): return getattr( self.value, key ) diff --git a/static/maps/mvc/ui/ui-misc.js.map b/static/maps/mvc/ui/ui-misc.js.map index 5bb060fa8e2..56be4113766 100644 --- a/static/maps/mvc/ui/ui-misc.js.map +++ b/static/maps/mvc/ui/ui-misc.js.map @@ -1 +1 @@ -{"version":3,"file":"ui-misc.js","sources":["../../../src/mvc/ui/ui-misc.js"],"names":["define","Utils","Select","Slider","Options","Drilldown","ButtonMenu","ButtonCheck","Modal","Image","Backbone","View","extend","optionsDefault","url","cls","initialize","options","this","merge","setElement","_template","Label","title","new_title","$el","html","value","Icon","floating","icon","tooltip","placement","$","el","Button","id","uid","on","hide","onclick","wait","removeClass","addClass","prop","unwait","str","ButtonIcon","$button","find","self","disabled","disable","enable","setIcon","icon_cls","width","Anchor","Message","message","status","persistent","update","append","fadeIn","timeout","window","clearTimeout","setTimeout","is","fadeOut","Searchbox","searchword","search_field","val","Input","type","placeholder","visible","area","undefined","onchange","new_val","Hidden","tmpl","info","RadioButton","Checkbox","Radio"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"ui-misc.js","sources":["../../../src/mvc/ui/ui-misc.js"],"names":["define","Utils","Select","Slider","Options","Drilldown","ButtonMenu","ButtonCheck","Modal","Image","Backbone","View","extend","optionsDefault","url","cls","initialize","options","this","merge","setElement","_template","Label","title","new_title","$el","html","value","Icon","floating","icon","tooltip","placement","$","el","Button","id","uid","on","hide","onclick","wait","removeClass","addClass","prop","unwait","str","ButtonIcon","$button","find","self","disabled","disable","enable","setIcon","icon_cls","width","Anchor","Message","message","status","persistent","update","append","fadeIn","timeout","window","clearTimeout","setTimeout","is","fadeOut","Searchbox","searchword","search_field","val","Input","type","placeholder","visible","area","undefined","onchange","new_val","Hidden","tmpl","info","RadioButton","Checkbox","Radio"],"mappings":"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"} \ No newline at end of file diff --git a/static/maps/mvc/ui/ui-select-library.js.map b/static/maps/mvc/ui/ui-select-library.js.map index cb1a9bce43d..fa57eb3ba80 100644 --- a/static/maps/mvc/ui/ui-select-library.js.map +++ b/static/maps/mvc/ui/ui-select-library.js.map @@ -1 +1 @@ -{"version":3,"file":"ui-select-library.js","sources":["../../../src/mvc/ui/ui-select-library.js"],"names":["define","Utils","Ui","Table","List","Libraries","Backbone","Collection","extend","url","galaxy_config","root","LibraryDatasets","initialize","self","this","config","Model","library_id","on","fetch","reset","get","View","options","libraries","datasets","library_select","Select","onchange","value","set","dataset_list","name","optional","trigger","data","each","model","push","id","label","update","library_current","text","setElement","_template","$","append","$el","success","undefined","val"],"mappings":"AACAA,QAAQ,cAAe,iBAAkB,kBAAmB,kBACpD,SAASC,EAAOC,EAAIC,EAAOC,GAGnC,GAAIC,GAAYC,SAASC,WAAWC,QAChCC,IAAKC,cAAcC,KAAO,kBAI1BC,EAAkBN,SAASC,WAAWC,QACtCK,WAAY,WACR,GAAIC,GAAOC,IACXA,MAAKC,OAAS,GAAIV,UAASW,OAAQC,WAAY,OAC/CH,KAAKC,OAAOG,GAAG,SAAU,WACrBL,EAAKM,OAAQC,OAAO,OAG5BZ,IAAK,WACD,MAAOC,eAAcC,KAAO,iBAAmBI,KAAKC,OAAOM,IAAI,cAAgB,eAKnFC,EAAOjB,SAASiB,KAAKf,QAErBK,WAAa,SAASW,GAElB,GAAIV,GAAOC,IAGXA,MAAKU,UAAa,GAAIpB,GACtBU,KAAKW,SAAa,GAAId,GAGtBG,KAAKS,QAAUA,EAIfT,KAAKY,eAAiB,GAAIzB,GAAG0B,OAAOL,MAChCM,SAAc,SAASC,GACnBhB,EAAKY,SAASV,OAAOe,IAAI,aAAcD,MAK/Cf,KAAKiB,aAAe,GAAI5B,GAAKmB,MACzBU,KAAc,UACdC,SAAcV,EAAQU,SACtBL,SAAc,WACVf,EAAKqB,QAAQ,aAKrBpB,KAAKU,UAAUN,GAAG,QAAS,WACvB,GAAIiB,KACJtB,GAAKW,UAAUY,KAAK,SAASC,GACzBF,EAAKG,MACDT,MAAUQ,EAAME,GAChBC,MAAUH,EAAMhB,IAAI,YAG5BR,EAAKa,eAAee,OAAON,KAI/BrB,KAAKW,SAASP,GAAG,QAAS,WACtB,GAAIiB,MACAO,EAAkB7B,EAAKa,eAAeiB,MAClB,QAApBD,GACA7B,EAAKY,SAASW,KAAK,SAASC,GACE,SAAtBA,EAAMhB,IAAI,SACVc,EAAKG,MACDT,MAAUQ,EAAME,GAChBC,MAAUH,EAAMhB,IAAI,YAKpCR,EAAKkB,aAAaU,OAAON,KAI7BrB,KAAKI,GAAG,SAAU,WACdK,EAAQK,UAAYL,EAAQK,SAASf,EAAKgB,WAI9Cf,KAAK8B,WAAW9B,KAAK+B,aACrB/B,KAAKgC,EAAE,mBAAmBC,OAAOjC,KAAKY,eAAesB,KACrDlC,KAAKkC,IAAID,OAAOjC,KAAKiB,aAAaiB,KAGlClC,KAAKU,UAAUL,OACXC,OAAO,EACP6B,QAAS,WACLpC,EAAKa,eAAeQ,QAAQ,UACDgB,SAAvBrC,EAAKU,QAAQM,OACbhB,EAAKgB,MAAMhB,EAAKU,QAAQM,WAOxCA,MAAO,SAASsB,GACZ,MAAOrC,MAAKiB,aAAaF,MAAMsB,IAInCN,UAAW,WACP,MAAQ,qKAShB,QACIvB,KAAMA"} \ No newline at end of file +{"version":3,"file":"ui-select-library.js","sources":["../../../src/mvc/ui/ui-select-library.js"],"names":["define","Utils","Ui","Table","List","Libraries","Backbone","Collection","extend","url","galaxy_config","root","LibraryDatasets","initialize","self","this","config","Model","library_id","on","fetch","reset","get","View","options","libraries","datasets","library_select","Select","onchange","value","set","dataset_list","name","optional","multiple","trigger","data","each","model","push","id","label","update","library_current","text","setElement","_template","$","append","$el","success","undefined","val"],"mappings":"AACAA,QAAQ,cAAe,iBAAkB,kBAAmB,kBACpD,SAASC,EAAOC,EAAIC,EAAOC,GAGnC,GAAIC,GAAYC,SAASC,WAAWC,QAChCC,IAAKC,cAAcC,KAAO,kBAI1BC,EAAkBN,SAASC,WAAWC,QACtCK,WAAY,WACR,GAAIC,GAAOC,IACXA,MAAKC,OAAS,GAAIV,UAASW,OAAQC,WAAY,OAC/CH,KAAKC,OAAOG,GAAG,SAAU,WACrBL,EAAKM,OAAQC,OAAO,OAG5BZ,IAAK,WACD,MAAOC,eAAcC,KAAO,iBAAmBI,KAAKC,OAAOM,IAAI,cAAgB,eAKnFC,EAAOjB,SAASiB,KAAKf,QAErBK,WAAa,SAASW,GAElB,GAAIV,GAAOC,IAGXA,MAAKU,UAAa,GAAIpB,GACtBU,KAAKW,SAAa,GAAId,GAGtBG,KAAKS,QAAUA,EAIfT,KAAKY,eAAiB,GAAIzB,GAAG0B,OAAOL,MAChCM,SAAc,SAASC,GACnBhB,EAAKY,SAASV,OAAOe,IAAI,aAAcD,MAK/Cf,KAAKiB,aAAe,GAAI5B,GAAKmB,MACzBU,KAAc,UACdC,SAAcV,EAAQU,SACtBC,SAAcX,EAAQW,SACtBN,SAAc,WACVf,EAAKsB,QAAQ,aAKrBrB,KAAKU,UAAUN,GAAG,QAAS,WACvB,GAAIkB,KACJvB,GAAKW,UAAUa,KAAK,SAASC,GACzBF,EAAKG,MACDV,MAAUS,EAAME,GAChBC,MAAUH,EAAMjB,IAAI,YAG5BR,EAAKa,eAAegB,OAAON,KAI/BtB,KAAKW,SAASP,GAAG,QAAS,WACtB,GAAIkB,MACAO,EAAkB9B,EAAKa,eAAekB,MAClB,QAApBD,GACA9B,EAAKY,SAASY,KAAK,SAASC,GACE,SAAtBA,EAAMjB,IAAI,SACVe,EAAKG,MACDV,MAAUS,EAAME,GAChBC,MAAUH,EAAMjB,IAAI,YAKpCR,EAAKkB,aAAaW,OAAON,KAI7BtB,KAAKI,GAAG,SAAU,WACdK,EAAQK,UAAYL,EAAQK,SAASf,EAAKgB,WAI9Cf,KAAK+B,WAAW/B,KAAKgC,aACrBhC,KAAKiC,EAAE,mBAAmBC,OAAOlC,KAAKY,eAAeuB,KACrDnC,KAAKmC,IAAID,OAAOlC,KAAKiB,aAAakB,KAGlCnC,KAAKU,UAAUL,OACXC,OAAO,EACP8B,QAAS,WACLrC,EAAKa,eAAeS,QAAQ,UACDgB,SAAvBtC,EAAKU,QAAQM,OACbhB,EAAKgB,MAAMhB,EAAKU,QAAQM,WAOxCA,MAAO,SAASuB,GACZ,MAAOtC,MAAKiB,aAAaF,MAAMuB,IAInCN,UAAW,WACP,MAAQ,qKAShB,QACIxB,KAAMA"} \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-list.js b/static/scripts/mvc/ui/ui-list.js index a47f5e7b4c1..28ad76b38f6 100644 --- a/static/scripts/mvc/ui/ui-list.js +++ b/static/scripts/mvc/ui/ui-list.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc"],function(a,b,c){var d=Backbone.View.extend({initialize:function(a){var d=this;this.options=a,this.name=a.name||"element",this.message=new c.Message({cls:"ui-margin-top"}),this.portlet=new b.View({cls:"ui-portlet-section"}),this.select=new c.Select.View({optional:a.optional}),this.button=new c.ButtonIcon({icon:"fa fa-sign-in",floating:"left",tooltip:"Insert new "+this.name,onclick:function(){d.add({id:d.select.value(),name:d.select.text()})}}),this.setElement(this._template(a)),this.$(".ui-list-message").append(this.message.$el),this.$(".ui-list-portlet").append(this.portlet.$el),this.$(".ui-list-button").append(this.button.$el),this.$(".ui-list-select").append(this.select.$el)},value:function(a){if(void 0!==a){if(this.portlet.empty(),$.isArray(a))for(var b in a)this.add({id:a[b].id,name:a[b].name});this._refresh()}var c=[];return this.$(".ui-list-id").each(function(){c.push({id:$(this).prop("id"),name:$(this).find(".ui-list-name").html()})}),c},add:function(b){var c=this;if(0===this.$("#"+b.id).length)if(a.validate(b.id)){var d=$(this._templateRow({id:b.id,name:b.name}));d.on("click",function(){d.remove(),c._refresh()}),d.on("mouseover",function(){d.addClass("portlet-highlight")}),d.on("mouseout",function(){d.removeClass("portlet-highlight")}),this.portlet.append(d),this._refresh()}else this.message.update({message:"Please select a valid "+this.name+".",status:"danger"});else this.message.update({message:"This "+this.name+" is already in the list."})},update:function(a){this.select.update(a)},_refresh:function(){this.$(".ui-list-id").length>0?this.$(".ui-list-portlet").show():this.$(".ui-list-portlet").hide(),this.options.onchange&&this.options.onchange()},_template:function(){return'
'},_templateRow:function(a){return'
'+a.name+"
"}});return{View:d}}); +define(["utils/utils","mvc/ui/ui-portlet","mvc/ui/ui-misc"],function(a,b,c){var d=Backbone.View.extend({initialize:function(a){var d=this;this.options=a,this.name=a.name||"element",this.multiple=a.multiple||!1,this.message=new c.Message({cls:"ui-margin-top"}),this.portlet=new b.View({cls:"ui-portlet-section"}),this.select=new c.Select.View({optional:a.optional}),this.button=new c.ButtonIcon({icon:"fa fa-sign-in",floating:"left",tooltip:"Insert new "+this.name,onclick:function(){d.add({id:d.select.value(),name:d.select.text()})}}),this.setElement(this._template(a)),this.$(".ui-list-message").append(this.message.$el),this.$(".ui-list-portlet").append(this.portlet.$el),this.$(".ui-list-button").append(this.button.$el),this.$(".ui-list-select").append(this.select.$el)},value:function(a){if(void 0!==a){if(this.portlet.empty(),$.isArray(a))for(var b in a)this.add({id:a[b].id,name:a[b].name});this._refresh()}var c=[];return this.$(".ui-list-id").each(function(){c.push({id:$(this).prop("id"),name:$(this).find(".ui-list-name").html()})}),c},add:function(b){var c=this;if(0===this.$("#"+b.id).length)if(a.validate(b.id)){var d=$(this._templateRow({id:b.id,name:b.name}));d.on("click",function(){d.remove(),c._refresh()}),d.on("mouseover",function(){d.addClass("portlet-highlight")}),d.on("mouseout",function(){d.removeClass("portlet-highlight")}),this.portlet.append(d),this._refresh()}else this.message.update({message:"Please select a valid "+this.name+".",status:"danger"});else this.message.update({message:"This "+this.name+" is already in the list."})},update:function(a){this.select.update(a)},_refresh:function(){this.$(".ui-list-id").length>0?(!this.multiple&&this.button.disable(),this.$(".ui-list-portlet").show()):(this.button.enable(),this.$(".ui-list-portlet").hide()),this.options.onchange&&this.options.onchange()},_template:function(){return'
'},_templateRow:function(a){return'
'+a.name+"
"}});return{View:d}}); //# sourceMappingURL=../../../maps/mvc/ui/ui-list.js.map \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-misc.js b/static/scripts/mvc/ui/ui-misc.js index 85c88678e86..9ac3d8ab1a3 100644 --- a/static/scripts/mvc/ui/ui-misc.js +++ b/static/scripts/mvc/ui/ui-misc.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-options","mvc/ui/ui-drilldown","mvc/ui/ui-button-menu","mvc/ui/ui-button-check","mvc/ui/ui-modal"],function(a,b,c,d,e,f,g,h){var i=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options))},_template:function(a){return''}}),j=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options))},title:function(a){this.$el.html(a)},_template:function(a){return'"},value:function(){return options.title}}),k=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},_template:function(a){return'
 '+a.title+"
"}}),l=Backbone.View.extend({optionsDefault:{id:a.uid(),title:"",floating:"right",cls:"ui-button btn btn-default",icon:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",function(){$(".tooltip").hide(),b.onclick&&b.onclick()}),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},wait:function(){this.$el.removeClass(this.options.cls).addClass("btn btn-info").prop("disabled",!0),this.$(".icon").removeClass(this.options.icon).addClass("fa-spinner fa-spin"),this.$(".title").html("Sending...")},unwait:function(){this.$el.removeClass("btn btn-info").addClass(this.options.cls).prop("disabled",!1),this.$(".icon").removeClass("fa-spinner fa-spin").addClass(this.options.icon),this.$(".title").html(this.options.title)},_template:function(a){var b='"}}),m=Backbone.View.extend({optionsDefault:{id:a.uid(),title:"",floating:"right",cls:"ui-button-icon",icon:"",tooltip:"",onclick:null},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),this.$button=this.$el.find(".button");var c=this;$(this.el).on("click",function(){$(".tooltip").hide(),b.onclick&&!c.disabled&&b.onclick()}),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},disable:function(){this.$button.addClass("disabled"),this.disabled=!0},enable:function(){this.$button.removeClass("disabled"),this.disabled=!1},setIcon:function(a){this.$("i").removeClass(this.options.icon).addClass(a),this.options.icon=a},_template:function(a){var b="";a.title&&(b="width: auto;");var c='
';return c+=a.title?'
 '+a.title+"
":'',c+="
"}}),n=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",b.onclick)},_template:function(a){return'"}}),o=Backbone.View.extend({optionsDefault:{message:null,status:"info",cls:"",persistent:!1},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement('
'),this.options.message&&this.update(this.options)},update:function(b){if(this.options=a.merge(b,this.optionsDefault),""!=b.message){if(this.$el.html(this._template(this.options)),this.$el.find(".alert").append(b.message),this.$el.fadeIn(),this.timeout&&window.clearTimeout(this.timeout),!b.persistent){var c=this;this.timeout=window.setTimeout(function(){c.$el.is(":visible")?c.$el.fadeOut():c.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(a){return'
'}}),p=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options));var c=this;this.options.onclick&&this.$el.on("submit",function(){var a=c.$el.find("#search");c.options.onclick(a.val())})},_template:function(a){return''}}),q=Backbone.View.extend({optionsDefault:{type:"text",placeholder:"",disabled:!1,visible:!0,cls:"",area:!1},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),void 0!==this.options.value&&this.value(this.options.value),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var c=this;this.$el.on("input",function(){c.options.onchange&&c.options.onchange(c.$el.val())})},value:function(a){return void 0!==a&&this.$el.val(a),this.$el.val()},_template:function(a){return a.area?'':''}}),r=Backbone.View.extend({initialize:function(a){this.options=a,this.setElement(this._template(this.options)),void 0!==this.options.value&&this.value(this.options.value)},value:function(a){return void 0!==a&&this.$("hidden").val(a),this.$("hidden").val()},_template:function(a){var b='
';return a.info&&(b+="
"+a.info+"
"),b+='
'}});return{Anchor:n,Button:l,ButtonIcon:m,ButtonCheck:g,ButtonMenu:f,Icon:k,Image:i,Input:q,Label:j,Message:o,Modal:h,RadioButton:d.RadioButton,Checkbox:d.Checkbox,Radio:d.Radio,Searchbox:p,Select:b,Hidden:r,Slider:c,Drilldown:e}}); +define(["utils/utils","mvc/ui/ui-select-default","mvc/ui/ui-slider","mvc/ui/ui-options","mvc/ui/ui-drilldown","mvc/ui/ui-button-menu","mvc/ui/ui-button-check","mvc/ui/ui-modal"],function(a,b,c,d,e,f,g,h){var i=Backbone.View.extend({optionsDefault:{url:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options))},_template:function(a){return''}}),j=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options))},title:function(a){this.$el.html(a)},_template:function(a){return'"},value:function(){return options.title}}),k=Backbone.View.extend({optionsDefault:{floating:"right",icon:"",tooltip:"",placement:"bottom",title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},_template:function(a){return'
 '+a.title+"
"}}),l=Backbone.View.extend({optionsDefault:{id:a.uid(),title:"",floating:"right",cls:"ui-button btn btn-default",icon:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",function(){$(".tooltip").hide(),b.onclick&&b.onclick()}),$(this.el).tooltip({title:b.tooltip,placement:"bottom"})},wait:function(){this.$el.removeClass(this.options.cls).addClass("btn btn-info").prop("disabled",!0),this.$(".icon").removeClass(this.options.icon).addClass("fa-spinner fa-spin"),this.$(".title").html("Sending...")},unwait:function(){this.$el.removeClass("btn btn-info").addClass(this.options.cls).prop("disabled",!1),this.$(".icon").removeClass("fa-spinner fa-spin").addClass(this.options.icon),this.$(".title").html(this.options.title)},_template:function(a){var b='"}}),m=Backbone.View.extend({optionsDefault:{id:a.uid(),title:"",floating:"right",cls:"ui-button-icon",icon:"",tooltip:"",onclick:null},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),this.$button=this.$el.find(".button");var c=this;$(this.el).on("click",function(){$(".tooltip").hide(),b.onclick&&!c.disabled&&b.onclick()}),this.$button.tooltip({title:b.tooltip,placement:"bottom"})},disable:function(){this.$button.addClass("disabled"),this.disabled=!0},enable:function(){this.$button.removeClass("disabled"),this.disabled=!1},setIcon:function(a){this.$("i").removeClass(this.options.icon).addClass(a),this.options.icon=a},_template:function(a){var b="";a.title&&(b="width: auto;");var c='
';return c+=a.title?' '+a.title+"":'',c+="
"}}),n=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",b.onclick)},_template:function(a){return'"}}),o=Backbone.View.extend({optionsDefault:{message:null,status:"info",cls:"",persistent:!1},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement('
'),this.options.message&&this.update(this.options)},update:function(b){if(this.options=a.merge(b,this.optionsDefault),""!=b.message){if(this.$el.html(this._template(this.options)),this.$el.find(".alert").append(b.message),this.$el.fadeIn(),this.timeout&&window.clearTimeout(this.timeout),!b.persistent){var c=this;this.timeout=window.setTimeout(function(){c.$el.is(":visible")?c.$el.fadeOut():c.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(a){return'
'}}),p=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options));var c=this;this.options.onclick&&this.$el.on("submit",function(){var a=c.$el.find("#search");c.options.onclick(a.val())})},_template:function(a){return''}}),q=Backbone.View.extend({optionsDefault:{type:"text",placeholder:"",disabled:!1,visible:!0,cls:"",area:!1},initialize:function(b){this.options=a.merge(b,this.optionsDefault),this.setElement(this._template(this.options)),void 0!==this.options.value&&this.value(this.options.value),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var c=this;this.$el.on("input",function(){c.options.onchange&&c.options.onchange(c.$el.val())})},value:function(a){return void 0!==a&&this.$el.val(a),this.$el.val()},_template:function(a){return a.area?'':''}}),r=Backbone.View.extend({initialize:function(a){this.options=a,this.setElement(this._template(this.options)),void 0!==this.options.value&&this.value(this.options.value)},value:function(a){return void 0!==a&&this.$("hidden").val(a),this.$("hidden").val()},_template:function(a){var b='
';return a.info&&(b+="
"+a.info+"
"),b+='
'}});return{Anchor:n,Button:l,ButtonIcon:m,ButtonCheck:g,ButtonMenu:f,Icon:k,Image:i,Input:q,Label:j,Message:o,Modal:h,RadioButton:d.RadioButton,Checkbox:d.Checkbox,Radio:d.Radio,Searchbox:p,Select:b,Hidden:r,Slider:c,Drilldown:e}}); //# sourceMappingURL=../../../maps/mvc/ui/ui-misc.js.map \ No newline at end of file diff --git a/static/scripts/mvc/ui/ui-select-library.js b/static/scripts/mvc/ui/ui-select-library.js index 7551263dc19..1248278a370 100644 --- a/static/scripts/mvc/ui/ui-select-library.js +++ b/static/scripts/mvc/ui/ui-select-library.js @@ -1,2 +1,2 @@ -define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-table","mvc/ui/ui-list"],function(a,b,c,d){var e=Backbone.Collection.extend({url:galaxy_config.root+"api/libraries"}),f=Backbone.Collection.extend({initialize:function(){var a=this;this.config=new Backbone.Model({library_id:null}),this.config.on("change",function(){a.fetch({reset:!0})})},url:function(){return galaxy_config.root+"api/libraries/"+this.config.get("library_id")+"/contents"}}),g=Backbone.View.extend({initialize:function(a){var c=this;this.libraries=new e,this.datasets=new f,this.options=a,this.library_select=new b.Select.View({onchange:function(a){c.datasets.config.set("library_id",a)}}),this.dataset_list=new d.View({name:"dataset",optional:a.optional,onchange:function(){c.trigger("change")}}),this.libraries.on("reset",function(){var a=[];c.libraries.each(function(b){a.push({value:b.id,label:b.get("name")})}),c.library_select.update(a)}),this.datasets.on("reset",function(){var a=[],b=c.library_select.text();null!==b&&c.datasets.each(function(b){"file"===b.get("type")&&a.push({value:b.id,label:b.get("name")})}),c.dataset_list.update(a)}),this.on("change",function(){a.onchange&&a.onchange(c.value())}),this.setElement(this._template()),this.$(".library-select").append(this.library_select.$el),this.$el.append(this.dataset_list.$el),this.libraries.fetch({reset:!0,success:function(){c.library_select.trigger("change"),void 0!==c.options.value&&c.value(c.options.value)}})},value:function(a){return this.dataset_list.value(a)},_template:function(){return'
Select Library
'}});return{View:g}}); +define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-table","mvc/ui/ui-list"],function(a,b,c,d){var e=Backbone.Collection.extend({url:galaxy_config.root+"api/libraries"}),f=Backbone.Collection.extend({initialize:function(){var a=this;this.config=new Backbone.Model({library_id:null}),this.config.on("change",function(){a.fetch({reset:!0})})},url:function(){return galaxy_config.root+"api/libraries/"+this.config.get("library_id")+"/contents"}}),g=Backbone.View.extend({initialize:function(a){var c=this;this.libraries=new e,this.datasets=new f,this.options=a,this.library_select=new b.Select.View({onchange:function(a){c.datasets.config.set("library_id",a)}}),this.dataset_list=new d.View({name:"dataset",optional:a.optional,multiple:a.multiple,onchange:function(){c.trigger("change")}}),this.libraries.on("reset",function(){var a=[];c.libraries.each(function(b){a.push({value:b.id,label:b.get("name")})}),c.library_select.update(a)}),this.datasets.on("reset",function(){var a=[],b=c.library_select.text();null!==b&&c.datasets.each(function(b){"file"===b.get("type")&&a.push({value:b.id,label:b.get("name")})}),c.dataset_list.update(a)}),this.on("change",function(){a.onchange&&a.onchange(c.value())}),this.setElement(this._template()),this.$(".library-select").append(this.library_select.$el),this.$el.append(this.dataset_list.$el),this.libraries.fetch({reset:!0,success:function(){c.library_select.trigger("change"),void 0!==c.options.value&&c.value(c.options.value)}})},value:function(a){return this.dataset_list.value(a)},_template:function(){return'
Select Library
'}});return{View:g}}); //# sourceMappingURL=../../../maps/mvc/ui/ui-select-library.js.map \ No newline at end of file From 0496310ef832368f6ad743b86c8a08e7a6844fa7 Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 20 Apr 2015 02:02:28 -0400 Subject: [PATCH 048/120] Merge new list wrapper functionality into default input wrapper --- lib/galaxy/tools/evaluation.py | 4 ---- lib/galaxy/tools/parameters/basic.py | 1 + lib/galaxy/tools/parameters/wrapped.py | 3 --- lib/galaxy/tools/wrappers.py | 20 ++------------------ 4 files changed, 3 insertions(+), 25 deletions(-) diff --git a/lib/galaxy/tools/evaluation.py b/lib/galaxy/tools/evaluation.py index 0909c39ed0b..4903838097d 100644 --- a/lib/galaxy/tools/evaluation.py +++ b/lib/galaxy/tools/evaluation.py @@ -13,7 +13,6 @@ from galaxy.tools.wrappers import ( DatasetCollectionWrapper, SelectToolParameterWrapper, InputValueWrapper, - ListValueWrapper, RawObjectWrapper ) from galaxy.tools.parameters.basic import ( @@ -227,9 +226,6 @@ class ToolEvaluator( object ): elif isinstance( input, SelectToolParameter ): input_values[ input.name ] = SelectToolParameterWrapper( input, input_values[ input.name ], self.app, other_values=param_dict, path_rewriter=self.unstructured_path_rewriter ) - elif isinstance( input_values[ input.name ], list ): - input_values[ input.name ] = ListValueWrapper( - input, input_values[ input.name ], param_dict ) else: input_values[ input.name ] = InputValueWrapper( input, input_values[ input.name ], param_dict ) diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 146720785ee..309d38c4d64 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -2379,6 +2379,7 @@ class LibraryDatasetToolParameter( ToolParameter ): """ def __init__( self, tool, input_source, context=None ): + input_source = ensure_input_source( input_source ) ToolParameter.__init__( self, tool, input_source ) self.multiple = input_source.get_bool( 'multiple', False ) diff --git a/lib/galaxy/tools/parameters/wrapped.py b/lib/galaxy/tools/parameters/wrapped.py index e8fc7aadf68..5765e40cb7b 100644 --- a/lib/galaxy/tools/parameters/wrapped.py +++ b/lib/galaxy/tools/parameters/wrapped.py @@ -7,7 +7,6 @@ from galaxy.tools.parameters.basic import ( ) from galaxy.tools.wrappers import ( InputValueWrapper, - ListValueWrapper, SelectToolParameterWrapper, DatasetFilenameWrapper, DatasetListWrapper, @@ -78,8 +77,6 @@ class WrappedParameters( object ): tool=tool, name=input.name, ) - elif isinstance( value, list ): - input_values[ input.name ] = ListValueWrapper( input, value, incoming ) else: input_values[ input.name ] = InputValueWrapper( input, value, incoming ) diff --git a/lib/galaxy/tools/wrappers.py b/lib/galaxy/tools/wrappers.py index a51049d29be..d7b2785a7a2 100644 --- a/lib/galaxy/tools/wrappers.py +++ b/lib/galaxy/tools/wrappers.py @@ -57,9 +57,9 @@ class RawObjectWrapper( ToolParameterValueWrapper ): return getattr( self.obj, key ) -class ListValueWrapper( ToolParameterValueWrapper ): +class InputValueWrapper( ToolParameterValueWrapper ): """ - Wraps an input so that __str__ gives the "param_dict" representation for list values. + Wraps an input so that __str__ gives the "param_dict" representation. """ def __init__( self, input, value, other_values={} ): self.input = input @@ -81,22 +81,6 @@ class ListValueWrapper( ToolParameterValueWrapper ): def __getattr__( self, key ): return getattr( self.value, key ) - -class InputValueWrapper( ToolParameterValueWrapper ): - """ - Wraps an input so that __str__ gives the "param_dict" representation. - """ - def __init__( self, input, value, other_values={} ): - self.input = input - self.value = value - self._other_values = other_values - - def __str__( self ): - return self.input.to_param_dict_string( self.value, self._other_values ) - - def __getattr__( self, key ): - return getattr( self.value, key ) - def __int__(self): return int(str(self)) From 138ae47036a45decc136cbe4946bb897b17d654a Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 20 Apr 2015 11:56:25 -0400 Subject: [PATCH 049/120] Move to_param_dict_string call back to previous location in parameter wrapper --- lib/galaxy/tools/wrappers.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/galaxy/tools/wrappers.py b/lib/galaxy/tools/wrappers.py index d7b2785a7a2..7d70c529584 100644 --- a/lib/galaxy/tools/wrappers.py +++ b/lib/galaxy/tools/wrappers.py @@ -64,19 +64,21 @@ class InputValueWrapper( ToolParameterValueWrapper ): def __init__( self, input, value, other_values={} ): self.input = input self.value = value - self.to_param_dict_string = self.input.to_param_dict_string( self.value, other_values ) + self._other_values = other_values def __str__( self ): - if isinstance( self.to_param_dict_string, list): - return ','.join( self.to_param_dict_string ) + to_param_dict_string = self.input.to_param_dict_string( self.value, self._other_values ) + if isinstance( to_param_dict_string, list): + return ','.join( to_param_dict_string ) else: - return self.to_param_dict_string + return to_param_dict_string def __iter__( self ): - if not isinstance( self.to_param_dict_string, list): - return iter( [self.to_param_dict_string] ) + to_param_dict_string = self.input.to_param_dict_string( self.value, self._other_values ) + if not isinstance( to_param_dict_string, list): + return iter( [ to_param_dict_string ] ) else: - return iter( self.to_param_dict_string ) + return iter( to_param_dict_string ) def __getattr__( self, key ): return getattr( self.value, key ) From 5876e5f80cc7f33c808822697eb2ae71d44a6307 Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 20 Apr 2015 14:21:42 -0400 Subject: [PATCH 050/120] Revise library data parameter tests --- lib/galaxy/tools/wrappers.py | 4 ++-- test/api/test_tools.py | 9 ++++++--- test/functional/tools/library_data.xml | 9 ++++++--- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/galaxy/tools/wrappers.py b/lib/galaxy/tools/wrappers.py index 7d70c529584..8cc29a6cfa7 100644 --- a/lib/galaxy/tools/wrappers.py +++ b/lib/galaxy/tools/wrappers.py @@ -68,14 +68,14 @@ class InputValueWrapper( ToolParameterValueWrapper ): def __str__( self ): to_param_dict_string = self.input.to_param_dict_string( self.value, self._other_values ) - if isinstance( to_param_dict_string, list): + if isinstance( to_param_dict_string, list ): return ','.join( to_param_dict_string ) else: return to_param_dict_string def __iter__( self ): to_param_dict_string = self.input.to_param_dict_string( self.value, self._other_values ) - if not isinstance( to_param_dict_string, list): + if not isinstance( to_param_dict_string, list ): return iter( [ to_param_dict_string ] ) else: return iter( to_param_dict_string ) diff --git a/test/api/test_tools.py b/test/api/test_tools.py index 767cb6e6b5f..6d71acdfb75 100644 --- a/test/api/test_tools.py +++ b/test/api/test_tools.py @@ -126,12 +126,15 @@ class ToolsTestCase( api.ApiTestCase ): history_id = self.dataset_populator.new_history() ld = LibraryPopulator( self ).new_library_dataset( "lda_test_library" ) inputs = { - "library_datasets": [ld[ "ldda_id" ]], + "library_dataset": ld[ "ldda_id" ], + "library_dataset_multiple": [ld[ "ldda_id" ], ld[ "ldda_id" ]] } response = self._run( "library_data", history_id, inputs, assert_ok=True ) output = response[ "outputs" ] - output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output[ 0 ] ) - assert output1_content == "TestData", output1_content + output_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output[ 0 ] ) + assert output_content == "TestData", output_content + output_multiple_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output[ 1 ] ) + assert output_multiple_content == "TestDataTestData", output_multiple_content @skip_without_tool( "multi_data_param" ) def test_multidata_param( self ): diff --git a/test/functional/tools/library_data.xml b/test/functional/tools/library_data.xml index 156414a4b0a..7e30bfd5419 100644 --- a/test/functional/tools/library_data.xml +++ b/test/functional/tools/library_data.xml @@ -1,14 +1,17 @@ - #for $input in $library_datasets - cat $input.get_file_name() >> $output + cat $library_dataset >> $output; + #for $input in $library_dataset_multiple + cat $input >> $output_multiple; #end for - + + + From e2175d66e95f9bb31b7566f2ec53b131654a80b4 Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 20 Apr 2015 18:31:19 -0400 Subject: [PATCH 051/120] Switch default for library data parameter to multiple entries --- lib/galaxy/tools/parameters/basic.py | 2 +- test/functional/tools/library_data.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 309d38c4d64..ccd37e7569f 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -2381,7 +2381,7 @@ class LibraryDatasetToolParameter( ToolParameter ): def __init__( self, tool, input_source, context=None ): input_source = ensure_input_source( input_source ) ToolParameter.__init__( self, tool, input_source ) - self.multiple = input_source.get_bool( 'multiple', False ) + self.multiple = input_source.get_bool( 'multiple', True ) def get_html_field( self, trans=None, value=None, other_values={} ): return form_builder.LibraryField( self.name, value=value, trans=trans ) diff --git a/test/functional/tools/library_data.xml b/test/functional/tools/library_data.xml index 7e30bfd5419..8fd1a147f49 100644 --- a/test/functional/tools/library_data.xml +++ b/test/functional/tools/library_data.xml @@ -6,8 +6,8 @@ #end for - - + + From 660b92074eaf6f80bd173e462f34afb50227c055 Mon Sep 17 00:00:00 2001 From: Bjoern Gruening Date: Thu, 23 Apr 2015 15:45:31 +0200 Subject: [PATCH 052/120] add emboss datatypes --- config/datatypes_conf.xml.sample | 98 ++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/config/datatypes_conf.xml.sample b/config/datatypes_conf.xml.sample index 42b874b46cc..3a43aebc275 100644 --- a/config/datatypes_conf.xml.sample +++ b/config/datatypes_conf.xml.sample @@ -271,6 +271,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + ${$site_id.startswith( 'local_' ) or $dataset.dbkey in $site_dbkeys} + + + ${redirect_url} + + + + #if ($dataset.dbkey in $site_dbkeys) + $site_organisms[ $site_dbkeys.index( $bed_file.dbkey ) ] + #else: + $bed_file.dbkey + #end if + + + <?xml version="1.0" encoding="utf-8"?> +<jnlp + spec="1.0+" + codebase="${site_link}"> + <information> + <title>IGV 1.5</title> + <vendor>The Broad Institute</vendor> + <homepage href="http://www.broadinstitute.org/igv"/> + <description>IGV Software</description> + <description kind="short">IGV</description> + </information> + <security> + <all-permissions/> + </security> + <resources> + +<j2se version="1.5+" initial-heap-size="256m" max-heap-size="1100m"/> + <jar href="igv.jar" download="eager" main="true"/> + <jar href="batik-codec.jar" download="eager"/> + <property name="apple.laf.useScreenMenuBar" value="true"/> + <property name="com.apple.mrj.application.growbox.intrudes" value="false"/> + <property name="com.apple.mrj.application.live-resize" value="true"/> + <property name="com.apple.macos.smallTabs" value="true"/> + </resources> + + <resources os="Mac" arch="i386"> + <property name="apple.awt.graphics.UseQuartz" value="false"/> + <nativelib href="hdfnative-macintel.jar"/> + </resources> + + <resources os="Mac" arch="ppc"> + <property name="apple.awt.graphics.UseQuartz" value="false"/> + <nativelib href="hdfnative-macppc.jar"/> + </resources> + + <resources os="Mac" arch="PowerPC"> + <property name="apple.awt.graphics.UseQuartz" value="false"/> + <nativelib href="hdfnative-macppc.jar"/> + </resources> + + <resources os="Windows"> + <property name="sun.java2d.noddraw" value="true"/> + <nativelib href="hdfnative-win.jar"/> + </resources> + + <resources os="Linux"> + <nativelib href="hdfnative-linux64.jar"/> + </resources> + + <application-desc main-class="org.broad.igv.ui.IGVMainFrame"> + <argument>-g</argument> + <argument>${site_organism}</argument> + <argument>${bed_file.url}</argument> + </application-desc> +</jnlp> + + + #if $site_id.startswith( 'local_' ) + ${site_link}?file=${bed_file.qp}&genome=${site_organism}&merge=true&name=${qp( $bed_file.name )} + #elif $site_id.startswith( 'web_link_' ): + ${site_link}?sessionURL=${bed_file.qp}&genome=${site_organism}&merge=true&name=${qp( $bed_file.name )} + #else: + ${jnlp.url} + #end if + + + + + + + + ${ $dataset.dbkey == $value } + + + http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${bed_file.qp}&genome=${bed_file.dbkey}&merge=true&name=${qp( $bed_file.name )} + + + + + + + From 3a998d0f2af3b7c85a55d87dc40a2c02142b9bd5 Mon Sep 17 00:00:00 2001 From: Daniel Blankenberg Date: Thu, 14 May 2015 14:57:04 -0400 Subject: [PATCH 107/120] Tweak display application id to match interval to bed. --- display_applications/igv/interval_as_bed.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/display_applications/igv/interval_as_bed.xml b/display_applications/igv/interval_as_bed.xml index 28fba5dd58e..1aa75bfa7f0 100644 --- a/display_applications/igv/interval_as_bed.xml +++ b/display_applications/igv/interval_as_bed.xml @@ -1,5 +1,5 @@ - + From 8965dd2cbfd40426f20345e63c894c53c8a4b6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gr=C3=BCning?= Date: Thu, 14 May 2015 21:23:27 +0200 Subject: [PATCH 108/120] Pin the IPython Docker Image to the 15.05. From now on we pin every Galaxy release to a special ipython-notebook image. --- .../interactive_environments/ipython/config/ipython.ini.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/plugins/interactive_environments/ipython/config/ipython.ini.sample b/config/plugins/interactive_environments/ipython/config/ipython.ini.sample index b8c9e8ed007..c1ffbff2aa2 100644 --- a/config/plugins/interactive_environments/ipython/config/ipython.ini.sample +++ b/config/plugins/interactive_environments/ipython/config/ipython.ini.sample @@ -12,7 +12,7 @@ command = docker # The docker image name that should be started. -image = bgruening/docker-ipython-notebook:0.2 +image = bgruening/docker-ipython-notebook:15.05 # Additional arguments that are passed to the `docker run` command. command_inject = --sig-proxy=true From 97c450293bd0fca71af9fec333e23429c43fa86e Mon Sep 17 00:00:00 2001 From: Daniel Blankenberg Date: Thu, 14 May 2015 15:59:44 -0400 Subject: [PATCH 109/120] IGV External displays cannot use a name with a comma in it, so replace commas with semicolons. --- display_applications/igv/bam.xml | 6 +++--- display_applications/igv/gff.xml | 6 +++--- display_applications/igv/interval_as_bed.xml | 6 +++--- display_applications/igv/vcf.xml | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/display_applications/igv/bam.xml b/display_applications/igv/bam.xml index 275e6aa16ef..be1758c870a 100644 --- a/display_applications/igv/bam.xml +++ b/display_applications/igv/bam.xml @@ -85,9 +85,9 @@ #if $site_id.startswith( 'local_' ) - ${site_link}?file=${bam_file.qp}&genome=${site_organism}&merge=true&name=${qp( $bam_file.name )} + ${site_link}?file=${bam_file.qp}&genome=${site_organism}&merge=true&name=${qp( ( $bam_file.name or $DATASET_HASH ).replace( ',', ';' ) )} #elif $site_id.startswith( 'web_link_' ): - ${site_link}?sessionURL=${bam_file.qp}&genome=${site_organism}&merge=true&name=${qp( $bam_file.name )} + ${site_link}?sessionURL=${bam_file.qp}&genome=${site_organism}&merge=true&name=${qp( ( $bam_file.name or $DATASET_HASH ).replace( ',', ';' ) )} #else: ${jnlp.url} #end if @@ -101,7 +101,7 @@ ${ $dataset.dbkey == $value } - http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${bam_file.qp}&genome=${bam_file.dbkey}&merge=true&name=${qp( $bam_file.name )} + http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${bam_file.qp}&genome=${bam_file.dbkey}&merge=true&name=${qp( ( $bam_file.name or $DATASET_HASH ).replace( ',', ';' ) )} diff --git a/display_applications/igv/gff.xml b/display_applications/igv/gff.xml index 57e60bbadc4..d23c4274e53 100644 --- a/display_applications/igv/gff.xml +++ b/display_applications/igv/gff.xml @@ -84,9 +84,9 @@ #if $site_id.startswith( 'local_' ) - ${site_link}?file=${gff_file.qp}&genome=${site_organism}&merge=true&name=${qp( $gff_file.name )} + ${site_link}?file=${gff_file.qp}&genome=${site_organism}&merge=true&name=${qp( ( $gff_file.name or $DATASET_HASH ).replace( ',', ';' ) )} #elif $site_id.startswith( 'web_link_' ): - ${site_link}?sessionURL=${gff_file.qp}&genome=${site_organism}&merge=true&name=${qp( $gff_file.name )} + ${site_link}?sessionURL=${gff_file.qp}&genome=${site_organism}&merge=true&name=${qp( ( $gff_file.name or $DATASET_HASH ).replace( ',', ';' ) )} #else: ${jnlp.url} #end if @@ -100,7 +100,7 @@ ${ $dataset.dbkey == $value } - http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${gff_file.qp}&genome=${gff_file.dbkey}&merge=true&name=${qp( $gff_file.name )} + http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${gff_file.qp}&genome=${gff_file.dbkey}&merge=true&name=${qp( ( $gff_file.name or $DATASET_HASH ).replace( ',', ';' ) )} diff --git a/display_applications/igv/interval_as_bed.xml b/display_applications/igv/interval_as_bed.xml index 1aa75bfa7f0..302c6f0fa17 100644 --- a/display_applications/igv/interval_as_bed.xml +++ b/display_applications/igv/interval_as_bed.xml @@ -84,9 +84,9 @@ #if $site_id.startswith( 'local_' ) - ${site_link}?file=${bed_file.qp}&genome=${site_organism}&merge=true&name=${qp( $bed_file.name )} + ${site_link}?file=${bed_file.qp}&genome=${site_organism}&merge=true&name=${qp( ( $bed_file.name or $DATASET_HASH ).replace( ',', ';' ) )} #elif $site_id.startswith( 'web_link_' ): - ${site_link}?sessionURL=${bed_file.qp}&genome=${site_organism}&merge=true&name=${qp( $bed_file.name )} + ${site_link}?sessionURL=${bed_file.qp}&genome=${site_organism}&merge=true&name=${qp( ( $bed_file.name or $DATASET_HASH ).replace( ',', ';' ) )} #else: ${jnlp.url} #end if @@ -100,7 +100,7 @@ ${ $dataset.dbkey == $value } - http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${bed_file.qp}&genome=${bed_file.dbkey}&merge=true&name=${qp( $bed_file.name )} + http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${bed_file.qp}&genome=${bed_file.dbkey}&merge=true&name=${qp( ( $bed_file.name or $DATASET_HASH ).replace( ',', ';' ) )} diff --git a/display_applications/igv/vcf.xml b/display_applications/igv/vcf.xml index 00321d22e77..28c76f25d46 100644 --- a/display_applications/igv/vcf.xml +++ b/display_applications/igv/vcf.xml @@ -85,9 +85,9 @@ #if $site_id.startswith( 'local_' ) - ${site_link}?file=${bgzip_file.qp}&genome=${site_organism}&merge=true&name=${qp( $bgzip_file.name )} + ${site_link}?file=${bgzip_file.qp}&genome=${site_organism}&merge=true&name=${qp( ( $bgzip_file.name or $DATASET_HASH ).replace( ',', ';' ) )} #elif $site_id.startswith( 'web_link_' ): - ${site_link}?sessionURL=${bgzip_file.qp}&genome=${site_organism}&merge=true&name=${qp( $bgzip_file.name )} + ${site_link}?sessionURL=${bgzip_file.qp}&genome=${site_organism}&merge=true&name=${qp( ( $bgzip_file.name or $DATASET_HASH ).replace( ',', ';' ) )} #else: ${jnlp.url} #end if @@ -101,7 +101,7 @@ ${ $dataset.dbkey == $value } - http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${bgzip_file.qp}&genome=$bgzip_file.dbkey&merge=true&name=${qp( $bgzip_file.name )} + http://www.broadinstitute.org/igv/projects/current/igv.php?sessionURL=${bgzip_file.qp}&genome=$bgzip_file.dbkey&merge=true&name=${qp( ( $bgzip_file.name or $DATASET_HASH ).replace( ',', ';' ) )} From fbaba4b463425f6bebde37cf4f1e33f5af24428c Mon Sep 17 00:00:00 2001 From: John Chilton Date: Thu, 14 May 2015 13:37:22 -0400 Subject: [PATCH 110/120] Fix auto-hiding collections when mapping over tools. Broken by that moron @jmchilton in 44f7317fa58aa1a4c61a49d911b2b5c56e5d7f37. --- lib/galaxy/managers/collections.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/managers/collections.py b/lib/galaxy/managers/collections.py index b129ff5d61e..eda9df90e71 100644 --- a/lib/galaxy/managers/collections.py +++ b/lib/galaxy/managers/collections.py @@ -73,7 +73,9 @@ class DatasetCollectionManager( object ): for input_name, input_collection in implicit_collection_info[ "implicit_inputs" ]: dataset_collection_instance.add_implicit_input_collection( input_name, input_collection ) for output_dataset in implicit_collection_info.get( "outputs" ): - if isinstance( output_dataset, model.HistoryDatasetCollectionAssociation ): + if isinstance( output_dataset, model.HistoryDatasetAssociation ): + output_dataset.hidden_beneath_collection_instance = dataset_collection_instance + elif isinstance( output_dataset, model.HistoryDatasetCollectionAssociation ): dataset_collection_instance.add_implicit_input_collection( input_name, input_collection ) else: # dataset collection, don't need to do anything... From 4ad4688fdec15a45f0df98aa03f17a4e098cd877 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Wed, 15 Apr 2015 15:49:28 -0400 Subject: [PATCH 111/120] Fix label's on output collections. Thanks to @kellrott for reporting the issue. https://trello.com/c/Qc2A4rsw --- lib/galaxy/tools/parser/xml.py | 2 ++ test/api/test_tools.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/tools/parser/xml.py b/lib/galaxy/tools/parser/xml.py index 180b76db90b..66be0ff435f 100644 --- a/lib/galaxy/tools/parser/xml.py +++ b/lib/galaxy/tools/parser/xml.py @@ -158,6 +158,7 @@ class XmlToolSource(ToolSource): for collection_elem in out_elem.findall("collection"): name = collection_elem.get( "name" ) + label = xml_text( collection_elem, "label" ) default_format = collection_elem.get( "format", "data" ) collection_type = collection_elem.get( "type", None ) structured_like = collection_elem.get( "structured_like", None ) @@ -180,6 +181,7 @@ class XmlToolSource(ToolSource): output_collection = galaxy.tools.ToolOutputCollection( name, structure, + label=label, default_format=default_format, inherit_format=inherit_format, inherit_metadata=inherit_metadata, diff --git a/test/api/test_tools.py b/test/api/test_tools.py index fe93e6cd436..e2469b71738 100644 --- a/test/api/test_tools.py +++ b/test/api/test_tools.py @@ -302,7 +302,7 @@ class ToolsTestCase( api.ApiTestCase ): self._assert_has_keys( output_collection, "id", "name", "elements", "populated" ) assert not output_collection[ "populated" ] assert len( output_collection[ "elements" ] ) == 0 - + self.assertEquals( output_collection[ "name" ], "Table split on first column" ) self.dataset_populator.wait_for_job( create["jobs"][0]["id"], assert_ok=True ) get_collection_response = self._get( "dataset_collections/%s" % output_collection[ "id" ], data={"instance_type": "history"} ) @@ -312,6 +312,8 @@ class ToolsTestCase( api.ApiTestCase ): self._assert_has_keys( output_collection, "id", "name", "elements", "populated" ) assert output_collection[ "populated" ] assert len( output_collection[ "elements" ] ) == 2 + self.assertEquals( output_collection[ "name" ], "Table split on first column" ) + # TODO: verify element identifiers @skip_without_tool( "cat1" ) From 62772bc86e2504982f207a982542cbcc3faf0c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gr=C3=BCning?= Date: Thu, 14 May 2015 23:16:55 +0200 Subject: [PATCH 112/120] Fix bug in history sharing. --- lib/galaxy/webapps/galaxy/controllers/history.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/webapps/galaxy/controllers/history.py b/lib/galaxy/webapps/galaxy/controllers/history.py index 617bb8ede97..93b682d5bc3 100644 --- a/lib/galaxy/webapps/galaxy/controllers/history.py +++ b/lib/galaxy/webapps/galaxy/controllers/history.py @@ -899,7 +899,7 @@ class HistoryController( BaseUIController, SharableMixin, UsesAnnotations, UsesI for history_id in ids: history_id = self.decode_id( history_id ) history = self.history_manager.get_owned( history_id, trans.user, current_history=trans.history ) - histories.append( ) + histories.append( history ) return histories def _get_users( self, trans, user, emails_or_ids ): From 22d4a1d8c33b5207f4f1424b38c52fe25dc3b74b Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Fri, 15 May 2015 11:51:46 +0100 Subject: [PATCH 113/120] dos2unix of tools/ directory. Some whitespace and PEP-8 fixes. --- tools/data_source/bed_convert.xml | 26 +- tools/data_source/genbank.xml | 50 +- tools/data_source/import.xml | 54 +- tools/data_source/microbial_import.xml | 228 +++---- .../data_source/ucsc_tablebrowser_archaea.xml | 84 +-- tools/data_source/ucsc_tablebrowser_test.xml | 84 +-- tools/extract/liftOver_wrapper.xml | 278 ++++----- tools/filters/axt_to_lav.xml | 188 +++--- tools/filters/axt_to_lav_code.py | 14 +- tools/filters/catWrapper.xml | 158 ++--- tools/filters/changeCase.xml | 154 ++--- tools/filters/condense_characters.xml | 96 +-- tools/filters/cutWrapper.xml | 424 +++++++------ tools/filters/gff/extract_GFF_Features.xml | 228 +++---- tools/filters/gff/gff_filter_by_attribute.xml | 106 ++-- .../gff/gff_filter_by_feature_count.xml | 106 ++-- .../gtf_filter_by_attribute_values_list.xml | 84 +-- tools/filters/headWrapper.xml | 84 +-- tools/filters/joiner2.xml | 26 +- tools/filters/lav_to_bed.py | 109 ++-- tools/filters/lav_to_bed.xml | 136 ++-- tools/filters/lav_to_bed_code.py | 38 +- tools/filters/pasteWrapper.xml | 136 ++-- tools/filters/remove_beginning.xml | 84 +-- tools/filters/tailWrapper.xml | 84 +-- .../filters/ucsc_gene_table_to_intervals.xml | 48 +- tools/maf/genebed_maf_to_fasta.xml | 191 +++--- tools/maf/interval2maf.xml | 584 +++++++++--------- tools/maf/interval2maf_pairwise.xml | 96 +-- tools/maf/interval_maf_to_merged_fasta.xml | 224 +++---- tools/maf/maf_by_block_number.xml | 76 +-- tools/maf/maf_filter.py | 137 ++-- tools/maf/maf_filter.xml | 399 ++++++------ tools/maf/maf_limit_size.xml | 68 +- tools/maf/maf_reverse_complement.py | 87 +-- tools/maf/maf_reverse_complement.xml | 102 +-- tools/maf/maf_split_by_species.xml | 6 +- tools/maf/maf_stats.xml | 228 +++---- tools/maf/maf_to_fasta.xml | 394 ++++++------ tools/plotting/bar_chart.xml | 118 ++-- tools/solid_tools/maq_cs_wrapper_code.py | 9 +- tools/stats/filtering.xml | 174 +++--- tools/stats/gsummary.xml.groups | 124 ++-- tools/visualization/LAJ.xml | 64 +- tools/visualization/LAJ_code.py | 81 +-- 45 files changed, 3137 insertions(+), 3132 deletions(-) diff --git a/tools/data_source/bed_convert.xml b/tools/data_source/bed_convert.xml index c7cdd93d126..eb414066926 100644 --- a/tools/data_source/bed_convert.xml +++ b/tools/data_source/bed_convert.xml @@ -1,14 +1,14 @@ - - creates a bed or xbed file containing from text query - noop - - creates a bed or xbed file containing user assigned input of $input - - - - - - - User specifies delimiter, header information, and column assignments and the file will be converted to BED or xBED. - + + creates a bed or xbed file containing from text query + noop + + creates a bed or xbed file containing user assigned input of $input + + + + + + + User specifies delimiter, header information, and column assignments and the file will be converted to BED or xBED. + \ No newline at end of file diff --git a/tools/data_source/genbank.xml b/tools/data_source/genbank.xml index b4755d4f19f..65bd9c79f8d 100644 --- a/tools/data_source/genbank.xml +++ b/tools/data_source/genbank.xml @@ -1,25 +1,25 @@ - - - genbank.py $mode "$text" $output - - - - - - - - - - - - - - -At the moment this tool allows the following simple searches: - -- by GI: **51594135** -- by accession: **CF622840** -- using text: **human hbb1** (this feature is experimental) - - - \ No newline at end of file + + + genbank.py $mode "$text" $output + + + + + + + + + + + + + + +At the moment this tool allows the following simple searches: + +- by GI: **51594135** +- by accession: **CF622840** +- using text: **human hbb1** (this feature is experimental) + + + diff --git a/tools/data_source/import.xml b/tools/data_source/import.xml index 7121128194a..99d04506c8a 100644 --- a/tools/data_source/import.xml +++ b/tools/data_source/import.xml @@ -1,27 +1,27 @@ - - (PSU prepared queries) - import.py $data $output - - $data - - - - - - - - - - - - - - - - - - - - - - + + (PSU prepared queries) + import.py $data $output + + $data + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/data_source/microbial_import.xml b/tools/data_source/microbial_import.xml index 44950b7761e..b07f557cb7e 100644 --- a/tools/data_source/microbial_import.xml +++ b/tools/data_source/microbial_import.xml @@ -1,114 +1,114 @@ - - microbial_import.py $CDS,$tRNA,$rRNA,$sequence,$GeneMark,$GeneMarkHMM,$Glimmer3 $output ${GALAXY_DATA_INDEX_DIR}/microbial_data.loc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -This tool will allow you to obtain various genomic datasets for any completed Microbial Genome Project as listed at NCBI_. - -.. _NCBI: http://www.ncbi.nlm.nih.gov/genomes/lproks.cgi?view=1 - -Current datasets available include - 1. CDS - 2. tRNA - 3. rRNA - 4. FASTA Sequences - 5. GeneMark Annotations - 6. GeneMarkHMM Annotations - 7. Glimmer3 Annotations - ------ - -Organisms in **bold** are available at the UCSC Browser. - ------ - -.. class:: infomark - -**Note:** Having trouble locating your organism? Click here_ for a list of available species and their location. - -.. _here: https://wiki.galaxyproject.org/Main/Data%20Libraries/Microbes - - + + microbial_import.py $CDS,$tRNA,$rRNA,$sequence,$GeneMark,$GeneMarkHMM,$Glimmer3 $output ${GALAXY_DATA_INDEX_DIR}/microbial_data.loc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +This tool will allow you to obtain various genomic datasets for any completed Microbial Genome Project as listed at NCBI_. + +.. _NCBI: http://www.ncbi.nlm.nih.gov/genomes/lproks.cgi?view=1 + +Current datasets available include + 1. CDS + 2. tRNA + 3. rRNA + 4. FASTA Sequences + 5. GeneMark Annotations + 6. GeneMarkHMM Annotations + 7. Glimmer3 Annotations + +----- + +Organisms in **bold** are available at the UCSC Browser. + +----- + +.. class:: infomark + +**Note:** Having trouble locating your organism? Click here_ for a list of available species and their location. + +.. _here: https://wiki.galaxyproject.org/Main/Data%20Libraries/Microbes + + diff --git a/tools/data_source/ucsc_tablebrowser_archaea.xml b/tools/data_source/ucsc_tablebrowser_archaea.xml index 5aa6916e559..3a352034b41 100644 --- a/tools/data_source/ucsc_tablebrowser_archaea.xml +++ b/tools/data_source/ucsc_tablebrowser_archaea.xml @@ -1,42 +1,42 @@ - - - - table browser - data_source.py $output $__app__.config.output_size_limit - - go to UCSC Table Browser $GALAXY_URL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + table browser + data_source.py $output $__app__.config.output_size_limit + + go to UCSC Table Browser $GALAXY_URL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/data_source/ucsc_tablebrowser_test.xml b/tools/data_source/ucsc_tablebrowser_test.xml index eb8fe2a9a29..43eacdcf083 100644 --- a/tools/data_source/ucsc_tablebrowser_test.xml +++ b/tools/data_source/ucsc_tablebrowser_test.xml @@ -1,42 +1,42 @@ - - - - table browser - data_source.py $output $__app__.config.output_size_limit - - go to UCSC Table Browser $GALAXY_URL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + table browser + data_source.py $output $__app__.config.output_size_limit + + go to UCSC Table Browser $GALAXY_URL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/extract/liftOver_wrapper.xml b/tools/extract/liftOver_wrapper.xml index b5709a65e3a..a6c9caa8f85 100644 --- a/tools/extract/liftOver_wrapper.xml +++ b/tools/extract/liftOver_wrapper.xml @@ -1,147 +1,147 @@ - - between assemblies and genomes - - liftOver_wrapper.py - $input - "$out_file1" - "$out_file2" - $dbkey - $to_dbkey - #if isinstance( $input.datatype, $__app__.datatypes_registry.get_datatype_by_extension('gff').__class__) or isinstance( $input.datatype, $__app__.datatypes_registry.get_datatype_by_extension('gtf').__class__): - "gff" - #else: - "interval" - #end if - $minMatch ${multiple.choice} ${multiple.minChainT} ${multiple.minChainQ} ${multiple.minSizeQ} - - - + + between assemblies and genomes + + liftOver_wrapper.py + $input + "$out_file1" + "$out_file2" + $dbkey + $to_dbkey + #if isinstance( $input.datatype, $__app__.datatypes_registry.get_datatype_by_extension('gff').__class__) or isinstance( $input.datatype, $__app__.datatypes_registry.get_datatype_by_extension('gtf').__class__): + "gff" + #else: + "interval" + #end if + $minMatch ${multiple.choice} ${multiple.minChainT} ${multiple.minChainQ} ${multiple.minSizeQ} + + + - + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ucsc_tools - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ucsc_tools + + - - -.. class:: warningmark - -Make sure that the genome build of the input dataset is specified (click the pencil icon in the history item to set it if necessary). - -.. class:: warningmark - + + +.. class:: warningmark + +Make sure that the genome build of the input dataset is specified (click the pencil icon in the history item to set it if necessary). + +.. class:: warningmark + This tool can work with interval, GFF, and GTF datasets. It requires the interval datasets to have chromosome in column 1, start co-ordinate in column 2 and end co-ordinate in column 3. BED comments and track and browser lines will be ignored, but if other non-interval lines -are present the tool will return empty output datasets. - ------ - -.. class:: infomark - -**What it does** - -This tool is based on the LiftOver utility and Chain track from `the UC Santa Cruz Genome Browser`__. - -It converts coordinates and annotations between assemblies and genomes. It produces 2 files, one containing all the mapped coordinates and the other containing the unmapped coordinates, if any. - - .. __: http://genome.ucsc.edu/ - ------ - -**Example** - -Converting the following hg16 intervals to hg18 intervals:: - - chrX 85170 112199 AK002185 0 + - chrX 110458 112199 AK097346 0 + - chrX 112203 121212 AK074528 0 - - -will produce the following hg18 intervals:: - - chrX 132991 160020 AK002185 0 + - chrX 158279 160020 AK097346 0 + - chrX 160024 169033 AK074528 0 - - - - +are present the tool will return empty output datasets. + +----- + +.. class:: infomark + +**What it does** + +This tool is based on the LiftOver utility and Chain track from `the UC Santa Cruz Genome Browser`__. + +It converts coordinates and annotations between assemblies and genomes. It produces 2 files, one containing all the mapped coordinates and the other containing the unmapped coordinates, if any. + + .. __: http://genome.ucsc.edu/ + +----- + +**Example** + +Converting the following hg16 intervals to hg18 intervals:: + + chrX 85170 112199 AK002185 0 + + chrX 110458 112199 AK097346 0 + + chrX 112203 121212 AK074528 0 - + +will produce the following hg18 intervals:: + + chrX 132991 160020 AK002185 0 + + chrX 158279 160020 AK097346 0 + + chrX 160024 169033 AK074528 0 - + + + diff --git a/tools/filters/axt_to_lav.xml b/tools/filters/axt_to_lav.xml index abc4a501b41..1d7fe85cc8e 100644 --- a/tools/filters/axt_to_lav.xml +++ b/tools/filters/axt_to_lav.xml @@ -1,94 +1,94 @@ - - Converts an AXT formatted file to LAV format - axt_to_lav.py /galaxy/data/$dbkey_1/seq/%s.nib:$dbkey_1:${GALAXY_DATA_INDEX_DIR}/shared/ucsc/chrom/${dbkey_1}.len /galaxy/data/$dbkey_2/seq/%s.nib:$dbkey_2:${GALAXY_DATA_INDEX_DIR}/shared/ucsc/chrom/${dbkey_2}.len $align_input $lav_file $seq_file1 $seq_file2 - - - - - - - - - - - - -.. class:: warningmark - -**IMPORTANT**: AXT formatted alignments will be phased out from Galaxy in the coming weeks. They will be replaced with pairwise MAF alignments, which are already available. To try pairwise MAF alignments use "Extract Pairwise MAF blocks" tool in *Fetch Sequences and Alignments* section. - --------- - - -**Syntax** - -This tool converts an AXT formatted file to the LAV format. - -- **AXT format** The alignments are produced from Blastz, an alignment tool available from Webb Miller's lab at Penn State University. The lav format Blastz output, which does not include the sequence, was converted to AXT format with lavToAxt. Each alignment block in an AXT file contains three lines: a summary line and 2 sequence lines. Blocks are separated from one another by blank lines. - -- **LAV format** LAV is an alignment format developed by Webb Miller's group. It is the primary output format for BLASTZ. - -- **FASTA format** a text-based format for representing both nucleic and protein sequences, in which base pairs or proteins are represented using a single-letter code. - - - This format contains an one line header. It starts with a ">" symbol. The first word on this line is the name of the sequence. The rest of the line is a description of the sequence. - - The remaining lines contain the sequence itself. - - Blank lines in a FASTA file are ignored, and so are spaces or other gap symbols (dashes, underscores, periods) in a sequence. - - Fasta files containing multiple sequences are just the same, with one sequence listed right after another. This format is accepted for many multiple sequence alignment programs. - ------ - -**Example** - -- AXT format:: - - 0 chr19 3001012 3001075 chr11 70568380 70568443 - 3500 - TCAGCTCATAAATCACCTCCTGCCACAAGCCTGGCCTGGTCCCAGGAGAGTGTCCAGGCTCAGA - TCTGTTCATAAACCACCTGCCATGACAAGCCTGGCCTGTTCCCAAGACAATGTCCAGGCTCAGA - - 1 chr19 3008279 3008357 chr11 70573976 70574054 - 3900 - CACAATCTTCACATTGAGATCCTGAGTTGCTGATCAGAATGGAAGGCTGAGCTAAGATGAGCGACGAGGCAATGTCACA - CACAGTCTTCACATTGAGGTACCAAGTTGTGGATCAGAATGGAAAGCTAGGCTATGATGAGGGACAGTGCGCTGTCACA - -- Convert the above file to LAV format:: - - #:lav - s { - "/galaxy/data/hg16/seq/chr19.nib" 1 63811651 0 1 - "/galaxy/data/mm5/seq/chr11.nib-" 1 121648857 0 1 - } - h { - "> hg16.chr19" - "> mm5.chr11 (reverse complement)" - } - a { - s 3500 - b 3001012 70568380 - e 3001075 70568443 - l 3001012 70568380 3001075 70568443 81 - } - a { - s 3900 - b 3008279 70573976 - e 3008357 70574054 - l 3008279 70573976 3008357 70574054 78 - } - #:eof - -- With two files in the FASTA format:: - - >hg16.chr19_-_3001011_3001075 - TCAGCTCATAAATCACCTCCTGCCACAAGCCTGGCCTGGTCCCAGGAGAGTGTCCAGGCTCAGA - - >hg16.chr19_-_3008278_3008357 - CACAATCTTCACATTGAGATCCTGAGTTGCTGATCAGAATGGAAGGCTGAGCTAAGATGAGCGACGAGGCAATGTCACA - - **and**:: - - >mm5.chr11_-_70568379_70568443 - TCTGTTCATAAACCACCTGCCATGACAAGCCTGGCCTGTTCCCAAGACAATGTCCAGGCTCAGA - - >mm5.chr11_-_70573975_70574054 - CACAGTCTTCACATTGAGGTACCAAGTTGTGGATCAGAATGGAAAGCTAGGCTATGATGAGGGACAGTGCGCTGTCACA - - - + + Converts an AXT formatted file to LAV format + axt_to_lav.py /galaxy/data/$dbkey_1/seq/%s.nib:$dbkey_1:${GALAXY_DATA_INDEX_DIR}/shared/ucsc/chrom/${dbkey_1}.len /galaxy/data/$dbkey_2/seq/%s.nib:$dbkey_2:${GALAXY_DATA_INDEX_DIR}/shared/ucsc/chrom/${dbkey_2}.len $align_input $lav_file $seq_file1 $seq_file2 + + + + + + + + + + + + +.. class:: warningmark + +**IMPORTANT**: AXT formatted alignments will be phased out from Galaxy in the coming weeks. They will be replaced with pairwise MAF alignments, which are already available. To try pairwise MAF alignments use "Extract Pairwise MAF blocks" tool in *Fetch Sequences and Alignments* section. + +-------- + + +**Syntax** + +This tool converts an AXT formatted file to the LAV format. + +- **AXT format** The alignments are produced from Blastz, an alignment tool available from Webb Miller's lab at Penn State University. The lav format Blastz output, which does not include the sequence, was converted to AXT format with lavToAxt. Each alignment block in an AXT file contains three lines: a summary line and 2 sequence lines. Blocks are separated from one another by blank lines. + +- **LAV format** LAV is an alignment format developed by Webb Miller's group. It is the primary output format for BLASTZ. + +- **FASTA format** a text-based format for representing both nucleic and protein sequences, in which base pairs or proteins are represented using a single-letter code. + + - This format contains an one line header. It starts with a ">" symbol. The first word on this line is the name of the sequence. The rest of the line is a description of the sequence. + - The remaining lines contain the sequence itself. + - Blank lines in a FASTA file are ignored, and so are spaces or other gap symbols (dashes, underscores, periods) in a sequence. + - Fasta files containing multiple sequences are just the same, with one sequence listed right after another. This format is accepted for many multiple sequence alignment programs. + +----- + +**Example** + +- AXT format:: + + 0 chr19 3001012 3001075 chr11 70568380 70568443 - 3500 + TCAGCTCATAAATCACCTCCTGCCACAAGCCTGGCCTGGTCCCAGGAGAGTGTCCAGGCTCAGA + TCTGTTCATAAACCACCTGCCATGACAAGCCTGGCCTGTTCCCAAGACAATGTCCAGGCTCAGA + + 1 chr19 3008279 3008357 chr11 70573976 70574054 - 3900 + CACAATCTTCACATTGAGATCCTGAGTTGCTGATCAGAATGGAAGGCTGAGCTAAGATGAGCGACGAGGCAATGTCACA + CACAGTCTTCACATTGAGGTACCAAGTTGTGGATCAGAATGGAAAGCTAGGCTATGATGAGGGACAGTGCGCTGTCACA + +- Convert the above file to LAV format:: + + #:lav + s { + "/galaxy/data/hg16/seq/chr19.nib" 1 63811651 0 1 + "/galaxy/data/mm5/seq/chr11.nib-" 1 121648857 0 1 + } + h { + "> hg16.chr19" + "> mm5.chr11 (reverse complement)" + } + a { + s 3500 + b 3001012 70568380 + e 3001075 70568443 + l 3001012 70568380 3001075 70568443 81 + } + a { + s 3900 + b 3008279 70573976 + e 3008357 70574054 + l 3008279 70573976 3008357 70574054 78 + } + #:eof + +- With two files in the FASTA format:: + + >hg16.chr19_-_3001011_3001075 + TCAGCTCATAAATCACCTCCTGCCACAAGCCTGGCCTGGTCCCAGGAGAGTGTCCAGGCTCAGA + + >hg16.chr19_-_3008278_3008357 + CACAATCTTCACATTGAGATCCTGAGTTGCTGATCAGAATGGAAGGCTGAGCTAAGATGAGCGACGAGGCAATGTCACA + + **and**:: + + >mm5.chr11_-_70568379_70568443 + TCTGTTCATAAACCACCTGCCATGACAAGCCTGGCCTGTTCCCAAGACAATGTCCAGGCTCAGA + + >mm5.chr11_-_70573975_70574054 + CACAGTCTTCACATTGAGGTACCAAGTTGTGGATCAGAATGGAAAGCTAGGCTATGATGAGGGACAGTGCGCTGTCACA + + + diff --git a/tools/filters/axt_to_lav_code.py b/tools/filters/axt_to_lav_code.py index 02b35ea764d..9c08c971f0b 100644 --- a/tools/filters/axt_to_lav_code.py +++ b/tools/filters/axt_to_lav_code.py @@ -1,8 +1,8 @@ - -def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr): - for name,data in out_data.items(): - if name == "seq_file2": - data.dbkey = param_dict['dbkey_2'] - app.model.context.add( data ) - app.model.context.flush() + +def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr): + for name,data in out_data.items(): + if name == "seq_file2": + data.dbkey = param_dict['dbkey_2'] + app.model.context.add( data ) + app.model.context.flush() break \ No newline at end of file diff --git a/tools/filters/catWrapper.xml b/tools/filters/catWrapper.xml index 5524825e8c6..33e67e1e5a4 100644 --- a/tools/filters/catWrapper.xml +++ b/tools/filters/catWrapper.xml @@ -1,79 +1,79 @@ - - tail-to-head - - catWrapper.py - $out_file1 - $input1 - #for $q in $queries - ${q.input2} - #end for - - - - - - - - - - - - - - - - - - - - -.. class:: warningmark - -**WARNING:** Be careful not to concatenate datasets of different kinds (e.g., sequences with intervals). This tool does not check if the datasets being concatenated are in the same format. - ------ - -**What it does** - -Concatenates datasets - ------ - -**Example** - -Concatenating Dataset:: - - chrX 151087187 151087355 A 0 - - chrX 151572400 151572481 B 0 + - -with Dataset1:: - - chr1 151242630 151242955 X 0 + - chr1 151271715 151271999 Y 0 + - chr1 151278832 151279227 Z 0 - - -and with Dataset2:: - - chr2 100000030 200000955 P 0 + - chr2 100000015 200000999 Q 0 + - -will result in the following:: - - chrX 151087187 151087355 A 0 - - chrX 151572400 151572481 B 0 + - chr1 151242630 151242955 X 0 + - chr1 151271715 151271999 Y 0 + - chr1 151278832 151279227 Z 0 - - chr2 100000030 200000955 P 0 + - chr2 100000015 200000999 Q 0 + - - - + + tail-to-head + + catWrapper.py + $out_file1 + $input1 + #for $q in $queries + ${q.input2} + #end for + + + + + + + + + + + + + + + + + + + + +.. class:: warningmark + +**WARNING:** Be careful not to concatenate datasets of different kinds (e.g., sequences with intervals). This tool does not check if the datasets being concatenated are in the same format. + +----- + +**What it does** + +Concatenates datasets + +----- + +**Example** + +Concatenating Dataset:: + + chrX 151087187 151087355 A 0 - + chrX 151572400 151572481 B 0 + + +with Dataset1:: + + chr1 151242630 151242955 X 0 + + chr1 151271715 151271999 Y 0 + + chr1 151278832 151279227 Z 0 - + +and with Dataset2:: + + chr2 100000030 200000955 P 0 + + chr2 100000015 200000999 Q 0 + + +will result in the following:: + + chrX 151087187 151087355 A 0 - + chrX 151572400 151572481 B 0 + + chr1 151242630 151242955 X 0 + + chr1 151271715 151271999 Y 0 + + chr1 151278832 151279227 Z 0 - + chr2 100000030 200000955 P 0 + + chr2 100000015 200000999 Q 0 + + + + diff --git a/tools/filters/changeCase.xml b/tools/filters/changeCase.xml index 251654a7ea8..6912bdd18f8 100644 --- a/tools/filters/changeCase.xml +++ b/tools/filters/changeCase.xml @@ -1,77 +1,77 @@ - - of selected columns - - - - changeCase.pl $input "$cols" $delimiter $casing $out_file1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -.. class:: warningmark - -**This tool breaks column assignments.** To re-establish column assignments run the tool and click on the pencil icon in the resulting history item. - -.. class:: warningmark - -The format of the resulting dataset from this tool is always tabular. - ------ - -**What it does** - -This tool selects specified columns from a dataset and converts the values of those columns to upper or lower case. - -- Columns are specified as **c1**, **c2**, and so on. -- Columns can be specified in any order (e.g., **c2,c1,c6**) - ------ - -**Example** - -Changing columns 1 and 3 ( delimited by Comma ) to upper case in:: - - apple,is,good - windows,is,bad - -will result in:: - - APPLE is GOOD - WINDOWS is BAD - - - + + of selected columns + + + + changeCase.pl $input "$cols" $delimiter $casing $out_file1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.. class:: warningmark + +**This tool breaks column assignments.** To re-establish column assignments run the tool and click on the pencil icon in the resulting history item. + +.. class:: warningmark + +The format of the resulting dataset from this tool is always tabular. + +----- + +**What it does** + +This tool selects specified columns from a dataset and converts the values of those columns to upper or lower case. + +- Columns are specified as **c1**, **c2**, and so on. +- Columns can be specified in any order (e.g., **c2,c1,c6**) + +----- + +**Example** + +Changing columns 1 and 3 ( delimited by Comma ) to upper case in:: + + apple,is,good + windows,is,bad + +will result in:: + + APPLE is GOOD + WINDOWS is BAD + + + diff --git a/tools/filters/condense_characters.xml b/tools/filters/condense_characters.xml index 41d75cdb445..f792851a502 100644 --- a/tools/filters/condense_characters.xml +++ b/tools/filters/condense_characters.xml @@ -1,48 +1,48 @@ - - consecutive characters - condense_characters.pl $input $character $out_file1 - - - - - - - - - - - - - - - - - - - - - - - - - -**What it does** - -This tool condenses all consecutive characters of a specified type. - ------ - -**Example** - -- Input file:: - - geneX,,,10,,,,,20 - geneY,,5,,,,,12,15,9, - -- Condense all consecutive commas. The above file will be converted into:: - - geneX,10,20 - geneY,5,12,15,9 - - - + + consecutive characters + condense_characters.pl $input $character $out_file1 + + + + + + + + + + + + + + + + + + + + + + + + + +**What it does** + +This tool condenses all consecutive characters of a specified type. + +----- + +**Example** + +- Input file:: + + geneX,,,10,,,,,20 + geneY,,5,,,,,12,15,9, + +- Condense all consecutive commas. The above file will be converted into:: + + geneX,10,20 + geneY,5,12,15,9 + + + diff --git a/tools/filters/cutWrapper.xml b/tools/filters/cutWrapper.xml index ab2365b6459..b7fed5ba9e1 100644 --- a/tools/filters/cutWrapper.xml +++ b/tools/filters/cutWrapper.xml @@ -1,213 +1,211 @@ - - columns from a table - cutWrapper.pl $input "$columnList" $delimiter $out_file1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -.. class:: warningmark - -**WARNING: This tool breaks column assignments.** To re-establish column assignments run the tools and click on the pencil icon in the latest history item. - -.. class:: infomark - -The output of this tool is always in tabular format (e.g., if your original delimiters are commas, they will be replaced with tabs). For example: - - Cutting columns 1 and 3 from:: - - apple,is,good - windows,is,bad - - will give:: - - apple good - windows bad - ------ - -**What it does** - -This tool selects (cuts out) specified columns from the dataset. - -- Columns are specified as **c1**, **c2**, and so on. Column count begins with **1** -- Columns can be specified in any order (e.g., **c2,c1,c6**) -- If you specify more columns than actually present - empty spaces will be filled with dots - ------ - -**Example** - -Input dataset (six columns: c1, c2, c3, c4, c5, and c6):: - - chr1 10 1000 gene1 0 + - chr2 100 1500 gene2 0 + - -**cut** on columns "**c1,c4,c6**" will return:: - - chr1 gene1 + - chr2 gene2 + - -**cut** on columns "**c6,c5,c4,c1**" will return:: - - + 0 gene1 chr1 - + 0 gene2 chr2 - -**cut** on columns "**c1-c3**" will return:: - - chr1 10 1000 - chr2 100 1500 - - -**cut** on columns "**c8,c7,c4**" will return:: - - . . gene1 - . . gene2 - - - - + + columns from a table + cutWrapper.pl $input "$columnList" $delimiter $out_file1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.. class:: warningmark + +**WARNING: This tool breaks column assignments.** To re-establish column assignments run the tools and click on the pencil icon in the latest history item. + +.. class:: infomark + +The output of this tool is always in tabular format (e.g., if your original delimiters are commas, they will be replaced with tabs). For example: + + Cutting columns 1 and 3 from:: + + apple,is,good + windows,is,bad + + will give:: + + apple good + windows bad + +----- + +**What it does** + +This tool selects (cuts out) specified columns from the dataset. + +- Columns are specified as **c1**, **c2**, and so on. Column count begins with **1** +- Columns can be specified in any order (e.g., **c2,c1,c6**) +- If you specify more columns than actually present - empty spaces will be filled with dots + +----- + +**Example** + +Input dataset (six columns: c1, c2, c3, c4, c5, and c6):: + + chr1 10 1000 gene1 0 + + chr2 100 1500 gene2 0 + + +**cut** on columns "**c1,c4,c6**" will return:: + + chr1 gene1 + + chr2 gene2 + + +**cut** on columns "**c6,c5,c4,c1**" will return:: + + + 0 gene1 chr1 + + 0 gene2 chr2 + +**cut** on columns "**c1-c3**" will return:: + + chr1 10 1000 + chr2 100 1500 + + +**cut** on columns "**c8,c7,c4**" will return:: + + . . gene1 + . . gene2 + + diff --git a/tools/filters/gff/extract_GFF_Features.xml b/tools/filters/gff/extract_GFF_Features.xml index d664d667447..69c62c3498b 100644 --- a/tools/filters/gff/extract_GFF_Features.xml +++ b/tools/filters/gff/extract_GFF_Features.xml @@ -1,114 +1,114 @@ - - from GFF data - extract_GFF_Features.py $input1 $out_file1 ${column_choice.col} ${column_choice.feature} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -**What it does** - -This tool extracts selected features from GFF data. - ------ - -**Example** - -Selecting **promoter** from the following GFF data:: - - chr22 GeneA enhancer 10000000 10001000 500 + . TGA - chr22 GeneA promoter 10010000 10010100 900 + . TGA - chr22 GeneB promoter 10020000 10025000 400 - . TGB - chr22 GeneB CCDS2220 10030000 10065000 800 - . TGB - -will produce the following output:: - - chr22 GeneA promoter 10010000 10010100 900 + . TGA - chr22 GeneB promoter 10020000 10025000 400 - . TGB - ----- - -.. class:: infomark - -**About formats** - -**GFF format** General Feature Format is a format for describing genes and other features associated with DNA, RNA and Protein sequences. GFF lines have nine tab-separated fields:: - - 1. seqname - Must be a chromosome or scaffold. - 2. source - The program that generated this feature. - 3. feature - The name of this type of feature. Some examples of standard feature types are "CDS", "start_codon", "stop_codon", and "exon". - 4. start - The starting position of the feature in the sequence. The first base is numbered 1. - 5. end - The ending position of the feature (inclusive). - 6. score - A score between 0 and 1000. If there is no score value, enter ".". - 7. strand - Valid entries include '+', '-', or '.' (for don't know/care). - 8. frame - If the feature is a coding exon, frame should be a number between 0-2 that represents the reading frame of the first base. If the feature is not a coding exon, the value should be '.'. - 9. group - All lines with the same group are linked together into a single item. - - - - + + from GFF data + extract_GFF_Features.py $input1 $out_file1 ${column_choice.col} ${column_choice.feature} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +**What it does** + +This tool extracts selected features from GFF data. + +----- + +**Example** + +Selecting **promoter** from the following GFF data:: + + chr22 GeneA enhancer 10000000 10001000 500 + . TGA + chr22 GeneA promoter 10010000 10010100 900 + . TGA + chr22 GeneB promoter 10020000 10025000 400 - . TGB + chr22 GeneB CCDS2220 10030000 10065000 800 - . TGB + +will produce the following output:: + + chr22 GeneA promoter 10010000 10010100 900 + . TGA + chr22 GeneB promoter 10020000 10025000 400 - . TGB + +---- + +.. class:: infomark + +**About formats** + +**GFF format** General Feature Format is a format for describing genes and other features associated with DNA, RNA and Protein sequences. GFF lines have nine tab-separated fields:: + + 1. seqname - Must be a chromosome or scaffold. + 2. source - The program that generated this feature. + 3. feature - The name of this type of feature. Some examples of standard feature types are "CDS", "start_codon", "stop_codon", and "exon". + 4. start - The starting position of the feature in the sequence. The first base is numbered 1. + 5. end - The ending position of the feature (inclusive). + 6. score - A score between 0 and 1000. If there is no score value, enter ".". + 7. strand - Valid entries include '+', '-', or '.' (for don't know/care). + 8. frame - If the feature is a coding exon, frame should be a number between 0-2 that represents the reading frame of the first base. If the feature is not a coding exon, the value should be '.'. + 9. group - All lines with the same group are linked together into a single item. + + + + diff --git a/tools/filters/gff/gff_filter_by_attribute.xml b/tools/filters/gff/gff_filter_by_attribute.xml index 4e64b84126e..475c3f55ffa 100644 --- a/tools/filters/gff/gff_filter_by_attribute.xml +++ b/tools/filters/gff/gff_filter_by_attribute.xml @@ -1,53 +1,53 @@ - - using simple expressions - - gff_filter_by_attribute.py $input $out_file1 "$cond" '${input.metadata.attribute_types}' - - - - - - - - - - - - - - - - - - - - - - - - - -.. class:: warningmark - -Double equal signs, ==, must be used as *"equal to"* (e.g., **c1 == 'chr22'**) - -.. class:: infomark - -**TIP:** Attempting to apply a filtering condition may throw exceptions if the data type (e.g., string, integer) in every line of the attribute being filtered is not appropriate for the condition (e.g., attempting certain numerical calculations on strings). If an exception is thrown when applying the condition to a line, that line is skipped as invalid for the filter condition. The number of invalid skipped lines is documented in the resulting history item as a "Condition/data issue". - -.. class:: infomark - -**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* - ------ - -**Syntax** - -The filter tool allows you to restrict the dataset using simple conditional statements. - -- Make sure that multi-character operators contain no white space ( e.g., **<=** is valid while **< =** is not valid ) -- When using 'equal-to' operator **double equal sign '==' must be used** ( e.g., **attribute_name=='chr1'** ) -- Non-numerical values must be included in single or double quotes ( e.g., **attribute_name=='XX22'** ) - - - + + using simple expressions + + gff_filter_by_attribute.py $input $out_file1 "$cond" '${input.metadata.attribute_types}' + + + + + + + + + + + + + + + + + + + + + + + + + +.. class:: warningmark + +Double equal signs, ==, must be used as *"equal to"* (e.g., **c1 == 'chr22'**) + +.. class:: infomark + +**TIP:** Attempting to apply a filtering condition may throw exceptions if the data type (e.g., string, integer) in every line of the attribute being filtered is not appropriate for the condition (e.g., attempting certain numerical calculations on strings). If an exception is thrown when applying the condition to a line, that line is skipped as invalid for the filter condition. The number of invalid skipped lines is documented in the resulting history item as a "Condition/data issue". + +.. class:: infomark + +**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* + +----- + +**Syntax** + +The filter tool allows you to restrict the dataset using simple conditional statements. + +- Make sure that multi-character operators contain no white space ( e.g., **<=** is valid while **< =** is not valid ) +- When using 'equal-to' operator **double equal sign '==' must be used** ( e.g., **attribute_name=='chr1'** ) +- Non-numerical values must be included in single or double quotes ( e.g., **attribute_name=='XX22'** ) + + + diff --git a/tools/filters/gff/gff_filter_by_feature_count.xml b/tools/filters/gff/gff_filter_by_feature_count.xml index 90fbd87c12f..75886432fb9 100644 --- a/tools/filters/gff/gff_filter_by_feature_count.xml +++ b/tools/filters/gff/gff_filter_by_feature_count.xml @@ -1,53 +1,53 @@ - - using simple expressions - - gff_filter_by_feature_count.py $input_file1 $out_file1 "$feature_name" "$cond" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -.. class:: infomark - -Valid comparison operators are: > < >=, <=, !=, and == - ------ - -**Syntax** - -The filter tool allows you to restrict the dataset based on transcripts' feature counts. - - - + + using simple expressions + + gff_filter_by_feature_count.py $input_file1 $out_file1 "$feature_name" "$cond" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.. class:: infomark + +Valid comparison operators are: > < >=, <=, !=, and == + +----- + +**Syntax** + +The filter tool allows you to restrict the dataset based on transcripts' feature counts. + + + diff --git a/tools/filters/gff/gtf_filter_by_attribute_values_list.xml b/tools/filters/gff/gtf_filter_by_attribute_values_list.xml index 5ac16d20c13..0f5d0dadabc 100644 --- a/tools/filters/gff/gtf_filter_by_attribute_values_list.xml +++ b/tools/filters/gff/gtf_filter_by_attribute_values_list.xml @@ -1,42 +1,42 @@ - - - - gtf_filter_by_attribute_values_list.py $input $attribute_name $ids $output - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -This tool filters a GTF file using a list of attribute values. The attribute values are -taken from the first column in the file; additional columns in the file are ignored. An example -use of this tool is to filter a GTF file using a list of transcript_ids or gene_ids obtained from Cuffdiff. - - - + + + + gtf_filter_by_attribute_values_list.py $input $attribute_name $ids $output + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +This tool filters a GTF file using a list of attribute values. The attribute values are +taken from the first column in the file; additional columns in the file are ignored. An example +use of this tool is to filter a GTF file using a list of transcript_ids or gene_ids obtained from Cuffdiff. + + + diff --git a/tools/filters/headWrapper.xml b/tools/filters/headWrapper.xml index 0c67a2d4bca..53451c44067 100644 --- a/tools/filters/headWrapper.xml +++ b/tools/filters/headWrapper.xml @@ -1,42 +1,42 @@ - - lines from a dataset - headWrapper.pl $input $lineNum $out_file1 - - - - - - - - - - - - - - - - -**What it does** - -This tool outputs specified number of lines from the **beginning** of a dataset - ------ - -**Example** - -Selecting 2 lines from this:: - - chr7 56632 56652 D17003_CTCF_R6 310 + - chr7 56736 56756 D17003_CTCF_R7 354 + - chr7 56761 56781 D17003_CTCF_R4 220 + - chr7 56772 56792 D17003_CTCF_R7 372 + - chr7 56775 56795 D17003_CTCF_R4 207 + - -will produce:: - - chr7 56632 56652 D17003_CTCF_R6 310 + - chr7 56736 56756 D17003_CTCF_R7 354 + - - - + + lines from a dataset + headWrapper.pl $input $lineNum $out_file1 + + + + + + + + + + + + + + + + +**What it does** + +This tool outputs specified number of lines from the **beginning** of a dataset + +----- + +**Example** + +Selecting 2 lines from this:: + + chr7 56632 56652 D17003_CTCF_R6 310 + + chr7 56736 56756 D17003_CTCF_R7 354 + + chr7 56761 56781 D17003_CTCF_R4 220 + + chr7 56772 56792 D17003_CTCF_R7 372 + + chr7 56775 56795 D17003_CTCF_R4 207 + + +will produce:: + + chr7 56632 56652 D17003_CTCF_R6 310 + + chr7 56736 56756 D17003_CTCF_R7 354 + + + + diff --git a/tools/filters/joiner2.xml b/tools/filters/joiner2.xml index a3061e8919b..93cc920efd5 100644 --- a/tools/filters/joiner2.xml +++ b/tools/filters/joiner2.xml @@ -1,13 +1,13 @@ - - two datasets a specific column of which has the same value - sort -k $col1 $input1 > $input1.tmp; sort -k $col2 $input2 > $input2.tmp; join -1 $col1 -2 $col2 $input1.tmp $input2.tmp | tr " " "\t" > $out_file1; rm -rf $input1.tmp $input2.tmp - - - - - - - - - - + + two datasets a specific column of which has the same value + sort -k $col1 $input1 > $input1.tmp; sort -k $col2 $input2 > $input2.tmp; join -1 $col1 -2 $col2 $input1.tmp $input2.tmp | tr " " "\t" > $out_file1; rm -rf $input1.tmp $input2.tmp + + + + + + + + + + diff --git a/tools/filters/lav_to_bed.py b/tools/filters/lav_to_bed.py index 6b1e067884d..c9ab8f13984 100644 --- a/tools/filters/lav_to_bed.py +++ b/tools/filters/lav_to_bed.py @@ -1,54 +1,55 @@ -#!/usr/bin/env python -#Reads a LAV file and writes two BED files. -import sys -from galaxy import eggs -import pkg_resources -pkg_resources.require( "bx-python" ) -import bx.align.lav - -assert sys.version_info[:2] >= ( 2, 4 ) - -def stop_err( msg ): - sys.stderr.write( msg ) - sys.exit() - -def main(): - try: - lav_file = open(sys.argv[1],'r') - bed_file1 = open(sys.argv[2],'w') - bed_file2 = open(sys.argv[3],'w') - except Exception, e: - stop_err( str( e ) ) - - lavsRead = 0 - bedsWritten = 0 - species = {} - # TODO: this is really bad since everything is read into memory. Can we eliminate this tool? - for lavBlock in bx.align.lav.Reader( lav_file ): - lavsRead += 1 - for c in lavBlock.components: - spec, chrom = bx.align.lav.src_split( c.src ) - if bedsWritten < 1: - if len( species )==0: - species[spec]=bed_file1 - elif len( species )==1: - species[spec]=bed_file2 - else: - continue #this is a pairwise alignment... - if spec in species: - species[spec].write( "%s\t%i\t%i\t%s_%s\t%i\t%s\n" % ( chrom, c.start, c.end, spec, str( bedsWritten ), 0, c.strand ) ) - bedsWritten += 1 - - - for spec,file in species.items(): - print "#FILE\t%s\t%s" % (file.name, spec) - - lav_file.close() - bed_file1.close() - bed_file2.close() - - print "%d lav blocks read, %d regions written\n" % (lavsRead,bedsWritten) - - - -if __name__ == "__main__": main() \ No newline at end of file +#!/usr/bin/env python +#Reads a LAV file and writes two BED files. +import sys +from galaxy import eggs +import pkg_resources +pkg_resources.require( "bx-python" ) +import bx.align.lav + +assert sys.version_info[:2] >= ( 2, 4 ) + + +def stop_err( msg ): + sys.stderr.write( msg ) + sys.exit() + + +def main(): + try: + lav_file = open(sys.argv[1], 'r') + bed_file1 = open(sys.argv[2], 'w') + bed_file2 = open(sys.argv[3], 'w') + except Exception, e: + stop_err( str( e ) ) + + lavsRead = 0 + bedsWritten = 0 + species = {} + # TODO: this is really bad since everything is read into memory. Can we eliminate this tool? + for lavBlock in bx.align.lav.Reader( lav_file ): + lavsRead += 1 + for c in lavBlock.components: + spec, chrom = bx.align.lav.src_split( c.src ) + if bedsWritten < 1: + if len( species ) == 0: + species[spec] = bed_file1 + elif len( species ) == 1: + species[spec] = bed_file2 + else: + continue # this is a pairwise alignment... + if spec in species: + species[spec].write( "%s\t%i\t%i\t%s_%s\t%i\t%s\n" % ( chrom, c.start, c.end, spec, str( bedsWritten ), 0, c.strand ) ) + bedsWritten += 1 + + for spec, file in species.items(): + print "#FILE\t%s\t%s" % (file.name, spec) + + lav_file.close() + bed_file1.close() + bed_file2.close() + + print "%d lav blocks read, %d regions written\n" % (lavsRead, bedsWritten) + + +if __name__ == "__main__": + main() diff --git a/tools/filters/lav_to_bed.xml b/tools/filters/lav_to_bed.xml index 30af59c369d..369a0e59618 100644 --- a/tools/filters/lav_to_bed.xml +++ b/tools/filters/lav_to_bed.xml @@ -1,68 +1,68 @@ - - Converts a LAV formatted file to BED format - lav_to_bed.py $lav_file $bed_file1 $bed_file2 - - - - - - - - - - - - - - - - -**Syntax** - -This tool converts a LAV formatted file to the BED format. - -- **LAV format** LAV is an alignment format developed by Webb Miller's group at Penn State University. It is the primary output format for BLASTZ. - -- **BED format** Browser Extensible Data format was designed at UCSC for displaying data tracks in the Genome Browser. - ------ - -**Example** - -- Convert LAV format:: - - #:lav - s { - "/galaxy/data/hg16/seq/chr19.nib" 1 63811651 0 1 - "/galaxy/data/mm5/seq/chr11.nib" 1 121648857 0 1 - } - h { - "> hg16.chr19" - "> mm5.chr11 (reverse complement)" - } - a { - s 3500 - b 3001012 70568380 - e 3001075 70568443 - l 3001012 70568380 3001075 70568443 81 - } - a { - s 3900 - b 3008279 70573976 - e 3008357 70574054 - l 3008279 70573976 3008357 70574054 78 - } - #:eof - -- To two BED formatted files:: - - chr19 3001011 3001075 hg16_0 0 + - chr19 3008278 3008357 hg16_1 0 + - - **and**:: - - chr11 70568379 70568443 mm5_0 0 + - chr11 70573975 70574054 mm5_1 0 + - - - + + Converts a LAV formatted file to BED format + lav_to_bed.py $lav_file $bed_file1 $bed_file2 + + + + + + + + + + + + + + + + +**Syntax** + +This tool converts a LAV formatted file to the BED format. + +- **LAV format** LAV is an alignment format developed by Webb Miller's group at Penn State University. It is the primary output format for BLASTZ. + +- **BED format** Browser Extensible Data format was designed at UCSC for displaying data tracks in the Genome Browser. + +----- + +**Example** + +- Convert LAV format:: + + #:lav + s { + "/galaxy/data/hg16/seq/chr19.nib" 1 63811651 0 1 + "/galaxy/data/mm5/seq/chr11.nib" 1 121648857 0 1 + } + h { + "> hg16.chr19" + "> mm5.chr11 (reverse complement)" + } + a { + s 3500 + b 3001012 70568380 + e 3001075 70568443 + l 3001012 70568380 3001075 70568443 81 + } + a { + s 3900 + b 3008279 70573976 + e 3008357 70574054 + l 3008279 70573976 3008357 70574054 78 + } + #:eof + +- To two BED formatted files:: + + chr19 3001011 3001075 hg16_0 0 + + chr19 3008278 3008357 hg16_1 0 + + + **and**:: + + chr11 70568379 70568443 mm5_0 0 + + chr11 70573975 70574054 mm5_1 0 + + + + diff --git a/tools/filters/lav_to_bed_code.py b/tools/filters/lav_to_bed_code.py index 80f47a7d076..a996301f1c9 100644 --- a/tools/filters/lav_to_bed_code.py +++ b/tools/filters/lav_to_bed_code.py @@ -1,19 +1,19 @@ -#Set build, name, and info for each output BED file -def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr): - new_stdout = "" - filename_to_build = {} - for line in stdout.split("\n"): - if line.startswith("#FILE"): - fields = line.split("\t") - filename_to_build[fields[1]]=fields[2].strip() - else: - new_stdout = "%s%s" % ( new_stdout, line ) - for name,data in out_data.items(): - try: - data.info = "%s\n%s" % ( new_stdout, stderr ) - data.dbkey = filename_to_build[data.file_name] - data.name = "%s (%s)" % ( data.name, data.dbkey ) - app.model.context.add( data ) - app.model.context.flush() - except: - continue +#Set build, name, and info for each output BED file +def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr): + new_stdout = "" + filename_to_build = {} + for line in stdout.split("\n"): + if line.startswith("#FILE"): + fields = line.split("\t") + filename_to_build[fields[1]]=fields[2].strip() + else: + new_stdout = "%s%s" % ( new_stdout, line ) + for name,data in out_data.items(): + try: + data.info = "%s\n%s" % ( new_stdout, stderr ) + data.dbkey = filename_to_build[data.file_name] + data.name = "%s (%s)" % ( data.name, data.dbkey ) + app.model.context.add( data ) + app.model.context.flush() + except: + continue diff --git a/tools/filters/pasteWrapper.xml b/tools/filters/pasteWrapper.xml index 8da6e48d95a..e853d6147a4 100644 --- a/tools/filters/pasteWrapper.xml +++ b/tools/filters/pasteWrapper.xml @@ -1,68 +1,68 @@ - - two files side by side - pasteWrapper.pl $input1 $input2 $delimiter $out_file1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -.. class:: infomark - -Paste preserves column assignments of the first dataset. - ------ - -**What it does** - -This tool merges two datasets side by side. If the first (left) dataset contains column assignments such as chromosome, start, end and strand, these will be preserved. However, if you would like to change column assignments, click the pencil icon in the history item. - ------ - -**Example** - -First dataset:: - - a 1 - a 2 - a 3 - -Second dataset:: - - 20 - 30 - 40 - -Pasting them together will produce:: - - a 1 20 - a 2 30 - a 3 40 - - - + + two files side by side + pasteWrapper.pl $input1 $input2 $delimiter $out_file1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.. class:: infomark + +Paste preserves column assignments of the first dataset. + +----- + +**What it does** + +This tool merges two datasets side by side. If the first (left) dataset contains column assignments such as chromosome, start, end and strand, these will be preserved. However, if you would like to change column assignments, click the pencil icon in the history item. + +----- + +**Example** + +First dataset:: + + a 1 + a 2 + a 3 + +Second dataset:: + + 20 + 30 + 40 + +Pasting them together will produce:: + + a 1 20 + a 2 30 + a 3 40 + + + diff --git a/tools/filters/remove_beginning.xml b/tools/filters/remove_beginning.xml index 909b0073a42..a929e483d83 100644 --- a/tools/filters/remove_beginning.xml +++ b/tools/filters/remove_beginning.xml @@ -1,42 +1,42 @@ - - of a file - remove_beginning.pl $input $num_lines $out_file1 - - - - - - - - - - - - - - - - -**What it does** - -This tool removes a specified number of lines from the beginning of a dataset. - ------ - -**Example** - -Input File:: - - chr7 56632 56652 D17003_CTCF_R6 310 + - chr7 56736 56756 D17003_CTCF_R7 354 + - chr7 56761 56781 D17003_CTCF_R4 220 + - chr7 56772 56792 D17003_CTCF_R7 372 + - chr7 56775 56795 D17003_CTCF_R4 207 + - -After removing the first 3 lines the dataset will look like this:: - - chr7 56772 56792 D17003_CTCF_R7 372 + - chr7 56775 56795 D17003_CTCF_R4 207 + - - - + + of a file + remove_beginning.pl $input $num_lines $out_file1 + + + + + + + + + + + + + + + + +**What it does** + +This tool removes a specified number of lines from the beginning of a dataset. + +----- + +**Example** + +Input File:: + + chr7 56632 56652 D17003_CTCF_R6 310 + + chr7 56736 56756 D17003_CTCF_R7 354 + + chr7 56761 56781 D17003_CTCF_R4 220 + + chr7 56772 56792 D17003_CTCF_R7 372 + + chr7 56775 56795 D17003_CTCF_R4 207 + + +After removing the first 3 lines the dataset will look like this:: + + chr7 56772 56792 D17003_CTCF_R7 372 + + chr7 56775 56795 D17003_CTCF_R4 207 + + + + diff --git a/tools/filters/tailWrapper.xml b/tools/filters/tailWrapper.xml index f302f0aa378..1a7d7789ad5 100644 --- a/tools/filters/tailWrapper.xml +++ b/tools/filters/tailWrapper.xml @@ -1,42 +1,42 @@ - - lines from a dataset - tailWrapper.pl $input $lineNum $out_file1 - - - - - - - - - - - - - - - - -**What it does** - -This tool outputs specified number of lines from the **end** of a dataset - ------ - -**Example** - -- Input File:: - - chr7 57134 57154 D17003_CTCF_R7 356 - - chr7 57247 57267 D17003_CTCF_R4 207 + - chr7 57314 57334 D17003_CTCF_R5 269 + - chr7 57341 57361 D17003_CTCF_R7 375 + - chr7 57457 57477 D17003_CTCF_R3 188 + - -- Show last two lines of above file. The result is:: - - chr7 57341 57361 D17003_CTCF_R7 375 + - chr7 57457 57477 D17003_CTCF_R3 188 + - - - + + lines from a dataset + tailWrapper.pl $input $lineNum $out_file1 + + + + + + + + + + + + + + + + +**What it does** + +This tool outputs specified number of lines from the **end** of a dataset + +----- + +**Example** + +- Input File:: + + chr7 57134 57154 D17003_CTCF_R7 356 - + chr7 57247 57267 D17003_CTCF_R4 207 + + chr7 57314 57334 D17003_CTCF_R5 269 + + chr7 57341 57361 D17003_CTCF_R7 375 + + chr7 57457 57477 D17003_CTCF_R3 188 + + +- Show last two lines of above file. The result is:: + + chr7 57341 57361 D17003_CTCF_R7 375 + + chr7 57457 57477 D17003_CTCF_R3 188 + + + + diff --git a/tools/filters/ucsc_gene_table_to_intervals.xml b/tools/filters/ucsc_gene_table_to_intervals.xml index d0232a28042..8e382f8e58f 100644 --- a/tools/filters/ucsc_gene_table_to_intervals.xml +++ b/tools/filters/ucsc_gene_table_to_intervals.xml @@ -1,25 +1,25 @@ - -Parse a UCSC Gene Table dump - ucsc_gene_table_to_intervals.py --input=$input1 --output=$out_file1 --region=$region $exon - - - - - - - - - - - - - - - - - - - -Read a table dump in the UCSC gene table format and create a BED file corresponding to the requested feature of each gene. - + +Parse a UCSC Gene Table dump + ucsc_gene_table_to_intervals.py --input=$input1 --output=$out_file1 --region=$region $exon + + + + + + + + + + + + + + + + + + + +Read a table dump in the UCSC gene table format and create a BED file corresponding to the requested feature of each gene. + \ No newline at end of file diff --git a/tools/maf/genebed_maf_to_fasta.xml b/tools/maf/genebed_maf_to_fasta.xml index 44673e63986..42c0473d511 100644 --- a/tools/maf/genebed_maf_to_fasta.xml +++ b/tools/maf/genebed_maf_to_fasta.xml @@ -1,96 +1,95 @@ - - given a set of coding exon intervals - - macros.xml - - - #if $maf_source_type.maf_source == "user" #interval_maf_to_merged_fasta.py --dbkey=$dbkey --species=$maf_source_type.species --mafSource=$maf_source_type.maf_file --mafIndex=$maf_source_type.maf_file.metadata.maf_index --interval_file=$input1 --output_file=$out_file1 --mafSourceType=$maf_source_type.maf_source --geneBED --mafIndexFileDir=${GALAXY_DATA_INDEX_DIR} - #else #interval_maf_to_merged_fasta.py --dbkey=$dbkey --species=$maf_source_type.species --mafSource=$maf_source_type.maf_identifier --interval_file=$input1 --output_file=$out_file1 --mafSourceType=$maf_source_type.maf_source --geneBED --mafIndexFileDir=${GALAXY_DATA_INDEX_DIR} - #end if# --overwrite_with_gaps=$overwrite_with_gaps - - - - - value.metadata.columns >= 12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - in aligning species - - - - - - - - - - - - - - - - -**What it does** - -The coding sequence of genes are usually composed of several coding exons. Each of these coding exons is an individual genomic region, which when concatenated with each other constitutes the coding sequence. A single genomic region can be covered by multiple alignment blocks. In many cases it is desirable to stitch these alignment blocks together. This tool accepts a list of gene-based intervals, in the Gene BED format. For every interval it performs the following: - - * finds all MAF blocks that overlap the coding regions; - * sorts MAF blocks by alignment score; - * stitches blocks together and resolves overlaps based on alignment score; - * outputs alignments in FASTA format. - -@HELP_CITATIONS@ - - - + + given a set of coding exon intervals + + macros.xml + + + #if $maf_source_type.maf_source == "user" #interval_maf_to_merged_fasta.py --dbkey=$dbkey --species=$maf_source_type.species --mafSource=$maf_source_type.maf_file --mafIndex=$maf_source_type.maf_file.metadata.maf_index --interval_file=$input1 --output_file=$out_file1 --mafSourceType=$maf_source_type.maf_source --geneBED --mafIndexFileDir=${GALAXY_DATA_INDEX_DIR} + #else #interval_maf_to_merged_fasta.py --dbkey=$dbkey --species=$maf_source_type.species --mafSource=$maf_source_type.maf_identifier --interval_file=$input1 --output_file=$out_file1 --mafSourceType=$maf_source_type.maf_source --geneBED --mafIndexFileDir=${GALAXY_DATA_INDEX_DIR} + #end if# --overwrite_with_gaps=$overwrite_with_gaps + + + + + value.metadata.columns >= 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + in aligning species + + + + + + + + + + + + + + + +**What it does** + +The coding sequence of genes are usually composed of several coding exons. Each of these coding exons is an individual genomic region, which when concatenated with each other constitutes the coding sequence. A single genomic region can be covered by multiple alignment blocks. In many cases it is desirable to stitch these alignment blocks together. This tool accepts a list of gene-based intervals, in the Gene BED format. For every interval it performs the following: + + * finds all MAF blocks that overlap the coding regions; + * sorts MAF blocks by alignment score; + * stitches blocks together and resolves overlaps based on alignment score; + * outputs alignments in FASTA format. + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/interval2maf.xml b/tools/maf/interval2maf.xml index 13b8f809e2a..d243690a938 100644 --- a/tools/maf/interval2maf.xml +++ b/tools/maf/interval2maf.xml @@ -1,292 +1,292 @@ - - given a set of genomic intervals - - macros.xml - - - #if $maf_source_type.maf_source == "user" #interval2maf.py --dbkey=${input1.dbkey} --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafFile=$maf_source_type.mafFile --mafIndex=$maf_source_type.mafFile.metadata.maf_index --interval_file=$input1 --output_file=$out_file1 --mafIndexFile=${GALAXY_DATA_INDEX_DIR}/maf_index.loc --species=$maf_source_type.species - #else #interval2maf.py --dbkey=${input1.dbkey} --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafType=$maf_source_type.mafType --interval_file=$input1 --output_file=$out_file1 --mafIndexFile=${GALAXY_DATA_INDEX_DIR}/maf_index.loc --species=$maf_source_type.species - #end if# --split_blocks_by_species=$split_blocks_by_species_selector.split_blocks_by_species - #if $split_blocks_by_species_selector.split_blocks_by_species == "split_blocks_by_species"# - --remove_all_gap_columns=$split_blocks_by_species_selector.remove_all_gap_columns - #end if - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -**What it does** - -This tool takes genomic coordinates, superimposes them on multiple alignments (in MAF format) stored on the Galaxy site or from your history, and excises alignment blocks corresponding to each set of coordinates. Alignment blocks that extend past START and/or END positions of an interval are trimmed. Note that a single genomic interval may correspond to two or more alignment blocks. - ------ - -**Example** - -Here a single interval is superimposed on three MAF blocks. Blocks 1 and 3 are trimmed because they extend beyond boundaries of the interval: - -.. image:: ${static_path}/images/maf_icons/interval2maf.png - -------- - -**Split blocks by species** - -This option examines each MAF block for multiple occurrences of a species in a single block. When this occurs, a block is split into multiple blocks where every combination of one sequence per species per block is represented. - -The interface for this option has two inputs: - - * **MAF file to split**. Choose multiple alignments from history to be split by species. - * **Collapse empty alignment columns**. Should alignment columns containing only gaps in the new blocks be removed. - - - -**Example 1**: **Collapse empty alignment columns is Yes**: - -For the following alignment:: - - ##maf version=1 - a score=2047408.0 - s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG - s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - -the tool will create **a single** history item containing 12 alignment blocks (notice that no columns contain only gaps):: - - ##maf version=1 - a score=2047408.0 - s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT-GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT-GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC--GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC-GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC-GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTAG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGCAG - - a score=2047408.0 - s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCAG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC---AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC---AG - - - -**Example 2**: **Collapse empty alignment columns is No**: - -For the following alignment:: - - ##maf version=1 - a score=2047408.0 - s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG - s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - -the tool will create **a single** history item containing 12 alignment blocks (notice that some columns contain only gaps):: - - ##maf version=1 - a score=2047408.0 - s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG - s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG - s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - - a score=2047408.0 - s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG - s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG - s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG - -@HELP_CITATIONS@ - - - + + given a set of genomic intervals + + macros.xml + + + #if $maf_source_type.maf_source == "user" #interval2maf.py --dbkey=${input1.dbkey} --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafFile=$maf_source_type.mafFile --mafIndex=$maf_source_type.mafFile.metadata.maf_index --interval_file=$input1 --output_file=$out_file1 --mafIndexFile=${GALAXY_DATA_INDEX_DIR}/maf_index.loc --species=$maf_source_type.species + #else #interval2maf.py --dbkey=${input1.dbkey} --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafType=$maf_source_type.mafType --interval_file=$input1 --output_file=$out_file1 --mafIndexFile=${GALAXY_DATA_INDEX_DIR}/maf_index.loc --species=$maf_source_type.species + #end if# --split_blocks_by_species=$split_blocks_by_species_selector.split_blocks_by_species + #if $split_blocks_by_species_selector.split_blocks_by_species == "split_blocks_by_species"# + --remove_all_gap_columns=$split_blocks_by_species_selector.remove_all_gap_columns + #end if + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +**What it does** + +This tool takes genomic coordinates, superimposes them on multiple alignments (in MAF format) stored on the Galaxy site or from your history, and excises alignment blocks corresponding to each set of coordinates. Alignment blocks that extend past START and/or END positions of an interval are trimmed. Note that a single genomic interval may correspond to two or more alignment blocks. + +----- + +**Example** + +Here a single interval is superimposed on three MAF blocks. Blocks 1 and 3 are trimmed because they extend beyond boundaries of the interval: + +.. image:: ${static_path}/images/maf_icons/interval2maf.png + +------- + +**Split blocks by species** + +This option examines each MAF block for multiple occurrences of a species in a single block. When this occurs, a block is split into multiple blocks where every combination of one sequence per species per block is represented. + +The interface for this option has two inputs: + + * **MAF file to split**. Choose multiple alignments from history to be split by species. + * **Collapse empty alignment columns**. Should alignment columns containing only gaps in the new blocks be removed. + + + +**Example 1**: **Collapse empty alignment columns is Yes**: + +For the following alignment:: + + ##maf version=1 + a score=2047408.0 + s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG + s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + +the tool will create **a single** history item containing 12 alignment blocks (notice that no columns contain only gaps):: + + ##maf version=1 + a score=2047408.0 + s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT-GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT-GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC--GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC-GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC-GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTAG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGCAG + + a score=2047408.0 + s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCAG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC---AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC---AG + + + +**Example 2**: **Collapse empty alignment columns is No**: + +For the following alignment:: + + ##maf version=1 + a score=2047408.0 + s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG + s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + +the tool will create **a single** history item containing 12 alignment blocks (notice that some columns contain only gaps):: + + ##maf version=1 + a score=2047408.0 + s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG + s species2.chr1 129723125 85 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG + s species2.chr1 129723125 83 - 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCT--GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTCGTCCTCAG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 85 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984545 83 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTT--GTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTCCTCAG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 + 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTT------AG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + + a score=2047408.0 + s species1.chr1 147984645 79 - 245522847 ATGGCGTCGGCCTCCTCCGGGCCGTCGTC---GGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTTGTC---AG + s species2.chr1 129723925 79 + 229575298 ATGGCGTCGGCCTCCTCCGGGCCGTCGTCTTCGGTCGGTTTTTCATCCTTTGATCCCGCGGTCCCTTCCTGTACCTC------AG + s species3.chr3 68255714 76 - 258222147 ATGGCGTCCGCCTCCTCAGGGCCAGCGGC---GGCGGGGTTTTCACCCCTTGATTCCGGGGTCCCTGCCGGTACCGC------AG + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/interval2maf_pairwise.xml b/tools/maf/interval2maf_pairwise.xml index 786fa2ac29e..99916f4edc0 100644 --- a/tools/maf/interval2maf_pairwise.xml +++ b/tools/maf/interval2maf_pairwise.xml @@ -1,48 +1,48 @@ - - given a set of genomic intervals - - macros.xml - - interval2maf.py --dbkey=${input1.dbkey} --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafType=$mafType --interval_file=$input1 --output_file=$out_file1 --indexLocation=${GALAXY_DATA_INDEX_DIR}/maf_pairwise.loc - - - - - - - - - - - - - - - - - - - - - - - - - - -**What it does** - -This tool takes genomic coordinates, superimposes them on pairwise alignments (in MAF format) stored on the Galaxy site, and excises alignment blocks corresponding to each set of coordinates. Alignment blocks that extend past START and/or END positions of an interval are trimmed. Note that a single genomic interval may correspond to two or more alignment blocks. - ------ - -**Example** - -Here a single interval is superimposed on three MAF blocks. Blocks 1 and 3 are trimmed because they extend beyond boundaries of the interval: - -.. image:: ${static_path}/images/maf_icons/interval2maf.png - -@HELP_CITATIONS@ - - - + + given a set of genomic intervals + + macros.xml + + interval2maf.py --dbkey=${input1.dbkey} --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafType=$mafType --interval_file=$input1 --output_file=$out_file1 --indexLocation=${GALAXY_DATA_INDEX_DIR}/maf_pairwise.loc + + + + + + + + + + + + + + + + + + + + + + + + + + +**What it does** + +This tool takes genomic coordinates, superimposes them on pairwise alignments (in MAF format) stored on the Galaxy site, and excises alignment blocks corresponding to each set of coordinates. Alignment blocks that extend past START and/or END positions of an interval are trimmed. Note that a single genomic interval may correspond to two or more alignment blocks. + +----- + +**Example** + +Here a single interval is superimposed on three MAF blocks. Blocks 1 and 3 are trimmed because they extend beyond boundaries of the interval: + +.. image:: ${static_path}/images/maf_icons/interval2maf.png + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/interval_maf_to_merged_fasta.xml b/tools/maf/interval_maf_to_merged_fasta.xml index 053b3c45d90..25d9d91e7f5 100644 --- a/tools/maf/interval_maf_to_merged_fasta.xml +++ b/tools/maf/interval_maf_to_merged_fasta.xml @@ -1,112 +1,112 @@ - - given a set of genomic intervals - - macros.xml - - - #if $maf_source_type.maf_source == "user" #interval_maf_to_merged_fasta.py --dbkey=$dbkey --species=$maf_source_type.species --mafSource=$maf_source_type.maf_file --mafIndex=$maf_source_type.maf_file.metadata.maf_index --interval_file=$input1 --output_file=$out_file1 --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafSourceType=$maf_source_type.maf_source --mafIndexFileDir=${GALAXY_DATA_INDEX_DIR} - #else #interval_maf_to_merged_fasta.py --dbkey=$dbkey --species=$maf_source_type.species --mafSource=$maf_source_type.maf_identifier --interval_file=$input1 --output_file=$out_file1 --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafSourceType=$maf_source_type.maf_source --mafIndexFileDir=${GALAXY_DATA_INDEX_DIR} - #end if# --overwrite_with_gaps=$overwrite_with_gaps - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -**What it does** - -A single genomic region can be covered by multiple alignment blocks. In many cases it is desirable to stitch these alignment blocks together. This tool accepts a list of genomic intervals. For every interval it performs the following: - - * finds all MAF blocks that overlap the interval; - * sorts MAF blocks by alignment score; - * stitches blocks together and resolves overlaps based on alignment score; - * outputs alignments in FASTA format. - ------- - -**Example** - -Here three MAF blocks overlapping a single interval are stitched together. Space between blocks 2 and 3 is filled with gaps: - -.. image:: ${static_path}/images/maf_icons/stitchMaf.png - -@HELP_CITATIONS@ - - - + + given a set of genomic intervals + + macros.xml + + + #if $maf_source_type.maf_source == "user" #interval_maf_to_merged_fasta.py --dbkey=$dbkey --species=$maf_source_type.species --mafSource=$maf_source_type.maf_file --mafIndex=$maf_source_type.maf_file.metadata.maf_index --interval_file=$input1 --output_file=$out_file1 --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafSourceType=$maf_source_type.maf_source --mafIndexFileDir=${GALAXY_DATA_INDEX_DIR} + #else #interval_maf_to_merged_fasta.py --dbkey=$dbkey --species=$maf_source_type.species --mafSource=$maf_source_type.maf_identifier --interval_file=$input1 --output_file=$out_file1 --chromCol=${input1.metadata.chromCol} --startCol=${input1.metadata.startCol} --endCol=${input1.metadata.endCol} --strandCol=${input1.metadata.strandCol} --mafSourceType=$maf_source_type.maf_source --mafIndexFileDir=${GALAXY_DATA_INDEX_DIR} + #end if# --overwrite_with_gaps=$overwrite_with_gaps + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +**What it does** + +A single genomic region can be covered by multiple alignment blocks. In many cases it is desirable to stitch these alignment blocks together. This tool accepts a list of genomic intervals. For every interval it performs the following: + + * finds all MAF blocks that overlap the interval; + * sorts MAF blocks by alignment score; + * stitches blocks together and resolves overlaps based on alignment score; + * outputs alignments in FASTA format. + +------ + +**Example** + +Here three MAF blocks overlapping a single interval are stitched together. Space between blocks 2 and 3 is filled with gaps: + +.. image:: ${static_path}/images/maf_icons/stitchMaf.png + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/maf_by_block_number.xml b/tools/maf/maf_by_block_number.xml index 3b9b578a130..474e461f0cf 100644 --- a/tools/maf/maf_by_block_number.xml +++ b/tools/maf/maf_by_block_number.xml @@ -1,38 +1,38 @@ - - given a set of block numbers and a MAF file - - macros.xml - - maf_by_block_number.py $input1 $input2 $out_file1 $block_col $species - - - - - - - - - - - - - - - - - - - - - - - - -**What it does** - -This tool takes a list of block numbers, one per line, and extracts the corresponding MAF blocks from the provided file. Block numbers start at 0. - -@HELP_CITATIONS@ - - - + + given a set of block numbers and a MAF file + + macros.xml + + maf_by_block_number.py $input1 $input2 $out_file1 $block_col $species + + + + + + + + + + + + + + + + + + + + + + + + +**What it does** + +This tool takes a list of block numbers, one per line, and extracts the corresponding MAF blocks from the provided file. Block numbers start at 0. + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/maf_filter.py b/tools/maf/maf_filter.py index c223f2912ff..d1e4ab089fd 100644 --- a/tools/maf/maf_filter.py +++ b/tools/maf/maf_filter.py @@ -1,65 +1,72 @@ -#Dan Blankenberg -#Filters a MAF file according to the provided code file, which is generated in maf_filter.xml -#Also allows filtering by number of columns in a block, and limiting output species -import sys, os, shutil -from galaxy import eggs -import pkg_resources; pkg_resources.require( "bx-python" ) -import bx.align.maf -from galaxy.tools.util import maf_utilities - -def main(): - #Read command line arguments - try: - script_file = sys.argv.pop( 1 ) - maf_file = sys.argv.pop( 1 ) - out_file = sys.argv.pop( 1 ) - additional_files_path = sys.argv.pop( 1 ) - species = maf_utilities.parse_species_option( sys.argv.pop( 1 ) ) - min_size = int( sys.argv.pop( 1 ) ) - max_size = int( sys.argv.pop( 1 ) ) - if max_size < 1: max_size = sys.maxint - min_species_per_block = int( sys.argv.pop( 1 ) ) - exclude_incomplete_blocks = int( sys.argv.pop( 1 ) ) - if species: - num_species = len( species ) - else: - num_species = len( sys.argv.pop( 1 ).split( ',') ) - except: - print >>sys.stderr, "One or more arguments is missing.\nUsage: maf_filter.py maf_filter_file input_maf output_maf path_to_save_debug species_to_keep" - sys.exit() - - #Open input and output MAF files - try: - maf_reader = bx.align.maf.Reader( open( maf_file,'r' ) ) - maf_writer = bx.align.maf.Writer( open( out_file,'w' ) ) - except: - print >>sys.stderr, "Your MAF file appears to be malformed." - sys.exit() - - #Save script file for debuging/verification info later - os.mkdir( additional_files_path ) - shutil.copy( script_file, os.path.join( additional_files_path, 'debug.txt' ) ) - - #Loop through blocks, running filter on each - #'maf_block' and 'ret_val' are used/shared in the provided code file - #'ret_val' should be set to True if the block is to be kept - i = 0 - blocks_kept = 0 - for i, maf_block in enumerate( maf_reader ): - if min_size <= maf_block.text_size <= max_size: - local = {'maf_block':maf_block, 'ret_val':False} - execfile( script_file, {}, local ) - if local['ret_val']: - #Species limiting must be done after filters as filters could be run on non-requested output species - if species: - maf_block = maf_block.limit_to_species( species ) - if len( maf_block.components ) >= min_species_per_block and ( not exclude_incomplete_blocks or len( maf_block.components ) >= num_species ): - maf_writer.write( maf_block ) - blocks_kept += 1 - maf_writer.close() - maf_reader.close() - if i == 0: print "Your file contains no valid maf_blocks." - else: print 'Kept %s of %s blocks (%.2f%%).' % ( blocks_kept, i + 1, float( blocks_kept ) / float( i + 1 ) * 100.0 ) - -if __name__ == "__main__": - main() +#Dan Blankenberg +#Filters a MAF file according to the provided code file, which is generated in maf_filter.xml +#Also allows filtering by number of columns in a block, and limiting output species +import os +import sys +import shutil +from galaxy import eggs +import pkg_resources +pkg_resources.require( "bx-python" ) +import bx.align.maf +from galaxy.tools.util import maf_utilities + + +def main(): + #Read command line arguments + try: + script_file = sys.argv.pop( 1 ) + maf_file = sys.argv.pop( 1 ) + out_file = sys.argv.pop( 1 ) + additional_files_path = sys.argv.pop( 1 ) + species = maf_utilities.parse_species_option( sys.argv.pop( 1 ) ) + min_size = int( sys.argv.pop( 1 ) ) + max_size = int( sys.argv.pop( 1 ) ) + if max_size < 1: + max_size = sys.maxint + min_species_per_block = int( sys.argv.pop( 1 ) ) + exclude_incomplete_blocks = int( sys.argv.pop( 1 ) ) + if species: + num_species = len( species ) + else: + num_species = len( sys.argv.pop( 1 ).split( ',') ) + except: + print >>sys.stderr, "One or more arguments is missing.\nUsage: maf_filter.py maf_filter_file input_maf output_maf path_to_save_debug species_to_keep" + sys.exit() + + #Open input and output MAF files + try: + maf_reader = bx.align.maf.Reader( open( maf_file, 'r' ) ) + maf_writer = bx.align.maf.Writer( open( out_file, 'w' ) ) + except: + print >>sys.stderr, "Your MAF file appears to be malformed." + sys.exit() + + #Save script file for debuging/verification info later + os.mkdir( additional_files_path ) + shutil.copy( script_file, os.path.join( additional_files_path, 'debug.txt' ) ) + + #Loop through blocks, running filter on each + #'maf_block' and 'ret_val' are used/shared in the provided code file + #'ret_val' should be set to True if the block is to be kept + i = 0 + blocks_kept = 0 + for i, maf_block in enumerate( maf_reader ): + if min_size <= maf_block.text_size <= max_size: + local = {'maf_block': maf_block, 'ret_val': False} + execfile( script_file, {}, local ) + if local['ret_val']: + #Species limiting must be done after filters as filters could be run on non-requested output species + if species: + maf_block = maf_block.limit_to_species( species ) + if len( maf_block.components ) >= min_species_per_block and ( not exclude_incomplete_blocks or len( maf_block.components ) >= num_species ): + maf_writer.write( maf_block ) + blocks_kept += 1 + maf_writer.close() + maf_reader.close() + if i == 0: + print "Your file contains no valid maf_blocks." + else: + print 'Kept %s of %s blocks (%.2f%%).' % ( blocks_kept, i + 1, float( blocks_kept ) / float( i + 1 ) * 100.0 ) + +if __name__ == "__main__": + main() diff --git a/tools/maf/maf_filter.xml b/tools/maf/maf_filter.xml index a69cdc681a7..7b33837c163 100644 --- a/tools/maf/maf_filter.xml +++ b/tools/maf/maf_filter.xml @@ -1,200 +1,199 @@ - - by specified attributes - - macros.xml - - maf_filter.py $maf_filter_file $input1 $out_file1 $out_file1.files_path $species $min_size $max_size $min_species_per_block $exclude_incomplete_blocks ${input1.metadata.species} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#set $is_isnot_valid = {"==":"==", "!=":"!=", "in":"in", "not in":"not in"} -def maf_block_pass_filter( maf_block ): -#for $maf_filter in $maf_filters: -#if $len( $maf_filter['species1_attributes']['filter_condition'] ) == 0: -#continue -#end if - primary_component = maf_block.get_component_by_src_start( """$maf_filter['species1'].value.encode( 'string_escape' )""".decode( 'string_escape' ) ) - if primary_component is not None: -#if $maf_filter['species1_attributes']['species1_attribute_type'] == 'attribute_chr': - if primary_component.src.split( "." )[-1] $is_isnot_valid.get( $maf_filter['species1_attributes']['species1_is_isnot'].value.strip(), 'is in' ) """$maf_filter['species1_attributes']['species1_attribute'].value.encode( 'string_escape' )""".decode( 'string_escape' ).split( "," ): -#else - if primary_component.strand $is_isnot_valid.get( $maf_filter['species1_attributes']['species1_is_isnot'].value.strip(), '==' ) """$maf_filter['species1_attributes']['species1_attribute'].value.encode( 'string_escape' )""".decode( 'string_escape' ): -#end if -#for $filter_condition in $maf_filter['species1_attributes']['filter_condition']: - secondary_component = maf_block.get_component_by_src_start( """$filter_condition['species2'].value.encode( 'string_escape' )""".decode( 'string_escape' ) ) -#if $filter_condition['species2_attributes']['species2_attribute_type'] == 'attribute_chr': - if secondary_component is not None: - if not ( secondary_component.src.split( "." )[-1] $is_isnot_valid.get( $filter_condition['species2_attributes']['species2_is_isnot'].value.strip(), 'is in' ) """$filter_condition['species2_attributes']['species2_attribute'].value.encode( 'string_escape' )""".decode( 'string_escape' ).split( "," ) ): - return False -#else: - if secondary_component is not None: - if not ( secondary_component.strand $is_isnot_valid.get( $filter_condition['species2_attributes']['species2_is_isnot'].value.strip(), '==' ) """$filter_condition['species2_attributes']['species2_attribute'].value.encode( 'string_escape' )""".decode( 'string_escape' ) ): - return False -#end if -#end for -#end for - return True -ret_val = maf_block_pass_filter( maf_block ) - - - - - - - -This tool allows you to build complex filters to be applied to each alignment block of a MAF file. You can define restraints on species based upon chromosome and strand. You can specify comma separated lists of chromosomes where appropriate. - -.. class:: infomark - -For example, this tool is useful to restrict a set of alignments to only those blocks which contain alignments between chromosomes that are considered homologous. - ------ - -.. class:: warningmark - -If a species is not found in a particular block, all filters on that species are ignored. - ------ - -This tool allows the user to remove any undesired species from a MAF file. If no species are specified then all species will be kept. If species are specified, columns which contain only gaps are removed. The options for this are: - - * **Exclude blocks which have missing species** - suppose you want to restrict an 8-way alignment to human, mouse, and rat. The tool will first remove all other species. Next, if this option is set to **YES** the tool WILL NOT return MAF blocks, which do not include human, mouse, or rat. This means that all alignment blocks returned by the tool will have exactly three sequences in this example. - - * **Exclude blocks which have only one species** - if this option is set to **YES** all single sequence alignment blocks WILL NOT be returned. - ------ - -You can also provide a size range and limit your output to the MAF blocks which fall within the specified range. - -@HELP_CITATIONS@ - - - + + by specified attributes + + macros.xml + + maf_filter.py $maf_filter_file $input1 $out_file1 $out_file1.files_path $species $min_size $max_size $min_species_per_block $exclude_incomplete_blocks ${input1.metadata.species} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#set $is_isnot_valid = {"==":"==", "!=":"!=", "in":"in", "not in":"not in"} +def maf_block_pass_filter( maf_block ): +#for $maf_filter in $maf_filters: +#if $len( $maf_filter['species1_attributes']['filter_condition'] ) == 0: +#continue +#end if + primary_component = maf_block.get_component_by_src_start( """$maf_filter['species1'].value.encode( 'string_escape' )""".decode( 'string_escape' ) ) + if primary_component is not None: +#if $maf_filter['species1_attributes']['species1_attribute_type'] == 'attribute_chr': + if primary_component.src.split( "." )[-1] $is_isnot_valid.get( $maf_filter['species1_attributes']['species1_is_isnot'].value.strip(), 'is in' ) """$maf_filter['species1_attributes']['species1_attribute'].value.encode( 'string_escape' )""".decode( 'string_escape' ).split( "," ): +#else + if primary_component.strand $is_isnot_valid.get( $maf_filter['species1_attributes']['species1_is_isnot'].value.strip(), '==' ) """$maf_filter['species1_attributes']['species1_attribute'].value.encode( 'string_escape' )""".decode( 'string_escape' ): +#end if +#for $filter_condition in $maf_filter['species1_attributes']['filter_condition']: + secondary_component = maf_block.get_component_by_src_start( """$filter_condition['species2'].value.encode( 'string_escape' )""".decode( 'string_escape' ) ) +#if $filter_condition['species2_attributes']['species2_attribute_type'] == 'attribute_chr': + if secondary_component is not None: + if not ( secondary_component.src.split( "." )[-1] $is_isnot_valid.get( $filter_condition['species2_attributes']['species2_is_isnot'].value.strip(), 'is in' ) """$filter_condition['species2_attributes']['species2_attribute'].value.encode( 'string_escape' )""".decode( 'string_escape' ).split( "," ) ): + return False +#else: + if secondary_component is not None: + if not ( secondary_component.strand $is_isnot_valid.get( $filter_condition['species2_attributes']['species2_is_isnot'].value.strip(), '==' ) """$filter_condition['species2_attributes']['species2_attribute'].value.encode( 'string_escape' )""".decode( 'string_escape' ) ): + return False +#end if +#end for +#end for + return True +ret_val = maf_block_pass_filter( maf_block ) + + + + + + + +This tool allows you to build complex filters to be applied to each alignment block of a MAF file. You can define restraints on species based upon chromosome and strand. You can specify comma separated lists of chromosomes where appropriate. + +.. class:: infomark + +For example, this tool is useful to restrict a set of alignments to only those blocks which contain alignments between chromosomes that are considered homologous. + +----- + +.. class:: warningmark + +If a species is not found in a particular block, all filters on that species are ignored. + +----- + +This tool allows the user to remove any undesired species from a MAF file. If no species are specified then all species will be kept. If species are specified, columns which contain only gaps are removed. The options for this are: + + * **Exclude blocks which have missing species** - suppose you want to restrict an 8-way alignment to human, mouse, and rat. The tool will first remove all other species. Next, if this option is set to **YES** the tool WILL NOT return MAF blocks, which do not include human, mouse, or rat. This means that all alignment blocks returned by the tool will have exactly three sequences in this example. + + * **Exclude blocks which have only one species** - if this option is set to **YES** all single sequence alignment blocks WILL NOT be returned. + +----- + +You can also provide a size range and limit your output to the MAF blocks which fall within the specified range. + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/maf_limit_size.xml b/tools/maf/maf_limit_size.xml index 51feb29d4ef..207628a9054 100644 --- a/tools/maf/maf_limit_size.xml +++ b/tools/maf/maf_limit_size.xml @@ -1,34 +1,34 @@ - - by Size - - macros.xml - - maf_limit_size.py $input1 $out_file1 $min_size $max_size - - - - - - - - - - - - - - - - - - - - -**What it does** - -This tool takes a MAF file and a size range and extracts the MAF blocks which fall within the specified range. - -@HELP_CITATIONS@ - - - + + by Size + + macros.xml + + maf_limit_size.py $input1 $out_file1 $min_size $max_size + + + + + + + + + + + + + + + + + + + + +**What it does** + +This tool takes a MAF file and a size range and extracts the MAF blocks which fall within the specified range. + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/maf_reverse_complement.py b/tools/maf/maf_reverse_complement.py index 14417041eee..8228b599805 100644 --- a/tools/maf/maf_reverse_complement.py +++ b/tools/maf/maf_reverse_complement.py @@ -1,42 +1,45 @@ -#!/usr/bin/env python - -""" -Reads a MAF file. Produces a MAF file containing -the reverse complement for each block in the source file. - -usage: %prog input_maf_file output_maf_file -""" -#Dan Blankenberg -from galaxy import eggs -import pkg_resources; pkg_resources.require( "bx-python" ) -import bx.align.maf -from galaxy.tools.util import maf_utilities -import sys - -assert sys.version_info[:2] >= ( 2, 4 ) - -def __main__(): - #Parse Command Line - input_file = sys.argv.pop( 1 ) - output_file = sys.argv.pop( 1 ) - species = maf_utilities.parse_species_option( sys.argv.pop( 1 ) ) - - try: - maf_writer = bx.align.maf.Writer( open( output_file, 'w' ) ) - except: - print sys.stderr, "Unable to open output file" - sys.exit() - try: - count = 0 - for count, maf in enumerate( bx.align.maf.Reader( open( input_file ) ) ): - maf = maf.reverse_complement() - if species: - maf = maf.limit_to_species( species ) - maf_writer.write( maf ) - except: - print >>sys.stderr, "Your MAF file appears to be malformed." - sys.exit() - print "%i regions were reverse complemented." % count - maf_writer.close() - -if __name__ == "__main__": __main__() +#!/usr/bin/env python + +""" +Reads a MAF file. Produces a MAF file containing +the reverse complement for each block in the source file. + +usage: %prog input_maf_file output_maf_file +""" +#Dan Blankenberg +from galaxy import eggs +import pkg_resources +pkg_resources.require( "bx-python" ) +import bx.align.maf +from galaxy.tools.util import maf_utilities +import sys + +assert sys.version_info[:2] >= ( 2, 4 ) + + +def __main__(): + #Parse Command Line + input_file = sys.argv.pop( 1 ) + output_file = sys.argv.pop( 1 ) + species = maf_utilities.parse_species_option( sys.argv.pop( 1 ) ) + + try: + maf_writer = bx.align.maf.Writer( open( output_file, 'w' ) ) + except: + print sys.stderr, "Unable to open output file" + sys.exit() + try: + count = 0 + for count, maf in enumerate( bx.align.maf.Reader( open( input_file ) ) ): + maf = maf.reverse_complement() + if species: + maf = maf.limit_to_species( species ) + maf_writer.write( maf ) + except: + print >>sys.stderr, "Your MAF file appears to be malformed." + sys.exit() + print "%i regions were reverse complemented." % count + maf_writer.close() + +if __name__ == "__main__": + __main__() diff --git a/tools/maf/maf_reverse_complement.xml b/tools/maf/maf_reverse_complement.xml index a35b72ffced..ce62d0db7a5 100644 --- a/tools/maf/maf_reverse_complement.xml +++ b/tools/maf/maf_reverse_complement.xml @@ -1,51 +1,51 @@ - - a MAF file - - macros.xml - - maf_reverse_complement.py $input1 $out_file1 $species - - - - - - - - - - - - - - - - - - - - - -**What it does** - -This tool takes a MAF file and creates a new MAF file, where each block has been reversed complemented. - -**Example** - -This MAF Block:: - - a score=8157.000000 - s hg17.chr7 127471526 58 + 158628139 AATTTGTGGTTTATTCATTTTTCATTATTTTGTTTAAGGAGGTCTATAGTGGAAGAGG - s panTro1.chr6 129885407 58 + 161576975 AATTTGTGGTTTATTCGTTTTTCATTATTTTGTTTAAGGAGGTCTATAGTGGAAGAGG - s mm5.chr6 28904928 54 + 149721531 AA----CGTTTCATTGATTGCTCATCATTTAAAAAAAGAAATTCCTCAGTGGAAGAGG - -becomes:: - - a score=8157.000000 - s hg17.chr7 31156555 58 - 158628139 CCTCTTCCACTATAGACCTCCTTAAACAAAATAATGAAAAATGAATAAACCACAAATT - s panTro1.chr6 31691510 58 - 161576975 CCTCTTCCACTATAGACCTCCTTAAACAAAATAATGAAAAACGAATAAACCACAAATT - s mm5.chr6 120816549 54 - 149721531 CCTCTTCCACTGAGGAATTTCTTTTTTTAAATGATGAGCAATCAATGAAACG----TT - -@HELP_CITATIONS@ - - - + + a MAF file + + macros.xml + + maf_reverse_complement.py $input1 $out_file1 $species + + + + + + + + + + + + + + + + + + + + + +**What it does** + +This tool takes a MAF file and creates a new MAF file, where each block has been reversed complemented. + +**Example** + +This MAF Block:: + + a score=8157.000000 + s hg17.chr7 127471526 58 + 158628139 AATTTGTGGTTTATTCATTTTTCATTATTTTGTTTAAGGAGGTCTATAGTGGAAGAGG + s panTro1.chr6 129885407 58 + 161576975 AATTTGTGGTTTATTCGTTTTTCATTATTTTGTTTAAGGAGGTCTATAGTGGAAGAGG + s mm5.chr6 28904928 54 + 149721531 AA----CGTTTCATTGATTGCTCATCATTTAAAAAAAGAAATTCCTCAGTGGAAGAGG + +becomes:: + + a score=8157.000000 + s hg17.chr7 31156555 58 - 158628139 CCTCTTCCACTATAGACCTCCTTAAACAAAATAATGAAAAATGAATAAACCACAAATT + s panTro1.chr6 31691510 58 - 161576975 CCTCTTCCACTATAGACCTCCTTAAACAAAATAATGAAAAACGAATAAACCACAAATT + s mm5.chr6 120816549 54 - 149721531 CCTCTTCCACTGAGGAATTTCTTTTTTTAAATGATGAGCAATCAATGAAACG----TT + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/maf_split_by_species.xml b/tools/maf/maf_split_by_species.xml index d1efd45075c..b33a029ffaa 100644 --- a/tools/maf/maf_split_by_species.xml +++ b/tools/maf/maf_split_by_species.xml @@ -6,9 +6,9 @@ maf_split_by_species.py $input1 $out_file1 $collapse_columns - - - + + + diff --git a/tools/maf/maf_stats.xml b/tools/maf/maf_stats.xml index 4dec43968a9..8576fedd3fe 100644 --- a/tools/maf/maf_stats.xml +++ b/tools/maf/maf_stats.xml @@ -1,118 +1,118 @@ - - Alignment coverage information - - macros.xml - - - maf_stats.py - #if $maf_source_type.maf_source == "user": - $maf_source_type.maf_source $input2 $input1 $out_file1 $dbkey ${input1.metadata.chromCol} ${input1.metadata.startCol} ${input1.metadata.endCol} $summary - #else: - $maf_source_type.maf_source $maf_source_type.mafType $input1 $out_file1 $dbkey ${input1.metadata.chromCol} ${input1.metadata.startCol} ${input1.metadata.endCol} $summary - #end if + + Alignment coverage information + + macros.xml + + + maf_stats.py + #if $maf_source_type.maf_source == "user": + $maf_source_type.maf_source $input2 $input1 $out_file1 $dbkey ${input1.metadata.chromCol} ${input1.metadata.startCol} ${input1.metadata.endCol} $summary + #else: + $maf_source_type.maf_source $maf_source_type.mafType $input1 $out_file1 $dbkey ${input1.metadata.chromCol} ${input1.metadata.startCol} ${input1.metadata.endCol} $summary + #end if ${GALAXY_DATA_INDEX_DIR} #if $maf_source_type.maf_source == "user": $input2.metadata.maf_index - #end if - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - numpy - - - - - - - - + #end if + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + numpy + + + + + + + + - - - - - - - - - - -**What it does** - -This tool takes a MAF file and an interval file and relates coverage information by interval for each species. -If a column does not exist in the reference genome, it is not included in the output. - -Consider the interval: "chrX 1000 1100 myInterval" - Let's suppose we want to do stats on three way alignments for H, M, and R. The result look like this: - - chrX 1000 1100 myInterval H XXX YYY - - chrX 1000 1100 myInterval M XXX YYY - - chrX 1000 1100 myInterval R XXX YYY - - - where XXX and YYY are: - - XXX = number of nucleotides - - YYY = number of gaps - ----- - -Alternatively, you can request only summary information for a set of intervals: - - ======== =========== ======== - #species nucleotides coverage - ======== =========== ======== - hg18 30639 0.2372 - rheMac2 7524 0.0582 - panTro2 30390 0.2353 - ======== =========== ======== - - where **coverage** is the number of nucleotides divided by the total length of the provided intervals. - -@HELP_CITATIONS@ - - - + + + + + + + + + + +**What it does** + +This tool takes a MAF file and an interval file and relates coverage information by interval for each species. +If a column does not exist in the reference genome, it is not included in the output. + +Consider the interval: "chrX 1000 1100 myInterval" + Let's suppose we want to do stats on three way alignments for H, M, and R. The result look like this: + + chrX 1000 1100 myInterval H XXX YYY + + chrX 1000 1100 myInterval M XXX YYY + + chrX 1000 1100 myInterval R XXX YYY + + + where XXX and YYY are: + + XXX = number of nucleotides + + YYY = number of gaps + +---- + +Alternatively, you can request only summary information for a set of intervals: + + ======== =========== ======== + #species nucleotides coverage + ======== =========== ======== + hg18 30639 0.2372 + rheMac2 7524 0.0582 + panTro2 30390 0.2353 + ======== =========== ======== + + where **coverage** is the number of nucleotides divided by the total length of the provided intervals. + +@HELP_CITATIONS@ + + + diff --git a/tools/maf/maf_to_fasta.xml b/tools/maf/maf_to_fasta.xml index bddba3c8d9d..ec2abfaa464 100644 --- a/tools/maf/maf_to_fasta.xml +++ b/tools/maf/maf_to_fasta.xml @@ -1,197 +1,197 @@ - - Converts a MAF formatted file to FASTA format - - macros.xml - - - #if $fasta_target_type.fasta_type == "multiple" #maf_to_fasta_multiple_sets.py $input1 $out_file1 $fasta_target_type.species $fasta_target_type.complete_blocks - #else #maf_to_fasta_concat.py $fasta_target_type.species $input1 $out_file1 - #end if# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -**Types of MAF to FASTA conversion** - - * **Multiple Blocks** converts a single MAF block to a single FASTA block. For example, if you have 6 MAF blocks, they will be converted to 6 FASTA blocks. - * **One Sequence per Species** converts MAF blocks to a single aggregated FASTA block. For example, if you have 6 MAF blocks, they will be converted and concatenated into a single FASTA block. - -------- - -**What it does** - -This tool converts MAF blocks to FASTA format and concatenates them into a single FASTA block or outputs multiple FASTA blocks separated by empty lines. - -The interface for this tool contains two pages (steps): - - * **Step 1 of 2**. Choose multiple alignments from history to be converted to FASTA format. - * **Step 2 of 2**. Choose the type of output as well as the species from the alignment to be included in the output. - - Multiple Block output has additional options: - - * **Choose species** - the tool reads the alignment provided during Step 1 and generates a list of species contained within that alignment. Using checkboxes you can specify taxa to be included in the output (all species are selected by default). - * **Choose to include/exclude blocks with missing species** - if an alignment block does not contain any one of the species you selected within **Choose species** menu and this option is set to **exclude blocks with missing species**, then such a block **will not** be included in the output (see **Example 2** below). For example, if you want to extract human, mouse, and rat from a series of alignments and one of the blocks does not contain mouse sequence, then this block will not be converted to FASTA and will not be returned. - - ------ - -**Example 1**: - -In the concatenated approach, the following alignment:: - - ##maf version=1 - a score=68686.000000 - s hg18.chr20 56827368 75 + 62435964 GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- - s panTro2.chr20 56528685 75 + 62293572 GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- - s rheMac2.chr10 89144112 69 - 94855758 GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA------- - s mm8.chr2 173910832 61 + 181976762 AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------- - s canFam2.chr24 46551822 67 + 50763139 CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C - - a score=10289.000000 - s hg18.chr20 56827443 37 + 62435964 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - s panTro2.chr20 56528760 37 + 62293572 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - s rheMac2.chr10 89144181 37 - 94855758 ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG - -will be converted to (**note** that because mm8 (mouse) and canFam2 (dog) are absent from the second block, they are replaced with gaps after concatenation):: - - >canFam2 - CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C------------------------------------- - >hg18 - GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC-ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - >mm8 - AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC-------------------------------------------- - >panTro2 - GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC-ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - >rheMac2 - GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA-------ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG - ------- - -**Example 2a**: Multiple Block Approach **Include all species** and **include blocks with missing species**: - -The following alignment:: - - ##maf version=1 - a score=68686.000000 - s hg18.chr20 56827368 75 + 62435964 GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- - s panTro2.chr20 56528685 75 + 62293572 GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- - s rheMac2.chr10 89144112 69 - 94855758 GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA------- - s mm8.chr2 173910832 61 + 181976762 AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------- - s canFam2.chr24 46551822 67 + 50763139 CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C - - a score=10289.000000 - s hg18.chr20 56827443 37 + 62435964 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - s panTro2.chr20 56528760 37 + 62293572 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - s rheMac2.chr10 89144181 37 - 94855758 ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG - -will be converted to:: - - >hg18.chr20(+):56827368-56827443|hg18_0 - GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- - >panTro2.chr20(+):56528685-56528760|panTro2_0 - GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- - >rheMac2.chr10(-):89144112-89144181|rheMac2_0 - GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA------- - >mm8.chr2(+):173910832-173910893|mm8_0 - AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------- - >canFam2.chr24(+):46551822-46551889|canFam2_0 - CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C - - >hg18.chr20(+):56827443-56827480|hg18_1 - ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - >panTro2.chr20(+):56528760-56528797|panTro2_1 - ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - >rheMac2.chr10(-):89144181-89144218|rheMac2_1 - ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG - ------ - -**Example 2b**: Multiple Block Approach **Include hg18 and mm8** and **exclude blocks with missing species**: - -The following alignment:: - - ##maf version=1 - a score=68686.000000 - s hg18.chr20 56827368 75 + 62435964 GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- - s panTro2.chr20 56528685 75 + 62293572 GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- - s rheMac2.chr10 89144112 69 - 94855758 GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA------- - s mm8.chr2 173910832 61 + 181976762 AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------- - s canFam2.chr24 46551822 67 + 50763139 CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C - - a score=10289.000000 - s hg18.chr20 56827443 37 + 62435964 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - s panTro2.chr20 56528760 37 + 62293572 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG - s rheMac2.chr10 89144181 37 - 94855758 ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG - -will be converted to (**note** that the second MAF block, which does not have mm8, is not included in the output):: - - >hg18.chr20(+):56827368-56827443|hg18_0 - GACAGGGTGCATCTGGGAGGGCCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC - >mm8.chr2(+):173910832-173910893|mm8_0 - AGAAGGATCCACCT---------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------ - ------- - -.. class:: infomark - -**About formats** - - **MAF format** multiple alignment format file. This format stores multiple alignments at the DNA level between entire genomes. - - - The .maf format is line-oriented. Each multiple alignment ends with a blank line. - - Each sequence in an alignment is on a single line. - - Lines starting with # are considered to be comments. - - Each multiple alignment is in a separate paragraph that begins with an "a" line and contains an "s" line for each sequence in the multiple alignment. - - Some MAF files may contain two optional line types: - - - An "i" line containing information about what is in the aligned species DNA before and after the immediately preceding "s" line; - - An "e" line containing information about the size of the gap between the alignments that span the current block. - -@HELP_CITATIONS@ - - - + + Converts a MAF formatted file to FASTA format + + macros.xml + + + #if $fasta_target_type.fasta_type == "multiple" #maf_to_fasta_multiple_sets.py $input1 $out_file1 $fasta_target_type.species $fasta_target_type.complete_blocks + #else #maf_to_fasta_concat.py $fasta_target_type.species $input1 $out_file1 + #end if# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +**Types of MAF to FASTA conversion** + + * **Multiple Blocks** converts a single MAF block to a single FASTA block. For example, if you have 6 MAF blocks, they will be converted to 6 FASTA blocks. + * **One Sequence per Species** converts MAF blocks to a single aggregated FASTA block. For example, if you have 6 MAF blocks, they will be converted and concatenated into a single FASTA block. + +------- + +**What it does** + +This tool converts MAF blocks to FASTA format and concatenates them into a single FASTA block or outputs multiple FASTA blocks separated by empty lines. + +The interface for this tool contains two pages (steps): + + * **Step 1 of 2**. Choose multiple alignments from history to be converted to FASTA format. + * **Step 2 of 2**. Choose the type of output as well as the species from the alignment to be included in the output. + + Multiple Block output has additional options: + + * **Choose species** - the tool reads the alignment provided during Step 1 and generates a list of species contained within that alignment. Using checkboxes you can specify taxa to be included in the output (all species are selected by default). + * **Choose to include/exclude blocks with missing species** - if an alignment block does not contain any one of the species you selected within **Choose species** menu and this option is set to **exclude blocks with missing species**, then such a block **will not** be included in the output (see **Example 2** below). For example, if you want to extract human, mouse, and rat from a series of alignments and one of the blocks does not contain mouse sequence, then this block will not be converted to FASTA and will not be returned. + + +----- + +**Example 1**: + +In the concatenated approach, the following alignment:: + + ##maf version=1 + a score=68686.000000 + s hg18.chr20 56827368 75 + 62435964 GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- + s panTro2.chr20 56528685 75 + 62293572 GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- + s rheMac2.chr10 89144112 69 - 94855758 GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA------- + s mm8.chr2 173910832 61 + 181976762 AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------- + s canFam2.chr24 46551822 67 + 50763139 CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C + + a score=10289.000000 + s hg18.chr20 56827443 37 + 62435964 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + s panTro2.chr20 56528760 37 + 62293572 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + s rheMac2.chr10 89144181 37 - 94855758 ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG + +will be converted to (**note** that because mm8 (mouse) and canFam2 (dog) are absent from the second block, they are replaced with gaps after concatenation):: + + >canFam2 + CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C------------------------------------- + >hg18 + GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC-ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + >mm8 + AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC-------------------------------------------- + >panTro2 + GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC-ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + >rheMac2 + GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA-------ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG + +------ + +**Example 2a**: Multiple Block Approach **Include all species** and **include blocks with missing species**: + +The following alignment:: + + ##maf version=1 + a score=68686.000000 + s hg18.chr20 56827368 75 + 62435964 GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- + s panTro2.chr20 56528685 75 + 62293572 GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- + s rheMac2.chr10 89144112 69 - 94855758 GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA------- + s mm8.chr2 173910832 61 + 181976762 AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------- + s canFam2.chr24 46551822 67 + 50763139 CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C + + a score=10289.000000 + s hg18.chr20 56827443 37 + 62435964 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + s panTro2.chr20 56528760 37 + 62293572 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + s rheMac2.chr10 89144181 37 - 94855758 ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG + +will be converted to:: + + >hg18.chr20(+):56827368-56827443|hg18_0 + GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- + >panTro2.chr20(+):56528685-56528760|panTro2_0 + GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- + >rheMac2.chr10(-):89144112-89144181|rheMac2_0 + GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA------- + >mm8.chr2(+):173910832-173910893|mm8_0 + AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------- + >canFam2.chr24(+):46551822-46551889|canFam2_0 + CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C + + >hg18.chr20(+):56827443-56827480|hg18_1 + ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + >panTro2.chr20(+):56528760-56528797|panTro2_1 + ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + >rheMac2.chr10(-):89144181-89144218|rheMac2_1 + ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG + +----- + +**Example 2b**: Multiple Block Approach **Include hg18 and mm8** and **exclude blocks with missing species**: + +The following alignment:: + + ##maf version=1 + a score=68686.000000 + s hg18.chr20 56827368 75 + 62435964 GACAGGGTGCATCTGGGAGGG---CCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- + s panTro2.chr20 56528685 75 + 62293572 GACAGGGTGCATCTGAGAGGG---CCTGCCAGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC- + s rheMac2.chr10 89144112 69 - 94855758 GACAGGGTGCATCTGAGAGGG---CCTGCTGGGCCTTTG-TTCAAAACTAGATATGCCCCAACTCCAATTCTA------- + s mm8.chr2 173910832 61 + 181976762 AGAAGGATCCACCT------------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------- + s canFam2.chr24 46551822 67 + 50763139 CG------GCGTCTGTAAGGGGCCACCGCCCGGCCTGTG-CTCAAAGCTACAAATGACTCAACTCCCAACCGA------C + + a score=10289.000000 + s hg18.chr20 56827443 37 + 62435964 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + s panTro2.chr20 56528760 37 + 62293572 ATGTGCAGAAAATGTGATACAGAAACCTGCAGAGCAG + s rheMac2.chr10 89144181 37 - 94855758 ATGTGCGGAAAATGTGATACAGAAACCTGCAGAGCAG + +will be converted to (**note** that the second MAF block, which does not have mm8, is not included in the output):: + + >hg18.chr20(+):56827368-56827443|hg18_0 + GACAGGGTGCATCTGGGAGGGCCTGCCGGGCCTTTA-TTCAACACTAGATACGCCCCATCTCCAATTCTAATGGAC + >mm8.chr2(+):173910832-173910893|mm8_0 + AGAAGGATCCACCT---------TGCTGGGCCTCTGCTCCAGCAAGACCCACCTCCCAACTCAAATGCCC------ + +------ + +.. class:: infomark + +**About formats** + + **MAF format** multiple alignment format file. This format stores multiple alignments at the DNA level between entire genomes. + + - The .maf format is line-oriented. Each multiple alignment ends with a blank line. + - Each sequence in an alignment is on a single line. + - Lines starting with # are considered to be comments. + - Each multiple alignment is in a separate paragraph that begins with an "a" line and contains an "s" line for each sequence in the multiple alignment. + - Some MAF files may contain two optional line types: + + - An "i" line containing information about what is in the aligned species DNA before and after the immediately preceding "s" line; + - An "e" line containing information about the size of the gap between the alignments that span the current block. + +@HELP_CITATIONS@ + + + diff --git a/tools/plotting/bar_chart.xml b/tools/plotting/bar_chart.xml index 229ba4157ec..d5f86bcc18d 100644 --- a/tools/plotting/bar_chart.xml +++ b/tools/plotting/bar_chart.xml @@ -1,60 +1,58 @@ - - for multiple columns - - #if $xtic.userSpecified == "Yes" #bar_chart.py $input $xtic.xticColumn $colList "$title" "$ylabel" $ymin $ymax $out_file1 "$pdf_size" - #else #bar_chart.py $input 0 $colList "$title" "$ylabel" $ymin $ymax $out_file1 "$pdf_size" - #end if - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Gnuplot - Numeric - - - -**What it does** - -This tool builds a bar chart on one or more columns. Suppose you have dataset like this one:: - - Gene1 10 15 - Gene2 20 14 - Gene3 67 45 - Gene4 55 12 - -Graphing columns 2 and 3 while using column 1 for X Tick Labels will produce the following plot: - -.. image:: ${static_path}/images/bar_chart.png - :height: 324 - :width: 540 - - - + + for multiple columns + + #if $xtic.userSpecified == "Yes" #bar_chart.py $input $xtic.xticColumn $colList "$title" "$ylabel" $ymin $ymax $out_file1 "$pdf_size" + #else #bar_chart.py $input 0 $colList "$title" "$ylabel" $ymin $ymax $out_file1 "$pdf_size" + #end if + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gnuplot + Numeric + + +**What it does** + +This tool builds a bar chart on one or more columns. Suppose you have dataset like this one:: + + Gene1 10 15 + Gene2 20 14 + Gene3 67 45 + Gene4 55 12 + +Graphing columns 2 and 3 while using column 1 for X Tick Labels will produce the following plot: + +.. image:: ${static_path}/images/bar_chart.png + :height: 324 + :width: 540 + + diff --git a/tools/solid_tools/maq_cs_wrapper_code.py b/tools/solid_tools/maq_cs_wrapper_code.py index c5b7e390841..7a0a7e7f108 100644 --- a/tools/solid_tools/maq_cs_wrapper_code.py +++ b/tools/solid_tools/maq_cs_wrapper_code.py @@ -1,5 +1,4 @@ -def exec_before_job(app, inp_data, out_data, param_dict, tool): - out_data['output1'].name = out_data['output1'].name + " [ ALIGNMENT INFO ]" - out_data['output2'].name = out_data['output2'].name + " [ PILEUP ]" - out_data['output3'].name = out_data['output3'].name + " [ CUSTOM TRACK ]" - +def exec_before_job(app, inp_data, out_data, param_dict, tool): + out_data['output1'].name = out_data['output1'].name + " [ ALIGNMENT INFO ]" + out_data['output2'].name = out_data['output2'].name + " [ PILEUP ]" + out_data['output3'].name = out_data['output3'].name + " [ CUSTOM TRACK ]" diff --git a/tools/stats/filtering.xml b/tools/stats/filtering.xml index a71481fb473..d6b446787a5 100644 --- a/tools/stats/filtering.xml +++ b/tools/stats/filtering.xml @@ -1,87 +1,87 @@ - - data on any column using simple expressions - - filtering.py $input $out_file1 "$cond" ${input.metadata.columns} "${input.metadata.column_types}" $header_lines - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -.. class:: warningmark - -Double equal signs, ==, must be used as *"equal to"* (e.g., **c1 == 'chr22'**) - -.. class:: infomark - -**TIP:** Attempting to apply a filtering condition may throw exceptions if the data type (e.g., string, integer) in every line of the columns being filtered is not appropriate for the condition (e.g., attempting certain numerical calculations on strings). If an exception is thrown when applying the condition to a line, that line is skipped as invalid for the filter condition. The number of invalid skipped lines is documented in the resulting history item as a "Condition/data issue". - -.. class:: infomark - -**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* - ------ - -**Syntax** - -The filter tool allows you to restrict the dataset using simple conditional statements. - -- Columns are referenced with **c** and a **number**. For example, **c1** refers to the first column of a tab-delimited file -- Make sure that multi-character operators contain no white space ( e.g., **<=** is valid while **< =** is not valid ) -- When using 'equal-to' operator **double equal sign '==' must be used** ( e.g., **c1=='chr1'** ) -- Non-numerical values must be included in single or double quotes ( e.g., **c6=='+'** ) -- Filtering condition can include logical operators, but **make sure operators are all lower case** ( e.g., **(c1!='chrX' and c1!='chrY') or not c6=='+'** ) - ------ - -**Example** - -- **c1=='chr1'** selects lines in which the first column is chr1 -- **c3-c2<100*c4** selects lines where subtracting column 3 from column 2 is less than the value of column 4 times 100 -- **len(c2.split(',')) < 4** will select lines where the second column has less than four comma separated elements -- **c2>=1** selects lines in which the value of column 2 is greater than or equal to 1 -- Numbers should not contain commas - **c2<=44,554,350** will not work, but **c2<=44554350** will -- Some words in the data can be used, but must be single or double quoted ( e.g., **c3=='exon'** ) - - - + + data on any column using simple expressions + + filtering.py $input $out_file1 "$cond" ${input.metadata.columns} "${input.metadata.column_types}" $header_lines + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.. class:: warningmark + +Double equal signs, ==, must be used as *"equal to"* (e.g., **c1 == 'chr22'**) + +.. class:: infomark + +**TIP:** Attempting to apply a filtering condition may throw exceptions if the data type (e.g., string, integer) in every line of the columns being filtered is not appropriate for the condition (e.g., attempting certain numerical calculations on strings). If an exception is thrown when applying the condition to a line, that line is skipped as invalid for the filter condition. The number of invalid skipped lines is documented in the resulting history item as a "Condition/data issue". + +.. class:: infomark + +**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* + +----- + +**Syntax** + +The filter tool allows you to restrict the dataset using simple conditional statements. + +- Columns are referenced with **c** and a **number**. For example, **c1** refers to the first column of a tab-delimited file +- Make sure that multi-character operators contain no white space ( e.g., **<=** is valid while **< =** is not valid ) +- When using 'equal-to' operator **double equal sign '==' must be used** ( e.g., **c1=='chr1'** ) +- Non-numerical values must be included in single or double quotes ( e.g., **c6=='+'** ) +- Filtering condition can include logical operators, but **make sure operators are all lower case** ( e.g., **(c1!='chrX' and c1!='chrY') or not c6=='+'** ) + +----- + +**Example** + +- **c1=='chr1'** selects lines in which the first column is chr1 +- **c3-c2<100*c4** selects lines where subtracting column 3 from column 2 is less than the value of column 4 times 100 +- **len(c2.split(',')) < 4** will select lines where the second column has less than four comma separated elements +- **c2>=1** selects lines in which the value of column 2 is greater than or equal to 1 +- Numbers should not contain commas - **c2<=44,554,350** will not work, but **c2<=44554350** will +- Some words in the data can be used, but must be single or double quoted ( e.g., **c3=='exon'** ) + + + diff --git a/tools/stats/gsummary.xml.groups b/tools/stats/gsummary.xml.groups index 8e625040e3c..218ab31aa38 100644 --- a/tools/stats/gsummary.xml.groups +++ b/tools/stats/gsummary.xml.groups @@ -1,62 +1,62 @@ - - of a column in a tab delimited file according to an expression - gsummary.py $input $out_file1 "$cond" "$groups" - - - - - - - - - - - -.. class:: warningmark - -This tool expects input datasets to consist of tab-delimited columns (blank or comment lines beginning with a # character are automatically skipped). - -.. class:: infomark - -**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* - -.. class:: infomark - -**TIP:** Computing summary statistics may throw exceptions if the data value in every line of the columns being summarized is not numerical. If a line is missing a value or contains a non-numerical value in the column being summarized, that line is skipped and the value is not included in the statistical computation. The number of invalid skipped lines is documented in the resulting history item. - -**Syntax** - -This tool computes basic summary statistics on a given column, or on an expression containing those columns - -- Columns are referenced with **c** and a **number**. For example, **c1** refers to the first column of a tab-delimited file -- To group the summary by the values in a column or columns, specify in the **group terms** box... - + **c1** *group by the values in column 1* - + **c1,c4** *group by the values in column 1, then by the values in column 4* - - ------ - -**Expression examples** - -- **log(c5)** calculates the summary statistics for the natural log of column 5 -- **(c5 + c6 + c7) / 3** calculates the summary statistics on the average of columns 5-7 -- **log(c5,10)** summary statistics of the base 10 log of column 5 -- **sqrt(c5+c9)** summary statistics of the square root of column 5 + column 9 - -**Group examples** - -- **c1** group by the values in column 1 -- **c1,c4** group by the values in column 1, then by the values in column 4 - ------ - -.. class:: infomark - -**TIP:** Most functions (like *abs*) take only a single expression. *log* can take one or two parameters, like *log(expression,base)* - -Currently, these R functions are supported: *abs, sign, sqrt, floor, ceiling, trunc, round, signif, exp, log, cos, sin, tan, acos, asin, atan, cosh, sinh, tanh, acosh, asinh, atanh, lgamma, gamma, gammaCody, digamma, trigamma, cumsum, cumprod, cummax, cummin* - -.. |INFO| image:: ./static/images/icon_info_sml.gif - - - + + of a column in a tab delimited file according to an expression + gsummary.py $input $out_file1 "$cond" "$groups" + + + + + + + + + + + +.. class:: warningmark + +This tool expects input datasets to consist of tab-delimited columns (blank or comment lines beginning with a # character are automatically skipped). + +.. class:: infomark + +**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* + +.. class:: infomark + +**TIP:** Computing summary statistics may throw exceptions if the data value in every line of the columns being summarized is not numerical. If a line is missing a value or contains a non-numerical value in the column being summarized, that line is skipped and the value is not included in the statistical computation. The number of invalid skipped lines is documented in the resulting history item. + +**Syntax** + +This tool computes basic summary statistics on a given column, or on an expression containing those columns + +- Columns are referenced with **c** and a **number**. For example, **c1** refers to the first column of a tab-delimited file +- To group the summary by the values in a column or columns, specify in the **group terms** box... + + **c1** *group by the values in column 1* + + **c1,c4** *group by the values in column 1, then by the values in column 4* + + +----- + +**Expression examples** + +- **log(c5)** calculates the summary statistics for the natural log of column 5 +- **(c5 + c6 + c7) / 3** calculates the summary statistics on the average of columns 5-7 +- **log(c5,10)** summary statistics of the base 10 log of column 5 +- **sqrt(c5+c9)** summary statistics of the square root of column 5 + column 9 + +**Group examples** + +- **c1** group by the values in column 1 +- **c1,c4** group by the values in column 1, then by the values in column 4 + +----- + +.. class:: infomark + +**TIP:** Most functions (like *abs*) take only a single expression. *log* can take one or two parameters, like *log(expression,base)* + +Currently, these R functions are supported: *abs, sign, sqrt, floor, ceiling, trunc, round, signif, exp, log, cos, sin, tan, acos, asin, atan, cosh, sinh, tanh, acosh, asinh, atanh, lgamma, gamma, gammaCody, digamma, trigamma, cumsum, cumprod, cummax, cummin* + +.. |INFO| image:: ./static/images/icon_info_sml.gif + + + diff --git a/tools/visualization/LAJ.xml b/tools/visualization/LAJ.xml index 9e2879e7e21..b5fa2c06609 100644 --- a/tools/visualization/LAJ.xml +++ b/tools/visualization/LAJ.xml @@ -1,32 +1,32 @@ - -Pairwise Alignment Viewer - LAJ.py $maf_input $out_file1 - - - - - - - - - - - - - - -You can use this tool to view a set of LAV alignments. You may include FASTA formatted sequences for both species. - -For detailed information on LAJ, click here_. - -.. _here: http://globin.cse.psu.edu/dist/laj/ - -Laj is a tool for viewing and manipulating the output from pairwise alignment programs such as blastz. It can display interactive dotplot, pip, and text representations of the alignments, a diagram showing the locations of exons and repeats, and annotation links to other web sites containing additional information about particular regions. - -.. class:: infomark - -**Note:** If you save output from the applet, you will need to manually refresh your history. - - - - \ No newline at end of file + +Pairwise Alignment Viewer + LAJ.py $maf_input $out_file1 + + + + + + + + + + + + + + +You can use this tool to view a set of LAV alignments. You may include FASTA formatted sequences for both species. + +For detailed information on LAJ, click here_. + +.. _here: http://globin.cse.psu.edu/dist/laj/ + +Laj is a tool for viewing and manipulating the output from pairwise alignment programs such as blastz. It can display interactive dotplot, pip, and text representations of the alignments, a diagram showing the locations of exons and repeats, and annotation links to other web sites containing additional information about particular regions. + +.. class:: infomark + +**Note:** If you save output from the applet, you will need to manually refresh your history. + + + + diff --git a/tools/visualization/LAJ_code.py b/tools/visualization/LAJ_code.py index f96b3d2af29..9a083d268f6 100644 --- a/tools/visualization/LAJ_code.py +++ b/tools/visualization/LAJ_code.py @@ -1,40 +1,41 @@ -#post processing, add sequence and additional annoation info if available -from urllib import urlencode -from galaxy.datatypes.images import create_applet_tag_peek - -def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr): - primary_data = out_data.items()[0][1] - - #default params for LAJ type - params = { - "alignfile1": "display?id=%s" % primary_data.id, - "buttonlabel": "Launch LAJ", - "title": "LAJ in Galaxy", - "posturl": "history_add_to?%s" % urlencode( { 'history_id': primary_data.history_id, 'ext': 'lav', 'name': 'LAJ Output', 'info': 'Added by LAJ', 'dbkey': primary_data.dbkey } ) - } - for name,data in inp_data.items(): - if name == "maf_input": - params["alignfile1"] = "display?id=%s" % data.id - elif name == "seq_file1" and data.state == data.states.OK and data.has_data(): - params["file1seq1"] = "display?id=%s" % data.id - elif name == "seq_file2" and data.state == data.states.OK and data.has_data(): - params["file1seq2"] = "display?id=%s" % data.id - elif name == "exonfile" and data.state == data.states.OK and data.has_data(): - params["exonfile"] = "display?id=%s" % data.id - elif name == "repeatfile" and data.state == data.states.OK and data.has_data(): - params["repeatfile"] = "display?id=%s" % data.id - elif name == "annotationfile" and data.state == data.states.OK and data.has_data(): - params["annotationfile"] = "display?id=%s" % data.id - elif name == "underlayfile" and data.state == data.states.OK and data.has_data(): - params["underlayfile"] = "display?id=%s" % data.id - elif name == "highlightfile" and data.state == data.states.OK and data.has_data(): - params["highlightfile"] = "display?id=%s" % data.id - - if "file1seq1" not in params and "file1seq2" not in params: - params["noseq"] = "true" - - class_name = "edu.psu.cse.bio.laj.LajApplet.class" - archive = "/static/laj/laj.jar" - primary_data.peek = create_applet_tag_peek( class_name, archive, params ) - app.model.context.add( primary_data ) - app.model.context.flush() +#post processing, add sequence and additional annoation info if available +from urllib import urlencode +from galaxy.datatypes.images import create_applet_tag_peek + + +def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr): + primary_data = out_data.items()[0][1] + + #default params for LAJ type + params = { + "alignfile1": "display?id=%s" % primary_data.id, + "buttonlabel": "Launch LAJ", + "title": "LAJ in Galaxy", + "posturl": "history_add_to?%s" % urlencode( { 'history_id': primary_data.history_id, 'ext': 'lav', 'name': 'LAJ Output', 'info': 'Added by LAJ', 'dbkey': primary_data.dbkey } ) + } + for name, data in inp_data.items(): + if name == "maf_input": + params["alignfile1"] = "display?id=%s" % data.id + elif name == "seq_file1" and data.state == data.states.OK and data.has_data(): + params["file1seq1"] = "display?id=%s" % data.id + elif name == "seq_file2" and data.state == data.states.OK and data.has_data(): + params["file1seq2"] = "display?id=%s" % data.id + elif name == "exonfile" and data.state == data.states.OK and data.has_data(): + params["exonfile"] = "display?id=%s" % data.id + elif name == "repeatfile" and data.state == data.states.OK and data.has_data(): + params["repeatfile"] = "display?id=%s" % data.id + elif name == "annotationfile" and data.state == data.states.OK and data.has_data(): + params["annotationfile"] = "display?id=%s" % data.id + elif name == "underlayfile" and data.state == data.states.OK and data.has_data(): + params["underlayfile"] = "display?id=%s" % data.id + elif name == "highlightfile" and data.state == data.states.OK and data.has_data(): + params["highlightfile"] = "display?id=%s" % data.id + + if "file1seq1" not in params and "file1seq2" not in params: + params["noseq"] = "true" + + class_name = "edu.psu.cse.bio.laj.LajApplet.class" + archive = "/static/laj/laj.jar" + primary_data.peek = create_applet_tag_peek( class_name, archive, params ) + app.model.context.add( primary_data ) + app.model.context.flush() From 224d8f3fc45d9319f749ee24ad7c1ed4cae6c9e8 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Fri, 15 May 2015 11:53:25 +0100 Subject: [PATCH 114/120] Remove numpy requirement, not used since commit 09ce7a9b1793b0400f7e6e8ee46a178a0543ad3a . --- tools/maf/maf_stats.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/maf/maf_stats.xml b/tools/maf/maf_stats.xml index 8576fedd3fe..39be20291fb 100644 --- a/tools/maf/maf_stats.xml +++ b/tools/maf/maf_stats.xml @@ -56,9 +56,6 @@ - - numpy - From 341a6cf7600df8d408853f154b510f1b5e8f26a5 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Fri, 15 May 2015 12:43:15 +0100 Subject: [PATCH 115/120] Use requirements of type="package" instead of deprecated "binary". --- tools/evolution/codingSnps.xml | 3 +-- tools/plotting/boxplot.xml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/evolution/codingSnps.xml b/tools/evolution/codingSnps.xml index bd9e346fe10..345a9932ef9 100644 --- a/tools/evolution/codingSnps.xml +++ b/tools/evolution/codingSnps.xml @@ -46,8 +46,7 @@ - cat - sort + gnu_coreutils ucsc_tools diff --git a/tools/plotting/boxplot.xml b/tools/plotting/boxplot.xml index 8a6a77e3109..38fc474b8bb 100644 --- a/tools/plotting/boxplot.xml +++ b/tools/plotting/boxplot.xml @@ -2,7 +2,7 @@ of quality statistics gnuplot < '$gnuplot_commands' 2>&1 || echo "Error running gnuplot." >&2 - gnuplot + gnuplot From 48023ed37428233fee04bc8d48d0469ed4225bba Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Fri, 15 May 2015 12:45:16 +0100 Subject: [PATCH 116/120] Remove outdated sentence. --- config/plugins/visualizations/README.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/plugins/visualizations/README.txt b/config/plugins/visualizations/README.txt index 5722c2dc573..07ca615cd1e 100644 --- a/config/plugins/visualizations/README.txt +++ b/config/plugins/visualizations/README.txt @@ -8,9 +8,6 @@ Properly configured and written visualizations will be accessible to the user when they click the 'visualizations' icon for a dataset in their history panel. -The framework must be enabled in your 'galaxy.ini' file by uncommenting (and -having a valid path for) the 'visualizations_plugin_directory' entry. - For more information, see http://wiki.galaxyproject.org/VisualizationsRegistry From 2cac7e817ba87ed2a7a513961f6c43ef696bf7f3 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Fri, 15 May 2015 11:05:08 -0400 Subject: [PATCH 117/120] Fix implicit output collection names when mapping over collections. --- lib/galaxy/tools/execute.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/tools/execute.py b/lib/galaxy/tools/execute.py index 8b6d5ce8e41..9b5f79b326e 100644 --- a/lib/galaxy/tools/execute.py +++ b/lib/galaxy/tools/execute.py @@ -113,12 +113,13 @@ class ToolExecutionTracker( object ): outputs=outputs ) try: - output_collection_name = self.tool_action.get_output_name( + output_collection_name = self.tool.tool_action.get_output_name( output, dataset=None, tool=self.tool, on_text=on_text, trans=trans, + history=history, params=params, incoming=None, job_params=None, From 906e9a08095529669381a751809848585ea6753a Mon Sep 17 00:00:00 2001 From: John Chilton Date: Fri, 15 May 2015 15:47:35 -0400 Subject: [PATCH 118/120] Fix function names for dynamic tool test functions. When finding methods to invoke it seems nose uses the raw function name instead of the class's attribute name (I guess this terminology makes sense), but when reporting results it uses the latter. Synchronizing these names therefore allows calling specific tool test methods from the command-line. This change is required to implement galaxyproject/planemo#145. --- test/functional/test_toolbox.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/functional/test_toolbox.py b/test/functional/test_toolbox.py index d707690c4c3..99d7c78d9f4 100644 --- a/test/functional/test_toolbox.py +++ b/test/functional/test_toolbox.py @@ -263,13 +263,18 @@ def build_tests( app=None, testing_shed_tools=False, master_api_key=None, user_a baseclasses = ( ToolTestCase, ) namespace = dict() for j, testdef in enumerate( tool.tests ): + test_function_name = 'test_tool_%06d' % j + def make_test_method( td ): def test_tool( self ): self.do_it( td ) + test_tool.__name__ = test_function_name + return test_tool + test_method = make_test_method( testdef ) test_method.__doc__ = "%s ( %s ) > %s" % ( tool.name, tool.id, testdef.name ) - namespace[ 'test_tool_%06d' % j ] = test_method + namespace[ test_function_name ] = test_method namespace[ 'shed_tool_id' ] = shed_tool_id namespace[ 'master_api_key' ] = master_api_key namespace[ 'user_api_key' ] = user_api_key From 98d8c2cc2e227ad81145c7013d210607d18fbfa4 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Mon, 18 May 2015 02:05:20 -0400 Subject: [PATCH 119/120] Allow config of shed tool conf used with ``run_tests.sh -installed``. Set with GALAXY_TEST_SHED_TOOL_CONF. This is required to implement galaxyproject/planemo#176. --- scripts/functional_tests.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/functional_tests.py b/scripts/functional_tests.py index de56a42b1c3..98d22f1f9c6 100644 --- a/scripts/functional_tests.py +++ b/scripts/functional_tests.py @@ -74,7 +74,10 @@ default_galaxy_test_port_max = 9999 default_galaxy_locales = 'en' default_galaxy_test_file_dir = "test-data,https://github.com/galaxyproject/galaxy-test-data.git" migrated_tool_panel_config = 'config/migrated_tools_conf.xml' -installed_tool_panel_configs = [ 'config/shed_tool_conf.xml' ] +installed_tool_panel_configs = [ + os.environ.get('GALAXY_TEST_SHED_TOOL_CONF', 'config/shed_tool_conf.xml') +] + # should this serve static resources (scripts, images, styles, etc.) STATIC_ENABLED = True From 15480dc4f1138cc67f6a207692a8d58712b2ccd7 Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 18 May 2015 18:39:47 -0400 Subject: [PATCH 120/120] Disable automated history creation in data tool parameters --- lib/galaxy/tools/parameters/basic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index adbd85890ee..ef783a5d827 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -1653,7 +1653,7 @@ class BaseDataToolParameter( ToolParameter ): class_name = self.__class__.__name__ assert trans is not None, "%s requires a trans" % class_name if history is None: - history = trans.get_history( create=True ) + history = trans.get_history() assert history is not None, "%s requires a history" % class_name return history