galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
[galaxyproject/usegalaxy-playbook] c55a48: disable new toolform by Aysam's request
by GitHub 05 Feb '15
by GitHub 05 Feb '15
05 Feb '15
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: c55a48d5a1f2b839e19bcd5bd8fec116fd9fc087
https://github.com/galaxyproject/usegalaxy-playbook/commit/c55a48d5a1f2b839…
Author: martenson <cech.marten(a)gmail.com>
Date: 2015-02-05 (Thu, 05 Feb 2015)
Changed paths:
M stage/group_vars/galaxyservers.yml
Log Message:
-----------
disable new toolform by Aysam's request
1
0
commit/galaxy-central: guerler: Workflow: Fix text and boolean parameter handling, simplify module update
by commits-noreply@bitbucket.org 05 Feb '15
by commits-noreply@bitbucket.org 05 Feb '15
05 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2f436edb5288/
Changeset: 2f436edb5288
User: guerler
Date: 2015-02-05 15:08:45+00:00
Summary: Workflow: Fix text and boolean parameter handling, simplify module update
Affected #: 3 files
diff -r 6133a80c7a08b88f1e7d2e83456acdc329b88b47 -r 2f436edb5288bf750382ae1ccddd95ed611db6a1 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -263,8 +263,15 @@
else:
return form_builder.TextField( self.name, self.size, value )
+ def to_string( self, value, app ):
+ """Convert a value to a string representation suitable for persisting"""
+ if value is None:
+ return ''
+ else:
+ return str( value )
+
def to_html_value( self, value, app ):
- if not value:
+ if value is None:
return ''
else:
return self.to_string( value, app )
@@ -335,13 +342,6 @@
return ""
raise ValueError( "An integer is required" )
- def to_string( self, value, app ):
- """Convert a value to a string representation suitable for persisting"""
- if value is None:
- return ""
- else:
- return str( value )
-
def to_python( self, value, app ):
try:
return int( value )
@@ -414,13 +414,6 @@
return ""
raise ValueError( "A real number is required" )
- def to_string( self, value, app ):
- """Convert a value to a string representation suitable for persisting"""
- if value is None:
- return ""
- else:
- return str( value )
-
def to_python( self, value, app ):
try:
return float( value )
@@ -480,7 +473,7 @@
return [ 'true' ]
def to_python( self, value, app ):
- return ( value == 'True' )
+ return ( value in [ 'True', 'true' ])
def get_initial_value( self, trans, context, history=None ):
return self.checked
diff -r 6133a80c7a08b88f1e7d2e83456acdc329b88b47 -r 2f436edb5288bf750382ae1ccddd95ed611db6a1 lib/galaxy/webapps/galaxy/controllers/workflow.py
--- a/lib/galaxy/webapps/galaxy/controllers/workflow.py
+++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py
@@ -619,17 +619,25 @@
} )
# create tool model and default tool state (if missing)
- tool_model = None
if type == 'tool' and not tool_state:
tool_model = module.tool.to_json(trans, **incoming)
module.state.inputs = copy.deepcopy(tool_model['state_inputs'])
+ return {
+ 'tool_model': tool_model,
+ 'tool_state': module.get_state(),
+ 'data_inputs': module.get_data_inputs(),
+ 'data_outputs': module.get_data_outputs(),
+ 'tool_errors': module.get_errors(),
+ 'form_html': module.get_config_form(),
+ 'annotation': annotation,
+ 'post_job_actions': module.get_post_job_actions(incoming)
+ }
# update module state
module.update_state( incoming )
if type == 'tool':
return {
- 'tool_model': tool_model,
'tool_state': module.get_state(),
'data_inputs': module.get_data_inputs(),
'data_outputs': module.get_data_outputs(),
diff -r 6133a80c7a08b88f1e7d2e83456acdc329b88b47 -r 2f436edb5288bf750382ae1ccddd95ed611db6a1 lib/galaxy/workflow/modules.py
--- a/lib/galaxy/workflow/modules.py
+++ b/lib/galaxy/workflow/modules.py
@@ -684,8 +684,11 @@
input_dicts.append( { "name": name, "description": "runtime parameter for tool %s" % self.get_name() } )
return input_dicts
- def get_post_job_actions( self ):
- return self.post_job_actions
+ def get_post_job_actions( self, incoming=None):
+ if incoming is None:
+ return self.post_job_actions
+ else:
+ return ActionBox.handle_incoming(incoming)
def get_config_form( self ):
self.add_dummy_datasets()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: pep8, cleanup in galaxy/buildapp
by commits-noreply@bitbucket.org 05 Feb '15
by commits-noreply@bitbucket.org 05 Feb '15
05 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6133a80c7a08/
Changeset: 6133a80c7a08
User: dannon
Date: 2015-02-05 14:45:15+00:00
Summary: pep8, cleanup in galaxy/buildapp
Affected #: 1 file
diff -r cca00d61df85a6ecd1be49265f0c92e7482b91f9 -r 6133a80c7a08b88f1e7d2e83456acdc329b88b47 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -6,8 +6,6 @@
import os
import os.path
import atexit
-import warnings
-import glob
from paste import httpexceptions
import pkg_resources
@@ -28,6 +26,7 @@
class GalaxyWebApplication( galaxy.web.framework.webapp.WebApplication ):
pass
+
def app_factory( global_conf, **kwargs ):
"""
Return a wsgi application serving the root object
@@ -41,7 +40,7 @@
else:
try:
from galaxy.app import UniverseApplication
- app = UniverseApplication( global_conf = global_conf, **kwargs )
+ app = UniverseApplication( global_conf=global_conf, **kwargs )
except:
import traceback
traceback.print_exc()
@@ -65,8 +64,8 @@
webapp.add_route( '/datasets/:dataset_id/display/{filename:.+?}', controller='dataset', action='display', dataset_id=None, filename=None)
webapp.add_route( '/datasets/:dataset_id/:action/:filename', controller='dataset', action='index', dataset_id=None, filename=None)
webapp.add_route( '/display_application/:dataset_id/:app_name/:link_name/:user_id/:app_action/:action_param',
- controller='dataset', action='display_application', dataset_id=None, user_id=None,
- app_name = None, link_name = None, app_action = None, action_param = None )
+ controller='dataset', action='display_application', dataset_id=None, user_id=None,
+ app_name=None, link_name=None, app_action=None, action_param=None )
webapp.add_route( '/u/:username/d/:slug/:filename', controller='dataset', action='display_by_username_and_slug', filename=None )
webapp.add_route( '/u/:username/p/:slug', controller='page', action='display_by_username_and_slug' )
webapp.add_route( '/u/:username/h/:slug', controller='history', action='display_by_username_and_slug' )
@@ -103,7 +102,6 @@
log.error("Static middleware is enabled in your configuration but this is a uwsgi process. Refusing to wrap in static middleware.")
else:
webapp = wrap_in_static( webapp, global_conf, plugin_frameworks=[ app.visualizations_registry ], **kwargs )
- #webapp = wrap_in_static( webapp, global_conf, plugin_frameworks=None, **kwargs )
if asbool(kwargs.get('pack_scripts', False)):
log.warn( "The 'pack_scripts' option is deprecated" )
pack_scripts()
@@ -112,7 +110,6 @@
galaxy.model.mapping.metadata.engine.connection_provider._pool.dispose()
except:
pass
- # Close any pooled database connections before forking
try:
galaxy.model.tool_shed_install.mapping.metadata.engine.connection_provider._pool.dispose()
except:
@@ -137,32 +134,32 @@
controller='history_contents',
path_prefix='/api/histories/:history_id/contents',
parent_resources=dict( member_name='history', collection_name='histories' ),
- )
+ )
# Legacy access to HDA details via histories/:history_id/contents/:hda_id
webapp.mapper.resource( 'content',
- 'contents',
- controller='history_contents',
- name_prefix='history_',
- path_prefix='/api/histories/:history_id',
- parent_resources=dict( member_name='history', collection_name='histories' ) )
- webapp.mapper.connect("history_contents_display",
- "/api/histories/:history_id/contents/:history_content_id/display",
- controller="datasets",
- action="display",
- conditions=dict(method=["GET"]))
+ 'contents',
+ controller='history_contents',
+ name_prefix='history_',
+ path_prefix='/api/histories/:history_id',
+ parent_resources=dict( member_name='history', collection_name='histories' ) )
+ webapp.mapper.connect( "history_contents_display",
+ "/api/histories/:history_id/contents/:history_content_id/display",
+ controller="datasets",
+ action="display",
+ conditions=dict(method=["GET"]))
webapp.mapper.resource( 'user',
- 'users',
- controller='group_users',
- name_prefix='group_',
- path_prefix='/api/groups/:group_id',
- parent_resources=dict( member_name='group', collection_name='groups' ) )
+ 'users',
+ controller='group_users',
+ name_prefix='group_',
+ path_prefix='/api/groups/:group_id',
+ parent_resources=dict( member_name='group', collection_name='groups' ) )
webapp.mapper.resource( 'role',
- 'roles',
- controller='group_roles',
- name_prefix='group_',
- path_prefix='/api/groups/:group_id',
- parent_resources=dict( member_name='group', collection_name='groups' ) )
+ 'roles',
+ controller='group_roles',
+ name_prefix='group_',
+ path_prefix='/api/groups/:group_id',
+ parent_resources=dict( member_name='group', collection_name='groups' ) )
_add_item_tags_controller( webapp,
name_prefix="history_content_",
path_prefix='/api/histories/:history_id/contents/:history_content_id' )
@@ -173,17 +170,17 @@
name_prefix="workflow_",
path_prefix='/api/workflows/:workflow_id' )
_add_item_annotation_controller( webapp,
- name_prefix="history_content_",
- path_prefix='/api/histories/:history_id/contents/:history_content_id' )
+ name_prefix="history_content_",
+ path_prefix='/api/histories/:history_id/contents/:history_content_id' )
_add_item_annotation_controller( webapp,
- name_prefix="history_",
- path_prefix='/api/histories/:history_id' )
+ name_prefix="history_",
+ path_prefix='/api/histories/:history_id' )
_add_item_annotation_controller( webapp,
- name_prefix="workflow_",
- path_prefix='/api/workflows/:workflow_id' )
+ name_prefix="workflow_",
+ path_prefix='/api/workflows/:workflow_id' )
_add_item_provenance_controller( webapp,
- name_prefix="history_content_",
- path_prefix='/api/histories/:history_id/contents/:history_content_id' )
+ name_prefix="history_content_",
+ path_prefix='/api/histories/:history_id/contents/:history_content_id' )
webapp.mapper.resource( 'dataset', 'datasets', path_prefix='/api' )
webapp.mapper.resource( 'tool_data', 'tool_data', path_prefix='/api' )
@@ -216,27 +213,28 @@
webapp.mapper.resource( 'datatype',
'datatypes',
path_prefix='/api',
- collection={ 'sniffers': 'GET', 'mapping' : 'GET', 'converters': 'GET' },
+ collection={ 'sniffers': 'GET', 'mapping': 'GET', 'converters': 'GET' },
parent_resources=dict( member_name='datatype', collection_name='datatypes' ) )
- #webapp.mapper.connect( 'run_workflow', '/api/workflow/{workflow_id}/library/{library_id}', controller='workflows', action='run', workflow_id=None, library_id=None, conditions=dict(method=["GET"]) )
webapp.mapper.resource( 'search', 'search', path_prefix='/api' )
webapp.mapper.resource( 'page', 'pages', path_prefix="/api")
webapp.mapper.resource( 'revision', 'revisions',
- path_prefix='/api/pages/:page_id',
- controller='page_revisions',
- parent_resources=dict( member_name='page', collection_name='pages' ) )
+ path_prefix='/api/pages/:page_id',
+ controller='page_revisions',
+ parent_resources=dict( member_name='page', collection_name='pages' ) )
- webapp.mapper.connect( "history_archive_export", "/api/histories/{id}/exports",
- controller="histories", action="archive_export", conditions=dict( method=[ "PUT" ] ) )
- webapp.mapper.connect( "history_archive_download", "/api/histories/{id}/exports/{jeha_id}",
- controller="histories", action="archive_download", conditions=dict( method=[ "GET" ] ) )
+ webapp.mapper.connect( "history_archive_export",
+ "/api/histories/{id}/exports", controller="histories",
+ action="archive_export", conditions=dict( method=[ "PUT" ] ) )
+ webapp.mapper.connect( "history_archive_download",
+ "/api/histories/{id}/exports/{jeha_id}", controller="histories",
+ action="archive_download", conditions=dict( method=[ "GET" ] ) )
webapp.mapper.connect( "create_api_key", "/api/users/:user_id/api_key",
- controller="users", action="api_key", user_id=None, conditions=dict( method=["POST"] ) )
+ controller="users", action="api_key", user_id=None,
+ conditions=dict( method=["POST"] ) )
# visualizations registry generic template renderer
- webapp.add_route( '/visualization/show/:visualization_name',
- controller='visualization', action='render', visualization_name=None )
+ webapp.add_route( '/visualization/show/:visualization_name', controller='visualization', action='render', visualization_name=None )
# Deprecated in favor of POST /api/workflows with 'workflow' in payload.
webapp.mapper.connect( 'import_workflow_deprecated', '/api/workflows/upload', controller='workflows', action='import_new_workflow_deprecated', conditions=dict( method=['POST'] ) )
@@ -446,8 +444,8 @@
parent_resources=dict( member_name="job", collection_name="jobs" ) )
_add_item_extended_metadata_controller( webapp,
- name_prefix="history_dataset_",
- path_prefix='/api/histories/:history_id/contents/:history_content_id' )
+ name_prefix="history_dataset_",
+ path_prefix='/api/histories/:history_id/contents/:history_content_id' )
# ====================
# ===== TOOLSHED =====
@@ -463,46 +461,46 @@
# Galaxy API for tool shed features.
webapp.mapper.resource( 'tool_shed_repository',
'tool_shed_repositories',
- member={ 'repair_repository_revision' : 'POST',
- 'exported_workflows' : 'GET',
- 'import_workflow' : 'POST',
- 'import_workflows' : 'POST' },
- collection={ 'get_latest_installable_revision' : 'POST',
- 'reset_metadata_on_installed_repositories' : 'POST' },
+ member={ 'repair_repository_revision': 'POST',
+ 'exported_workflows': 'GET',
+ 'import_workflow': 'POST',
+ 'import_workflows': 'POST' },
+ collection={ 'get_latest_installable_revision': 'POST',
+ 'reset_metadata_on_installed_repositories': 'POST' },
controller='tool_shed_repositories',
name_prefix='tool_shed_repository_',
path_prefix='/api',
- new={ 'install_repository_revision' : 'POST' },
+ new={ 'install_repository_revision': 'POST' },
parent_resources=dict( member_name='tool_shed_repository', collection_name='tool_shed_repositories' ) )
-
# ==== Trace/Metrics Logger
# Connect logger from app
if app.trace_logger:
webapp.trace_logger = app.trace_logger
# metrics logging API
- #webapp.mapper.connect( "index", "/api/metrics",
+ # webapp.mapper.connect( "index", "/api/metrics",
# controller="metrics", action="index", conditions=dict( method=["GET"] ) )
- #webapp.mapper.connect( "show", "/api/metrics/{id}",
+ # webapp.mapper.connect( "show", "/api/metrics/{id}",
# controller="metrics", action="show", conditions=dict( method=["GET"] ) )
- webapp.mapper.connect( "create", "/api/metrics",
- controller="metrics", action="create", conditions=dict( method=["POST"] ) )
+ webapp.mapper.connect( "create", "/api/metrics", controller="metrics",
+ action="create", conditions=dict( method=["POST"] ) )
def pack_scripts():
from glob import glob
from subprocess import call
cmd = "java -jar scripts/yuicompressor.jar --type js static/scripts/%(fname)s -o static/scripts/packed/%(fname)s"
- raw_js= [os.path.basename(g) for g in glob( "static/scripts/*.js" )]
+ raw_js = [os.path.basename(g) for g in glob( "static/scripts/*.js" )]
for fname in raw_js:
if os.path.exists('static/scripts/packed/%s' % fname):
if os.path.getmtime('static/scripts/packed/%s' % fname) > os.path.getmtime('static/scripts/%s' % fname):
- continue # Skip, packed is newer than source.
+ continue # Skip, packed is newer than source.
d = dict( fname=fname )
log.info("%(fname)s --> packed/%(fname)s" % d)
call( cmd % d, shell=True )
+
def _add_item_tags_controller( webapp, name_prefix, path_prefix, **kwd ):
# Not just using map.resources because actions should be based on name not id
controller = "%stags" % name_prefix
@@ -511,24 +509,24 @@
map = webapp.mapper
# Allow view items' tags.
map.connect(name, path,
- controller=controller, action="index",
- conditions=dict(method=["GET"]))
+ controller=controller, action="index",
+ conditions=dict(method=["GET"]))
# Allow remove tag from item
map.connect("%s_delete" % name, "%s/tags/:tag_name" % path_prefix,
- controller=controller, action="delete",
- conditions=dict(method=["DELETE"]))
+ controller=controller, action="delete",
+ conditions=dict(method=["DELETE"]))
# Allow create a new tag with from name
map.connect("%s_create" % name, "%s/tags/:tag_name" % path_prefix,
- controller=controller, action="create",
- conditions=dict(method=["POST"]))
+ controller=controller, action="create",
+ conditions=dict(method=["POST"]))
# Allow update tag value
map.connect("%s_update" % name, "%s/tags/:tag_name" % path_prefix,
- controller=controller, action="update",
- conditions=dict(method=["PUT"]))
+ controller=controller, action="update",
+ conditions=dict(method=["PUT"]))
# Allow show tag by name
map.connect("%s_show" % name, "%s/tags/:tag_name" % path_prefix,
- controller=controller, action="show",
- conditions=dict(method=["GET"]))
+ controller=controller, action="show",
+ conditions=dict(method=["GET"]))
def _add_item_extended_metadata_controller( webapp, name_prefix, path_prefix, **kwd ):
@@ -536,11 +534,13 @@
name = "%sextended_metadata" % name_prefix
webapp.mapper.resource(name, "extended_metadata", path_prefix=path_prefix, controller=controller)
+
def _add_item_annotation_controller( webapp, name_prefix, path_prefix, **kwd ):
controller = "%sannotations" % name_prefix
name = "%sannotation" % name_prefix
webapp.mapper.resource(name, "annotation", path_prefix=path_prefix, controller=controller)
+
def _add_item_provenance_controller( webapp, name_prefix, path_prefix, **kwd ):
controller = "%sprovenance" % name_prefix
name = "%sprovenance" % name_prefix
@@ -566,11 +566,11 @@
# upstream server
if asbool(conf.get( 'use_remote_user', False )):
from galaxy.web.framework.middleware.remoteuser import RemoteUser
- app = RemoteUser( app, maildomain = conf.get( 'remote_user_maildomain', None ),
- display_servers = util.listify( conf.get( 'display_servers', '' ) ),
- admin_users = conf.get( 'admin_users', '' ).split( ',' ),
- remote_user_header = conf.get( 'remote_user_header', 'HTTP_REMOTE_USER' ),
- remote_user_secret_header = conf.get('remote_user_secret', None) )
+ app = RemoteUser( app, maildomain=conf.get( 'remote_user_maildomain', None ),
+ display_servers=util.listify( conf.get( 'display_servers', '' ) ),
+ admin_users=conf.get( 'admin_users', '' ).split( ',' ),
+ remote_user_header=conf.get( 'remote_user_header', 'HTTP_REMOTE_USER' ),
+ remote_user_secret_header=conf.get('remote_user_secret', None) )
# The recursive middleware allows for including requests in other
# requests or forwarding of requests, all on the server side.
if asbool(conf.get('use_recursive', True)):
@@ -626,6 +626,7 @@
log.debug( "Enabling 'Request ID' middleware" )
return app
+
def wrap_in_static( app, global_conf, plugin_frameworks=None, **local_conf ):
from galaxy.web.framework.middleware.static import CacheableStaticURLParser as Static
urlmap, cache_time = galaxy.web.framework.webapp.build_url_map( app, global_conf, local_conf )
@@ -642,6 +643,7 @@
# URL mapper becomes the root webapp
return urlmap
+
def build_template_error_formatters():
"""
Build a list of template error formatters for WebError. When an error
@@ -651,6 +653,7 @@
formatters = []
# Formatter for mako
import mako.exceptions
+
def mako_html_data( exc_value ):
if isinstance( exc_value, ( mako.exceptions.CompileException, mako.exceptions.SyntaxException ) ):
return mako.exceptions.html_error_template().render( full=False, css=False )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Prevent uwsgi from ever loading static middleware -- it can serve static files directly with appropriate routes in its config (see wiki).
by commits-noreply@bitbucket.org 05 Feb '15
by commits-noreply@bitbucket.org 05 Feb '15
05 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/cca00d61df85/
Changeset: cca00d61df85
User: dannon
Date: 2015-02-05 14:35:36+00:00
Summary: Prevent uwsgi from ever loading static middleware -- it can serve static files directly with appropriate routes in its config (see wiki).
Affected #: 1 file
diff -r 1989401bb9009e76fbaaafdeeffa68c0f12959ab -r cca00d61df85a6ecd1be49265f0c92e7482b91f9 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -86,9 +86,24 @@
# Wrap the webapp in some useful middleware
if kwargs.get( 'middleware', True ):
webapp = wrap_in_middleware( webapp, global_conf, **kwargs )
- if asbool( kwargs.get( 'static_enabled', True ) ):
- webapp = wrap_in_static( webapp, global_conf, plugin_frameworks=[ app.visualizations_registry ], **kwargs )
- #webapp = wrap_in_static( webapp, global_conf, plugin_frameworks=None, **kwargs )
+ # TEST FOR UWSGI -- TODO save this somewhere so we only have to do it once.
+ is_uwsgi = False
+ try:
+ # The uwsgi module is automatically injected by the parent uwsgi
+ # process and only exists that way. If anything works, this is a
+ # uwsgi-managed process.
+ import uwsgi
+ is_uwsgi = uwsgi.numproc
+ is_uwsgi = True
+ except ImportError:
+ # This is not a uwsgi process, or something went horribly wrong.
+ pass
+ if asbool( kwargs.get( 'static_enabled', True) ):
+ if is_uwsgi:
+ log.error("Static middleware is enabled in your configuration but this is a uwsgi process. Refusing to wrap in static middleware.")
+ else:
+ webapp = wrap_in_static( webapp, global_conf, plugin_frameworks=[ app.visualizations_registry ], **kwargs )
+ #webapp = wrap_in_static( webapp, global_conf, plugin_frameworks=None, **kwargs )
if asbool(kwargs.get('pack_scripts', False)):
log.warn( "The 'pack_scripts' option is deprecated" )
pack_scripts()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Fixed typo'd require for lunr.
by commits-noreply@bitbucket.org 05 Feb '15
by commits-noreply@bitbucket.org 05 Feb '15
05 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/1989401bb900/
Changeset: 1989401bb900
User: dannon
Date: 2015-02-05 13:38:14+00:00
Summary: Fixed typo'd require for lunr.
Affected #: 3 files
diff -r 19079eea7d2285d701866b0df77beeff20a677e8 -r 1989401bb9009e76fbaaafdeeffa68c0f12959ab client/galaxy/scripts/mvc/tools.js
--- a/client/galaxy/scripts/mvc/tools.js
+++ b/client/galaxy/scripts/mvc/tools.js
@@ -2,7 +2,7 @@
* Model, view, and controller objects for Galaxy tools and tool panel.
*/
- define( ["libs/underscore", "viz/trackster/util", "mvc/data", "libs/lunr.js" ],
+ define( ["libs/underscore", "viz/trackster/util", "mvc/data", "libs/lunr" ],
function(_, util, data) {
/**
diff -r 19079eea7d2285d701866b0df77beeff20a677e8 -r 1989401bb9009e76fbaaafdeeffa68c0f12959ab static/scripts/mvc/tools.js
--- a/static/scripts/mvc/tools.js
+++ b/static/scripts/mvc/tools.js
@@ -2,7 +2,7 @@
* Model, view, and controller objects for Galaxy tools and tool panel.
*/
- define( ["libs/underscore", "viz/trackster/util", "mvc/data", "libs/lunr.js" ],
+ define( ["libs/underscore", "viz/trackster/util", "mvc/data", "libs/lunr" ],
function(_, util, data) {
/**
diff -r 19079eea7d2285d701866b0df77beeff20a677e8 -r 1989401bb9009e76fbaaafdeeffa68c0f12959ab static/scripts/packed/mvc/tools.js
--- a/static/scripts/packed/mvc/tools.js
+++ b/static/scripts/packed/mvc/tools.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","viz/trackster/util","mvc/data","libs/lunr.js"],function(x,a,y){var g={hidden:false,show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},toggle:function(){this.set("hidden",!this.get("hidden"))},is_visible:function(){return !this.attributes.hidden}};var e=Backbone.Model.extend({defaults:{name:null,label:null,type:null,value:null,html:null,num_samples:5},initialize:function(z){this.attributes.html=unescape(this.attributes.html)},copy:function(){return new e(this.toJSON())},set_value:function(z){this.set("value",z||"")}});var i=Backbone.Collection.extend({model:e});var k=e.extend({});var d=e.extend({set_value:function(z){this.set("value",parseInt(z,10))},get_samples:function(){return d3.scale.linear().domain([this.get("min"),this.get("max")]).ticks(this.get("num_samples"))}});var f=d.extend({set_value:function(z){this.set("value",parseFloat(z))}});var t=e.extend({get_samples:function(){return x.map(this.get("options"),function(z){return z[0]})}});e.subModelTypes={integer:d,"float":f,data:k,select:t};var j=Backbone.Model.extend({defaults:{id:null,name:null,description:null,target:null,inputs:[],outputs:[]},urlRoot:galaxy_config.root+"api/tools",initialize:function(z){this.set("inputs",new i(x.map(z.inputs,function(A){var B=e.subModelTypes[A.type]||e;return new B(A)})))},toJSON:function(){var z=Backbone.Model.prototype.toJSON.call(this);z.inputs=this.get("inputs").map(function(A){return A.toJSON()});return z},remove_inputs:function(A){var z=this,B=z.get("inputs").filter(function(C){return(A.indexOf(C.get("type"))!==-1)});z.get("inputs").remove(B)},copy:function(A){var B=new j(this.toJSON());if(A){var z=new Backbone.Collection();B.get("inputs").each(function(C){if(C.get_samples()){z.push(C)}});B.set("inputs",z)}return B},apply_search_results:function(z){(x.indexOf(z,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()},set_input_value:function(z,A){this.get("inputs").find(function(B){return B.get("name")===z}).set("value",A)},set_input_values:function(A){var z=this;x.each(x.keys(A),function(B){z.set_input_value(B,A[B])})},run:function(){return this._run()},rerun:function(A,z){return this._run({action:"rerun",target_dataset_id:A.id,regions:z})},get_inputs_dict:function(){var z={};this.get("inputs").each(function(A){z[A.get("name")]=A.get("value")});return z},_run:function(B){var C=x.extend({tool_id:this.id,inputs:this.get_inputs_dict()},B);var A=$.Deferred(),z=new a.ServerStateDeferred({ajax_settings:{url:this.urlRoot,data:JSON.stringify(C),dataType:"json",contentType:"application/json",type:"POST"},interval:2000,success_fn:function(D){return D!=="pending"}});$.when(z.go()).then(function(D){A.resolve(new y.DatasetCollection().reset(D))});return A}});x.extend(j.prototype,g);var q=Backbone.View.extend({});var n=Backbone.Collection.extend({model:j});var v=Backbone.Model.extend(g);var l=Backbone.Model.extend({defaults:{elems:[],open:false},clear_search_results:function(){x.each(this.attributes.elems,function(z){z.show()});this.show();this.set("open",false)},apply_search_results:function(A){var B=true,z;x.each(this.attributes.elems,function(C){if(C instanceof v){z=C;z.hide()}else{if(C instanceof j){if(C.apply_search_results(A)){B=false;if(z){z.show()}}}}});if(B){this.hide()}else{this.show();this.set("open",true)}}});x.extend(l.prototype,g);var c=Backbone.Model.extend({defaults:{search_hint_string:"search tools",min_chars_for_search:3,spinner_url:"",clear_btn_url:"",search_url:"",visible:true,query:"",results:null,clear_key:27},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var B=this.attributes.query;if(B.length<this.attributes.min_chars_for_search){this.set("results",null);return}var A=B+"*";if(this.timer){clearTimeout(this.timer)}$("#search-clear-btn").hide();$("#search-spinner").show();var z=this;this.timer=setTimeout(function(){$.get(z.attributes.search_url,{query:A},function(C){z.set("results",C);$("#search-spinner").hide();$("#search-clear-btn").show()},"json")},200)},clear_search:function(){this.set("query","");this.set("results",null)}});x.extend(c.prototype,g);var o=Backbone.Model.extend({initialize:function(z){this.attributes.tool_search=z.tool_search;this.attributes.tool_search.on("change:results",this.apply_search_results,this);this.attributes.tools=z.tools;this.attributes.layout=new Backbone.Collection(this.parse(z.layout))},parse:function(A){var z=this,B=function(E){var D=E.model_class;if(D.indexOf("Tool")===D.length-4){return z.attributes.tools.get(E.id)}else{if(D==="ToolSection"){var C=x.map(E.elems,B);E.elems=C;return new l(E)}else{if(D==="ToolSectionLabel"){return new v(E)}}}};return x.map(A,B)},clear_search_results:function(){this.get("layout").each(function(z){if(z instanceof l){z.clear_search_results()}else{z.show()}})},apply_search_results:function(){var A=this.get("tool_search").get("results");if(A===null){this.clear_search_results();return}var z=null;this.get("layout").each(function(B){if(B instanceof v){z=B;z.hide()}else{if(B instanceof j){if(B.apply_search_results(A)){if(z){z.show()}}}else{z=null;B.apply_search_results(A)}}})}});var s=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){(this.model.attributes.hidden?this.$el.hide():this.$el.show())}});var m=s.extend({tagName:"div",render:function(){var z=$("<div/>");z.append(Handlebars.templates.tool_link(this.model.toJSON()));if(this.model.id==="upload1"){z.find("a").on("click",function(A){A.preventDefault();Galaxy.upload.show()})}this.$el.append(z);return this}});var b=s.extend({tagName:"div",className:"toolPanelLabel",render:function(){this.$el.append($("<span/>").text(this.model.attributes.text));return this}});var r=s.extend({tagName:"div",className:"toolSectionWrapper",initialize:function(){s.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(Handlebars.templates.panel_section(this.model.toJSON()));var z=this.$el.find(".toolSectionBody");x.each(this.model.attributes.elems,function(A){if(A instanceof j){var B=new m({model:A,className:"toolTitle"});B.render();z.append(B.$el)}else{if(A instanceof v){var C=new b({model:A});C.render();z.append(C.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var p=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",events:{click:"focus_and_select","keyup :input":"query_changed","click #search-clear-btn":"clear"},render:function(){this.$el.append(Handlebars.templates.tool_search(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}this.$el.find("[title]").tooltip();return this},focus_and_select:function(){this.$el.find(":input").focus().select()},clear:function(){this.model.clear_search();this.$el.find(":input").val(this.model.attributes.search_hint_string);this.focus_and_select();return false},query_changed:function(z){if((this.model.attributes.clear_key)&&(this.model.attributes.clear_key===z.which)){this.clear();return false}this.model.set("query",this.$el.find(":input").val())}});var w=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(){this.model.get("tool_search").on("change:results",this.handle_search_results,this)},render:function(){var z=this;var A=new p({model:this.model.get("tool_search")});A.render();z.$el.append(A.$el);this.model.get("layout").each(function(C){if(C instanceof l){var B=new r({model:C});B.render();z.$el.append(B.$el)}else{if(C instanceof j){var D=new m({model:C,className:"toolTitleNoSection"});D.render();z.$el.append(D.$el)}else{if(C instanceof v){var E=new b({model:C});E.render();z.$el.append(E.$el)}}}});z.$el.find("a.tool-link").click(function(D){var C=$(this).attr("class").split(/\s+/)[0],B=z.model.get("tools").get(C);z.trigger("tool_link_click",D,B)});return this},handle_search_results:function(){var z=this.model.get("tool_search").get("results");if(z&&z.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}});var u=Backbone.View.extend({className:"toolForm",render:function(){this.$el.children().remove();this.$el.append(Handlebars.templates.tool_form(this.model.toJSON()))}});var h=Backbone.View.extend({className:"toolMenuAndView",initialize:function(){this.tool_panel_view=new w({collection:this.collection});this.tool_form_view=new u()},render:function(){this.tool_panel_view.render();this.tool_panel_view.$el.css("float","left");this.$el.append(this.tool_panel_view.$el);this.tool_form_view.$el.hide();this.$el.append(this.tool_form_view.$el);var z=this;this.tool_panel_view.on("tool_link_click",function(B,A){B.preventDefault();z.show_tool(A)})},show_tool:function(A){var z=this;A.fetch().done(function(){z.tool_form_view.model=A;z.tool_form_view.render();z.tool_form_view.$el.show();$("#left").width("650px")})}});return{ToolParameter:e,IntegerToolParameter:d,SelectToolParameter:t,Tool:j,ToolCollection:n,ToolSearch:c,ToolPanel:o,ToolPanelView:w,ToolFormView:u}});
\ No newline at end of file
+define(["libs/underscore","viz/trackster/util","mvc/data","libs/lunr"],function(x,a,y){var g={hidden:false,show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},toggle:function(){this.set("hidden",!this.get("hidden"))},is_visible:function(){return !this.attributes.hidden}};var e=Backbone.Model.extend({defaults:{name:null,label:null,type:null,value:null,html:null,num_samples:5},initialize:function(z){this.attributes.html=unescape(this.attributes.html)},copy:function(){return new e(this.toJSON())},set_value:function(z){this.set("value",z||"")}});var i=Backbone.Collection.extend({model:e});var k=e.extend({});var d=e.extend({set_value:function(z){this.set("value",parseInt(z,10))},get_samples:function(){return d3.scale.linear().domain([this.get("min"),this.get("max")]).ticks(this.get("num_samples"))}});var f=d.extend({set_value:function(z){this.set("value",parseFloat(z))}});var t=e.extend({get_samples:function(){return x.map(this.get("options"),function(z){return z[0]})}});e.subModelTypes={integer:d,"float":f,data:k,select:t};var j=Backbone.Model.extend({defaults:{id:null,name:null,description:null,target:null,inputs:[],outputs:[]},urlRoot:galaxy_config.root+"api/tools",initialize:function(z){this.set("inputs",new i(x.map(z.inputs,function(A){var B=e.subModelTypes[A.type]||e;return new B(A)})))},toJSON:function(){var z=Backbone.Model.prototype.toJSON.call(this);z.inputs=this.get("inputs").map(function(A){return A.toJSON()});return z},remove_inputs:function(A){var z=this,B=z.get("inputs").filter(function(C){return(A.indexOf(C.get("type"))!==-1)});z.get("inputs").remove(B)},copy:function(A){var B=new j(this.toJSON());if(A){var z=new Backbone.Collection();B.get("inputs").each(function(C){if(C.get_samples()){z.push(C)}});B.set("inputs",z)}return B},apply_search_results:function(z){(x.indexOf(z,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()},set_input_value:function(z,A){this.get("inputs").find(function(B){return B.get("name")===z}).set("value",A)},set_input_values:function(A){var z=this;x.each(x.keys(A),function(B){z.set_input_value(B,A[B])})},run:function(){return this._run()},rerun:function(A,z){return this._run({action:"rerun",target_dataset_id:A.id,regions:z})},get_inputs_dict:function(){var z={};this.get("inputs").each(function(A){z[A.get("name")]=A.get("value")});return z},_run:function(B){var C=x.extend({tool_id:this.id,inputs:this.get_inputs_dict()},B);var A=$.Deferred(),z=new a.ServerStateDeferred({ajax_settings:{url:this.urlRoot,data:JSON.stringify(C),dataType:"json",contentType:"application/json",type:"POST"},interval:2000,success_fn:function(D){return D!=="pending"}});$.when(z.go()).then(function(D){A.resolve(new y.DatasetCollection().reset(D))});return A}});x.extend(j.prototype,g);var q=Backbone.View.extend({});var n=Backbone.Collection.extend({model:j});var v=Backbone.Model.extend(g);var l=Backbone.Model.extend({defaults:{elems:[],open:false},clear_search_results:function(){x.each(this.attributes.elems,function(z){z.show()});this.show();this.set("open",false)},apply_search_results:function(A){var B=true,z;x.each(this.attributes.elems,function(C){if(C instanceof v){z=C;z.hide()}else{if(C instanceof j){if(C.apply_search_results(A)){B=false;if(z){z.show()}}}}});if(B){this.hide()}else{this.show();this.set("open",true)}}});x.extend(l.prototype,g);var c=Backbone.Model.extend({defaults:{search_hint_string:"search tools",min_chars_for_search:3,spinner_url:"",clear_btn_url:"",search_url:"",visible:true,query:"",results:null,clear_key:27},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var B=this.attributes.query;if(B.length<this.attributes.min_chars_for_search){this.set("results",null);return}var A=B+"*";if(this.timer){clearTimeout(this.timer)}$("#search-clear-btn").hide();$("#search-spinner").show();var z=this;this.timer=setTimeout(function(){$.get(z.attributes.search_url,{query:A},function(C){z.set("results",C);$("#search-spinner").hide();$("#search-clear-btn").show()},"json")},200)},clear_search:function(){this.set("query","");this.set("results",null)}});x.extend(c.prototype,g);var o=Backbone.Model.extend({initialize:function(z){this.attributes.tool_search=z.tool_search;this.attributes.tool_search.on("change:results",this.apply_search_results,this);this.attributes.tools=z.tools;this.attributes.layout=new Backbone.Collection(this.parse(z.layout))},parse:function(A){var z=this,B=function(E){var D=E.model_class;if(D.indexOf("Tool")===D.length-4){return z.attributes.tools.get(E.id)}else{if(D==="ToolSection"){var C=x.map(E.elems,B);E.elems=C;return new l(E)}else{if(D==="ToolSectionLabel"){return new v(E)}}}};return x.map(A,B)},clear_search_results:function(){this.get("layout").each(function(z){if(z instanceof l){z.clear_search_results()}else{z.show()}})},apply_search_results:function(){var A=this.get("tool_search").get("results");if(A===null){this.clear_search_results();return}var z=null;this.get("layout").each(function(B){if(B instanceof v){z=B;z.hide()}else{if(B instanceof j){if(B.apply_search_results(A)){if(z){z.show()}}}else{z=null;B.apply_search_results(A)}}})}});var s=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){(this.model.attributes.hidden?this.$el.hide():this.$el.show())}});var m=s.extend({tagName:"div",render:function(){var z=$("<div/>");z.append(Handlebars.templates.tool_link(this.model.toJSON()));if(this.model.id==="upload1"){z.find("a").on("click",function(A){A.preventDefault();Galaxy.upload.show()})}this.$el.append(z);return this}});var b=s.extend({tagName:"div",className:"toolPanelLabel",render:function(){this.$el.append($("<span/>").text(this.model.attributes.text));return this}});var r=s.extend({tagName:"div",className:"toolSectionWrapper",initialize:function(){s.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(Handlebars.templates.panel_section(this.model.toJSON()));var z=this.$el.find(".toolSectionBody");x.each(this.model.attributes.elems,function(A){if(A instanceof j){var B=new m({model:A,className:"toolTitle"});B.render();z.append(B.$el)}else{if(A instanceof v){var C=new b({model:A});C.render();z.append(C.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var p=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",events:{click:"focus_and_select","keyup :input":"query_changed","click #search-clear-btn":"clear"},render:function(){this.$el.append(Handlebars.templates.tool_search(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}this.$el.find("[title]").tooltip();return this},focus_and_select:function(){this.$el.find(":input").focus().select()},clear:function(){this.model.clear_search();this.$el.find(":input").val(this.model.attributes.search_hint_string);this.focus_and_select();return false},query_changed:function(z){if((this.model.attributes.clear_key)&&(this.model.attributes.clear_key===z.which)){this.clear();return false}this.model.set("query",this.$el.find(":input").val())}});var w=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(){this.model.get("tool_search").on("change:results",this.handle_search_results,this)},render:function(){var z=this;var A=new p({model:this.model.get("tool_search")});A.render();z.$el.append(A.$el);this.model.get("layout").each(function(C){if(C instanceof l){var B=new r({model:C});B.render();z.$el.append(B.$el)}else{if(C instanceof j){var D=new m({model:C,className:"toolTitleNoSection"});D.render();z.$el.append(D.$el)}else{if(C instanceof v){var E=new b({model:C});E.render();z.$el.append(E.$el)}}}});z.$el.find("a.tool-link").click(function(D){var C=$(this).attr("class").split(/\s+/)[0],B=z.model.get("tools").get(C);z.trigger("tool_link_click",D,B)});return this},handle_search_results:function(){var z=this.model.get("tool_search").get("results");if(z&&z.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}});var u=Backbone.View.extend({className:"toolForm",render:function(){this.$el.children().remove();this.$el.append(Handlebars.templates.tool_form(this.model.toJSON()))}});var h=Backbone.View.extend({className:"toolMenuAndView",initialize:function(){this.tool_panel_view=new w({collection:this.collection});this.tool_form_view=new u()},render:function(){this.tool_panel_view.render();this.tool_panel_view.$el.css("float","left");this.$el.append(this.tool_panel_view.$el);this.tool_form_view.$el.hide();this.$el.append(this.tool_form_view.$el);var z=this;this.tool_panel_view.on("tool_link_click",function(B,A){B.preventDefault();z.show_tool(A)})},show_tool:function(A){var z=this;A.fetch().done(function(){z.tool_form_view.model=A;z.tool_form_view.render();z.tool_form_view.$el.show();$("#left").width("650px")})}});return{ToolParameter:e,IntegerToolParameter:d,SelectToolParameter:t,Tool:j,ToolCollection:n,ToolSearch:c,ToolPanel:o,ToolPanelView:w,ToolFormView:u}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9eeb924b5204/
Changeset: 9eeb924b5204
User: dannon
Date: 2015-02-05 13:12:54+00:00
Summary: Add lunr library for toolbox (and potentially more things in the future) search.
Affected #: 5 files
diff -r 85b1de6a6ebdfe30e14b96f8dc7d13105ae04c2b -r 9eeb924b5204ff10bac0998612549de468f9bc2a client/GruntFile.js
--- a/client/GruntFile.js
+++ b/client/GruntFile.js
@@ -69,11 +69,11 @@
libraryLocations : {
"jquery": [ "dist/jquery.js", "jquery/jquery.js" ],
"jquery-migrate": [ "jquery-migrate.js", "jquery/jquery.migrate.js" ],
-
"traceKit": [ "tracekit.js", "tracekit.js" ],
"ravenjs": [ "dist/raven.js", "raven.js" ],
"underscore": [ "underscore.js", "underscore.js" ],
- "handlebars": [ "handlebars.runtime.js", "handlebars.runtime.js" ]
+ "handlebars": [ "handlebars.runtime.js", "handlebars.runtime.js" ],
+ "lunr.js": [ "lunr.js", "lunr.js" ]
//"backbone": [ "backbone.js", "backbone/backbone.js" ],
// these need to be updated and tested
diff -r 85b1de6a6ebdfe30e14b96f8dc7d13105ae04c2b -r 9eeb924b5204ff10bac0998612549de468f9bc2a client/bower.json
--- a/client/bower.json
+++ b/client/bower.json
@@ -32,7 +32,8 @@
"jquery-ui": "git://github.com/jquery/jquery-ui.git#~1.11.2",
"jquery.event.drag-drop": "~2.2.1",
"handlebars": "~2.0.0",
- "jquery-migrate": "~1.2.1"
+ "jquery-migrate": "~1.2.1",
+ "lunr.js": "git://github.com/olivernn/lunr.js.git#~0.5.7"
},
"resolutions": {
"jquery": "~1.11.1"
diff -r 85b1de6a6ebdfe30e14b96f8dc7d13105ae04c2b -r 9eeb924b5204ff10bac0998612549de468f9bc2a client/galaxy/scripts/libs/lunr.js
--- /dev/null
+++ b/client/galaxy/scripts/libs/lunr.js
@@ -0,0 +1,1910 @@
+/**
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.7
+ * Copyright (C) 2014 Oliver Nightingale
+ * MIT Licensed
+ * @license
+ */
+
+(function(){
+
+/**
+ * Convenience function for instantiating a new lunr index and configuring it
+ * with the default pipeline functions and the passed config function.
+ *
+ * When using this convenience function a new index will be created with the
+ * following functions already in the pipeline:
+ *
+ * lunr.StopWordFilter - filters out any stop words before they enter the
+ * index
+ *
+ * lunr.stemmer - stems the tokens before entering the index.
+ *
+ * Example:
+ *
+ * var idx = lunr(function () {
+ * this.field('title', 10)
+ * this.field('tags', 100)
+ * this.field('body')
+ *
+ * this.ref('cid')
+ *
+ * this.pipeline.add(function () {
+ * // some custom pipeline function
+ * })
+ *
+ * })
+ *
+ * @param {Function} config A function that will be called with the new instance
+ * of the lunr.Index as both its context and first parameter. It can be used to
+ * customize the instance of new lunr.Index.
+ * @namespace
+ * @module
+ * @returns {lunr.Index}
+ *
+ */
+var lunr = function (config) {
+ var idx = new lunr.Index
+
+ idx.pipeline.add(
+ lunr.trimmer,
+ lunr.stopWordFilter,
+ lunr.stemmer
+ )
+
+ if (config) config.call(idx, idx)
+
+ return idx
+}
+
+lunr.version = "0.5.7"
+/*!
+ * lunr.utils
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * A namespace containing utils for the rest of the lunr library
+ */
+lunr.utils = {}
+
+/**
+ * Print a warning message to the console.
+ *
+ * @param {String} message The message to be printed.
+ * @memberOf Utils
+ */
+lunr.utils.warn = (function (global) {
+ return function (message) {
+ if (global.console && console.warn) {
+ console.warn(message)
+ }
+ }
+})(this)
+
+/*!
+ * lunr.EventEmitter
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * lunr.EventEmitter is an event emitter for lunr. It manages adding and removing event handlers and triggering events and their handlers.
+ *
+ * @constructor
+ */
+lunr.EventEmitter = function () {
+ this.events = {}
+}
+
+/**
+ * Binds a handler function to a specific event(s).
+ *
+ * Can bind a single function to many different events in one call.
+ *
+ * @param {String} [eventName] The name(s) of events to bind this function to.
+ * @param {Function} handler The function to call when an event is fired.
+ * @memberOf EventEmitter
+ */
+lunr.EventEmitter.prototype.addListener = function () {
+ var args = Array.prototype.slice.call(arguments),
+ fn = args.pop(),
+ names = args
+
+ if (typeof fn !== "function") throw new TypeError ("last argument must be a function")
+
+ names.forEach(function (name) {
+ if (!this.hasHandler(name)) this.events[name] = []
+ this.events[name].push(fn)
+ }, this)
+}
+
+/**
+ * Removes a handler function from a specific event.
+ *
+ * @param {String} eventName The name of the event to remove this function from.
+ * @param {Function} handler The function to remove from an event.
+ * @memberOf EventEmitter
+ */
+lunr.EventEmitter.prototype.removeListener = function (name, fn) {
+ if (!this.hasHandler(name)) return
+
+ var fnIndex = this.events[name].indexOf(fn)
+ this.events[name].splice(fnIndex, 1)
+
+ if (!this.events[name].length) delete this.events[name]
+}
+
+/**
+ * Calls all functions bound to the given event.
+ *
+ * Additional data can be passed to the event handler as arguments to `emit`
+ * after the event name.
+ *
+ * @param {String} eventName The name of the event to emit.
+ * @memberOf EventEmitter
+ */
+lunr.EventEmitter.prototype.emit = function (name) {
+ if (!this.hasHandler(name)) return
+
+ var args = Array.prototype.slice.call(arguments, 1)
+
+ this.events[name].forEach(function (fn) {
+ fn.apply(undefined, args)
+ })
+}
+
+/**
+ * Checks whether a handler has ever been stored against an event.
+ *
+ * @param {String} eventName The name of the event to check.
+ * @private
+ * @memberOf EventEmitter
+ */
+lunr.EventEmitter.prototype.hasHandler = function (name) {
+ return name in this.events
+}
+
+/*!
+ * lunr.tokenizer
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * A function for splitting a string into tokens ready to be inserted into
+ * the search index.
+ *
+ * @module
+ * @param {String} obj The string to convert into tokens
+ * @returns {Array}
+ */
+lunr.tokenizer = function (obj) {
+ if (!arguments.length || obj == null || obj == undefined) return []
+ if (Array.isArray(obj)) return obj.map(function (t) { return t.toLowerCase() })
+
+ var str = obj.toString().replace(/^\s+/, '')
+
+ for (var i = str.length - 1; i >= 0; i--) {
+ if (/\S/.test(str.charAt(i))) {
+ str = str.substring(0, i + 1)
+ break
+ }
+ }
+
+ return str
+ .split(/(?:\s+|\-)/)
+ .filter(function (token) {
+ return !!token
+ })
+ .map(function (token) {
+ return token.toLowerCase()
+ })
+}
+/*!
+ * lunr.Pipeline
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * lunr.Pipelines maintain an ordered list of functions to be applied to all
+ * tokens in documents entering the search index and queries being ran against
+ * the index.
+ *
+ * An instance of lunr.Index created with the lunr shortcut will contain a
+ * pipeline with a stop word filter and an English language stemmer. Extra
+ * functions can be added before or after either of these functions or these
+ * default functions can be removed.
+ *
+ * When run the pipeline will call each function in turn, passing a token, the
+ * index of that token in the original list of all tokens and finally a list of
+ * all the original tokens.
+ *
+ * The output of functions in the pipeline will be passed to the next function
+ * in the pipeline. To exclude a token from entering the index the function
+ * should return undefined, the rest of the pipeline will not be called with
+ * this token.
+ *
+ * For serialisation of pipelines to work, all functions used in an instance of
+ * a pipeline should be registered with lunr.Pipeline. Registered functions can
+ * then be loaded. If trying to load a serialised pipeline that uses functions
+ * that are not registered an error will be thrown.
+ *
+ * If not planning on serialising the pipeline then registering pipeline functions
+ * is not necessary.
+ *
+ * @constructor
+ */
+lunr.Pipeline = function () {
+ this._stack = []
+}
+
+lunr.Pipeline.registeredFunctions = {}
+
+/**
+ * Register a function with the pipeline.
+ *
+ * Functions that are used in the pipeline should be registered if the pipeline
+ * needs to be serialised, or a serialised pipeline needs to be loaded.
+ *
+ * Registering a function does not add it to a pipeline, functions must still be
+ * added to instances of the pipeline for them to be used when running a pipeline.
+ *
+ * @param {Function} fn The function to check for.
+ * @param {String} label The label to register this function with
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.registerFunction = function (fn, label) {
+ if (label in this.registeredFunctions) {
+ lunr.utils.warn('Overwriting existing registered function: ' + label)
+ }
+
+ fn.label = label
+ lunr.Pipeline.registeredFunctions[fn.label] = fn
+}
+
+/**
+ * Warns if the function is not registered as a Pipeline function.
+ *
+ * @param {Function} fn The function to check for.
+ * @private
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {
+ var isRegistered = fn.label && (fn.label in this.registeredFunctions)
+
+ if (!isRegistered) {
+ lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\n', fn)
+ }
+}
+
+/**
+ * Loads a previously serialised pipeline.
+ *
+ * All functions to be loaded must already be registered with lunr.Pipeline.
+ * If any function from the serialised data has not been registered then an
+ * error will be thrown.
+ *
+ * @param {Object} serialised The serialised pipeline to load.
+ * @returns {lunr.Pipeline}
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.load = function (serialised) {
+ var pipeline = new lunr.Pipeline
+
+ serialised.forEach(function (fnName) {
+ var fn = lunr.Pipeline.registeredFunctions[fnName]
+
+ if (fn) {
+ pipeline.add(fn)
+ } else {
+ throw new Error ('Cannot load un-registered function: ' + fnName)
+ }
+ })
+
+ return pipeline
+}
+
+/**
+ * Adds new functions to the end of the pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {Function} functions Any number of functions to add to the pipeline.
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.add = function () {
+ var fns = Array.prototype.slice.call(arguments)
+
+ fns.forEach(function (fn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(fn)
+ this._stack.push(fn)
+ }, this)
+}
+
+/**
+ * Adds a single function after a function that already exists in the
+ * pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {Function} existingFn A function that already exists in the pipeline.
+ * @param {Function} newFn The new function to add to the pipeline.
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.after = function (existingFn, newFn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(newFn)
+
+ var pos = this._stack.indexOf(existingFn) + 1
+ this._stack.splice(pos, 0, newFn)
+}
+
+/**
+ * Adds a single function before a function that already exists in the
+ * pipeline.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @param {Function} existingFn A function that already exists in the pipeline.
+ * @param {Function} newFn The new function to add to the pipeline.
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.before = function (existingFn, newFn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(newFn)
+
+ var pos = this._stack.indexOf(existingFn)
+ this._stack.splice(pos, 0, newFn)
+}
+
+/**
+ * Removes a function from the pipeline.
+ *
+ * @param {Function} fn The function to remove from the pipeline.
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.remove = function (fn) {
+ var pos = this._stack.indexOf(fn)
+ this._stack.splice(pos, 1)
+}
+
+/**
+ * Runs the current list of functions that make up the pipeline against the
+ * passed tokens.
+ *
+ * @param {Array} tokens The tokens to run through the pipeline.
+ * @returns {Array}
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.run = function (tokens) {
+ var out = [],
+ tokenLength = tokens.length,
+ stackLength = this._stack.length
+
+ for (var i = 0; i < tokenLength; i++) {
+ var token = tokens[i]
+
+ for (var j = 0; j < stackLength; j++) {
+ token = this._stack[j](token, i, tokens)
+ if (token === void 0) break
+ };
+
+ if (token !== void 0) out.push(token)
+ };
+
+ return out
+}
+
+/**
+ * Resets the pipeline by removing any existing processors.
+ *
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.reset = function () {
+ this._stack = []
+}
+
+/**
+ * Returns a representation of the pipeline ready for serialisation.
+ *
+ * Logs a warning if the function has not been registered.
+ *
+ * @returns {Array}
+ * @memberOf Pipeline
+ */
+lunr.Pipeline.prototype.toJSON = function () {
+ return this._stack.map(function (fn) {
+ lunr.Pipeline.warnIfFunctionNotRegistered(fn)
+
+ return fn.label
+ })
+}
+/*!
+ * lunr.Vector
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * lunr.Vectors implement vector related operations for
+ * a series of elements.
+ *
+ * @constructor
+ */
+lunr.Vector = function () {
+ this._magnitude = null
+ this.list = undefined
+ this.length = 0
+}
+
+/**
+ * lunr.Vector.Node is a simple struct for each node
+ * in a lunr.Vector.
+ *
+ * @private
+ * @param {Number} The index of the node in the vector.
+ * @param {Object} The data at this node in the vector.
+ * @param {lunr.Vector.Node} The node directly after this node in the vector.
+ * @constructor
+ * @memberOf Vector
+ */
+lunr.Vector.Node = function (idx, val, next) {
+ this.idx = idx
+ this.val = val
+ this.next = next
+}
+
+/**
+ * Inserts a new value at a position in a vector.
+ *
+ * @param {Number} The index at which to insert a value.
+ * @param {Object} The object to insert in the vector.
+ * @memberOf Vector.
+ */
+lunr.Vector.prototype.insert = function (idx, val) {
+ var list = this.list
+
+ if (!list) {
+ this.list = new lunr.Vector.Node (idx, val, list)
+ return this.length++
+ }
+
+ var prev = list,
+ next = list.next
+
+ while (next != undefined) {
+ if (idx < next.idx) {
+ prev.next = new lunr.Vector.Node (idx, val, next)
+ return this.length++
+ }
+
+ prev = next, next = next.next
+ }
+
+ prev.next = new lunr.Vector.Node (idx, val, next)
+ return this.length++
+}
+
+/**
+ * Calculates the magnitude of this vector.
+ *
+ * @returns {Number}
+ * @memberOf Vector
+ */
+lunr.Vector.prototype.magnitude = function () {
+ if (this._magniture) return this._magnitude
+ var node = this.list,
+ sumOfSquares = 0,
+ val
+
+ while (node) {
+ val = node.val
+ sumOfSquares += val * val
+ node = node.next
+ }
+
+ return this._magnitude = Math.sqrt(sumOfSquares)
+}
+
+/**
+ * Calculates the dot product of this vector and another vector.
+ *
+ * @param {lunr.Vector} otherVector The vector to compute the dot product with.
+ * @returns {Number}
+ * @memberOf Vector
+ */
+lunr.Vector.prototype.dot = function (otherVector) {
+ var node = this.list,
+ otherNode = otherVector.list,
+ dotProduct = 0
+
+ while (node && otherNode) {
+ if (node.idx < otherNode.idx) {
+ node = node.next
+ } else if (node.idx > otherNode.idx) {
+ otherNode = otherNode.next
+ } else {
+ dotProduct += node.val * otherNode.val
+ node = node.next
+ otherNode = otherNode.next
+ }
+ }
+
+ return dotProduct
+}
+
+/**
+ * Calculates the cosine similarity between this vector and another
+ * vector.
+ *
+ * @param {lunr.Vector} otherVector The other vector to calculate the
+ * similarity with.
+ * @returns {Number}
+ * @memberOf Vector
+ */
+lunr.Vector.prototype.similarity = function (otherVector) {
+ return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude())
+}
+/*!
+ * lunr.SortedSet
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * lunr.SortedSets are used to maintain an array of uniq values in a sorted
+ * order.
+ *
+ * @constructor
+ */
+lunr.SortedSet = function () {
+ this.length = 0
+ this.elements = []
+}
+
+/**
+ * Loads a previously serialised sorted set.
+ *
+ * @param {Array} serialisedData The serialised set to load.
+ * @returns {lunr.SortedSet}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.load = function (serialisedData) {
+ var set = new this
+
+ set.elements = serialisedData
+ set.length = serialisedData.length
+
+ return set
+}
+
+/**
+ * Inserts new items into the set in the correct position to maintain the
+ * order.
+ *
+ * @param {Object} The objects to add to this set.
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.add = function () {
+ Array.prototype.slice.call(arguments).forEach(function (element) {
+ if (~this.indexOf(element)) return
+ this.elements.splice(this.locationFor(element), 0, element)
+ }, this)
+
+ this.length = this.elements.length
+}
+
+/**
+ * Converts this sorted set into an array.
+ *
+ * @returns {Array}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.toArray = function () {
+ return this.elements.slice()
+}
+
+/**
+ * Creates a new array with the results of calling a provided function on every
+ * element in this sorted set.
+ *
+ * Delegates to Array.prototype.map and has the same signature.
+ *
+ * @param {Function} fn The function that is called on each element of the
+ * set.
+ * @param {Object} ctx An optional object that can be used as the context
+ * for the function fn.
+ * @returns {Array}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.map = function (fn, ctx) {
+ return this.elements.map(fn, ctx)
+}
+
+/**
+ * Executes a provided function once per sorted set element.
+ *
+ * Delegates to Array.prototype.forEach and has the same signature.
+ *
+ * @param {Function} fn The function that is called on each element of the
+ * set.
+ * @param {Object} ctx An optional object that can be used as the context
+ * @memberOf SortedSet
+ * for the function fn.
+ */
+lunr.SortedSet.prototype.forEach = function (fn, ctx) {
+ return this.elements.forEach(fn, ctx)
+}
+
+/**
+ * Returns the index at which a given element can be found in the
+ * sorted set, or -1 if it is not present.
+ *
+ * @param {Object} elem The object to locate in the sorted set.
+ * @param {Number} start An optional index at which to start searching from
+ * within the set.
+ * @param {Number} end An optional index at which to stop search from within
+ * the set.
+ * @returns {Number}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.indexOf = function (elem, start, end) {
+ var start = start || 0,
+ end = end || this.elements.length,
+ sectionLength = end - start,
+ pivot = start + Math.floor(sectionLength / 2),
+ pivotElem = this.elements[pivot]
+
+ if (sectionLength <= 1) {
+ if (pivotElem === elem) {
+ return pivot
+ } else {
+ return -1
+ }
+ }
+
+ if (pivotElem < elem) return this.indexOf(elem, pivot, end)
+ if (pivotElem > elem) return this.indexOf(elem, start, pivot)
+ if (pivotElem === elem) return pivot
+}
+
+/**
+ * Returns the position within the sorted set that an element should be
+ * inserted at to maintain the current order of the set.
+ *
+ * This function assumes that the element to search for does not already exist
+ * in the sorted set.
+ *
+ * @param {Object} elem The elem to find the position for in the set
+ * @param {Number} start An optional index at which to start searching from
+ * within the set.
+ * @param {Number} end An optional index at which to stop search from within
+ * the set.
+ * @returns {Number}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.locationFor = function (elem, start, end) {
+ var start = start || 0,
+ end = end || this.elements.length,
+ sectionLength = end - start,
+ pivot = start + Math.floor(sectionLength / 2),
+ pivotElem = this.elements[pivot]
+
+ if (sectionLength <= 1) {
+ if (pivotElem > elem) return pivot
+ if (pivotElem < elem) return pivot + 1
+ }
+
+ if (pivotElem < elem) return this.locationFor(elem, pivot, end)
+ if (pivotElem > elem) return this.locationFor(elem, start, pivot)
+}
+
+/**
+ * Creates a new lunr.SortedSet that contains the elements in the intersection
+ * of this set and the passed set.
+ *
+ * @param {lunr.SortedSet} otherSet The set to intersect with this set.
+ * @returns {lunr.SortedSet}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.intersect = function (otherSet) {
+ var intersectSet = new lunr.SortedSet,
+ i = 0, j = 0,
+ a_len = this.length, b_len = otherSet.length,
+ a = this.elements, b = otherSet.elements
+
+ while (true) {
+ if (i > a_len - 1 || j > b_len - 1) break
+
+ if (a[i] === b[j]) {
+ intersectSet.add(a[i])
+ i++, j++
+ continue
+ }
+
+ if (a[i] < b[j]) {
+ i++
+ continue
+ }
+
+ if (a[i] > b[j]) {
+ j++
+ continue
+ }
+ };
+
+ return intersectSet
+}
+
+/**
+ * Makes a copy of this set
+ *
+ * @returns {lunr.SortedSet}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.clone = function () {
+ var clone = new lunr.SortedSet
+
+ clone.elements = this.toArray()
+ clone.length = clone.elements.length
+
+ return clone
+}
+
+/**
+ * Creates a new lunr.SortedSet that contains the elements in the union
+ * of this set and the passed set.
+ *
+ * @param {lunr.SortedSet} otherSet The set to union with this set.
+ * @returns {lunr.SortedSet}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.union = function (otherSet) {
+ var longSet, shortSet, unionSet
+
+ if (this.length >= otherSet.length) {
+ longSet = this, shortSet = otherSet
+ } else {
+ longSet = otherSet, shortSet = this
+ }
+
+ unionSet = longSet.clone()
+
+ unionSet.add.apply(unionSet, shortSet.toArray())
+
+ return unionSet
+}
+
+/**
+ * Returns a representation of the sorted set ready for serialisation.
+ *
+ * @returns {Array}
+ * @memberOf SortedSet
+ */
+lunr.SortedSet.prototype.toJSON = function () {
+ return this.toArray()
+}
+/*!
+ * lunr.Index
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * lunr.Index is object that manages a search index. It contains the indexes
+ * and stores all the tokens and document lookups. It also provides the main
+ * user facing API for the library.
+ *
+ * @constructor
+ */
+lunr.Index = function () {
+ this._fields = []
+ this._ref = 'id'
+ this.pipeline = new lunr.Pipeline
+ this.documentStore = new lunr.Store
+ this.tokenStore = new lunr.TokenStore
+ this.corpusTokens = new lunr.SortedSet
+ this.eventEmitter = new lunr.EventEmitter
+
+ this._idfCache = {}
+
+ this.on('add', 'remove', 'update', (function () {
+ this._idfCache = {}
+ }).bind(this))
+}
+
+/**
+ * Bind a handler to events being emitted by the index.
+ *
+ * The handler can be bound to many events at the same time.
+ *
+ * @param {String} [eventName] The name(s) of events to bind the function to.
+ * @param {Function} handler The serialised set to load.
+ * @memberOf Index
+ */
+lunr.Index.prototype.on = function () {
+ var args = Array.prototype.slice.call(arguments)
+ return this.eventEmitter.addListener.apply(this.eventEmitter, args)
+}
+
+/**
+ * Removes a handler from an event being emitted by the index.
+ *
+ * @param {String} eventName The name of events to remove the function from.
+ * @param {Function} handler The serialised set to load.
+ * @memberOf Index
+ */
+lunr.Index.prototype.off = function (name, fn) {
+ return this.eventEmitter.removeListener(name, fn)
+}
+
+/**
+ * Loads a previously serialised index.
+ *
+ * Issues a warning if the index being imported was serialised
+ * by a different version of lunr.
+ *
+ * @param {Object} serialisedData The serialised set to load.
+ * @returns {lunr.Index}
+ * @memberOf Index
+ */
+lunr.Index.load = function (serialisedData) {
+ if (serialisedData.version !== lunr.version) {
+ lunr.utils.warn('version mismatch: current ' + lunr.version + ' importing ' + serialisedData.version)
+ }
+
+ var idx = new this
+
+ idx._fields = serialisedData.fields
+ idx._ref = serialisedData.ref
+
+ idx.documentStore = lunr.Store.load(serialisedData.documentStore)
+ idx.tokenStore = lunr.TokenStore.load(serialisedData.tokenStore)
+ idx.corpusTokens = lunr.SortedSet.load(serialisedData.corpusTokens)
+ idx.pipeline = lunr.Pipeline.load(serialisedData.pipeline)
+
+ return idx
+}
+
+/**
+ * Adds a field to the list of fields that will be searchable within documents
+ * in the index.
+ *
+ * An optional boost param can be passed to affect how much tokens in this field
+ * rank in search results, by default the boost value is 1.
+ *
+ * Fields should be added before any documents are added to the index, fields
+ * that are added after documents are added to the index will only apply to new
+ * documents added to the index.
+ *
+ * @param {String} fieldName The name of the field within the document that
+ * should be indexed
+ * @param {Number} boost An optional boost that can be applied to terms in this
+ * field.
+ * @returns {lunr.Index}
+ * @memberOf Index
+ */
+lunr.Index.prototype.field = function (fieldName, opts) {
+ var opts = opts || {},
+ field = { name: fieldName, boost: opts.boost || 1 }
+
+ this._fields.push(field)
+ return this
+}
+
+/**
+ * Sets the property used to uniquely identify documents added to the index,
+ * by default this property is 'id'.
+ *
+ * This should only be changed before adding documents to the index, changing
+ * the ref property without resetting the index can lead to unexpected results.
+ *
+ * @param {String} refName The property to use to uniquely identify the
+ * documents in the index.
+ * @param {Boolean} emitEvent Whether to emit add events, defaults to true
+ * @returns {lunr.Index}
+ * @memberOf Index
+ */
+lunr.Index.prototype.ref = function (refName) {
+ this._ref = refName
+ return this
+}
+
+/**
+ * Add a document to the index.
+ *
+ * This is the way new documents enter the index, this function will run the
+ * fields from the document through the index's pipeline and then add it to
+ * the index, it will then show up in search results.
+ *
+ * An 'add' event is emitted with the document that has been added and the index
+ * the document has been added to. This event can be silenced by passing false
+ * as the second argument to add.
+ *
+ * @param {Object} doc The document to add to the index.
+ * @param {Boolean} emitEvent Whether or not to emit events, default true.
+ * @memberOf Index
+ */
+lunr.Index.prototype.add = function (doc, emitEvent) {
+ var docTokens = {},
+ allDocumentTokens = new lunr.SortedSet,
+ docRef = doc[this._ref],
+ emitEvent = emitEvent === undefined ? true : emitEvent
+
+ this._fields.forEach(function (field) {
+ var fieldTokens = this.pipeline.run(lunr.tokenizer(doc[field.name]))
+
+ docTokens[field.name] = fieldTokens
+ lunr.SortedSet.prototype.add.apply(allDocumentTokens, fieldTokens)
+ }, this)
+
+ this.documentStore.set(docRef, allDocumentTokens)
+ lunr.SortedSet.prototype.add.apply(this.corpusTokens, allDocumentTokens.toArray())
+
+ for (var i = 0; i < allDocumentTokens.length; i++) {
+ var token = allDocumentTokens.elements[i]
+ var tf = this._fields.reduce(function (memo, field) {
+ var fieldLength = docTokens[field.name].length
+
+ if (!fieldLength) return memo
+
+ var tokenCount = docTokens[field.name].filter(function (t) { return t === token }).length
+
+ return memo + (tokenCount / fieldLength * field.boost)
+ }, 0)
+
+ this.tokenStore.add(token, { ref: docRef, tf: tf })
+ };
+
+ if (emitEvent) this.eventEmitter.emit('add', doc, this)
+}
+
+/**
+ * Removes a document from the index.
+ *
+ * To make sure documents no longer show up in search results they can be
+ * removed from the index using this method.
+ *
+ * The document passed only needs to have the same ref property value as the
+ * document that was added to the index, they could be completely different
+ * objects.
+ *
+ * A 'remove' event is emitted with the document that has been removed and the index
+ * the document has been removed from. This event can be silenced by passing false
+ * as the second argument to remove.
+ *
+ * @param {Object} doc The document to remove from the index.
+ * @param {Boolean} emitEvent Whether to emit remove events, defaults to true
+ * @memberOf Index
+ */
+lunr.Index.prototype.remove = function (doc, emitEvent) {
+ var docRef = doc[this._ref],
+ emitEvent = emitEvent === undefined ? true : emitEvent
+
+ if (!this.documentStore.has(docRef)) return
+
+ var docTokens = this.documentStore.get(docRef)
+
+ this.documentStore.remove(docRef)
+
+ docTokens.forEach(function (token) {
+ this.tokenStore.remove(token, docRef)
+ }, this)
+
+ if (emitEvent) this.eventEmitter.emit('remove', doc, this)
+}
+
+/**
+ * Updates a document in the index.
+ *
+ * When a document contained within the index gets updated, fields changed,
+ * added or removed, to make sure it correctly matched against search queries,
+ * it should be updated in the index.
+ *
+ * This method is just a wrapper around `remove` and `add`
+ *
+ * An 'update' event is emitted with the document that has been updated and the index.
+ * This event can be silenced by passing false as the second argument to update. Only
+ * an update event will be fired, the 'add' and 'remove' events of the underlying calls
+ * are silenced.
+ *
+ * @param {Object} doc The document to update in the index.
+ * @param {Boolean} emitEvent Whether to emit update events, defaults to true
+ * @see Index.prototype.remove
+ * @see Index.prototype.add
+ * @memberOf Index
+ */
+lunr.Index.prototype.update = function (doc, emitEvent) {
+ var emitEvent = emitEvent === undefined ? true : emitEvent
+
+ this.remove(doc, false)
+ this.add(doc, false)
+
+ if (emitEvent) this.eventEmitter.emit('update', doc, this)
+}
+
+/**
+ * Calculates the inverse document frequency for a token within the index.
+ *
+ * @param {String} token The token to calculate the idf of.
+ * @see Index.prototype.idf
+ * @private
+ * @memberOf Index
+ */
+lunr.Index.prototype.idf = function (term) {
+ var cacheKey = "@" + term
+ if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey]
+
+ var documentFrequency = this.tokenStore.count(term),
+ idf = 1
+
+ if (documentFrequency > 0) {
+ idf = 1 + Math.log(this.tokenStore.length / documentFrequency)
+ }
+
+ return this._idfCache[cacheKey] = idf
+}
+
+/**
+ * Searches the index using the passed query.
+ *
+ * Queries should be a string, multiple words are allowed and will lead to an
+ * AND based query, e.g. `idx.search('foo bar')` will run a search for
+ * documents containing both 'foo' and 'bar'.
+ *
+ * All query tokens are passed through the same pipeline that document tokens
+ * are passed through, so any language processing involved will be run on every
+ * query term.
+ *
+ * Each query term is expanded, so that the term 'he' might be expanded to
+ * 'hello' and 'help' if those terms were already included in the index.
+ *
+ * Matching documents are returned as an array of objects, each object contains
+ * the matching document ref, as set for this index, and the similarity score
+ * for this document against the query.
+ *
+ * @param {String} query The query to search the index with.
+ * @returns {Object}
+ * @see Index.prototype.idf
+ * @see Index.prototype.documentVector
+ * @memberOf Index
+ */
+lunr.Index.prototype.search = function (query) {
+ var queryTokens = this.pipeline.run(lunr.tokenizer(query)),
+ queryVector = new lunr.Vector,
+ documentSets = [],
+ fieldBoosts = this._fields.reduce(function (memo, f) { return memo + f.boost }, 0)
+
+ var hasSomeToken = queryTokens.some(function (token) {
+ return this.tokenStore.has(token)
+ }, this)
+
+ if (!hasSomeToken) return []
+
+ queryTokens
+ .forEach(function (token, i, tokens) {
+ var tf = 1 / tokens.length * this._fields.length * fieldBoosts,
+ self = this
+
+ var set = this.tokenStore.expand(token).reduce(function (memo, key) {
+ var pos = self.corpusTokens.indexOf(key),
+ idf = self.idf(key),
+ similarityBoost = 1,
+ set = new lunr.SortedSet
+
+ // if the expanded key is not an exact match to the token then
+ // penalise the score for this key by how different the key is
+ // to the token.
+ if (key !== token) {
+ var diff = Math.max(3, key.length - token.length)
+ similarityBoost = 1 / Math.log(diff)
+ }
+
+ // calculate the query tf-idf score for this token
+ // applying an similarityBoost to ensure exact matches
+ // these rank higher than expanded terms
+ if (pos > -1) queryVector.insert(pos, tf * idf * similarityBoost)
+
+ // add all the documents that have this key into a set
+ Object.keys(self.tokenStore.get(key)).forEach(function (ref) { set.add(ref) })
+
+ return memo.union(set)
+ }, new lunr.SortedSet)
+
+ documentSets.push(set)
+ }, this)
+
+ var documentSet = documentSets.reduce(function (memo, set) {
+ return memo.intersect(set)
+ })
+
+ return documentSet
+ .map(function (ref) {
+ return { ref: ref, score: queryVector.similarity(this.documentVector(ref)) }
+ }, this)
+ .sort(function (a, b) {
+ return b.score - a.score
+ })
+}
+
+/**
+ * Generates a vector containing all the tokens in the document matching the
+ * passed documentRef.
+ *
+ * The vector contains the tf-idf score for each token contained in the
+ * document with the passed documentRef. The vector will contain an element
+ * for every token in the indexes corpus, if the document does not contain that
+ * token the element will be 0.
+ *
+ * @param {Object} documentRef The ref to find the document with.
+ * @returns {lunr.Vector}
+ * @private
+ * @memberOf Index
+ */
+lunr.Index.prototype.documentVector = function (documentRef) {
+ var documentTokens = this.documentStore.get(documentRef),
+ documentTokensLength = documentTokens.length,
+ documentVector = new lunr.Vector
+
+ for (var i = 0; i < documentTokensLength; i++) {
+ var token = documentTokens.elements[i],
+ tf = this.tokenStore.get(token)[documentRef].tf,
+ idf = this.idf(token)
+
+ documentVector.insert(this.corpusTokens.indexOf(token), tf * idf)
+ };
+
+ return documentVector
+}
+
+/**
+ * Returns a representation of the index ready for serialisation.
+ *
+ * @returns {Object}
+ * @memberOf Index
+ */
+lunr.Index.prototype.toJSON = function () {
+ return {
+ version: lunr.version,
+ fields: this._fields,
+ ref: this._ref,
+ documentStore: this.documentStore.toJSON(),
+ tokenStore: this.tokenStore.toJSON(),
+ corpusTokens: this.corpusTokens.toJSON(),
+ pipeline: this.pipeline.toJSON()
+ }
+}
+
+/**
+ * Applies a plugin to the current index.
+ *
+ * A plugin is a function that is called with the index as its context.
+ * Plugins can be used to customise or extend the behaviour the index
+ * in some way. A plugin is just a function, that encapsulated the custom
+ * behaviour that should be applied to the index.
+ *
+ * The plugin function will be called with the index as its argument, additional
+ * arguments can also be passed when calling use. The function will be called
+ * with the index as its context.
+ *
+ * Example:
+ *
+ * var myPlugin = function (idx, arg1, arg2) {
+ * // `this` is the index to be extended
+ * // apply any extensions etc here.
+ * }
+ *
+ * var idx = lunr(function () {
+ * this.use(myPlugin, 'arg1', 'arg2')
+ * })
+ *
+ * @param {Function} plugin The plugin to apply.
+ * @memberOf Index
+ */
+lunr.Index.prototype.use = function (plugin) {
+ var args = Array.prototype.slice.call(arguments, 1)
+ args.unshift(this)
+ plugin.apply(this, args)
+}
+/*!
+ * lunr.Store
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * lunr.Store is a simple key-value store used for storing sets of tokens for
+ * documents stored in index.
+ *
+ * @constructor
+ * @module
+ */
+lunr.Store = function () {
+ this.store = {}
+ this.length = 0
+}
+
+/**
+ * Loads a previously serialised store
+ *
+ * @param {Object} serialisedData The serialised store to load.
+ * @returns {lunr.Store}
+ * @memberOf Store
+ */
+lunr.Store.load = function (serialisedData) {
+ var store = new this
+
+ store.length = serialisedData.length
+ store.store = Object.keys(serialisedData.store).reduce(function (memo, key) {
+ memo[key] = lunr.SortedSet.load(serialisedData.store[key])
+ return memo
+ }, {})
+
+ return store
+}
+
+/**
+ * Stores the given tokens in the store against the given id.
+ *
+ * @param {Object} id The key used to store the tokens against.
+ * @param {Object} tokens The tokens to store against the key.
+ * @memberOf Store
+ */
+lunr.Store.prototype.set = function (id, tokens) {
+ if (!this.has(id)) this.length++
+ this.store[id] = tokens
+}
+
+/**
+ * Retrieves the tokens from the store for a given key.
+ *
+ * @param {Object} id The key to lookup and retrieve from the store.
+ * @returns {Object}
+ * @memberOf Store
+ */
+lunr.Store.prototype.get = function (id) {
+ return this.store[id]
+}
+
+/**
+ * Checks whether the store contains a key.
+ *
+ * @param {Object} id The id to look up in the store.
+ * @returns {Boolean}
+ * @memberOf Store
+ */
+lunr.Store.prototype.has = function (id) {
+ return id in this.store
+}
+
+/**
+ * Removes the value for a key in the store.
+ *
+ * @param {Object} id The id to remove from the store.
+ * @memberOf Store
+ */
+lunr.Store.prototype.remove = function (id) {
+ if (!this.has(id)) return
+
+ delete this.store[id]
+ this.length--
+}
+
+/**
+ * Returns a representation of the store ready for serialisation.
+ *
+ * @returns {Object}
+ * @memberOf Store
+ */
+lunr.Store.prototype.toJSON = function () {
+ return {
+ store: this.store,
+ length: this.length
+ }
+}
+
+/*!
+ * lunr.stemmer
+ * Copyright (C) 2014 Oliver Nightingale
+ * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt
+ */
+
+/**
+ * lunr.stemmer is an english language stemmer, this is a JavaScript
+ * implementation of the PorterStemmer taken from http://tartaurs.org/~martin
+ *
+ * @module
+ * @param {String} str The string to stem
+ * @returns {String}
+ * @see lunr.Pipeline
+ */
+lunr.stemmer = (function(){
+ var step2list = {
+ "ational" : "ate",
+ "tional" : "tion",
+ "enci" : "ence",
+ "anci" : "ance",
+ "izer" : "ize",
+ "bli" : "ble",
+ "alli" : "al",
+ "entli" : "ent",
+ "eli" : "e",
+ "ousli" : "ous",
+ "ization" : "ize",
+ "ation" : "ate",
+ "ator" : "ate",
+ "alism" : "al",
+ "iveness" : "ive",
+ "fulness" : "ful",
+ "ousness" : "ous",
+ "aliti" : "al",
+ "iviti" : "ive",
+ "biliti" : "ble",
+ "logi" : "log"
+ },
+
+ step3list = {
+ "icate" : "ic",
+ "ative" : "",
+ "alize" : "al",
+ "iciti" : "ic",
+ "ical" : "ic",
+ "ful" : "",
+ "ness" : ""
+ },
+
+ c = "[^aeiou]", // consonant
+ v = "[aeiouy]", // vowel
+ C = c + "[^aeiouy]*", // consonant sequence
+ V = v + "[aeiou]*", // vowel sequence
+
+ mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0
+ meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1
+ mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1
+ s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ var re_mgr0 = new RegExp(mgr0);
+ var re_mgr1 = new RegExp(mgr1);
+ var re_meq1 = new RegExp(meq1);
+ var re_s_v = new RegExp(s_v);
+
+ var re_1a = /^(.+?)(ss|i)es$/;
+ var re2_1a = /^(.+?)([^s])s$/;
+ var re_1b = /^(.+?)eed$/;
+ var re2_1b = /^(.+?)(ed|ing)$/;
+ var re_1b_2 = /.$/;
+ var re2_1b_2 = /(at|bl|iz)$/;
+ var re3_1b_2 = new RegExp("([^aeiouylsz])\\1$");
+ var re4_1b_2 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+
+ var re_1c = /^(.+?[^aeiou])y$/;
+ var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+
+ var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+
+ var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ var re2_4 = /^(.+?)(s|t)(ion)$/;
+
+ var re_5 = /^(.+?)e$/;
+ var re_5_1 = /ll$/;
+ var re3_5 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+
+ var porterStemmer = function porterStemmer(w) {
+ var stem,
+ suffix,
+ firstch,
+ re,
+ re2,
+ re3,
+ re4;
+
+ if (w.length < 3) { return w; }
+
+ firstch = w.substr(0,1);
+ if (firstch == "y") {
+ w = firstch.toUpperCase() + w.substr(1);
+ }
+
+ // Step 1a
+ re = re_1a
+ re2 = re2_1a;
+
+ if (re.test(w)) { w = w.replace(re,"$1$2"); }
+ else if (re2.test(w)) { w = w.replace(re2,"$1$2"); }
+
+ // Step 1b
+ re = re_1b;
+ re2 = re2_1b;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = re_mgr0;
+ if (re.test(fp[1])) {
+ re = re_1b_2;
+ w = w.replace(re,"");
+ }
+ } else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = re_s_v;
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = re2_1b_2;
+ re3 = re3_1b_2;
+ re4 = re4_1b_2;
+ if (re2.test(w)) { w = w + "e"; }
+ else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,""); }
+ else if (re4.test(w)) { w = w + "e"; }
+ }
+ }
+
+ // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)
+ re = re_1c;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = re_2;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = re_mgr0;
+ if (re.test(stem)) {
+ w = stem + step2list[suffix];
+ }
+ }
+
+ // Step 3
+ re = re_3;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = re_mgr0;
+ if (re.test(stem)) {
+ w = stem + step3list[suffix];
+ }
+ }
+
+ // Step 4
+ re = re_4;
+ re2 = re2_4;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = re_mgr1;
+ if (re.test(stem)) {
+ w = stem;
+ }
+ } else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = re_mgr1;
+ if (re2.test(stem)) {
+ w = stem;
+ }
+ }
+
+ // Step 5
+ re = re_5;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = re_mgr1;
+ re2 = re_meq1;
+ re3 = re3_5;
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {
+ w = stem;
+ }
+ }
+
+ re = re_5_1;
+ re2 = re_mgr1;
+ if (re.test(w) && re2.test(w)) {
+ re = re_1b_2;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+
+ if (firstch == "y") {
+ w = firstch.toLowerCase() + w.substr(1);
+ }
+
+ return w;
+ };
+
+ return porterStemmer;
+})();
+
+lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')
+/*!
+ * lunr.stopWordFilter
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * lunr.stopWordFilter is an English language stop word list filter, any words
+ * contained in the list will not be passed through the filter.
+ *
+ * This is intended to be used in the Pipeline. If the token does not pass the
+ * filter then undefined will be returned.
+ *
+ * @module
+ * @param {String} token The token to pass through the filter
+ * @returns {String}
+ * @see lunr.Pipeline
+ */
+lunr.stopWordFilter = function (token) {
+ if (lunr.stopWordFilter.stopWords.indexOf(token) === -1) return token
+}
+
+lunr.stopWordFilter.stopWords = new lunr.SortedSet
+lunr.stopWordFilter.stopWords.length = 119
+lunr.stopWordFilter.stopWords.elements = [
+ "",
+ "a",
+ "able",
+ "about",
+ "across",
+ "after",
+ "all",
+ "almost",
+ "also",
+ "am",
+ "among",
+ "an",
+ "and",
+ "any",
+ "are",
+ "as",
+ "at",
+ "be",
+ "because",
+ "been",
+ "but",
+ "by",
+ "can",
+ "cannot",
+ "could",
+ "dear",
+ "did",
+ "do",
+ "does",
+ "either",
+ "else",
+ "ever",
+ "every",
+ "for",
+ "from",
+ "get",
+ "got",
+ "had",
+ "has",
+ "have",
+ "he",
+ "her",
+ "hers",
+ "him",
+ "his",
+ "how",
+ "however",
+ "i",
+ "if",
+ "in",
+ "into",
+ "is",
+ "it",
+ "its",
+ "just",
+ "least",
+ "let",
+ "like",
+ "likely",
+ "may",
+ "me",
+ "might",
+ "most",
+ "must",
+ "my",
+ "neither",
+ "no",
+ "nor",
+ "not",
+ "of",
+ "off",
+ "often",
+ "on",
+ "only",
+ "or",
+ "other",
+ "our",
+ "own",
+ "rather",
+ "said",
+ "say",
+ "says",
+ "she",
+ "should",
+ "since",
+ "so",
+ "some",
+ "than",
+ "that",
+ "the",
+ "their",
+ "them",
+ "then",
+ "there",
+ "these",
+ "they",
+ "this",
+ "tis",
+ "to",
+ "too",
+ "twas",
+ "us",
+ "wants",
+ "was",
+ "we",
+ "were",
+ "what",
+ "when",
+ "where",
+ "which",
+ "while",
+ "who",
+ "whom",
+ "why",
+ "will",
+ "with",
+ "would",
+ "yet",
+ "you",
+ "your"
+]
+
+lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')
+/*!
+ * lunr.trimmer
+ * Copyright (C) 2014 Oliver Nightingale
+ */
+
+/**
+ * lunr.trimmer is a pipeline function for trimming non word
+ * characters from the begining and end of tokens before they
+ * enter the index.
+ *
+ * This implementation may not work correctly for non latin
+ * characters and should either be removed or adapted for use
+ * with languages with non-latin characters.
+ *
+ * @module
+ * @param {String} token The token to pass through the filter
+ * @returns {String}
+ * @see lunr.Pipeline
+ */
+lunr.trimmer = function (token) {
+ return token
+ .replace(/^\W+/, '')
+ .replace(/\W+$/, '')
+}
+
+lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')
+/*!
+ * lunr.stemmer
+ * Copyright (C) 2014 Oliver Nightingale
+ * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt
+ */
+
+/**
+ * lunr.TokenStore is used for efficient storing and lookup of the reverse
+ * index of token to document ref.
+ *
+ * @constructor
+ */
+lunr.TokenStore = function () {
+ this.root = { docs: {} }
+ this.length = 0
+}
+
+/**
+ * Loads a previously serialised token store
+ *
+ * @param {Object} serialisedData The serialised token store to load.
+ * @returns {lunr.TokenStore}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.load = function (serialisedData) {
+ var store = new this
+
+ store.root = serialisedData.root
+ store.length = serialisedData.length
+
+ return store
+}
+
+/**
+ * Adds a new token doc pair to the store.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to store the doc under
+ * @param {Object} doc The doc to store against the token
+ * @param {Object} root An optional node at which to start looking for the
+ * correct place to enter the doc, by default the root of this lunr.TokenStore
+ * is used.
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.add = function (token, doc, root) {
+ var root = root || this.root,
+ key = token[0],
+ rest = token.slice(1)
+
+ if (!(key in root)) root[key] = {docs: {}}
+
+ if (rest.length === 0) {
+ root[key].docs[doc.ref] = doc
+ this.length += 1
+ return
+ } else {
+ return this.add(rest, doc, root[key])
+ }
+}
+
+/**
+ * Checks whether this key is contained within this lunr.TokenStore.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to check for
+ * @param {Object} root An optional node at which to start
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.has = function (token) {
+ if (!token) return false
+
+ var node = this.root
+
+ for (var i = 0; i < token.length; i++) {
+ if (!node[token[i]]) return false
+
+ node = node[token[i]]
+ }
+
+ return true
+}
+
+/**
+ * Retrieve a node from the token store for a given token.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to get the node for.
+ * @param {Object} root An optional node at which to start.
+ * @returns {Object}
+ * @see TokenStore.prototype.get
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.getNode = function (token) {
+ if (!token) return {}
+
+ var node = this.root
+
+ for (var i = 0; i < token.length; i++) {
+ if (!node[token[i]]) return {}
+
+ node = node[token[i]]
+ }
+
+ return node
+}
+
+/**
+ * Retrieve the documents for a node for the given token.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to get the documents for.
+ * @param {Object} root An optional node at which to start.
+ * @returns {Object}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.get = function (token, root) {
+ return this.getNode(token, root).docs || {}
+}
+
+lunr.TokenStore.prototype.count = function (token, root) {
+ return Object.keys(this.get(token, root)).length
+}
+
+/**
+ * Remove the document identified by ref from the token in the store.
+ *
+ * By default this function starts at the root of the current store, however
+ * it can start at any node of any token store if required.
+ *
+ * @param {String} token The token to get the documents for.
+ * @param {String} ref The ref of the document to remove from this token.
+ * @param {Object} root An optional node at which to start.
+ * @returns {Object}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.remove = function (token, ref) {
+ if (!token) return
+ var node = this.root
+
+ for (var i = 0; i < token.length; i++) {
+ if (!(token[i] in node)) return
+ node = node[token[i]]
+ }
+
+ delete node.docs[ref]
+}
+
+/**
+ * Find all the possible suffixes of the passed token using tokens
+ * currently in the store.
+ *
+ * @param {String} token The token to expand.
+ * @returns {Array}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.expand = function (token, memo) {
+ var root = this.getNode(token),
+ docs = root.docs || {},
+ memo = memo || []
+
+ if (Object.keys(docs).length) memo.push(token)
+
+ Object.keys(root)
+ .forEach(function (key) {
+ if (key === 'docs') return
+
+ memo.concat(this.expand(token + key, memo))
+ }, this)
+
+ return memo
+}
+
+/**
+ * Returns a representation of the token store ready for serialisation.
+ *
+ * @returns {Object}
+ * @memberOf TokenStore
+ */
+lunr.TokenStore.prototype.toJSON = function () {
+ return {
+ root: this.root,
+ length: this.length
+ }
+}
+
+
+ /**
+ * export the module via AMD, CommonJS or as a browser global
+ * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js
+ */
+ ;(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory)
+ } else if (typeof exports === 'object') {
+ /**
+ * Node. Does not work with strict CommonJS, but
+ * only CommonJS-like enviroments that support module.exports,
+ * like Node.
+ */
+ module.exports = factory()
+ } else {
+ // Browser globals (root is window)
+ root.lunr = factory()
+ }
+ }(this, function () {
+ /**
+ * Just return a value to define the module export.
+ * This example returns an object, but the module
+ * can return a function as the exported value.
+ */
+ return lunr
+ }))
+})()
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/galaxy/galaxy-central/commits/19079eea7d22/
Changeset: 19079eea7d22
User: dannon
Date: 2015-02-05 13:32:25+00:00
Summary: Add require, TODO for where to integrate lunr.
Affected #: 3 files
diff -r 9eeb924b5204ff10bac0998612549de468f9bc2a -r 19079eea7d2285d701866b0df77beeff20a677e8 client/galaxy/scripts/mvc/tools.js
--- a/client/galaxy/scripts/mvc/tools.js
+++ b/client/galaxy/scripts/mvc/tools.js
@@ -2,7 +2,7 @@
* Model, view, and controller objects for Galaxy tools and tool panel.
*/
- define( ["libs/underscore", "viz/trackster/util", "mvc/data" ],
+ define( ["libs/underscore", "viz/trackster/util", "mvc/data", "libs/lunr.js" ],
function(_, util, data) {
/**
@@ -14,7 +14,7 @@
show: function() {
this.set("hidden", false);
},
-
+
hide: function() {
this.set("hidden", true);
},
@@ -22,7 +22,7 @@
toggle: function() {
this.set("hidden", !this.get("hidden"));
},
-
+
is_visible: function() {
return !this.attributes.hidden;
}
@@ -88,7 +88,7 @@
}
});
-/**
+/**
* A select tool parameter.
*/
var SelectToolParameter = ToolParameter.extend({
@@ -157,7 +157,7 @@
});
tool.get('inputs').remove(incompatible_inputs);
},
-
+
/**
* Returns object copy, optionally including only inputs that can be sampled.
*/
@@ -177,12 +177,12 @@
return copy;
},
-
+
apply_search_results: function(results) {
( _.indexOf(results, this.attributes.id) !== -1 ? this.show() : this.hide() );
return this.is_visible();
},
-
+
/**
* Set a tool input's value.
*/
@@ -191,24 +191,24 @@
return input.get('name') === name;
}).set('value', value);
},
-
+
/**
* Set many input values at once.
*/
set_input_values: function(inputs_dict) {
var self = this;
_.each(_.keys(inputs_dict), function(input_name) {
- self.set_input_value(input_name, inputs_dict[input_name]);
+ self.set_input_value(input_name, inputs_dict[input_name]);
});
},
-
+
/**
* Run tool; returns a Deferred that resolves to the tool's output(s).
*/
run: function() {
return this._run();
},
-
+
/**
* Rerun tool using regions and a target dataset.
*/
@@ -230,7 +230,7 @@
});
return input_dict;
},
-
+
/**
* Run tool; returns a Deferred that resolves to the tool's output(s).
* NOTE: this method is a helper method and should not be called directly.
@@ -259,7 +259,7 @@
return response !== "pending";
}
});
-
+
// Run job and resolve run_deferred to tool outputs.
$.when(ss_deferred.go()).then(function(result) {
run_deferred.resolve(new data.DatasetCollection().reset(result));
@@ -296,20 +296,20 @@
elems: [],
open: false
},
-
+
clear_search_results: function() {
_.each(this.attributes.elems, function(elt) {
elt.show();
});
-
+
this.show();
this.set("open", false);
},
-
+
apply_search_results: function(results) {
var all_hidden = true,
cur_label;
- _.each(this.attributes.elems, function(elt) {
+ _.each(this.attributes.elems, function(elt) {
if (elt instanceof ToolSectionLabel) {
cur_label = elt;
cur_label.hide();
@@ -323,7 +323,7 @@
}
}
});
-
+
if (all_hidden) {
this.hide();
}
@@ -340,6 +340,11 @@
* indicates that query was not run; if not null, results are from search using
* query.
*/
+
+/**
+ * TODO: Integrate lunr search here with tools from API instead of making
+ * repeated requests.
+ */
var ToolSearch = Backbone.Model.extend({
defaults: {
search_hint_string: "search tools",
@@ -353,23 +358,23 @@
// ESC (27) will clear the input field and tool search filters
clear_key: 27
},
-
+
initialize: function() {
this.on("change:query", this.do_search);
},
-
+
/**
* Do the search and update the results.
*/
do_search: function() {
var query = this.attributes.query;
-
+
// If query is too short, do not search.
if (query.length < this.attributes.min_chars_for_search) {
this.set("results", null);
return;
}
-
+
// Do search via AJAX.
var q = query + '*';
// Stop previous ajax-request
@@ -388,12 +393,12 @@
}, "json" );
}, 200 );
},
-
+
clear_search: function() {
this.set("query", "");
this.set("results", null);
}
-
+
});
_.extend(ToolSearch.prototype, VisibilityMixin);
@@ -433,7 +438,7 @@
return new ToolSectionLabel(elt_dict);
}
};
-
+
return _.map(response, parse_elt);
},
@@ -448,14 +453,14 @@
}
});
},
-
+
apply_search_results: function() {
var results = this.get('tool_search').get('results');
if (results === null) {
this.clear_search_results();
return;
}
-
+
var cur_label = null;
this.get('layout').each(function(panel_elt) {
if (panel_elt instanceof ToolSectionLabel) {
@@ -479,13 +484,13 @@
});
/**
- * View classes for Galaxy tools and tool panel.
- *
+ * View classes for Galaxy tools and tool panel.
+ *
* Views use precompiled Handlebars templates for rendering. Views update as needed
* based on (a) model/collection events and (b) user interactions; in this sense,
* they are controllers are well and the HTML is the real view in the MVC architecture.
*/
-
+
/**
* Base view that handles visibility based on model's hidden attribute.
*/
@@ -496,9 +501,9 @@
},
update_visible: function() {
( this.model.attributes.hidden ? this.$el.hide() : this.$el.show() );
- }
+ }
});
-
+
/**
* Link to a tool.
*/
@@ -509,7 +514,7 @@
// create element
var $link = $('<div/>');
$link.append(Handlebars.templates.tool_link(this.model.toJSON()));
-
+
// open upload dialog for upload tool
if (this.model.id === 'upload1') {
$link.find('a').on('click', function(e) {
@@ -517,7 +522,7 @@
Galaxy.upload.show();
});
}
-
+
// add element
this.$el.append($link);
return this;
@@ -543,7 +548,7 @@
var ToolSectionView = BaseView.extend({
tagName: 'div',
className: 'toolSectionWrapper',
-
+
initialize: function() {
BaseView.prototype.initialize.call(this);
this.model.on("change:open", this.update_open, this);
@@ -552,7 +557,7 @@
render: function() {
// Build using template.
this.$el.append( Handlebars.templates.panel_section(this.model.toJSON()) );
-
+
// Add tools to section.
var section_body = this.$el.find(".toolSectionBody");
_.each(this.model.attributes.elems, function(elt) {
@@ -572,25 +577,25 @@
});
return this;
},
-
+
events: {
'click .toolSectionTitle > a': 'toggle'
},
-
- /**
+
+ /**
* Toggle visibility of tool section.
*/
toggle: function() {
this.model.set("open", !this.model.attributes.open);
},
-
+
/**
* Update whether section is open or close.
*/
update_open: function() {
(this.model.attributes.open ?
this.$el.children(".toolSectionBody").slideDown("fast") :
- this.$el.children(".toolSectionBody").slideUp("fast")
+ this.$el.children(".toolSectionBody").slideUp("fast")
);
}
});
@@ -599,13 +604,13 @@
tagName: 'div',
id: 'tool-search',
className: 'bar',
-
+
events: {
'click': 'focus_and_select',
'keyup :input': 'query_changed',
'click #search-clear-btn': 'clear'
},
-
+
render: function() {
this.$el.append( Handlebars.templates.tool_search(this.model.toJSON()) );
if (!this.model.is_visible()) {
@@ -614,18 +619,18 @@
this.$el.find('[title]').tooltip();
return this;
},
-
+
focus_and_select: function() {
this.$el.find(":input").focus().select();
},
-
+
clear: function() {
this.model.clear_search();
this.$el.find(":input").val(this.model.attributes.search_hint_string);
this.focus_and_select();
return false;
},
-
+
query_changed: function( evData ) {
// check for the 'clear key' (ESC) first
if( ( this.model.attributes.clear_key ) &&
@@ -644,22 +649,22 @@
var ToolPanelView = Backbone.View.extend({
tagName: 'div',
className: 'toolMenu',
-
+
/**
* Set up view.
*/
initialize: function() {
this.model.get('tool_search').on("change:results", this.handle_search_results, this);
},
-
+
render: function() {
var self = this;
-
+
// Render search.
var search_view = new ToolSearchView( { model: this.model.get('tool_search') } );
search_view.render();
self.$el.append(search_view.$el);
-
+
// Render panel.
this.model.get('layout').each(function(panel_elt) {
if (panel_elt instanceof ToolSection) {
@@ -678,20 +683,20 @@
self.$el.append(label_view.$el);
}
});
-
+
// Setup tool link click eventing.
self.$el.find("a.tool-link").click(function(e) {
// Tool id is always the first class.
- var
+ var
tool_id = $(this).attr('class').split(/\s+/)[0],
tool = self.model.get('tools').get(tool_id);
-
+
self.trigger("tool_link_click", e, tool);
});
-
+
return this;
},
-
+
handle_search_results: function() {
var results = this.model.get('tool_search').get('results');
if (results && results.length === 0) {
@@ -708,7 +713,7 @@
*/
var ToolFormView = Backbone.View.extend({
className: 'toolForm',
-
+
render: function() {
this.$el.children().remove();
this.$el.append( Handlebars.templates.tool_form(this.model.toJSON()) );
@@ -720,22 +725,22 @@
*/
var IntegratedToolMenuAndView = Backbone.View.extend({
className: 'toolMenuAndView',
-
+
initialize: function() {
this.tool_panel_view = new ToolPanelView({collection: this.collection});
this.tool_form_view = new ToolFormView();
},
-
+
render: function() {
// Render and append tool panel.
this.tool_panel_view.render();
this.tool_panel_view.$el.css("float", "left");
this.$el.append(this.tool_panel_view.$el);
-
+
// Append tool form view.
this.tool_form_view.$el.hide();
this.$el.append(this.tool_form_view.$el);
-
+
// On tool link click, show tool.
var self = this;
this.tool_panel_view.on("tool_link_click", function(e, tool) {
@@ -745,7 +750,7 @@
self.show_tool(tool);
});
},
-
+
/**
* Fetch and display tool.
*/
diff -r 9eeb924b5204ff10bac0998612549de468f9bc2a -r 19079eea7d2285d701866b0df77beeff20a677e8 static/scripts/mvc/tools.js
--- a/static/scripts/mvc/tools.js
+++ b/static/scripts/mvc/tools.js
@@ -2,7 +2,7 @@
* Model, view, and controller objects for Galaxy tools and tool panel.
*/
- define( ["libs/underscore", "viz/trackster/util", "mvc/data" ],
+ define( ["libs/underscore", "viz/trackster/util", "mvc/data", "libs/lunr.js" ],
function(_, util, data) {
/**
@@ -14,7 +14,7 @@
show: function() {
this.set("hidden", false);
},
-
+
hide: function() {
this.set("hidden", true);
},
@@ -22,7 +22,7 @@
toggle: function() {
this.set("hidden", !this.get("hidden"));
},
-
+
is_visible: function() {
return !this.attributes.hidden;
}
@@ -88,7 +88,7 @@
}
});
-/**
+/**
* A select tool parameter.
*/
var SelectToolParameter = ToolParameter.extend({
@@ -157,7 +157,7 @@
});
tool.get('inputs').remove(incompatible_inputs);
},
-
+
/**
* Returns object copy, optionally including only inputs that can be sampled.
*/
@@ -177,12 +177,12 @@
return copy;
},
-
+
apply_search_results: function(results) {
( _.indexOf(results, this.attributes.id) !== -1 ? this.show() : this.hide() );
return this.is_visible();
},
-
+
/**
* Set a tool input's value.
*/
@@ -191,24 +191,24 @@
return input.get('name') === name;
}).set('value', value);
},
-
+
/**
* Set many input values at once.
*/
set_input_values: function(inputs_dict) {
var self = this;
_.each(_.keys(inputs_dict), function(input_name) {
- self.set_input_value(input_name, inputs_dict[input_name]);
+ self.set_input_value(input_name, inputs_dict[input_name]);
});
},
-
+
/**
* Run tool; returns a Deferred that resolves to the tool's output(s).
*/
run: function() {
return this._run();
},
-
+
/**
* Rerun tool using regions and a target dataset.
*/
@@ -230,7 +230,7 @@
});
return input_dict;
},
-
+
/**
* Run tool; returns a Deferred that resolves to the tool's output(s).
* NOTE: this method is a helper method and should not be called directly.
@@ -259,7 +259,7 @@
return response !== "pending";
}
});
-
+
// Run job and resolve run_deferred to tool outputs.
$.when(ss_deferred.go()).then(function(result) {
run_deferred.resolve(new data.DatasetCollection().reset(result));
@@ -296,20 +296,20 @@
elems: [],
open: false
},
-
+
clear_search_results: function() {
_.each(this.attributes.elems, function(elt) {
elt.show();
});
-
+
this.show();
this.set("open", false);
},
-
+
apply_search_results: function(results) {
var all_hidden = true,
cur_label;
- _.each(this.attributes.elems, function(elt) {
+ _.each(this.attributes.elems, function(elt) {
if (elt instanceof ToolSectionLabel) {
cur_label = elt;
cur_label.hide();
@@ -323,7 +323,7 @@
}
}
});
-
+
if (all_hidden) {
this.hide();
}
@@ -340,6 +340,11 @@
* indicates that query was not run; if not null, results are from search using
* query.
*/
+
+/**
+ * TODO: Integrate lunr search here with tools from API instead of making
+ * repeated requests.
+ */
var ToolSearch = Backbone.Model.extend({
defaults: {
search_hint_string: "search tools",
@@ -353,23 +358,23 @@
// ESC (27) will clear the input field and tool search filters
clear_key: 27
},
-
+
initialize: function() {
this.on("change:query", this.do_search);
},
-
+
/**
* Do the search and update the results.
*/
do_search: function() {
var query = this.attributes.query;
-
+
// If query is too short, do not search.
if (query.length < this.attributes.min_chars_for_search) {
this.set("results", null);
return;
}
-
+
// Do search via AJAX.
var q = query + '*';
// Stop previous ajax-request
@@ -388,12 +393,12 @@
}, "json" );
}, 200 );
},
-
+
clear_search: function() {
this.set("query", "");
this.set("results", null);
}
-
+
});
_.extend(ToolSearch.prototype, VisibilityMixin);
@@ -433,7 +438,7 @@
return new ToolSectionLabel(elt_dict);
}
};
-
+
return _.map(response, parse_elt);
},
@@ -448,14 +453,14 @@
}
});
},
-
+
apply_search_results: function() {
var results = this.get('tool_search').get('results');
if (results === null) {
this.clear_search_results();
return;
}
-
+
var cur_label = null;
this.get('layout').each(function(panel_elt) {
if (panel_elt instanceof ToolSectionLabel) {
@@ -479,13 +484,13 @@
});
/**
- * View classes for Galaxy tools and tool panel.
- *
+ * View classes for Galaxy tools and tool panel.
+ *
* Views use precompiled Handlebars templates for rendering. Views update as needed
* based on (a) model/collection events and (b) user interactions; in this sense,
* they are controllers are well and the HTML is the real view in the MVC architecture.
*/
-
+
/**
* Base view that handles visibility based on model's hidden attribute.
*/
@@ -496,9 +501,9 @@
},
update_visible: function() {
( this.model.attributes.hidden ? this.$el.hide() : this.$el.show() );
- }
+ }
});
-
+
/**
* Link to a tool.
*/
@@ -509,7 +514,7 @@
// create element
var $link = $('<div/>');
$link.append(Handlebars.templates.tool_link(this.model.toJSON()));
-
+
// open upload dialog for upload tool
if (this.model.id === 'upload1') {
$link.find('a').on('click', function(e) {
@@ -517,7 +522,7 @@
Galaxy.upload.show();
});
}
-
+
// add element
this.$el.append($link);
return this;
@@ -543,7 +548,7 @@
var ToolSectionView = BaseView.extend({
tagName: 'div',
className: 'toolSectionWrapper',
-
+
initialize: function() {
BaseView.prototype.initialize.call(this);
this.model.on("change:open", this.update_open, this);
@@ -552,7 +557,7 @@
render: function() {
// Build using template.
this.$el.append( Handlebars.templates.panel_section(this.model.toJSON()) );
-
+
// Add tools to section.
var section_body = this.$el.find(".toolSectionBody");
_.each(this.model.attributes.elems, function(elt) {
@@ -572,25 +577,25 @@
});
return this;
},
-
+
events: {
'click .toolSectionTitle > a': 'toggle'
},
-
- /**
+
+ /**
* Toggle visibility of tool section.
*/
toggle: function() {
this.model.set("open", !this.model.attributes.open);
},
-
+
/**
* Update whether section is open or close.
*/
update_open: function() {
(this.model.attributes.open ?
this.$el.children(".toolSectionBody").slideDown("fast") :
- this.$el.children(".toolSectionBody").slideUp("fast")
+ this.$el.children(".toolSectionBody").slideUp("fast")
);
}
});
@@ -599,13 +604,13 @@
tagName: 'div',
id: 'tool-search',
className: 'bar',
-
+
events: {
'click': 'focus_and_select',
'keyup :input': 'query_changed',
'click #search-clear-btn': 'clear'
},
-
+
render: function() {
this.$el.append( Handlebars.templates.tool_search(this.model.toJSON()) );
if (!this.model.is_visible()) {
@@ -614,18 +619,18 @@
this.$el.find('[title]').tooltip();
return this;
},
-
+
focus_and_select: function() {
this.$el.find(":input").focus().select();
},
-
+
clear: function() {
this.model.clear_search();
this.$el.find(":input").val(this.model.attributes.search_hint_string);
this.focus_and_select();
return false;
},
-
+
query_changed: function( evData ) {
// check for the 'clear key' (ESC) first
if( ( this.model.attributes.clear_key ) &&
@@ -644,22 +649,22 @@
var ToolPanelView = Backbone.View.extend({
tagName: 'div',
className: 'toolMenu',
-
+
/**
* Set up view.
*/
initialize: function() {
this.model.get('tool_search').on("change:results", this.handle_search_results, this);
},
-
+
render: function() {
var self = this;
-
+
// Render search.
var search_view = new ToolSearchView( { model: this.model.get('tool_search') } );
search_view.render();
self.$el.append(search_view.$el);
-
+
// Render panel.
this.model.get('layout').each(function(panel_elt) {
if (panel_elt instanceof ToolSection) {
@@ -678,20 +683,20 @@
self.$el.append(label_view.$el);
}
});
-
+
// Setup tool link click eventing.
self.$el.find("a.tool-link").click(function(e) {
// Tool id is always the first class.
- var
+ var
tool_id = $(this).attr('class').split(/\s+/)[0],
tool = self.model.get('tools').get(tool_id);
-
+
self.trigger("tool_link_click", e, tool);
});
-
+
return this;
},
-
+
handle_search_results: function() {
var results = this.model.get('tool_search').get('results');
if (results && results.length === 0) {
@@ -708,7 +713,7 @@
*/
var ToolFormView = Backbone.View.extend({
className: 'toolForm',
-
+
render: function() {
this.$el.children().remove();
this.$el.append( Handlebars.templates.tool_form(this.model.toJSON()) );
@@ -720,22 +725,22 @@
*/
var IntegratedToolMenuAndView = Backbone.View.extend({
className: 'toolMenuAndView',
-
+
initialize: function() {
this.tool_panel_view = new ToolPanelView({collection: this.collection});
this.tool_form_view = new ToolFormView();
},
-
+
render: function() {
// Render and append tool panel.
this.tool_panel_view.render();
this.tool_panel_view.$el.css("float", "left");
this.$el.append(this.tool_panel_view.$el);
-
+
// Append tool form view.
this.tool_form_view.$el.hide();
this.$el.append(this.tool_form_view.$el);
-
+
// On tool link click, show tool.
var self = this;
this.tool_panel_view.on("tool_link_click", function(e, tool) {
@@ -745,7 +750,7 @@
self.show_tool(tool);
});
},
-
+
/**
* Fetch and display tool.
*/
diff -r 9eeb924b5204ff10bac0998612549de468f9bc2a -r 19079eea7d2285d701866b0df77beeff20a677e8 static/scripts/packed/mvc/tools.js
--- a/static/scripts/packed/mvc/tools.js
+++ b/static/scripts/packed/mvc/tools.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","viz/trackster/util","mvc/data"],function(x,a,y){var g={hidden:false,show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},toggle:function(){this.set("hidden",!this.get("hidden"))},is_visible:function(){return !this.attributes.hidden}};var e=Backbone.Model.extend({defaults:{name:null,label:null,type:null,value:null,html:null,num_samples:5},initialize:function(z){this.attributes.html=unescape(this.attributes.html)},copy:function(){return new e(this.toJSON())},set_value:function(z){this.set("value",z||"")}});var i=Backbone.Collection.extend({model:e});var k=e.extend({});var d=e.extend({set_value:function(z){this.set("value",parseInt(z,10))},get_samples:function(){return d3.scale.linear().domain([this.get("min"),this.get("max")]).ticks(this.get("num_samples"))}});var f=d.extend({set_value:function(z){this.set("value",parseFloat(z))}});var t=e.extend({get_samples:function(){return x.map(this.get("options"),function(z){return z[0]})}});e.subModelTypes={integer:d,"float":f,data:k,select:t};var j=Backbone.Model.extend({defaults:{id:null,name:null,description:null,target:null,inputs:[],outputs:[]},urlRoot:galaxy_config.root+"api/tools",initialize:function(z){this.set("inputs",new i(x.map(z.inputs,function(A){var B=e.subModelTypes[A.type]||e;return new B(A)})))},toJSON:function(){var z=Backbone.Model.prototype.toJSON.call(this);z.inputs=this.get("inputs").map(function(A){return A.toJSON()});return z},remove_inputs:function(A){var z=this,B=z.get("inputs").filter(function(C){return(A.indexOf(C.get("type"))!==-1)});z.get("inputs").remove(B)},copy:function(A){var B=new j(this.toJSON());if(A){var z=new Backbone.Collection();B.get("inputs").each(function(C){if(C.get_samples()){z.push(C)}});B.set("inputs",z)}return B},apply_search_results:function(z){(x.indexOf(z,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()},set_input_value:function(z,A){this.get("inputs").find(function(B){return B.get("name")===z}).set("value",A)},set_input_values:function(A){var z=this;x.each(x.keys(A),function(B){z.set_input_value(B,A[B])})},run:function(){return this._run()},rerun:function(A,z){return this._run({action:"rerun",target_dataset_id:A.id,regions:z})},get_inputs_dict:function(){var z={};this.get("inputs").each(function(A){z[A.get("name")]=A.get("value")});return z},_run:function(B){var C=x.extend({tool_id:this.id,inputs:this.get_inputs_dict()},B);var A=$.Deferred(),z=new a.ServerStateDeferred({ajax_settings:{url:this.urlRoot,data:JSON.stringify(C),dataType:"json",contentType:"application/json",type:"POST"},interval:2000,success_fn:function(D){return D!=="pending"}});$.when(z.go()).then(function(D){A.resolve(new y.DatasetCollection().reset(D))});return A}});x.extend(j.prototype,g);var q=Backbone.View.extend({});var n=Backbone.Collection.extend({model:j});var v=Backbone.Model.extend(g);var l=Backbone.Model.extend({defaults:{elems:[],open:false},clear_search_results:function(){x.each(this.attributes.elems,function(z){z.show()});this.show();this.set("open",false)},apply_search_results:function(A){var B=true,z;x.each(this.attributes.elems,function(C){if(C instanceof v){z=C;z.hide()}else{if(C instanceof j){if(C.apply_search_results(A)){B=false;if(z){z.show()}}}}});if(B){this.hide()}else{this.show();this.set("open",true)}}});x.extend(l.prototype,g);var c=Backbone.Model.extend({defaults:{search_hint_string:"search tools",min_chars_for_search:3,spinner_url:"",clear_btn_url:"",search_url:"",visible:true,query:"",results:null,clear_key:27},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var B=this.attributes.query;if(B.length<this.attributes.min_chars_for_search){this.set("results",null);return}var A=B+"*";if(this.timer){clearTimeout(this.timer)}$("#search-clear-btn").hide();$("#search-spinner").show();var z=this;this.timer=setTimeout(function(){$.get(z.attributes.search_url,{query:A},function(C){z.set("results",C);$("#search-spinner").hide();$("#search-clear-btn").show()},"json")},200)},clear_search:function(){this.set("query","");this.set("results",null)}});x.extend(c.prototype,g);var o=Backbone.Model.extend({initialize:function(z){this.attributes.tool_search=z.tool_search;this.attributes.tool_search.on("change:results",this.apply_search_results,this);this.attributes.tools=z.tools;this.attributes.layout=new Backbone.Collection(this.parse(z.layout))},parse:function(A){var z=this,B=function(E){var D=E.model_class;if(D.indexOf("Tool")===D.length-4){return z.attributes.tools.get(E.id)}else{if(D==="ToolSection"){var C=x.map(E.elems,B);E.elems=C;return new l(E)}else{if(D==="ToolSectionLabel"){return new v(E)}}}};return x.map(A,B)},clear_search_results:function(){this.get("layout").each(function(z){if(z instanceof l){z.clear_search_results()}else{z.show()}})},apply_search_results:function(){var A=this.get("tool_search").get("results");if(A===null){this.clear_search_results();return}var z=null;this.get("layout").each(function(B){if(B instanceof v){z=B;z.hide()}else{if(B instanceof j){if(B.apply_search_results(A)){if(z){z.show()}}}else{z=null;B.apply_search_results(A)}}})}});var s=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){(this.model.attributes.hidden?this.$el.hide():this.$el.show())}});var m=s.extend({tagName:"div",render:function(){var z=$("<div/>");z.append(Handlebars.templates.tool_link(this.model.toJSON()));if(this.model.id==="upload1"){z.find("a").on("click",function(A){A.preventDefault();Galaxy.upload.show()})}this.$el.append(z);return this}});var b=s.extend({tagName:"div",className:"toolPanelLabel",render:function(){this.$el.append($("<span/>").text(this.model.attributes.text));return this}});var r=s.extend({tagName:"div",className:"toolSectionWrapper",initialize:function(){s.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(Handlebars.templates.panel_section(this.model.toJSON()));var z=this.$el.find(".toolSectionBody");x.each(this.model.attributes.elems,function(A){if(A instanceof j){var B=new m({model:A,className:"toolTitle"});B.render();z.append(B.$el)}else{if(A instanceof v){var C=new b({model:A});C.render();z.append(C.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var p=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",events:{click:"focus_and_select","keyup :input":"query_changed","click #search-clear-btn":"clear"},render:function(){this.$el.append(Handlebars.templates.tool_search(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}this.$el.find("[title]").tooltip();return this},focus_and_select:function(){this.$el.find(":input").focus().select()},clear:function(){this.model.clear_search();this.$el.find(":input").val(this.model.attributes.search_hint_string);this.focus_and_select();return false},query_changed:function(z){if((this.model.attributes.clear_key)&&(this.model.attributes.clear_key===z.which)){this.clear();return false}this.model.set("query",this.$el.find(":input").val())}});var w=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(){this.model.get("tool_search").on("change:results",this.handle_search_results,this)},render:function(){var z=this;var A=new p({model:this.model.get("tool_search")});A.render();z.$el.append(A.$el);this.model.get("layout").each(function(C){if(C instanceof l){var B=new r({model:C});B.render();z.$el.append(B.$el)}else{if(C instanceof j){var D=new m({model:C,className:"toolTitleNoSection"});D.render();z.$el.append(D.$el)}else{if(C instanceof v){var E=new b({model:C});E.render();z.$el.append(E.$el)}}}});z.$el.find("a.tool-link").click(function(D){var C=$(this).attr("class").split(/\s+/)[0],B=z.model.get("tools").get(C);z.trigger("tool_link_click",D,B)});return this},handle_search_results:function(){var z=this.model.get("tool_search").get("results");if(z&&z.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}});var u=Backbone.View.extend({className:"toolForm",render:function(){this.$el.children().remove();this.$el.append(Handlebars.templates.tool_form(this.model.toJSON()))}});var h=Backbone.View.extend({className:"toolMenuAndView",initialize:function(){this.tool_panel_view=new w({collection:this.collection});this.tool_form_view=new u()},render:function(){this.tool_panel_view.render();this.tool_panel_view.$el.css("float","left");this.$el.append(this.tool_panel_view.$el);this.tool_form_view.$el.hide();this.$el.append(this.tool_form_view.$el);var z=this;this.tool_panel_view.on("tool_link_click",function(B,A){B.preventDefault();z.show_tool(A)})},show_tool:function(A){var z=this;A.fetch().done(function(){z.tool_form_view.model=A;z.tool_form_view.render();z.tool_form_view.$el.show();$("#left").width("650px")})}});return{ToolParameter:e,IntegerToolParameter:d,SelectToolParameter:t,Tool:j,ToolCollection:n,ToolSearch:c,ToolPanel:o,ToolPanelView:w,ToolFormView:u}});
\ No newline at end of file
+define(["libs/underscore","viz/trackster/util","mvc/data","libs/lunr.js"],function(x,a,y){var g={hidden:false,show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},toggle:function(){this.set("hidden",!this.get("hidden"))},is_visible:function(){return !this.attributes.hidden}};var e=Backbone.Model.extend({defaults:{name:null,label:null,type:null,value:null,html:null,num_samples:5},initialize:function(z){this.attributes.html=unescape(this.attributes.html)},copy:function(){return new e(this.toJSON())},set_value:function(z){this.set("value",z||"")}});var i=Backbone.Collection.extend({model:e});var k=e.extend({});var d=e.extend({set_value:function(z){this.set("value",parseInt(z,10))},get_samples:function(){return d3.scale.linear().domain([this.get("min"),this.get("max")]).ticks(this.get("num_samples"))}});var f=d.extend({set_value:function(z){this.set("value",parseFloat(z))}});var t=e.extend({get_samples:function(){return x.map(this.get("options"),function(z){return z[0]})}});e.subModelTypes={integer:d,"float":f,data:k,select:t};var j=Backbone.Model.extend({defaults:{id:null,name:null,description:null,target:null,inputs:[],outputs:[]},urlRoot:galaxy_config.root+"api/tools",initialize:function(z){this.set("inputs",new i(x.map(z.inputs,function(A){var B=e.subModelTypes[A.type]||e;return new B(A)})))},toJSON:function(){var z=Backbone.Model.prototype.toJSON.call(this);z.inputs=this.get("inputs").map(function(A){return A.toJSON()});return z},remove_inputs:function(A){var z=this,B=z.get("inputs").filter(function(C){return(A.indexOf(C.get("type"))!==-1)});z.get("inputs").remove(B)},copy:function(A){var B=new j(this.toJSON());if(A){var z=new Backbone.Collection();B.get("inputs").each(function(C){if(C.get_samples()){z.push(C)}});B.set("inputs",z)}return B},apply_search_results:function(z){(x.indexOf(z,this.attributes.id)!==-1?this.show():this.hide());return this.is_visible()},set_input_value:function(z,A){this.get("inputs").find(function(B){return B.get("name")===z}).set("value",A)},set_input_values:function(A){var z=this;x.each(x.keys(A),function(B){z.set_input_value(B,A[B])})},run:function(){return this._run()},rerun:function(A,z){return this._run({action:"rerun",target_dataset_id:A.id,regions:z})},get_inputs_dict:function(){var z={};this.get("inputs").each(function(A){z[A.get("name")]=A.get("value")});return z},_run:function(B){var C=x.extend({tool_id:this.id,inputs:this.get_inputs_dict()},B);var A=$.Deferred(),z=new a.ServerStateDeferred({ajax_settings:{url:this.urlRoot,data:JSON.stringify(C),dataType:"json",contentType:"application/json",type:"POST"},interval:2000,success_fn:function(D){return D!=="pending"}});$.when(z.go()).then(function(D){A.resolve(new y.DatasetCollection().reset(D))});return A}});x.extend(j.prototype,g);var q=Backbone.View.extend({});var n=Backbone.Collection.extend({model:j});var v=Backbone.Model.extend(g);var l=Backbone.Model.extend({defaults:{elems:[],open:false},clear_search_results:function(){x.each(this.attributes.elems,function(z){z.show()});this.show();this.set("open",false)},apply_search_results:function(A){var B=true,z;x.each(this.attributes.elems,function(C){if(C instanceof v){z=C;z.hide()}else{if(C instanceof j){if(C.apply_search_results(A)){B=false;if(z){z.show()}}}}});if(B){this.hide()}else{this.show();this.set("open",true)}}});x.extend(l.prototype,g);var c=Backbone.Model.extend({defaults:{search_hint_string:"search tools",min_chars_for_search:3,spinner_url:"",clear_btn_url:"",search_url:"",visible:true,query:"",results:null,clear_key:27},initialize:function(){this.on("change:query",this.do_search)},do_search:function(){var B=this.attributes.query;if(B.length<this.attributes.min_chars_for_search){this.set("results",null);return}var A=B+"*";if(this.timer){clearTimeout(this.timer)}$("#search-clear-btn").hide();$("#search-spinner").show();var z=this;this.timer=setTimeout(function(){$.get(z.attributes.search_url,{query:A},function(C){z.set("results",C);$("#search-spinner").hide();$("#search-clear-btn").show()},"json")},200)},clear_search:function(){this.set("query","");this.set("results",null)}});x.extend(c.prototype,g);var o=Backbone.Model.extend({initialize:function(z){this.attributes.tool_search=z.tool_search;this.attributes.tool_search.on("change:results",this.apply_search_results,this);this.attributes.tools=z.tools;this.attributes.layout=new Backbone.Collection(this.parse(z.layout))},parse:function(A){var z=this,B=function(E){var D=E.model_class;if(D.indexOf("Tool")===D.length-4){return z.attributes.tools.get(E.id)}else{if(D==="ToolSection"){var C=x.map(E.elems,B);E.elems=C;return new l(E)}else{if(D==="ToolSectionLabel"){return new v(E)}}}};return x.map(A,B)},clear_search_results:function(){this.get("layout").each(function(z){if(z instanceof l){z.clear_search_results()}else{z.show()}})},apply_search_results:function(){var A=this.get("tool_search").get("results");if(A===null){this.clear_search_results();return}var z=null;this.get("layout").each(function(B){if(B instanceof v){z=B;z.hide()}else{if(B instanceof j){if(B.apply_search_results(A)){if(z){z.show()}}}else{z=null;B.apply_search_results(A)}}})}});var s=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){(this.model.attributes.hidden?this.$el.hide():this.$el.show())}});var m=s.extend({tagName:"div",render:function(){var z=$("<div/>");z.append(Handlebars.templates.tool_link(this.model.toJSON()));if(this.model.id==="upload1"){z.find("a").on("click",function(A){A.preventDefault();Galaxy.upload.show()})}this.$el.append(z);return this}});var b=s.extend({tagName:"div",className:"toolPanelLabel",render:function(){this.$el.append($("<span/>").text(this.model.attributes.text));return this}});var r=s.extend({tagName:"div",className:"toolSectionWrapper",initialize:function(){s.prototype.initialize.call(this);this.model.on("change:open",this.update_open,this)},render:function(){this.$el.append(Handlebars.templates.panel_section(this.model.toJSON()));var z=this.$el.find(".toolSectionBody");x.each(this.model.attributes.elems,function(A){if(A instanceof j){var B=new m({model:A,className:"toolTitle"});B.render();z.append(B.$el)}else{if(A instanceof v){var C=new b({model:A});C.render();z.append(C.$el)}else{}}});return this},events:{"click .toolSectionTitle > a":"toggle"},toggle:function(){this.model.set("open",!this.model.attributes.open)},update_open:function(){(this.model.attributes.open?this.$el.children(".toolSectionBody").slideDown("fast"):this.$el.children(".toolSectionBody").slideUp("fast"))}});var p=Backbone.View.extend({tagName:"div",id:"tool-search",className:"bar",events:{click:"focus_and_select","keyup :input":"query_changed","click #search-clear-btn":"clear"},render:function(){this.$el.append(Handlebars.templates.tool_search(this.model.toJSON()));if(!this.model.is_visible()){this.$el.hide()}this.$el.find("[title]").tooltip();return this},focus_and_select:function(){this.$el.find(":input").focus().select()},clear:function(){this.model.clear_search();this.$el.find(":input").val(this.model.attributes.search_hint_string);this.focus_and_select();return false},query_changed:function(z){if((this.model.attributes.clear_key)&&(this.model.attributes.clear_key===z.which)){this.clear();return false}this.model.set("query",this.$el.find(":input").val())}});var w=Backbone.View.extend({tagName:"div",className:"toolMenu",initialize:function(){this.model.get("tool_search").on("change:results",this.handle_search_results,this)},render:function(){var z=this;var A=new p({model:this.model.get("tool_search")});A.render();z.$el.append(A.$el);this.model.get("layout").each(function(C){if(C instanceof l){var B=new r({model:C});B.render();z.$el.append(B.$el)}else{if(C instanceof j){var D=new m({model:C,className:"toolTitleNoSection"});D.render();z.$el.append(D.$el)}else{if(C instanceof v){var E=new b({model:C});E.render();z.$el.append(E.$el)}}}});z.$el.find("a.tool-link").click(function(D){var C=$(this).attr("class").split(/\s+/)[0],B=z.model.get("tools").get(C);z.trigger("tool_link_click",D,B)});return this},handle_search_results:function(){var z=this.model.get("tool_search").get("results");if(z&&z.length===0){$("#search-no-results").show()}else{$("#search-no-results").hide()}}});var u=Backbone.View.extend({className:"toolForm",render:function(){this.$el.children().remove();this.$el.append(Handlebars.templates.tool_form(this.model.toJSON()))}});var h=Backbone.View.extend({className:"toolMenuAndView",initialize:function(){this.tool_panel_view=new w({collection:this.collection});this.tool_form_view=new u()},render:function(){this.tool_panel_view.render();this.tool_panel_view.$el.css("float","left");this.$el.append(this.tool_panel_view.$el);this.tool_form_view.$el.hide();this.$el.append(this.tool_form_view.$el);var z=this;this.tool_panel_view.on("tool_link_click",function(B,A){B.preventDefault();z.show_tool(A)})},show_tool:function(A){var z=this;A.fetch().done(function(){z.tool_form_view.model=A;z.tool_form_view.render();z.tool_form_view.$el.show();$("#left").width("650px")})}});return{ToolParameter:e,IntegerToolParameter:d,SelectToolParameter:t,Tool:j,ToolCollection:n,ToolSearch:c,ToolPanel:o,ToolPanelView:w,ToolFormView:u}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Minor bug fixes for main.py (webless Galaxy entry point).
by commits-noreply@bitbucket.org 04 Feb '15
by commits-noreply@bitbucket.org 04 Feb '15
04 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/85b1de6a6ebd/
Changeset: 85b1de6a6ebd
User: natefoo
Date: 2015-02-05 04:40:59+00:00
Summary: Minor bug fixes for main.py (webless Galaxy entry point).
Affected #: 1 file
diff -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 -r 85b1de6a6ebdfe30e14b96f8dc7d13105ae04c2b lib/galaxy/main.py
--- a/lib/galaxy/main.py
+++ b/lib/galaxy/main.py
@@ -36,7 +36,7 @@
# Vaguely Python 2.6 compatibile ArgumentParser import
try:
- from argparser import ArgumentParser
+ from argparse import ArgumentParser
except ImportError:
from optparse import OptionParser
@@ -202,9 +202,6 @@
def main():
- if Daemonize is None:
- raise ImportError(REQUIRES_DAEMONIZE_MESSAGE)
-
arg_parser = ArgumentParser(description=DESCRIPTION)
GalaxyConfigBuilder.populate_options(arg_parser)
args = arg_parser.parse_args()
@@ -217,6 +214,9 @@
log.setLevel(logging.DEBUG)
log.propagate = False
if args.daemonize:
+ if Daemonize is None:
+ raise ImportError(REQUIRES_DAEMONIZE_MESSAGE)
+
keep_fds = []
if args.daemon_log_file:
fh = logging.FileHandler(args.daemon_log_file, "w")
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Allow reloading External Display applications without restarting Galaxy.
by commits-noreply@bitbucket.org 04 Feb '15
by commits-noreply@bitbucket.org 04 Feb '15
04 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/00f4c600b89f/
Changeset: 00f4c600b89f
User: dan
Date: 2015-02-04 21:12:03+00:00
Summary: Allow reloading External Display applications without restarting Galaxy.
Affected #: 5 files
diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 lib/galaxy/datatypes/display_applications/application.py
--- a/lib/galaxy/datatypes/display_applications/application.py
+++ b/lib/galaxy/datatypes/display_applications/application.py
@@ -167,23 +167,21 @@
class DisplayApplication( object ):
@classmethod
def from_file( cls, filename, datatypes_registry ):
- return cls.from_elem( parse_xml( filename ).getroot(), datatypes_registry )
+ return cls.from_elem( parse_xml( filename ).getroot(), datatypes_registry, filename=filename )
@classmethod
- def from_elem( cls, elem, datatypes_registry ):
+ def from_elem( cls, elem, datatypes_registry, filename=None ):
+ att_dict = cls._get_attributes_from_elem( elem )
+ rval = DisplayApplication( att_dict['id'], att_dict['name'], datatypes_registry, att_dict['version'], filename=filename, elem=elem )
+ rval._load_links_from_elem( elem )
+ return rval
+ @classmethod
+ def _get_attributes_from_elem( cls, elem ):
display_id = elem.get( 'id', None )
assert display_id, "ID tag is required for a Display Application"
name = elem.get( 'name', display_id )
version = elem.get( 'version', None )
- rval = DisplayApplication( display_id, name, datatypes_registry, version )
- for link_elem in elem.findall( 'link' ):
- link = DisplayApplicationLink.from_elem( link_elem, rval )
- if link:
- rval.links[ link.id ] = link
- for dynamic_links in elem.findall( 'dynamic_links' ):
- for link in DynamicDisplayApplicationBuilder( dynamic_links, rval, datatypes_registry.build_sites ):
- rval.links[ link.id ] = link
- return rval
- def __init__( self, display_id, name, datatypes_registry, version = None ):
+ return dict( id=display_id, name=name, version=version )
+ def __init__( self, display_id, name, datatypes_registry, version = None, filename=None, elem=None ):
self.id = display_id
self.name = name
self.datatypes_registry = datatypes_registry
@@ -191,6 +189,16 @@
version = "1.0.0"
self.version = version
self.links = odict()
+ self._filename = filename
+ self._elem = elem
+ def _load_links_from_elem( self, elem ):
+ for link_elem in elem.findall( 'link' ):
+ link = DisplayApplicationLink.from_elem( link_elem, self )
+ if link:
+ self.links[ link.id ] = link
+ for dynamic_links in elem.findall( 'dynamic_links' ):
+ for link in DynamicDisplayApplicationBuilder( dynamic_links, self, self.datatypes_registry.build_sites ):
+ self.links[ link.id ] = link
def get_link( self, link_name, data, dataset_hash, user_hash, trans, app_kwds ):
#returns a link object with data knowledge to generate links
return PopulatedDisplayApplicationLink( self.links[ link_name ], data, dataset_hash, user_hash, trans, app_kwds )
@@ -200,3 +208,23 @@
if link_value.filter_by_dataset( data, trans ):
filtered.links[link_name] = link_value
return filtered
+ def reload( self ):
+ if self._filename:
+ elem = parse_xml( self._filename ).getroot()
+ elif self._elem:
+ elem = self._elem
+ else:
+ raise Exception( "Unable to reload DisplayApplication %s." % ( self.name ) )
+ # All toolshed-specific attributes added by e.g the registry will remain
+ attr_dict = self._get_attributes_from_elem( elem )
+ # We will not allow changing the id at this time (we'll need to fix several mappings upstream to handle this case)
+ assert attr_dict.get( 'id' ) == self.id, ValueError( "You cannot reload a Display application where the ID has changed. You will need to restart the server instead." )
+ # clear old links
+ for key in self.links.keys():
+ del self.links[key]
+ # Set new attributes
+ for key, value in attr_dict.iteritems():
+ setattr( self, key, value )
+ # Load new links
+ self._load_links_from_elem( elem )
+ return self
diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 lib/galaxy/datatypes/registry.py
--- a/lib/galaxy/datatypes/registry.py
+++ b/lib/galaxy/datatypes/registry.py
@@ -621,6 +621,26 @@
self.log.debug( "Adding inherited display application '%s' to datatype '%s'" % ( display_app.id, extension ) )
d_type1.add_display_application( display_app )
+ def reload_display_applications( self, display_application_ids=None ):
+ """
+ Reloads display applications: by id, or all if no ids provided
+ Returns tuple( [reloaded_ids], [failed_ids] )
+ """
+ if not display_application_ids:
+ display_application_ids = self.display_applications.keys()
+ elif not isinstance( display_application_ids, list ):
+ display_application_ids = [ display_application_ids ]
+ reloaded = []
+ failed = []
+ for display_application_id in display_application_ids:
+ try:
+ self.display_applications[ display_application_id ].reload()
+ reloaded.append( display_application_id )
+ except Exception, e:
+ self.log.debug( 'Requested to reload display application "%s", but failed: %s.', display_application_id, e )
+ failed.append( display_application_id )
+ return ( reloaded, failed )
+
def load_external_metadata_tool( self, toolbox ):
"""Adds a tool which is used to set external metadata"""
# We need to be able to add a job to the queue to set metadata. The queue will currently only accept jobs with an associated
diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 lib/galaxy/webapps/galaxy/controllers/admin.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin.py
@@ -883,3 +883,21 @@
message = escape( galaxy.util.restore_text( kwd.get( 'message', '' ) ) )
status = galaxy.util.restore_text( kwd.get( 'status', 'done' ) )
return trans.fill_template( 'admin/view_data_tables_registry.mako', message=message, status=status )
+
+ @web.expose
+ @web.require_admin
+ def display_applications( self, trans, **kwd ):
+ return trans.fill_template( 'admin/view_display_applications.mako', display_applications=trans.app.datatypes_registry.display_applications )
+
+ @web.expose
+ @web.require_admin
+ def reload_display_application( self, trans, **kwd ):
+ reloaded, failed = trans.app.datatypes_registry.reload_display_applications( kwd.get( 'id' ) )
+ if not reloaded and failed:
+ return trans.show_error_message( 'Unable to reload any of the %i requested display applications ("%s").' % ( len( failed ), '", "'.join( failed ) ) )
+ if failed:
+ return trans.show_warn_message( 'Reloaded %i display applications ("%s"), but failed to reload %i display applications ("%s").'
+ % ( len( reloaded ), '", "'.join( reloaded ), len( failed ), '", "'.join( failed ) ) )
+ if not reloaded:
+ return trans.show_warn_message( 'You need to request at least one display application to reload.' )
+ return trans.show_ok_message( 'Reloaded %i requested display applications ("%s").' % ( len( reloaded ), '", "'.join( reloaded ) ) )
diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 templates/webapps/galaxy/admin/index.mako
--- a/templates/webapps/galaxy/admin/index.mako
+++ b/templates/webapps/galaxy/admin/index.mako
@@ -75,6 +75,7 @@
<div class="toolSectionBg"><div class="toolTitle"><a href="${h.url_for( controller='admin', action='view_datatypes_registry' )}" target="galaxy_main">View data types registry</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='view_tool_data_tables' )}" target="galaxy_main">View data tables registry</a></div>
+ <div class="toolTitle"><a href="${h.url_for( controller='admin', action='display_applications' )}" target="galaxy_main">View display applications</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='tool_versions' )}" target="galaxy_main">View tool lineage</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='package_tool' )}" target="galaxy_main">Download tool tarball</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='reload_tool' )}" target="galaxy_main">Reload a tool's configuration</a></div>
diff -r dee88f35c796e413ae071a49716dff1a9238d66c -r 00f4c600b89fdd52b0296e8bfc599a16485838b2 templates/webapps/galaxy/admin/view_display_applications.mako
--- /dev/null
+++ b/templates/webapps/galaxy/admin/view_display_applications.mako
@@ -0,0 +1,48 @@
+<%inherit file="/base.mako"/>
+<%namespace file="/message.mako" import="render_msg" />
+
+%if message:
+ ${render_msg( message, status )}
+%endif
+
+<div class="toolForm">
+ <div class="toolFormTitle">There are currently ${len( display_applications )} <a class="icon-btn" href="${ h.url_for( controller='admin', action='reload_display_application' ) }" title="Reload all display applications" data-placement="bottom">
+ <span class="fa fa-refresh"></span>
+ </a> display applications loaded.</div>
+ <div class="toolFormBody">
+ <table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
+ <tr>
+ <th bgcolor="#D8D8D8">Reload</th>
+ <th bgcolor="#D8D8D8">Name</th>
+ <th bgcolor="#D8D8D8">ID</th>
+ <th bgcolor="#D8D8D8">Version</th>
+ <th bgcolor="#D8D8D8">Links</th>
+ <th bgcolor="#D8D8D8">Filename</th>
+ </tr>
+ <% ctr = 0 %>
+ %for display_app in display_applications.values():
+ %if ctr % 2 == 1:
+ <tr class="odd_row">
+ %else:
+ <tr class="tr">
+ %endif
+ <td>
+ <a class="icon-btn" href="${ h.url_for( controller='admin', action='reload_display_application', id=display_app.id ) }" title="Reload ${ display_app.name | h } display application" data-placement="bottom">
+ <span class="fa fa-refresh"></span>
+ </a>
+ </td>
+ <td>${ display_app.name | h }</td>
+ <td>${ display_app.id | h }</td>
+ <td>${ display_app.version | h }</td>
+ <td><ul>
+ %for link in display_app.links.values():
+ <li>${ link.name | h }</li>
+ %endfor
+ </ul></td>
+ <td>${ display_app._filename | h }</td>
+ </tr>
+ <% ctr += 1 %>
+ %endfor
+ </table>
+ </div>
+</div>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Merged in dan/galaxy-central-prs (pull request #659)
by commits-noreply@bitbucket.org 04 Feb '15
by commits-noreply@bitbucket.org 04 Feb '15
04 Feb '15
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/dee88f35c796/
Changeset: dee88f35c796
User: dannon
Date: 2015-02-04 17:45:56+00:00
Summary: Merged in dan/galaxy-central-prs (pull request #659)
In API, when removing or refreshing a data table, send the reload signal to the worker queue. Change return values of reload and delete to be the new table contents, instead of the only-internally-useful 'version'.
Affected #: 1 file
diff -r 7c04c98d7b6af49164615bf3988942a19a1fc620 -r dee88f35c796e413ae071a49716dff1a9238d66c lib/galaxy/webapps/galaxy/api/tool_data.py
--- a/lib/galaxy/webapps/galaxy/api/tool_data.py
+++ b/lib/galaxy/webapps/galaxy/api/tool_data.py
@@ -5,6 +5,7 @@
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_raw as expose_api_raw
from galaxy.web.base.controller import BaseAPIController
+import galaxy.queue_worker
class ToolData( BaseAPIController ):
@@ -36,7 +37,11 @@
"""
decoded_tool_data_id = id
data_table = trans.app.tool_data_tables.data_tables.get(decoded_tool_data_id)
- return data_table.reload_from_files()
+ data_table.reload_from_files()
+ galaxy.queue_worker.send_control_task( trans, 'reload_tool_data_tables',
+ noop_self=True,
+ kwargs={'table_name': decoded_tool_data_id} )
+ return self._data_table( decoded_tool_data_id ).to_dict( view='element' )
@web.require_admin
@@ -78,7 +83,11 @@
trans.response.status = 400
return "Invalid data table item ( %s ) specified. Wrong number of columns (%s given, %s required)." % ( str( values ), str(len(split_values)), str(len(data_table.get_column_name_list())))
- return data_table.remove_entry(split_values)
+ data_table.remove_entry(split_values)
+ galaxy.queue_worker.send_control_task( trans, 'reload_tool_data_tables',
+ noop_self=True,
+ kwargs={'table_name': decoded_tool_data_id} )
+ return self._data_table( decoded_tool_data_id ).to_dict( view='element' )
@web.require_admin
@expose_api
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5435d68586aa/
Changeset: 5435d68586aa
User: dan
Date: 2015-02-04 15:02:20+00:00
Summary: In API, when removing or refreshing a data table, send the reload signal to the worker queue. Change return values of reload and delete to be the new table contents, instead of the only-internally-useful 'version'.
Affected #: 1 file
diff -r 9bc22ec1a8156fe640fd049399cb39c8755eef73 -r 5435d68586aa09f74391504030b6d30eb627f66e lib/galaxy/webapps/galaxy/api/tool_data.py
--- a/lib/galaxy/webapps/galaxy/api/tool_data.py
+++ b/lib/galaxy/webapps/galaxy/api/tool_data.py
@@ -5,6 +5,7 @@
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_raw as expose_api_raw
from galaxy.web.base.controller import BaseAPIController
+import galaxy.queue_worker
class ToolData( BaseAPIController ):
@@ -36,7 +37,11 @@
"""
decoded_tool_data_id = id
data_table = trans.app.tool_data_tables.data_tables.get(decoded_tool_data_id)
- return data_table.reload_from_files()
+ data_table.reload_from_files()
+ galaxy.queue_worker.send_control_task( trans, 'reload_tool_data_tables',
+ noop_self=True,
+ kwargs={'table_name': decoded_tool_data_id} )
+ return self._data_table( decoded_tool_data_id ).to_dict( view='element' )
@web.require_admin
@@ -78,7 +83,11 @@
trans.response.status = 400
return "Invalid data table item ( %s ) specified. Wrong number of columns (%s given, %s required)." % ( str( values ), str(len(split_values)), str(len(data_table.get_column_name_list())))
- return data_table.remove_entry(split_values)
+ data_table.remove_entry(split_values)
+ galaxy.queue_worker.send_control_task( trans, 'reload_tool_data_tables',
+ noop_self=True,
+ kwargs={'table_name': decoded_tool_data_id} )
+ return self._data_table( decoded_tool_data_id ).to_dict( view='element' )
@web.require_admin
@expose_api
https://bitbucket.org/galaxy/galaxy-central/commits/dee88f35c796/
Changeset: dee88f35c796
User: dannon
Date: 2015-02-04 17:45:56+00:00
Summary: Merged in dan/galaxy-central-prs (pull request #659)
In API, when removing or refreshing a data table, send the reload signal to the worker queue. Change return values of reload and delete to be the new table contents, instead of the only-internally-useful 'version'.
Affected #: 1 file
diff -r 7c04c98d7b6af49164615bf3988942a19a1fc620 -r dee88f35c796e413ae071a49716dff1a9238d66c lib/galaxy/webapps/galaxy/api/tool_data.py
--- a/lib/galaxy/webapps/galaxy/api/tool_data.py
+++ b/lib/galaxy/webapps/galaxy/api/tool_data.py
@@ -5,6 +5,7 @@
from galaxy.web import _future_expose_api as expose_api
from galaxy.web import _future_expose_api_raw as expose_api_raw
from galaxy.web.base.controller import BaseAPIController
+import galaxy.queue_worker
class ToolData( BaseAPIController ):
@@ -36,7 +37,11 @@
"""
decoded_tool_data_id = id
data_table = trans.app.tool_data_tables.data_tables.get(decoded_tool_data_id)
- return data_table.reload_from_files()
+ data_table.reload_from_files()
+ galaxy.queue_worker.send_control_task( trans, 'reload_tool_data_tables',
+ noop_self=True,
+ kwargs={'table_name': decoded_tool_data_id} )
+ return self._data_table( decoded_tool_data_id ).to_dict( view='element' )
@web.require_admin
@@ -78,7 +83,11 @@
trans.response.status = 400
return "Invalid data table item ( %s ) specified. Wrong number of columns (%s given, %s required)." % ( str( values ), str(len(split_values)), str(len(data_table.get_column_name_list())))
- return data_table.remove_entry(split_values)
+ data_table.remove_entry(split_values)
+ galaxy.queue_worker.send_control_task( trans, 'reload_tool_data_tables',
+ noop_self=True,
+ kwargs={'table_name': decoded_tool_data_id} )
+ return self._data_table( decoded_tool_data_id ).to_dict( view='element' )
@web.require_admin
@expose_api
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0