4 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/e7d7c6fb9e48/ Changeset: e7d7c6fb9e48 User: Daniel Blankenberg Date: 2015-02-18 19:39:07+00:00 Summary: Fixes for handling Data Managers that use undeclared data tables. Affected #: 3 files diff -r 503b95e63d0a5268c16a0a87016449bfe969e382 -r e7d7c6fb9e48d5f737ec6247c208cbadc0ec5e64 lib/galaxy/tools/data/__init__.py --- a/lib/galaxy/tools/data/__init__.py +++ b/lib/galaxy/tools/data/__init__.py @@ -154,7 +154,7 @@ with open( full_path, 'wb' ) as out: out.write( '<?xml version="1.0"?>\n<tables>\n' ) for elem in out_elems: - out.write( util.xml_to_string( elem ) ) + out.write( util.xml_to_string( elem, pretty=True ) ) out.write( '</tables>\n' ) os.chmod( full_path, 0644 ) @@ -452,19 +452,53 @@ """ Returns table entry associated with a col/val pair. """ + rval = self.get_entries( query_attr, query_val, return_attr, default=default, limit=1 ) + if rval: + return rval[0] + return default + + def get_entries( self, query_attr, query_val, return_attr, default=None, limit=None ): + """ + Returns table entry associated with a col/val pair. + """ query_col = self.columns.get( query_attr, None ) if query_col is None: return default - return_col = self.columns.get( return_attr, None ) - if return_col is None: - return default - rval = default + if return_attr is not None: + return_col = self.columns.get( return_attr, None ) + if return_col is None: + return default + rval = [] # Look for table entry. for fields in self.get_fields(): if fields[ query_col ] == query_val: - rval = fields[ return_col ] + if return_attr is None: + field_dict = {} + for i, col_name in enumerate( self.get_column_name_list() ): + field_dict[ col_name or i ] = fields[i] + rval.append( field_dict ) + else: + rval.append( fields[ return_col ] ) + if limit is not None and len( rval ) == limit: + break + return rval or default + + def get_filename_for_source( self, source, default=None ): + if source: + #if dict, assume is compatible info dict, otherwise call method + if isinstance( source, dict ): + source_repo_info = source + else: + source_repo_info = source.get_tool_shed_repository_info_dict() + else: + source_repo_info = None + filename = default + for name, value in self.filenames.iteritems(): + repo_info = value.get( 'tool_shed_repository', None ) + if ( not source_repo_info and not repo_info ) or ( source_repo_info and repo_info and source_repo_info == repo_info ): + filename = name break - return rval + return filename def _add_entry( self, entry, allow_duplicates=True, persist=False, persist_on_error=False, entry_source=None, **kwd ): #accepts dict or list of columns @@ -493,19 +527,7 @@ filename = None if persist and ( not is_error or persist_on_error ): - if entry_source: - #if dict, assume is compatible info dict, otherwise call method - if isinstance( entry_source, dict ): - source_repo_info = entry_source - else: - source_repo_info = entry_source.get_tool_shed_repository_info_dict() - else: - source_repo_info = None - for name, value in self.filenames.iteritems(): - repo_info = value.get( 'tool_shed_repository', None ) - if ( not source_repo_info and not repo_info ) or ( source_repo_info and repo_info and source_repo_info == repo_info ): - filename = name - break + filename = self.get_filename_for_source( entry_source ) if filename is None: #should we default to using any filename here instead? log.error( "Unable to determine filename for persisting data table '%s' values: '%s'.", self.name, fields ) diff -r 503b95e63d0a5268c16a0a87016449bfe969e382 -r e7d7c6fb9e48d5f737ec6247c208cbadc0ec5e64 lib/galaxy/tools/data_manager/manager.py --- a/lib/galaxy/tools/data_manager/manager.py +++ b/lib/galaxy/tools/data_manager/manager.py @@ -117,6 +117,7 @@ self.move_by_data_table_column = {} self.value_translation_by_data_table_column = {} self.tool_shed_repository_info_dict = None + self.undeclared_tables = False if elem is not None: self.load_from_element( elem, tool_path or self.data_managers.tool_path ) @@ -175,6 +176,7 @@ tool_shed_repository_id=tool_shed_repository_id ) self.name = elem.get( 'name', self.tool.name ) self.description = elem.get( 'description', self.tool.description ) + self.undeclared_tables = util.asbool( elem.get( 'undeclared_tables', self.undeclared_tables ) ) for data_table_elem in elem.findall( 'data_table' ): data_table_name = data_table_elem.get( "name" ) @@ -299,11 +301,28 @@ moved = self.process_move( data_table_name, name, output_ref_values[ name ].extra_files_path, **data_table_value ) data_table_value[ name ] = self.process_value_translation( data_table_name, name, **data_table_value ) data_table.add_entry( data_table_value, persist=True, entry_source=self ) - - for data_table_name, data_table_values in data_tables_dict.iteritems(): - #tool returned extra data table entries, but data table was not declared in data manager - #do not add these values, but do provide messages - log.warning( 'The data manager "%s" returned an undeclared data table "%s" with new entries "%s". These entries will not be created. Please confirm that an entry for "%s" exists in your "%s" file.' % ( self.id, data_table_name, data_table_values, data_table_name, self.data_managers.filename ) ) + if self.undeclared_tables and data_tables_dict: + # We handle the data move, by just moving all the data out of the extra files path + # moving a directory and the target already exists, we move the contents instead + log.debug( 'Attempting to add entries for undeclared tables: %s.', ', '.join( data_tables_dict.keys() ) ) + for ref_file in out_data.values(): + util.move_merge( ref_file.extra_files_path, self.data_managers.app.config.galaxy_data_manager_data_path ) + path_column_names = [ 'path' ] + for data_table_name, data_table_values in data_tables_dict.iteritems(): + data_table = self.data_managers.app.tool_data_tables.get( data_table_name, None ) + if not isinstance( data_table_values, list ): + data_table_values = [ data_table_values ] + for data_table_row in data_table_values: + data_table_value = dict( **data_table_row ) #keep original values here + for name, value in data_table_row.iteritems(): + if name in path_column_names: + data_table_value[ name ] = os.path.abspath( os.path.join( self.data_managers.app.config.galaxy_data_manager_data_path, value ) ) + data_table.add_entry( data_table_value, persist=True, entry_source=self ) + else: + for data_table_name, data_table_values in data_tables_dict.iteritems(): + # tool returned extra data table entries, but data table was not declared in data manager + # do not add these values, but do provide messages + log.warning( 'The data manager "%s" returned an undeclared data table "%s" with new entries "%s". These entries will not be created. Please confirm that an entry for "%s" exists in your "%s" file.' % ( self.id, data_table_name, data_table_values, data_table_name, self.data_managers.filename ) ) def process_move( self, data_table_name, column_name, source_base_path, relative_symlinks=False, **kwd ): if data_table_name in self.move_by_data_table_column and column_name in self.move_by_data_table_column[ data_table_name ]: diff -r 503b95e63d0a5268c16a0a87016449bfe969e382 -r e7d7c6fb9e48d5f737ec6247c208cbadc0ec5e64 lib/tool_shed/tools/data_table_manager.py --- a/lib/tool_shed/tools/data_table_manager.py +++ b/lib/tool_shed/tools/data_table_manager.py @@ -113,16 +113,20 @@ error = True return error, message + def get_target_install_dir( self, tool_shed_repository ): + tool_path, relative_target_dir = tool_shed_repository.get_tool_relative_path( self.app ) + # This is where index files will reside on a per repo/installed version basis. + target_dir = os.path.join( self.app.config.shed_tool_data_path, relative_target_dir ) + if not os.path.exists( target_dir ): + os.makedirs( target_dir ) + return target_dir, tool_path, relative_target_dir + def install_tool_data_tables( self, tool_shed_repository, tool_index_sample_files ): TOOL_DATA_TABLE_FILE_NAME = 'tool_data_table_conf.xml' TOOL_DATA_TABLE_FILE_SAMPLE_NAME = '%s.sample' % ( TOOL_DATA_TABLE_FILE_NAME ) SAMPLE_SUFFIX = '.sample' SAMPLE_SUFFIX_OFFSET = -len( SAMPLE_SUFFIX ) - tool_path, relative_target_dir = tool_shed_repository.get_tool_relative_path( self.app ) - # This is where index files will reside on a per repo/installed version basis. - target_dir = os.path.join( self.app.config.shed_tool_data_path, relative_target_dir ) - if not os.path.exists( target_dir ): - os.makedirs( target_dir ) + target_dir, tool_path, relative_target_dir = self.get_target_install_dir( tool_shed_repository ) for sample_file in tool_index_sample_files: path, filename = os.path.split ( sample_file ) target_filename = filename https://bitbucket.org/galaxy/galaxy-central/commits/103d62154004/ Changeset: 103d62154004 User: lepsiobec Date: 2015-02-19 19:37:17+00:00 Summary: fi the missing import Affected #: 1 file diff -r e7d7c6fb9e48d5f737ec6247c208cbadc0ec5e64 -r 103d621540041522781a086bff4ac322255aeb49 lib/galaxy/webapps/tool_shed/model/migrate/check.py --- a/lib/galaxy/webapps/tool_shed/model/migrate/check.py +++ b/lib/galaxy/webapps/tool_shed/model/migrate/check.py @@ -1,4 +1,5 @@ import sys, os.path, logging +import pkg_resources from galaxy import eggs https://bitbucket.org/galaxy/galaxy-central/commits/4b4eee11c31b/ Changeset: 4b4eee11c31b User: dannon Date: 2015-02-19 19:45:44+00:00 Summary: Slightly adjust aforementioned import, use the standard eggs.require Affected #: 1 file diff -r 103d621540041522781a086bff4ac322255aeb49 -r 4b4eee11c31b90eae05db88047a5a675ec645f1b lib/galaxy/webapps/tool_shed/model/migrate/check.py --- a/lib/galaxy/webapps/tool_shed/model/migrate/check.py +++ b/lib/galaxy/webapps/tool_shed/model/migrate/check.py @@ -1,5 +1,6 @@ -import sys, os.path, logging -import pkg_resources +import logging +import os.path +import sys from galaxy import eggs @@ -39,7 +40,7 @@ try: egg = dialect_to_egg[dialect] try: - pkg_resources.require( egg ) + eggs.require( egg ) log.debug( "%s egg successfully loaded for %s dialect" % ( egg, dialect ) ) except: # If the module is in the path elsewhere (i.e. non-egg), it'll still load. https://bitbucket.org/galaxy/galaxy-central/commits/d99406f5b690/ Changeset: d99406f5b690 User: dannon Date: 2015-02-19 22:53:12+00:00 Summary: Per IRC discussion, remove demo_sequencer webapp. Affected #: 19 files diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 config/demo_sequencer_wsgi.ini.sample --- a/config/demo_sequencer_wsgi.ini.sample +++ /dev/null @@ -1,66 +0,0 @@ -# ---- HTTP Server ---------------------------------------------------------- - -[server:main] - -use = egg:Paste#http -port = 9011 -host = 0.0.0.0 -use_threadpool = true -threadpool_workers = 10 - -# ---- Galaxy Demo Sequencer Emulator Interface ------------------------------------------------- - -[app:main] - -# Specifies the factory for the universe WSGI application -paste.app_factory = galaxy.webapps.demo_sequencer.buildapp:app_factory -log_level = DEBUG - -# Where dataset files are saved -file_path = database/demo_sequencer_files -# Temporary storage for additional datasets, this should be shared through the cluster -new_file_path = database/tmp - -# Sequencer emulator actions -sequencer_actions_config_file = %(here)s/lib/galaxy/webapps/demo_sequencer/sequencer_actions.xml - -# Session support (beaker) -use_beaker_session = True -session_type = memory -session_data_dir = %(here)s/database/beaker_sessions -session_key = galaxysessions -session_secret = changethisinproduction - -# Galaxy session security -id_secret = changethisinproductiontoo - -# Configuration for debugging middleware -debug = true -use_lint = false - -# NEVER enable this on a public site (even test or QA) -# use_interactive = true - -# this should be a comma-separated list of valid Galaxy users -#admin_users = test@bx.psu.edu - -# Force everyone to log in (disable anonymous access) -require_login = False - -# Write thread status periodically to 'heartbeat.log' (careful, uses disk space rapidly!) -## use_heartbeat = True - -# Profiling middleware (cProfile based) -## use_profile = True - -# Use the new iframe / javascript based layout -use_new_layout = true - -# Serving static files (needed if running standalone) -static_enabled = True -static_cache_time = 360 -static_dir = %(here)s/static/ -static_images_dir = %(here)s/static/images -static_favicon_dir = %(here)s/static/favicon.ico -static_scripts_dir = %(here)s/static/scripts/ -static_style_dir = %(here)s/static/june_2007_style/blue diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 doc/source/lib/galaxy.webapps.demo_sequencer.controllers.rst --- a/doc/source/lib/galaxy.webapps.demo_sequencer.controllers.rst +++ /dev/null @@ -1,19 +0,0 @@ -controllers Package -=================== - -:mod:`controllers` Package --------------------------- - -.. automodule:: galaxy.webapps.demo_sequencer.controllers - :members: - :undoc-members: - :show-inheritance: - -:mod:`common` Module --------------------- - -.. automodule:: galaxy.webapps.demo_sequencer.controllers.common - :members: - :undoc-members: - :show-inheritance: - diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 doc/source/lib/galaxy.webapps.demo_sequencer.framework.rst --- a/doc/source/lib/galaxy.webapps.demo_sequencer.framework.rst +++ /dev/null @@ -1,11 +0,0 @@ -framework Package -================= - -:mod:`framework` Package ------------------------- - -.. automodule:: galaxy.webapps.demo_sequencer.framework - :members: - :undoc-members: - :show-inheritance: - diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 doc/source/lib/galaxy.webapps.demo_sequencer.rst --- a/doc/source/lib/galaxy.webapps.demo_sequencer.rst +++ /dev/null @@ -1,51 +0,0 @@ -demo_sequencer Package -====================== - -:mod:`demo_sequencer` Package ------------------------------ - -.. automodule:: galaxy.webapps.demo_sequencer - :members: - :undoc-members: - :show-inheritance: - -:mod:`app` Module ------------------ - -.. automodule:: galaxy.webapps.demo_sequencer.app - :members: - :undoc-members: - :show-inheritance: - -:mod:`buildapp` Module ----------------------- - -.. automodule:: galaxy.webapps.demo_sequencer.buildapp - :members: - :undoc-members: - :show-inheritance: - -:mod:`config` Module --------------------- - -.. automodule:: galaxy.webapps.demo_sequencer.config - :members: - :undoc-members: - :show-inheritance: - -:mod:`registry` Module ----------------------- - -.. automodule:: galaxy.webapps.demo_sequencer.registry - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - - galaxy.webapps.demo_sequencer.controllers - galaxy.webapps.demo_sequencer.framework - diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 doc/source/lib/galaxy.webapps.rst --- a/doc/source/lib/galaxy.webapps.rst +++ b/doc/source/lib/galaxy.webapps.rst @@ -15,7 +15,6 @@ .. toctree:: galaxy.webapps.community - galaxy.webapps.demo_sequencer galaxy.webapps.galaxy galaxy.webapps.reports diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/__init__.py --- a/lib/galaxy/webapps/demo_sequencer/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""The Galaxy Demo Sequencer Emulator application.""" -# This webapp is for demo purposes only! - -from galaxy.web.framework import url_for -from galaxy.web.framework.decorators import expose diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/app.py --- a/lib/galaxy/webapps/demo_sequencer/app.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys, config -from galaxy.web import security -import galaxy.webapps.demo_sequencer.registry - -class UniverseApplication( object ): - """Encapsulates the state of a Universe application""" - def __init__( self, **kwargs ): - print >> sys.stderr, "python path is: " + ", ".join( sys.path ) - self.name = "demo_sequencer" - # Read config file and check for errors - self.config = config.Configuration( **kwargs ) - self.config.check() - config.configure_logging( self.config ) - # Set up sequencer actions registry - self.sequencer_actions_registry = galaxy.webapps.demo_sequencer.registry.Registry( self.config.root, self.config.sequencer_actions_config ) - # Security helper - self.security = security.SecurityHelper( id_secret=self.config.id_secret ) - def shutdown( self ): - pass diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/buildapp.py --- a/lib/galaxy/webapps/demo_sequencer/buildapp.py +++ /dev/null @@ -1,171 +0,0 @@ -""" -Provides factory methods to assemble the Galaxy web application -""" - -import logging, atexit -import os, os.path, sys - -from inspect import isclass - -from paste.request import parse_formvars -from paste.util import import_string -from paste import httpexceptions -from galaxy.util import asbool -import pkg_resources - -log = logging.getLogger( __name__ ) - -import config -import galaxy.webapps.demo_sequencer.framework - -def add_ui_controllers( webapp, app ): - """ - Search for controllers in the 'galaxy.webapps.demo_sequencer.controllers' - directory and add them to the webapp. - """ - from galaxy.web.base.controller import BaseUIController - from galaxy.web.base.controller import ControllerUnavailable - import galaxy.webapps.demo_sequencer.controllers - controller_dir = galaxy.webapps.demo_sequencer.controllers.__path__[0] - for fname in os.listdir( controller_dir ): - if not fname.startswith( "_" ) and fname.endswith( ".py" ): - name = fname[:-3] - module_name = "galaxy.webapps.demo_sequencer.controllers." + name - module = __import__( module_name ) - for comp in module_name.split( "." )[1:]: - module = getattr( module, comp ) - # Look for a controller inside the modules - for key in dir( module ): - T = getattr( module, key ) - if isclass( T ) and T is not BaseUIController and issubclass( T, BaseUIController ): - webapp.add_ui_controller( name, T( app ) ) - -def app_factory( global_conf, **kwargs ): - """Return a wsgi application serving the root object""" - # Create the Galaxy application unless passed in - if 'app' in kwargs: - app = kwargs.pop( 'app' ) - else: - try: - from galaxy.webapps.demo_sequencer.app import UniverseApplication - app = UniverseApplication( global_conf = global_conf, **kwargs ) - except: - import traceback, sys - traceback.print_exc() - sys.exit( 1 ) - atexit.register( app.shutdown ) - # Create the universe WSGI application - webapp = galaxy.webapps.demo_sequencer.framework.WebApplication( app, session_cookie='galaxydemo_sequencersession', name="demo_sequencer" ) - add_ui_controllers( webapp, app ) - # These two routes handle our simple needs at the moment - webapp.add_route( '/:controller/:action', action='index' ) - webapp.add_route( '/:action', controller='common', action='index' ) - webapp.finalize_config() - # Wrap the webapp in some useful middleware - if kwargs.get( 'middleware', True ): - webapp = wrap_in_middleware( webapp, global_conf, **kwargs ) - if kwargs.get( 'static_enabled', True ): - webapp = wrap_in_static( webapp, global_conf, **kwargs ) - # Return - return webapp - -def wrap_in_middleware( app, global_conf, **local_conf ): - """Based on the configuration wrap `app` in a set of common and useful middleware.""" - # Merge the global and local configurations - conf = global_conf.copy() - conf.update(local_conf) - debug = asbool( conf.get( 'debug', False ) ) - # First put into place httpexceptions, which must be most closely - # wrapped around the application (it can interact poorly with - # other middleware): - app = httpexceptions.make_middleware( app, conf ) - log.debug( "Enabling 'httpexceptions' middleware" ) - # 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)): - from paste import recursive - app = recursive.RecursiveMiddleware( app, conf ) - log.debug( "Enabling 'recursive' middleware" ) - # Various debug middleware that can only be turned on if the debug - # flag is set, either because they are insecure or greatly hurt - # performance - if debug: - # Middleware to check for WSGI compliance - if asbool( conf.get( 'use_lint', True ) ): - from paste import lint - app = lint.make_middleware( app, conf ) - log.debug( "Enabling 'lint' middleware" ) - # Middleware to run the python profiler on each request - if asbool( conf.get( 'use_profile', False ) ): - import profile - app = profile.ProfileMiddleware( app, conf ) - log.debug( "Enabling 'profile' middleware" ) - # Middleware that intercepts print statements and shows them on the - # returned page - if asbool( conf.get( 'use_printdebug', True ) ): - from paste.debug import prints - app = prints.PrintDebugMiddleware( app, conf ) - log.debug( "Enabling 'print debug' middleware" ) - if debug and asbool( conf.get( 'use_interactive', False ) ): - # Interactive exception debugging, scary dangerous if publicly - # accessible, if not enabled we'll use the regular error printing - # middleware. - pkg_resources.require( "WebError" ) - from weberror import evalexception - app = evalexception.EvalException( app, conf, - templating_formatters=build_template_error_formatters() ) - log.debug( "Enabling 'eval exceptions' middleware" ) - else: - # Not in interactive debug mode, just use the regular error middleware - from paste.exceptions import errormiddleware - app = errormiddleware.ErrorMiddleware( app, conf ) - log.debug( "Enabling 'error' middleware" ) - # Transaction logging (apache access.log style) - if asbool( conf.get( 'use_translogger', True ) ): - from paste.translogger import TransLogger - app = TransLogger( app ) - log.debug( "Enabling 'trans logger' middleware" ) - # X-Forwarded-Host handling - from galaxy.web.framework.middleware.xforwardedhost import XForwardedHostMiddleware - app = XForwardedHostMiddleware( app ) - log.debug( "Enabling 'x-forwarded-host' middleware" ) - return app - -def wrap_in_static( app, global_conf, **local_conf ): - from paste.urlmap import URLMap - from galaxy.web.framework.middleware.static import CacheableStaticURLParser as Static - urlmap = URLMap() - # Merge the global and local configurations - conf = global_conf.copy() - conf.update(local_conf) - # Get cache time in seconds - cache_time = conf.get( "static_cache_time", None ) - if cache_time is not None: - cache_time = int( cache_time ) - # Send to dynamic app by default - urlmap["/"] = app - # Define static mappings from config - urlmap["/static"] = Static( conf.get( "static_dir" ), cache_time ) - urlmap["/images"] = Static( conf.get( "static_images_dir" ), cache_time ) - urlmap["/static/scripts"] = Static( conf.get( "static_scripts_dir" ), cache_time ) - urlmap["/static/style"] = Static( conf.get( "static_style_dir" ), cache_time ) - urlmap["/favicon.ico"] = Static( conf.get( "static_favicon_dir" ), cache_time ) - # 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 - occurs, WebError pass the exception to each function in this list until - one returns a value, which will be displayed on the error page. - """ - 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 ) - if isinstance( exc_value, AttributeError ) and exc_value.args[0].startswith( "'Undefined' object has no attribute" ): - return mako.exceptions.html_error_template().render( full=False, css=False ) - formatters.append( mako_html_data ) - return formatters diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/config.py --- a/lib/galaxy/webapps/demo_sequencer/config.py +++ /dev/null @@ -1,121 +0,0 @@ -""" -Universe configuration builder. -""" - -import sys, os -import logging, logging.config -from optparse import OptionParser -import ConfigParser -from galaxy.util import string_as_bool - -from galaxy import eggs -import pkg_resources - -log = logging.getLogger( __name__ ) - -def resolve_path( path, root ): - """If 'path' is relative make absolute by prepending 'root'""" - if not( os.path.isabs( path ) ): - path = os.path.join( root, path ) - return path - -class ConfigurationError( Exception ): - pass - -class Configuration( object ): - def __init__( self, **kwargs ): - self.config_dict = kwargs - self.root = kwargs.get( 'root_dir', '.' ) - # Collect the umask and primary gid from the environment - self.umask = os.umask( 077 ) # get the current umask - os.umask( self.umask ) # can't get w/o set, so set it back - # Where dataset files are stored - self.file_path = resolve_path( kwargs.get( "file_path", "database/files" ), self.root ) - self.new_file_path = resolve_path( kwargs.get( "new_file_path", "database/tmp" ), self.root ) - self.cookie_path = kwargs.get( "cookie_path", "/" ) - self.test_conf = resolve_path( kwargs.get( "test_conf", "" ), self.root ) - self.id_secret = kwargs.get( "id_secret", "USING THE DEFAULT IS NOT SECURE!" ) - self.use_remote_user = string_as_bool( kwargs.get( "use_remote_user", "False" ) ) - self.remote_user_maildomain = kwargs.get( "remote_user_maildomain", None ) - self.remote_user_logout_href = kwargs.get( "remote_user_logout_href", None ) - self.require_login = string_as_bool( kwargs.get( "require_login", "False" ) ) - self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) ) - self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) ) - self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root ) - self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates/demo_sequencer" ), self.root ) - self.admin_users = kwargs.get( "admin_users", "" ) - self.sendmail_path = kwargs.get('sendmail_path',"/usr/sbin/sendmail") - self.mailing_join_addr = kwargs.get('mailing_join_addr',"galaxy-announce-join@bx.psu.edu") - self.error_email_to = kwargs.get( 'error_email_to', None ) - self.smtp_server = kwargs.get( 'smtp_server', None ) - self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) ) - self.brand = kwargs.get( 'brand', None ) - self.wiki_url = kwargs.get( 'wiki_url', 'https://wiki.galaxyproject.org/' ) - self.blog_url = kwargs.get( 'blog_url', None ) - self.screencasts_url = kwargs.get( 'screencasts_url', None ) - self.log_events = False - self.cloud_controller_instance = False - # Proxy features - self.apache_xsendfile = kwargs.get( 'apache_xsendfile', False ) - self.nginx_x_accel_redirect_base = kwargs.get( 'nginx_x_accel_redirect_base', False ) - self.sequencer_actions_config = kwargs.get( 'sequencer_actions_config_file', 'galaxy/webapps/demo_sequencer/sequencer_actions.xml' ) - # Parse global_conf and save the parser - global_conf = kwargs.get( 'global_conf', None ) - global_conf_parser = ConfigParser.ConfigParser() - self.global_conf_parser = global_conf_parser - if global_conf and "__file__" in global_conf: - global_conf_parser.read(global_conf['__file__']) - def get( self, key, default ): - return self.config_dict.get( key, default ) - def get_bool( self, key, default ): - if key in self.config_dict: - return string_as_bool( self.config_dict[key] ) - else: - return default - def check( self ): - # Check that required directories exist - for path in self.root, self.file_path, self.template_path: - if not os.path.isdir( path ): - raise ConfigurationError("Directory does not exist: %s" % path ) - def is_admin_user( self, user ): - """ - Determine if the provided user is listed in `admin_users`. - """ - admin_users = self.get( "admin_users", "" ).split( "," ) - return user is not None and user.email in admin_users - -def configure_logging( config ): - """ - Allow some basic logging configuration to be read from the cherrpy - config. - """ - # PasteScript will have already configured the logger if the appropriate - # sections were found in the config file, so we do nothing if the - # config has a loggers section, otherwise we do some simple setup - # using the 'log_*' values from the config. - if config.global_conf_parser.has_section( "loggers" ): - return - format = config.get( "log_format", "%(name)s %(levelname)s %(asctime)s %(message)s" ) - level = logging._levelNames[ config.get( "log_level", "DEBUG" ) ] - destination = config.get( "log_destination", "stdout" ) - log.info( "Logging at '%s' level to '%s'" % ( level, destination ) ) - # Get root logger - root = logging.getLogger() - # Set level - root.setLevel( level ) - # Turn down paste httpserver logging - if level <= logging.DEBUG: - logging.getLogger( "paste.httpserver.ThreadPool" ).setLevel( logging.WARN ) - # Remove old handlers - for h in root.handlers[:]: - root.removeHandler(h) - # Create handler - if destination == "stdout": - handler = logging.StreamHandler( sys.stdout ) - else: - handler = logging.FileHandler( destination ) - # Create formatter - formatter = logging.Formatter( format ) - # Hook everything up - handler.setFormatter( formatter ) - root.addHandler( handler ) diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/controllers/__init__.py --- a/lib/galaxy/webapps/demo_sequencer/controllers/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -"""Galaxy demo sequencer emulator controllers.""" diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/controllers/common.py --- a/lib/galaxy/webapps/demo_sequencer/controllers/common.py +++ /dev/null @@ -1,228 +0,0 @@ -from galaxy.web.base.controller import * -from galaxy.web.framework.helpers import time_ago -from galaxy import util -import time, socket, urllib, urllib2, base64, copy -from galaxy.util.json import * -from urllib import quote_plus, unquote_plus -from markupsafe import escape - -import logging -log = logging.getLogger( __name__ ) - -class CommonController( BaseUIController ): - @web.expose - def index( self, trans, **kwd ): - redirect_action = util.restore_text( kwd.get( 'redirect_action', '' ) ) - titles = util.restore_text( kwd.get( 'titles', '' ) ) - titles = util.listify( titles ) - JobId = util.restore_text( kwd.get( 'JobId', '' ) ) - sample_id = util.restore_text( kwd.get( 'sample_id', '' ) ) - message = escape( util.restore_text( kwd.get( 'message', '' ) ) ) - status = kwd.get( 'status', 'done' ) - redirect_delay = trans.app.sequencer_actions_registry.redirect_delay - sequencer_redirects = copy.deepcopy( trans.app.sequencer_actions_registry.sequencer_redirects ) - sequencer_requests = copy.deepcopy( trans.app.sequencer_actions_registry.sequencer_requests ) - requests = [] - if redirect_action == 'stop': - # Handle any additional requests - for request_tup in sequencer_requests: - url, http_method, request_params, response_type = self.parse_request_tup( request_tup, **kwd ) - response = self.handle_request( trans, url, http_method, **request_params ) - # Handle response, currently only handles json - if response_type == 'json': - response = loads( response ) - # Handle response that is an error, for example: - # { "Success":false, "Message":"some error string" } - if 'Success' in response and response[ 'Success' ] == 'false': - message = response[ 'Message' ] - return self.handle_failure( trans, url, message ) - if 'JobId' in response: - JobId = str( response[ 'JobId' ] ) - kwd[ 'JobId' ] = JobId - # Handle the final redirect, if any ( should only be 0 or 1 ). - for request_tup in trans.app.sequencer_actions_registry.final_redirect: - url, http_method, request_params, response_type = self.parse_request_tup( request_tup, **kwd ) - return trans.fill_template( 'webapps/demo_sequencer/redirect.mako', redirect_url=url ) - # Exit if we have no redirection - redirect_action = 'exit' - elif not redirect_action: - # Specially handle the initial request to the demo sequencer by starting with the first defined redirect. - redirect_action, action_dict = sequencer_redirects.items()[0] - titles = [ action_dict[ 'title' ] ] - if 'requests' in action_dict: - requests = action_dict[ 'requests' ] - else: - for index, key in enumerate( sequencer_redirects.iterkeys() ): - if redirect_action == key: - try: - # Move to the next action, if there is one. - redirect_action = sequencer_redirects.keys()[ index + 1 ] - action_dict = sequencer_redirects[ redirect_action ] - titles.append( action_dict[ 'title' ] ) - except: - # If we're done redirecting, stop. - redirect_action = 'stop' - break - if not trans.app.sequencer_actions_registry.authenticated: - # Support various types of authentication - if trans.app.sequencer_actions_registry.browser_login: - # We'll just build the URL here since authentication will be handled in the browser - url = trans.app.sequencer_actions_registry.browser_login[ 'url' ] - params = trans.app.sequencer_actions_registry.browser_login[ 'params' ] - trans.app.sequencer_actions_registry.browser_login = '%s?%s' %( url, urllib.urlencode( params ) ) - if not trans.app.sequencer_actions_registry.final_redirect: - # If we don't have a final_redirect tag, but we want our browser to authenticate, - # do it ow. If we have a final_redirect tag, browser authentication will happen there. - url = web.url_for( controller='common', action='index', **kwd ) - return trans.fill_template( 'webapps/demo_sequencer/redirect.mako', redirect_url=url ) - if trans.app.sequencer_actions_registry.basic_http_authentication: - # Example tag: - # <basic_http_authentication user="administrator" password="galaxy" url="http://127.0.0.1" realm="" /> - user, password, url, realm = trans.app.sequencer_actions_registry.basic_http_authentication - # Create a password manager - password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() - # Add the username, password and realm. - if not realm: - realm = None - password_mgr.add_password( realm, url, user, password ) - handler = urllib2.HTTPBasicAuthHandler( password_mgr ) - # Create "opener" (OpenerDirector instance) - opener = urllib2.build_opener( handler ) - # Install the opener, now all calls to urllib2.urlopen use our opener. - urllib2.install_opener( opener ) - trans.app.sequencer_actions_registry.authenticated = True - if trans.app.sequencer_actions_registry.http_headers_authorization: - # Example tag: - # <http_headers_authorization credentials="administrator:galaxy" url="http://127.0.0.1" /> - url, credentials = trans.app.sequencer_actions_registry.http_headers_authorization - req = urllib2.Request( url ) - req.add_header( 'Authorization', 'Basic %s' % base64.b64encode( credentials ) ) - trans.app.sequencer_actions_registry.authenticated = True - if trans.app.sequencer_actions_registry.http_cookie_processor_authentication: - # Example tag: - # <http_cookie_processor_authentication url="http://127.0.0.1/login"> - # <param name="user" value="administrator"/> - # <param name="password" value="galaxy"/> - # </http_cookie_processor_authentication> - url = trans.app.sequencer_actions_registry.http_cookie_processor_authentication[ 'url' ] - params = trans.app.sequencer_actions_registry.http_cookie_processor_authentication[ 'params' ] - # Build opener with HTTPCookieProcessor - opener = urllib2.build_opener( urllib2.HTTPCookieProcessor() ) - urllib2.install_opener( opener ) - # Perform login with params - page = opener.open( url, urllib.urlencode( params ) ) - response = page.read() - page.close() - # Any additional requests should automatically pass back any - # cookies received during login, thanks to the HTTPCookieProcessor - trans.app.sequencer_actions_registry.authenticated = True - # Handle requests, if there are any - for request_tup in requests: - url, http_method, request_params, response_type = self.parse_request_tup( request_tup, **kwd ) - response = self.handle_request( trans, url, http_method, **request_params ) - # Handle response, currently only handles json - if response_type == 'json': - response = loads( response ) - # Handle response that is an error, for example: - # { "Success":false, "Message":"some error string" } - if 'Success' in response and response[ 'Success' ] == 'false': - message = response[ 'Message' ] - return self.handle_failure( trans, url, message ) - if 'JobId' in response: - JobId = str( response[ 'JobId' ] ) - kwd[ 'JobId' ] = JobId - titles = ','.join( titles ) - return trans.fill_template( "webapps/demo_sequencer/index.mako", - redirect_action=redirect_action, - redirect_delay=redirect_delay, - titles=titles, - sample_id=sample_id, - JobId=JobId, - message=message, - status=status ) - def parse_request_tup( self, request_tup, **kwd ): - redirect_action = util.restore_text( kwd.get( 'redirect_action', '' ) ) - titles = util.restore_text( kwd.get( 'titles', '' ) ) - JobId = util.restore_text( kwd.get( 'JobId', '' ) ) - sample_id = util.restore_text( kwd.get( 'sample_id', '' ) ) - message = escape( util.restore_text( kwd.get( 'message', '' ) ) ) - status = kwd.get( 'status', 'done' ) - url, http_method, request_params, response_type = request_tup - url = unquote_plus( url ) - # Handle URLs in which we replace param values, which will look something like: - # http://127.0.0.1/getinfo/{id}. - replace_with_param = url.find( '{' ) > 0 - if replace_with_param: - # Handle the special-case {JobId} param. - if url.find( '{JobId}' ) > 0: - if JobId: - url = url.replace( '{JobId}', str( JobId ) ) - for key, value in kwd.items(): - # Don't attempt to replace if there is nothing with which to do it - # or if the value itself should be replaced with something. - if value and not value.startswith( '{' ): - replace_str = '{%s}' % key - if url.find( replace_str ) > 0: - url = url.replace( replace_str, value ) - # Handle request parameters in which we replace param values. - for key, val in request_params.items(): - if val and val.startswith( '{' ): - replace_key = val.lstrip( '{' ).rstrip( '}' ) - if replace_key in kwd: - request_params[ key ] = kwd[ replace_key ] - return url, http_method, request_params, response_type - def handle_request( self, trans, url, http_method=None, **kwd ): - if 'Name' in kwd and not kwd[ 'Name' ]: - # Hack: specially handle parameters named "Name" if no param_value is given - # by providing a date / time string - guarantees uniqueness, if required. - kwd[ 'Name' ] = time.strftime( "%a, %d %b %Y %H:%M:%S", time.gmtime() ) - if 'Comments' in kwd and not kwd[ 'Comments' ]: - # Hack: specially handle parameters named "Comments" if no param_value is given - # by providing a date / time string. - kwd[ 'Comments' ] = time.strftime( "%a, %d %b %Y %H:%M:%S", time.gmtime() ) - socket.setdefaulttimeout( 600 ) - # The following calls to urllib2.urlopen() will use the above default timeout. - try: - if not http_method or http_method == 'get': - page = urllib2.urlopen( url ) - response = page.read() - page.close() - return response - elif http_method == 'post': - page = urllib2.urlopen( url, urllib.urlencode( kwd ) ) - response = page.read() - page.close() - return response - elif http_method == 'put': - url += '/' + str( kwd.pop( 'id' ) ) + '?key=' + kwd.pop( 'key' ) - output = self.put( url, **kwd ) - except Exception, e: - raise - message = 'Problem sending request to the web application: %s. URL: %s. kwd: %s. Http method: %s' % \ - ( str( e ), str( url ), str( kwd ), str( http_method ) ) - return self.handle_failure( trans, url, message ) - def handle_failure( self, trans, url, message ): - message = '%s, URL: %s' % ( message, url ) - params = dict( message = message, - status = 'error', - redirect_action = 'exit', - titles = 'Error' ) - return trans.response.send_redirect( web.url_for( controller='common', - action='index', - **params ) ) - def put( self, url, **kwd ): - opener = urllib2.build_opener( urllib2.HTTPHandler ) - request = urllib2.Request( url, data=dumps( kwd ) ) - request.add_header( 'Content-Type', 'application/json' ) - request.get_method = lambda: 'PUT' - url = opener.open( request ) - output = url.read() - return loads( output ) - @web.expose - def login( self, trans, **kwd ): - trans.app.sequencer_actions_registry.authenticated = True - return trans.fill_template( "webapps/demo_sequencer/login.mako" ) - @web.expose - def empty_page( self, trans, **kwd ): - # Hack to not display responses in the browser - src for a hidden iframe. - return trans.fill_template( "webapps/demo_sequencer/empty.mako" ) diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/framework/__init__.py --- a/lib/galaxy/webapps/demo_sequencer/framework/__init__.py +++ /dev/null @@ -1,215 +0,0 @@ -""" -Demo sequencer web application framework -""" - -import json -import os -import pkg_resources -import random -import socket -import string -import sys -import time - -pkg_resources.require( "Cheetah" ) -from Cheetah.Template import Template - -from galaxy.web.framework import helpers - -from galaxy import util -from galaxy.util.json import dumps -from galaxy.util.json import loads -from galaxy.web.framework import url_for -from galaxy.web.framework.decorators import expose -from galaxy.web.framework.decorators import json -from galaxy.web.framework.decorators import json_pretty -from galaxy.web.framework.decorators import require_login -from galaxy.web.framework.decorators import expose_api -from galaxy.web.framework.decorators import error -from galaxy.web.framework.formbuilder import form -from galaxy.web.framework.formbuilder import FormBuilder -from galaxy.web.framework.formbuilder import FormInput -from galaxy.web.framework.formbuilder import FormData -import galaxy.web.framework.base - -from galaxy.util.bunch import Bunch -from galaxy.exceptions import MessageException -from galaxy.util import asbool - -pkg_resources.require( "Mako" ) -import mako.template -import mako.lookup -import mako.runtime - -pkg_resources.require( "pexpect" ) -pkg_resources.require( "amqp" ) - -import logging -log = logging.getLogger( __name__ ) - -class WebApplication( galaxy.web.framework.base.WebApplication ): - def __init__( self, demo_app, session_cookie='demosequencersession' ): - galaxy.web.framework.base.WebApplication.__init__( self ) - self.set_transaction_factory( lambda e: self.transaction_chooser( e, demo_app, session_cookie ) ) - # Mako support - self.mako_template_lookup = mako.lookup.TemplateLookup( - directories = [ demo_app.config.template_path ] , - module_directory = demo_app.config.template_cache, - collection_size = 500, - output_encoding = 'utf-8' ) - # Security helper - self.security = demo_app.security - def handle_controller_exception( self, e, trans, **kwargs ): - if isinstance( e, MessageException ): - return trans.show_message( e.err_msg, e.type ) - def make_body_iterable( self, trans, body ): - if isinstance( body, FormBuilder ): - body = trans.show_form( body ) - return galaxy.web.framework.base.WebApplication.make_body_iterable( self, trans, body ) - def transaction_chooser( self, environ, demo_app, session_cookie ): - if 'is_api_request' in environ: - return DemoWebAPITransaction( environ, demo_app, self ) - else: - return DemoWebUITransaction( environ, demo_app, self, session_cookie ) - -class DemoWebTransaction( galaxy.web.framework.base.DefaultWebTransaction ): - """ - Encapsulates web transaction specific state for the Demo application - (specifically the user's "cookie") - """ - def __init__( self, environ, app, webapp ): - self.app = app - self.webapp = webapp - self.security = webapp.security - galaxy.web.framework.base.DefaultWebTransaction.__init__( self, environ ) - self.debug = asbool( self.app.config.get( 'debug', False ) ) - def get_cookie( self, name='demosequencersession' ): - """Convenience method for getting a session cookie""" - try: - # If we've changed the cookie during the request return the new value - if name in self.response.cookies: - return self.response.cookies[name].value - else: - return self.request.cookies[name].value - except: - return None - def set_cookie( self, value, name='demosequencersession', path='/', age=90, version='1' ): - """Convenience method for setting a session cookie""" - # The demosequencersession cookie value must be a high entropy 128 bit random number encrypted - # using a server secret key. Any other value is invalid and could pose security issues. - self.response.cookies[name] = value - self.response.cookies[name]['path'] = path - self.response.cookies[name]['max-age'] = 3600 * 24 * age # 90 days - tstamp = time.localtime ( time.time() + 3600 * 24 * age ) - self.response.cookies[name]['expires'] = time.strftime( '%a, %d-%b-%Y %H:%M:%S GMT', tstamp ) - self.response.cookies[name]['version'] = version - def __update_session_cookie( self, name='galaxysession' ): - """ - Update the session cookie to match the current session. - """ - self.set_cookie( self.security.encode_guid( self.galaxy_session.session_key ), name=name, path=self.app.config.cookie_path ) - def get_galaxy_session( self ): - """ - Return the current galaxy session - """ - return self.galaxy_session - @galaxy.web.framework.base.lazy_property - def template_context( self ): - return dict() - - def set_message( self, message, type=None ): - """ - Convenience method for setting the 'message' and 'message_type' - element of the template context. - """ - self.template_context['message'] = message - if type: - self.template_context['status'] = type - def get_message( self ): - """ - Convenience method for getting the 'message' element of the template - context. - """ - return self.template_context['message'] - def show_message( self, message, type='info', refresh_frames=[], cont=None, use_panels=False, active_view="" ): - """ - Convenience method for displaying a simple page with a single message. - - `type`: one of "error", "warning", "info", or "done"; determines the - type of dialog box and icon displayed with the message - - `refresh_frames`: names of frames in the interface that should be - refreshed when the message is displayed - """ - return self.fill_template( "message.mako", status=type, message=message, refresh_frames=refresh_frames, cont=cont, use_panels=use_panels, active_view=active_view ) - def show_error_message( self, message, refresh_frames=[], use_panels=False, active_view="" ): - """ - Convenience method for displaying an error message. See `show_message`. - """ - return self.show_message( message, 'error', refresh_frames, use_panels=use_panels, active_view=active_view ) - def show_ok_message( self, message, refresh_frames=[], use_panels=False, active_view="" ): - """ - Convenience method for displaying an ok message. See `show_message`. - """ - return self.show_message( message, 'done', refresh_frames, use_panels=use_panels, active_view=active_view ) - def show_warn_message( self, message, refresh_frames=[], use_panels=False, active_view="" ): - """ - Convenience method for displaying an warn message. See `show_message`. - """ - return self.show_message( message, 'warning', refresh_frames, use_panels=use_panels, active_view=active_view ) - def show_form( self, form, header=None, template="form.mako", use_panels=False, active_view="" ): - """ - Convenience method for displaying a simple page with a single HTML - form. - """ - return self.fill_template( template, form=form, header=header, use_panels=( form.use_panels or use_panels ), - active_view=active_view ) - def fill_template(self, filename, **kwargs): - """ - Fill in a template, putting any keyword arguments on the context. - """ - if filename.endswith( ".mako" ): - return self.fill_template_mako( filename, **kwargs ) - else: - template = Template( file=os.path.join(self.app.config.template_path, filename), - searchList=[kwargs, self.template_context, dict(caller=self, t=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app)] ) - return str( template ) - def fill_template_mako( self, filename, **kwargs ): - template = self.webapp.mako_template_lookup.get_template( filename ) - template.output_encoding = 'utf-8' - data = dict( caller=self, t=self, trans=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app ) - data.update( self.template_context ) - data.update( kwargs ) - return template.render( **data ) - def stream_template_mako( self, filename, **kwargs ): - template = self.webapp.mako_template_lookup.get_template( filename ) - template.output_encoding = 'utf-8' - data = dict( caller=self, t=self, trans=self, h=helpers, util=util, request=self.request, response=self.response, app=self.app ) - data.update( self.template_context ) - data.update( kwargs ) - ## return template.render( **data ) - def render( environ, start_response ): - response_write = start_response( self.response.wsgi_status(), self.response.wsgi_headeritems() ) - class StreamBuffer( object ): - def write( self, d ): - response_write( d.encode( 'utf-8' ) ) - buffer = StreamBuffer() - context = mako.runtime.Context( buffer, **data ) - template.render_context( context ) - return [] - return render - def fill_template_string(self, template_string, context=None, **kwargs): - """ - Fill in a template, putting any keyword arguments on the context. - """ - template = Template( source=template_string, - searchList=[context or kwargs, dict(caller=self)] ) - return str(template) - -class DemoWebAPITransaction( DemoWebTransaction ): - def __init__( self, environ, app, webapp ): - DemoWebTransaction.__init__( self, environ, app, webapp ) - -class DemoWebUITransaction( DemoWebTransaction ): - def __init__( self, environ, app, webapp, session_cookie ): - DemoWebTransaction.__init__( self, environ, app, webapp ) diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/registry.py --- a/lib/galaxy/webapps/demo_sequencer/registry.py +++ /dev/null @@ -1,109 +0,0 @@ -import logging -import galaxy.util -from galaxy.util.odict import odict - -class Registry( object ): - def __init__( self, root_dir=None, config=None ): - self.log = logging.getLogger( __name__ ) - self.log.addHandler( logging.NullHandler() ) - self.redirect_delay = 2.0 # Default to 2 seconds - self.final_redirect = [] - self.sequencer_redirects = odict() - self.sequencer_requests = [] - self.authenticated = False - self.browser_login = None - self.http_headers_authorization = None - self.basic_http_authentication = None - self.http_cookie_processor_authentication = None - if root_dir and config: - tree = galaxy.util.parse_xml( config ) - root = tree.getroot() - self.log.debug( 'Loading sequencer actions from %s' % config ) - try: - # Load the redirect delay value, if any ( default is 2 seconds ). - for redirect_delay in root.findall( 'redirect_delay' ): - delay = redirect_delay.get( 'value', self.redirect_delay ) - self.redirect_delay = float( delay ) - # Load http_headers_authorization information, if any. - for authentication_elem in root.findall( 'http_headers_authorization' ): - # Example tag: - # <http_headers_authorization credentials="administrator:galaxy" url="http://127.0.0.1" /> - url = authentication_elem.get( 'url', '' ) - credentials = authentication_elem.get( 'credentials', '' ) - self.http_headers_authorization = ( url, credentials ) - # Load basic_http_authentication information, if any. - for authentication_elem in root.findall( 'basic_http_authentication' ): - # Example tag: - # <basic_http_authentication user="administrator" password="galaxy" url="http://127.0.0.1" realm="" /> - urls = [] - user = authentication_elem.get( 'user', '' ) - password = authentication_elem.get( 'password', '' ) - url = authentication_elem.get( 'url', '' ) - realm = authentication_elem.get( 'realm', '' ) - self.basic_http_authentication.append( ( user, password, url, realm ) ) - # Load http_cookie_processor_authentication information, if any. - for authentication_elem in root.findall( 'http_cookie_processor_authentication' ): - # Example tag: - # <http_cookie_processor_authentication url="http://127.0.0.1/login"> - # <param name="user" value="administrator"/> - # <param name="password" value="galaxy"/> - # </http_cookie_processor_authentication> - url = authentication_elem.get( 'url', None ) - if url: - # Include parameters, if any - params = {} - for param_elem in authentication_elem.findall( 'param' ): - param_name = param_elem.get( 'name' ) - param_value = param_elem.get( 'value' ) - params[ param_name ] = param_value - self.http_cookie_processor_authentication = dict( url=url, params=params ) - # Load browser_login information, if any. - for authentication_elem in root.findall( 'browser_login' ): - url = authentication_elem.get( 'url', None ) - if url: - # Include parameters, if any - params = {} - for param_elem in authentication_elem.findall( 'param' ): - param_name = param_elem.get( 'name' ) - param_value = param_elem.get( 'value' ) - params[ param_name ] = param_value - self.browser_login = dict( url=url, params=params ) - # Load redirects - for redirect_elem in root.findall( 'redirect' ): - requests = [] - action_dict = {} - action_dict[ 'title' ] = redirect_elem.get( 'title', None ) - action = redirect_elem.get( 'action', None ) - # Load the external webapp requests, if any exist for this redirect action - for request_elem in redirect_elem.findall( 'external_webapp' ): - requests.append( self.parse_request_elem( request_elem ) ) - if requests: - action_dict[ 'requests' ] = requests - self.sequencer_redirects[ action ] = action_dict - # Load the external webapp requests, if any exist for the sequencer action - for request_elem in root.findall( 'external_webapp' ): - self.sequencer_requests.append( self.parse_request_elem( request_elem ) ) - # Load the special final redirect, used to redirect the browser to defined URL. - for request_elem in root.findall( 'final_redirect' ): - self.final_redirect.append( self.parse_request_elem( request_elem ) ) - except Exception, e: - self.log.debug( 'Error loading sequencer action: %s' % str( e ) ) - # Default values - if not self.sequencer_redirects: - self.sequencer_redirects[ 'start_run' ] = dict( title = 'Start run' ) - self.sequencer_redirects[ 'run_finished' ] = dict( title = 'Run finished' ) - def parse_request_elem( self, request_elem ): - request = request_elem.get( 'request', None ) - # Get the http method, default is get - http_method = request_elem.get( 'http_method', 'get' ) - # Include request parameters, if any - params = {} - for param_elem in request_elem.findall( 'param' ): - param_name = param_elem.get( 'name' ) - param_value = param_elem.get( 'value' ) - params[ param_name ] = param_value - # Handle response, if any ( there should only be 0 or 1 ). - response_type = None - for response_elem in request_elem.findall( 'response' ): - response_type = response_elem.get( 'type', None ) - return ( request, http_method, params, response_type ) diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 lib/galaxy/webapps/demo_sequencer/sequencer_actions.xml.sample --- a/lib/galaxy/webapps/demo_sequencer/sequencer_actions.xml.sample +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0"?> -<sequencer_actions> - <redirect title="Start run" action="start_run"/> - <redirect title="Run finished" action="run_finished"/> -</sequencer_actions> diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 run_demo_sequencer.sh --- a/run_demo_sequencer.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd `dirname $0` -python ./scripts/paster.py serve demo_sequencer_wsgi.ini --pid-file=demo_sequencer_webapp.pid --log-file=demo_sequencer_webapp.log $@ \ No newline at end of file diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 templates/webapps/demo_sequencer/empty.mako --- a/templates/webapps/demo_sequencer/empty.mako +++ /dev/null @@ -1,4 +0,0 @@ -<html> - <body> - </body> -</html> diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 templates/webapps/demo_sequencer/index.mako --- a/templates/webapps/demo_sequencer/index.mako +++ /dev/null @@ -1,54 +0,0 @@ -<%inherit file="/base.mako"/> - -<% - import galaxy.util - titles_list = util.listify( titles ) -%> - -<%def name="javascripts()"> - ${parent.javascripts()} - %if redirect_action != 'exit': - <script type="text/javascript"> - function redirect(){ - top.location.href = "${h.url_for( controller='common', action='index', redirect_action=redirect_action, titles=titles, JobId=JobId, sample_id=sample_id )}"; - } - function set_redirect(){ - %if redirect_delay: - setTimeout("redirect()", ${int(redirect_delay)*1000}); - %else: - setTimeout("redirect()", 2000); - %endif - } - </script> - %endif -</%def> - -## Render a message - can't import because we don't support language encoding here -<%def name="render_message( message, status='done' )"> - <div class="${status}message">${message}</div> - <br/> -</%def> - -%if message: - ${render_message( message, status )} -%endif - -<body onload="set_redirect()"> - <table border="0" align="center" valign="center" cellpadding="5" cellspacing="5"> - <tr><td><img src='static/images/sequencer.png' alt="Sequencer" /></td></tr> - <tr> - <td align="center"> - %if titles_list: - %for title in titles_list: - <h2>${title}</h2> - %endfor - %else: - <h2> </h2> - %endif - </td> - </tr> - </table> - %if not trans.app.sequencer_actions_registry.authenticated and trans.app.sequencer_actions_registry.browser_login: - <iframe name="login" id="login" frameborder="0" style="position: absolute; width: 0%; height: 0%;" src="${h.url_for( controller="common", action="login" )}"></iframe> - %endif -</body> diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 templates/webapps/demo_sequencer/login.mako --- a/templates/webapps/demo_sequencer/login.mako +++ /dev/null @@ -1,10 +0,0 @@ -<html> - <body> - <iframe name="trash" frameborder="0" style="position: absolute; width: 0%; height: 0%;" src="${h.url_for( controller="common", action="empty_page" )}"></iframe> - <form id="logOnForm" name="logOnForm" method="post" action="${trans.app.sequencer_actions_registry.browser_login}" target="trash"> - </form> - <script type="text/javascript"> - document.logOnForm.submit(); - </script> - </body> -</html> diff -r 4b4eee11c31b90eae05db88047a5a675ec645f1b -r d99406f5b690ed130023d8b51cbb5b50a0f4ed12 templates/webapps/demo_sequencer/redirect.mako --- a/templates/webapps/demo_sequencer/redirect.mako +++ /dev/null @@ -1,10 +0,0 @@ -<html> - <head> - <meta http-equiv="refresh" content="1;url=${redirect_url}"> - </head> - <body> - %if trans.app.sequencer_actions_registry.browser_login: - <iframe name="login" id="login" frameborder="0" style="position: absolute; width: 0%; height: 0%;" src="${h.url_for( controller="common", action="login" )}"></iframe> - %endif - </body> -</html> 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.