def reset_config(self): '''FIXME: This method is probably not doing what people would expect. It will reset the configuration to values cached when CKAN started. If these were coming from the database during startup, that's the ones that will get applied on reset, not the ones in the ini file. Only after restarting the server and having CKAN reset the values from the ini file (as the db ones are not there anymore) will these be used. ''' if 'cancel' in request.params: h.redirect_to(controller='admin', action='config') if request.method == 'POST': #check against csrf attacks custom_base.csrf_check(self) # remove sys info items for item in self._get_config_form_items(): name = item['name'] model.delete_system_info(name) # reset to values in config app_globals.reset() h.redirect_to(controller='admin', action='config') return base.render('admin/confirm_reset.html')
def post(self): # remove sys info items for item in _get_config_items(): model.delete_system_info(item) # reset to values in config app_globals.reset() return h.redirect_to(u'admin.config')
def load_environment(conf): """ Configure the Pylons environment via the ``pylons.config`` object. This code should only need to be run once. """ os.environ['CKAN_CONFIG'] = conf['__file__'] # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) valid_base_public_folder_names = ['public'] static_files = conf.get('ckan.base_public_folder', 'public') conf['ckan.base_public_folder'] = static_files if static_files not in valid_base_public_folder_names: raise CkanConfigurationException( 'You provided an invalid value for ckan.base_public_folder. ' 'Possible values are: "public".' ) log.info('Loading static files from %s' % static_files) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, static_files), templates=[]) # Initialize main CKAN config object config.update(conf) # Setup the SQLAlchemy database engine # Suppress a couple of sqlalchemy warnings msgs = ['^Unicode type received non-unicode bind param value', "^Did not recognize type 'BIGINT' of column 'size'", "^Did not recognize type 'tsvector' of column 'search_vector'" ] for msg in msgs: warnings.filterwarnings('ignore', msg, sqlalchemy.exc.SAWarning) # load all CKAN plugins p.load_all() # Check Redis availability if not is_redis_available(): log.critical('Could not connect to Redis.') app_globals.reset() # issue #3260: remove idle transaction # Session that was used for getting all config params nor committed, # neither removed and we have idle connection as result model.Session.commit() # Build JavaScript translations. Must be done after plugins have # been loaded. build_js_translations()
def reset_config(self): if 'cancel' in request.params: h.redirect_to(controller='ckanext.cloud_connector.s3.controller:S3Controller', action='config') if request.method == 'POST': # remove sys info items for item in s3_option_items: app_globals.delete_global(item) # reset to values in config app_globals.reset() h.redirect_to(controller='ckanext.cloud_connector.s3.controller:S3Controller', action='config')
def reset_config(self): if "cancel" in request.params: h.redirect_to(controller="admin", action="config") if request.method == "POST": # remove sys info items for item in self._get_config_form_items(): name = item["name"] app_globals.delete_global(name) # reset to values in config app_globals.reset() h.redirect_to(controller="admin", action="config") return base.render("admin/confirm_reset.html")
def reset_config(self): if 'cancel' in request.params: h.redirect_to(controller='admin', action='config') if request.method == 'POST': # remove sys info items for item in self._get_config_form_items(): name = item['name'] app_globals.delete_global(name) # reset to values in config app_globals.reset() h.redirect_to(controller='admin', action='config') return base.render('admin/confirm_reset.html')
def config(self): data = request.POST if 'save' in data: # update config from form for item in s3_option_items: if item in data: app_globals.set_global(item, data[item]) app_globals.reset() h.redirect_to(controller='ckanext.cloud_connector.s3.controller:S3Controller', action='config') data = {} for item in s3_option_items: data[item] = config.get(item) vars = {'data': data, 'errors': {}, 'form_items': s3_option_items} return base.render('admin/cloud_connector_config.html', extra_vars = vars)
def load_environment(conf: Union[Config, CKANConfig]): """ Configure the Pylons environment via the ``pylons.config`` object. This code should only need to be run once. """ os.environ['CKAN_CONFIG'] = cast(str, conf['__file__']) valid_base_public_folder_names = ['public', 'public-bs3'] static_files = conf.get('ckan.base_public_folder', 'public') conf['ckan.base_public_folder'] = static_files if static_files not in valid_base_public_folder_names: raise CkanConfigurationException( 'You provided an invalid value for ckan.base_public_folder. ' 'Possible values are: "public" and "public-bs3".') log.info('Loading static files from %s' % static_files) # Initialize main CKAN config object config.update(conf) # Setup the SQLAlchemy database engine # Suppress a couple of sqlalchemy warnings msgs = [ '^Unicode type received non-unicode bind param value', "^Did not recognize type 'BIGINT' of column 'size'", "^Did not recognize type 'tsvector' of column 'search_vector'" ] for msg in msgs: warnings.filterwarnings('ignore', msg, sqlalchemy.exc.SAWarning) # load all CKAN plugins p.load_all() # Check Redis availability if not is_redis_available(): log.critical('Could not connect to Redis.') app_globals.reset() # Build JavaScript translations. Must be done after plugins have # been loaded. build_js_translations()
def config(self): items = self._get_config_form_items() data = request.POST if "save" in data: # update config from form for item in items: name = item["name"] if name in data: app_globals.set_global(name, data[name]) app_globals.reset() h.redirect_to(controller="admin", action="config") data = {} for item in items: name = item["name"] data[name] = config.get(name) vars = {"data": data, "errors": {}, "form_items": items} return base.render("admin/config.html", extra_vars=vars)
def config(self): items = self._get_config_form_items() data = request.POST if 'save' in data: # update config from form for item in items: name = item['name'] if name in data: app_globals.set_global(name, data[name]) app_globals.reset() h.redirect_to(controller='admin', action='config') data = {} for item in items: name = item['name'] data[name] = config.get(name) vars = {'data': data, 'errors': {}, 'form_items': items} return base.render('admin/config.html', extra_vars=vars)
def config(self): items = self._get_config_form_items() data = request.POST if 'save' in data: # update config from form for item in items: name = item['name'] if name in data: app_globals.set_global(name, data[name]) app_globals.reset() h.redirect_to(controller='admin', action='config') data = {} for item in items: name = item['name'] data[name] = config.get(name) vars = {'data': data, 'errors': {}, 'form_items': items} return base.render('admin/config.html', extra_vars = vars)
def config(self, items): """ If this method gets called from the vanilla admin page for custom UI settings, then we update the ckan.* config variables through the 'app_globals' module and CKAN stores that information in the 'system_info' table so that custom configs will persist through a server failure. If this method gets called from the NGDS admin page for data settings, then the 'app_globals' module gets updated in memory but we write the configs to a custom 'ngds_system_info' table. @param items: pylons global config options @return: dictionary """ data = request.POST if 'data-config' in data: if db.ngds_system_info is None: db.init(model) update_db = db.SysadminConfig.get(active_config=True) if data.get('data-config') == 'save': class Featured: def __init__(self, config, description): self.config = config self.description = description posted_data = tuple([ Featured(key, value) for (key, value) in data.iteritems() for item in items if key == item['name'] ]) if posted_data: posted_key = posted_data[0].config featured_data = [] for post in posted_data: featured_data.append({post.config: post.description}) featured_json = json.dumps(featured_data) app_globals.set_global(posted_key, featured_json) setattr(update_db, posted_key, featured_json) app_globals.reset() update_db.last_edited = datetime.datetime.utcnow() update_db.save() session = model.Session session.add(update_db) session.commit() h.redirect_to(controller=self.controller, action='data_config') if data.get('data-config') == 'reset': app_globals.set_global('ngds.featured_data', None) setattr(update_db, 'ngds.featured_data', None) app_globals.reset() update_db.last_edited = datetime.datetime.utcnow() update_db.save() session = model.Session session.add(update_db) session.commit() h.redirect_to(controller=self.controller, action='data_config') if 'save-operating-config' in data: # Set up ORM if it's not already set if db.ngds_system_info is None: db.init(model) # Get db data to update update_db = db.SysadminConfig.get(active_config=True) for item in items: name = item['name'] if name in data: # Update app_globals in memory app_globals.set_global(name, data[name]) # Update database setattr(update_db, name, data.get(name)) app_globals.reset() update_db.last_edited = datetime.datetime.utcnow() update_db.save() session = model.Session session.add(update_db) session.commit() h.redirect_to(controller=self.controller, action='operating_config') if 'save-style-config' in data: for item in items: name = item['name'] if name in data: app_globals.set_global(name, data[name]) app_globals.reset() h.redirect_to(controller=self.controller, action='style_config') data = {} for item in items: name = item['name'] data[name] = config.get(name) try: data = json.loads(data) except: pass return {'data': data, 'errors': {}, 'form_items': items}
def load_environment(conf): """ Configure the Pylons environment via the ``pylons.config`` object. This code should only need to be run once. """ if six.PY2: # this must be run at a time when the env is semi-setup, thus inlined # here. Required by the deliverance plugin and iATI from pylons.wsgiapp import PylonsApp import pkg_resources find_controller_generic = getattr(PylonsApp.find_controller, '_old_find_controller', PylonsApp.find_controller) # This is from pylons 1.0 source, will monkey-patch into 0.9.7 def find_controller(self, controller): if controller in self.controller_classes: return self.controller_classes[controller] # Check to see if its a dotted name if '.' in controller or ':' in controller: ep = pkg_resources.EntryPoint.parse('x={0}'.format(controller)) if hasattr(ep, 'resolve'): # setuptools >= 10.2 mycontroller = ep.resolve() else: # setuptools >= 11.3 mycontroller = ep.load(False) self.controller_classes[controller] = mycontroller return mycontroller return find_controller_generic(self, controller) find_controller._old_find_controller = find_controller_generic PylonsApp.find_controller = find_controller os.environ['CKAN_CONFIG'] = conf['__file__'] # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) valid_base_public_folder_names = ['public'] static_files = conf.get('ckan.base_public_folder', 'public') conf['ckan.base_public_folder'] = static_files if static_files not in valid_base_public_folder_names: raise CkanConfigurationException( 'You provided an invalid value for ckan.base_public_folder. ' 'Possible values are: "public".') log.info('Loading static files from %s' % static_files) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, static_files), templates=[]) # Initialize main CKAN config object config.update(conf) if six.PY2: # Initialize Pylons own config object pylons_config.init_app(conf['global_conf'], conf, package='ckan', paths=paths) # Update the main CKAN config object with the Pylons specific stuff, # as it is quite hard to keep them separated. This should be removed # once Pylons support is dropped config.update(pylons_config) # Setup the SQLAlchemy database engine # Suppress a couple of sqlalchemy warnings msgs = [ '^Unicode type received non-unicode bind param value', "^Did not recognize type 'BIGINT' of column 'size'", "^Did not recognize type 'tsvector' of column 'search_vector'" ] for msg in msgs: warnings.filterwarnings('ignore', msg, sqlalchemy.exc.SAWarning) # load all CKAN plugins p.load_all() if not p.plugin_loaded('managed_search_schema'): search.check_solr_schema_version() # Check Redis availability if not is_redis_available(): log.critical('Could not connect to Redis.') app_globals.reset() # issue #3260: remove idle transaction # Session that was used for getting all config params nor committed, # neither removed and we have idle connection as result model.Session.commit() # Build JavaScript translations. Must be done after plugins have # been loaded. build_js_translations()
def load_environment(global_conf, app_conf): """ Configure the Pylons environment via the ``pylons.config`` object. This code should only need to be run once. """ # this must be run at a time when the env is semi-setup, thus inlined here. # Required by the deliverance plugin and iATI from pylons.wsgiapp import PylonsApp import pkg_resources find_controller_generic = PylonsApp.find_controller # This is from pylons 1.0 source, will monkey-patch into 0.9.7 def find_controller(self, controller): if controller in self.controller_classes: return self.controller_classes[controller] # Check to see if its a dotted name if '.' in controller or ':' in controller: ep = pkg_resources.EntryPoint.parse('x={0}'.format(controller)) if hasattr(ep, 'resolve'): # setuptools >= 10.2 mycontroller = ep.resolve() else: # setuptools >= 11.3 mycontroller = ep.load(False) self.controller_classes[controller] = mycontroller return mycontroller return find_controller_generic(self, controller) PylonsApp.find_controller = find_controller os.environ['CKAN_CONFIG'] = global_conf['__file__'] # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) valid_base_public_folder_names = ['public', 'public-bs2'] static_files = app_conf.get('ckan.base_public_folder', 'public') app_conf['ckan.base_public_folder'] = static_files if static_files not in valid_base_public_folder_names: raise CkanConfigurationException( 'You provided an invalid value for ckan.base_public_folder. ' 'Possible values are: "public" and "public-bs2".' ) log.info('Loading static files from %s' % static_files) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, static_files), templates=[]) # Initialize main CKAN config object config.update(global_conf) config.update(app_conf) # Initialize Pylons own config object pylons_config.init_app(global_conf, app_conf, package='ckan', paths=paths) # Update the main CKAN config object with the Pylons specific stuff, as it # quite hard to keep them separated. This should be removed once Pylons # support is dropped config.update(pylons_config) # Setup the SQLAlchemy database engine # Suppress a couple of sqlalchemy warnings msgs = ['^Unicode type received non-unicode bind param value', "^Did not recognize type 'BIGINT' of column 'size'", "^Did not recognize type 'tsvector' of column 'search_vector'" ] for msg in msgs: warnings.filterwarnings('ignore', msg, sqlalchemy.exc.SAWarning) # load all CKAN plugins p.load_all() # Check Redis availability if not is_redis_available(): log.critical('Could not connect to Redis.') app_globals.reset() # issue #3260: remove idle transaction # Session that was used for getting all config params nor committed, # neither removed and we have idle connection as result model.Session.commit() # Build JavaScript translations. Must be done after plugins have # been loaded. build_js_translations()
def make_app(conf, full_stack=True, static_files=True, **app_conf): """Create a Pylons WSGI application and return it ``conf`` The inherited configuration for this application. Normally from the [DEFAULT] section of the Paste ini file. ``full_stack`` Whether this application provides a full WSGI stack (by default, meaning it handles its own exceptions and errors). Disable full_stack when this application is "managed" by another WSGI middleware. ``static_files`` Whether this application serves its own static files; disable when another web server is responsible for serving them. ``app_conf`` The application's local configuration. Normally specified in the [app:<name>] section of the Paste ini file (where <name> defaults to main). """ # Configure the Pylons environment load_environment(conf, app_conf) # The Pylons WSGI app app = PylonsApp() # set pylons globals app_globals.reset() for plugin in PluginImplementations(IMiddleware): app = plugin.make_middleware(app, config) # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map']) # we want to be able to retrieve the routes middleware to be able to update # the mapper. We store it in the pylons config to allow this. config['routes.middleware'] = app app = SessionMiddleware(app, config) app = CacheMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) #app = QueueLogMiddleware(app) # Fanstatic if asbool(config.get('debug', False)): fanstatic_config = { 'versioning': True, 'recompute_hashes': True, 'minified': False, 'bottom': True, 'bundle': False, } else: fanstatic_config = { 'versioning': True, 'recompute_hashes': False, 'minified': True, 'bottom': True, 'bundle': True, } app = Fanstatic(app, **fanstatic_config) if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, conf, **config['pylons.errorware']) # Display error documents for 401, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app, [400, 404]) else: app = StatusCodeRedirect(app, [400, 404, 500]) # Initialize repoze.who who_parser = WhoConfig(conf['here']) who_parser.parse(open(app_conf['who.config_file'])) if asbool(config.get('openid_enabled', 'true')): from repoze.who.plugins.openid.identification import OpenIdIdentificationPlugin # Monkey patches for repoze.who.openid # Fixes #1659 - enable log-out when CKAN mounted at non-root URL from ckan.lib import repoze_patch OpenIdIdentificationPlugin.identify = repoze_patch.identify OpenIdIdentificationPlugin.redirect_to_logged_in = repoze_patch.redirect_to_logged_in OpenIdIdentificationPlugin._redirect_to_loginform = repoze_patch._redirect_to_loginform OpenIdIdentificationPlugin.challenge = repoze_patch.challenge who_parser.identifiers = [i for i in who_parser.identifiers if \ not isinstance(i, OpenIdIdentificationPlugin)] who_parser.challengers = [i for i in who_parser.challengers if \ not isinstance(i, OpenIdIdentificationPlugin)] app = PluggableAuthenticationMiddleware(app, who_parser.identifiers, who_parser.authenticators, who_parser.challengers, who_parser.mdproviders, who_parser.request_classifier, who_parser.challenge_decider, logging.getLogger('repoze.who'), logging.WARN, # ignored who_parser.remote_user_key, ) # Establish the Registry for this application app = RegistryManager(app) app = I18nMiddleware(app, config) if asbool(static_files): # Serve static files static_max_age = None if not asbool(config.get('ckan.cache_enabled')) \ else int(config.get('ckan.static_max_age', 3600)) static_app = StaticURLParser(config['pylons.paths']['static_files'], cache_max_age=static_max_age) static_parsers = [static_app, app] # Configurable extra static file paths extra_static_parsers = [] for public_path in config.get('extra_public_paths', '').split(','): if public_path.strip(): extra_static_parsers.append( StaticURLParser(public_path.strip(), cache_max_age=static_max_age) ) app = Cascade(extra_static_parsers + static_parsers) # Page cache if asbool(config.get('ckan.page_cache_enabled')): app = PageCacheMiddleware(app, config) # Tracking if asbool(config.get('ckan.tracking_enabled', 'false')): app = TrackingMiddleware(app, config) return app
def load_environment(global_conf, app_conf): """ Configure the Pylons environment via the ``pylons.config`` object. This code should only need to be run once. """ # this must be run at a time when the env is semi-setup, thus inlined here. # Required by the deliverance plugin and iATI from pylons.wsgiapp import PylonsApp import pkg_resources find_controller_generic = PylonsApp.find_controller # This is from pylons 1.0 source, will monkey-patch into 0.9.7 def find_controller(self, controller): if controller in self.controller_classes: return self.controller_classes[controller] # Check to see if its a dotted name if '.' in controller or ':' in controller: ep = pkg_resources.EntryPoint.parse('x={0}'.format(controller)) if hasattr(ep, 'resolve'): # setuptools >= 10.2 mycontroller = ep.resolve() else: # setuptools >= 11.3 mycontroller = ep.load(False) self.controller_classes[controller] = mycontroller return mycontroller return find_controller_generic(self, controller) PylonsApp.find_controller = find_controller os.environ['CKAN_CONFIG'] = global_conf['__file__'] # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[]) # Initialize main CKAN config object config.update(global_conf) config.update(app_conf) # Initialize Pylons own config object pylons_config.init_app(global_conf, app_conf, package='ckan', paths=paths) # Update the main CKAN config object with the Pylons specific stuff, as it # quite hard to keep them separated. This should be removed once Pylons # support is dropped config.update(pylons_config) # Setup the SQLAlchemy database engine # Suppress a couple of sqlalchemy warnings msgs = [ '^Unicode type received non-unicode bind param value', "^Did not recognize type 'BIGINT' of column 'size'", "^Did not recognize type 'tsvector' of column 'search_vector'" ] for msg in msgs: warnings.filterwarnings('ignore', msg, sqlalchemy.exc.SAWarning) # Check Redis availability if not is_redis_available(): log.critical('Could not connect to Redis.') # load all CKAN plugins p.load_all() app_globals.reset()
def config(self, items): """ If this method gets called from the vanilla admin page for custom UI settings, then we update the ckan.* config variables through the 'app_globals' module and CKAN stores that information in the 'system_info' table so that custom configs will persist through a server failure. If this method gets called from the NGDS admin page for data settings, then the 'app_globals' module gets updated in memory but we write the configs to a custom 'ngds_system_info' table. @param items: pylons global config options @return: dictionary """ data = request.POST if 'data-config' in data: if db.ngds_system_info is None: db.init(model) update_db = db.SysadminConfig.get(active_config=True) if data.get('data-config') == 'save': class Featured: def __init__(self, config, description): self.config = config self.description = description posted_data = tuple([Featured(key, value) for (key, value) in data.iteritems() for item in items if key == item['name']]) if posted_data: posted_key = posted_data[0].config featured_data = [] for post in posted_data: featured_data.append({post.config: post.description}) featured_json = json.dumps(featured_data) app_globals.set_global(posted_key, featured_json) setattr(update_db, posted_key, featured_json) app_globals.reset() update_db.last_edited = datetime.datetime.utcnow() update_db.save() session = model.Session session.add(update_db) session.commit() h.redirect_to(controller=self.controller, action='data_config') if data.get('data-config') == 'reset': app_globals.set_global('ngds.featured_data', None) setattr(update_db, 'ngds.featured_data', None) app_globals.reset() update_db.last_edited = datetime.datetime.utcnow() update_db.save() session = model.Session session.add(update_db) session.commit() h.redirect_to(controller=self.controller, action='data_config') if 'save-operating-config' in data: # Set up ORM if it's not already set if db.ngds_system_info is None: db.init(model) # Get db data to update update_db = db.SysadminConfig.get(active_config=True) for item in items: name = item['name'] if name in data: # Update app_globals in memory app_globals.set_global(name, data[name]) # Update database setattr(update_db, name, data.get(name)) app_globals.reset() update_db.last_edited = datetime.datetime.utcnow() update_db.save() session = model.Session session.add(update_db) session.commit() h.redirect_to(controller=self.controller, action='operating_config') if 'save-style-config' in data: for item in items: name = item['name'] if name in data: app_globals.set_global(name, data[name]) app_globals.reset() h.redirect_to(controller=self.controller, action='style_config') data = {} for item in items: name = item['name'] data[name] = config.get(name) try: data = json.loads(data) except: pass return {'data': data, 'errors': {}, 'form_items': items}
def make_pylons_stack(conf, full_stack=True, static_files=True, **app_conf): """Create a Pylons WSGI application and return it ``conf`` The inherited configuration for this application. Normally from the [DEFAULT] section of the Paste ini file. ``full_stack`` Whether this application provides a full WSGI stack (by default, meaning it handles its own exceptions and errors). Disable full_stack when this application is "managed" by another WSGI middleware. ``static_files`` Whether this application serves its own static files; disable when another web server is responsible for serving them. ``app_conf`` The application's local configuration. Normally specified in the [app:<name>] section of the Paste ini file (where <name> defaults to main). """ # Configure the Pylons environment load_environment(conf, app_conf) # The Pylons WSGI app app = pylons_app = CKANPylonsApp() # set pylons globals app_globals.reset() for plugin in PluginImplementations(IMiddleware): app = plugin.make_middleware(app, config) # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map']) # we want to be able to retrieve the routes middleware to be able to update # the mapper. We store it in the pylons config to allow this. config['routes.middleware'] = app app = SessionMiddleware(app, config) app = CacheMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) # app = QueueLogMiddleware(app) if asbool(config.get('ckan.use_pylons_response_cleanup_middleware', True)): app = execute_on_completion(app, config, cleanup_pylons_response_string) # Fanstatic if asbool(config.get('debug', False)): fanstatic_config = { 'versioning': True, 'recompute_hashes': True, 'minified': False, 'bottom': True, 'bundle': False, } else: fanstatic_config = { 'versioning': True, 'recompute_hashes': False, 'minified': True, 'bottom': True, 'bundle': True, } app = Fanstatic(app, **fanstatic_config) for plugin in PluginImplementations(IMiddleware): try: app = plugin.make_error_log_middleware(app, config) except AttributeError: log.critical('Middleware class {0} is missing the method' 'make_error_log_middleware.' .format(plugin.__class__.__name__)) if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, conf, **config['pylons.errorware']) # Display error documents for 400, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app, [400, 403, 404]) else: app = StatusCodeRedirect(app, [400, 403, 404, 500]) # Initialize repoze.who who_parser = WhoConfig(conf['here']) who_parser.parse(open(app_conf['who.config_file'])) app = PluggableAuthenticationMiddleware( app, who_parser.identifiers, who_parser.authenticators, who_parser.challengers, who_parser.mdproviders, who_parser.request_classifier, who_parser.challenge_decider, logging.getLogger('repoze.who'), logging.WARN, # ignored who_parser.remote_user_key ) # Establish the Registry for this application app = RegistryManager(app) app = common_middleware.I18nMiddleware(app, config) if asbool(static_files): # Serve static files static_max_age = None if not asbool(config.get('ckan.cache_enabled')) \ else int(config.get('ckan.static_max_age', 3600)) static_app = StaticURLParser(config['pylons.paths']['static_files'], cache_max_age=static_max_age) static_parsers = [static_app, app] storage_directory = uploader.get_storage_path() if storage_directory: path = os.path.join(storage_directory, 'storage') try: os.makedirs(path) except OSError, e: # errno 17 is file already exists if e.errno != 17: raise storage_app = StaticURLParser(path, cache_max_age=static_max_age) static_parsers.insert(0, storage_app) # Configurable extra static file paths extra_static_parsers = [] for public_path in config.get('extra_public_paths', '').split(','): if public_path.strip(): extra_static_parsers.append( StaticURLParser(public_path.strip(), cache_max_age=static_max_age) ) app = Cascade(extra_static_parsers + static_parsers)
def load_environment(global_conf, app_conf): """ Configure the Pylons environment via the ``pylons.config`` object. This code should only need to be run once. """ # this must be run at a time when the env is semi-setup, thus inlined here. # Required by the deliverance plugin and iATI from pylons.wsgiapp import PylonsApp import pkg_resources find_controller_generic = PylonsApp.find_controller # This is from pylons 1.0 source, will monkey-patch into 0.9.7 def find_controller(self, controller): if controller in self.controller_classes: return self.controller_classes[controller] # Check to see if its a dotted name if '.' in controller or ':' in controller: ep = pkg_resources.EntryPoint.parse('x={0}'.format(controller)) if hasattr(ep, 'resolve'): # setuptools >= 10.2 mycontroller = ep.resolve() else: # setuptools >= 11.3 mycontroller = ep.load(False) self.controller_classes[controller] = mycontroller return mycontroller return find_controller_generic(self, controller) PylonsApp.find_controller = find_controller os.environ['CKAN_CONFIG'] = global_conf['__file__'] # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[]) # Initialize main CKAN config object config.update(global_conf) config.update(app_conf) # Initialize Pylons own config object pylons_config.init_app(global_conf, app_conf, package='ckan', paths=paths) # Update the main CKAN config object with the Pylons specific stuff, as it # quite hard to keep them separated. This should be removed once Pylons # support is dropped config.update(pylons_config) # Setup the SQLAlchemy database engine # Suppress a couple of sqlalchemy warnings msgs = ['^Unicode type received non-unicode bind param value', "^Did not recognize type 'BIGINT' of column 'size'", "^Did not recognize type 'tsvector' of column 'search_vector'" ] for msg in msgs: warnings.filterwarnings('ignore', msg, sqlalchemy.exc.SAWarning) # load all CKAN plugins p.load_all() app_globals.reset()
def make_pylons_stack(conf, full_stack=True, static_files=True, **app_conf): """Create a Pylons WSGI application and return it ``conf`` The inherited configuration for this application. Normally from the [DEFAULT] section of the Paste ini file. ``full_stack`` Whether this application provides a full WSGI stack (by default, meaning it handles its own exceptions and errors). Disable full_stack when this application is "managed" by another WSGI middleware. ``static_files`` Whether this application serves its own static files; disable when another web server is responsible for serving them. ``app_conf`` The application's local configuration. Normally specified in the [app:<name>] section of the Paste ini file (where <name> defaults to main). """ # Configure the Pylons environment load_environment(conf, app_conf) # The Pylons WSGI app app = PylonsApp() # set pylons globals app_globals.reset() for plugin in PluginImplementations(IMiddleware): app = plugin.make_middleware(app, config) # Routing/Session/Cache Middleware app = RoutesMiddleware(app, config['routes.map']) # we want to be able to retrieve the routes middleware to be able to update # the mapper. We store it in the pylons config to allow this. config['routes.middleware'] = app app = SessionMiddleware(app, config) app = CacheMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) # app = QueueLogMiddleware(app) if asbool(config.get('ckan.use_pylons_response_cleanup_middleware', True)): app = execute_on_completion(app, config, cleanup_pylons_response_string) # Fanstatic if asbool(config.get('debug', False)): fanstatic_config = { 'versioning': True, 'recompute_hashes': True, 'minified': False, 'bottom': True, 'bundle': False, } else: fanstatic_config = { 'versioning': True, 'recompute_hashes': False, 'minified': True, 'bottom': True, 'bundle': True, } app = Fanstatic(app, **fanstatic_config) for plugin in PluginImplementations(IMiddleware): try: app = plugin.make_error_log_middleware(app, config) except AttributeError: log.critical('Middleware class {0} is missing the method' 'make_error_log_middleware.'.format( plugin.__class__.__name__)) if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, conf, **config['pylons.errorware']) # Display error documents for 400, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app, [400, 403, 404]) else: app = StatusCodeRedirect(app, [400, 403, 404, 500]) # Initialize repoze.who who_parser = WhoConfig(conf['here']) who_parser.parse(open(app_conf['who.config_file'])) app = PluggableAuthenticationMiddleware( app, who_parser.identifiers, who_parser.authenticators, who_parser.challengers, who_parser.mdproviders, who_parser.request_classifier, who_parser.challenge_decider, logging.getLogger('repoze.who'), logging.WARN, # ignored who_parser.remote_user_key) # Establish the Registry for this application app = RegistryManager(app) app = I18nMiddleware(app, config) if asbool(static_files): # Serve static files static_max_age = None if not asbool(config.get('ckan.cache_enabled')) \ else int(config.get('ckan.static_max_age', 3600)) static_app = StaticURLParser(config['pylons.paths']['static_files'], cache_max_age=static_max_age) static_parsers = [static_app, app] storage_directory = uploader.get_storage_path() if storage_directory: path = os.path.join(storage_directory, 'storage') try: os.makedirs(path) except OSError, e: # errno 17 is file already exists if e.errno != 17: raise storage_app = StaticURLParser(path, cache_max_age=static_max_age) static_parsers.insert(0, storage_app) # Configurable extra static file paths extra_static_parsers = [] for public_path in config.get('extra_public_paths', '').split(','): if public_path.strip(): extra_static_parsers.append( StaticURLParser(public_path.strip(), cache_max_age=static_max_age)) app = Cascade(extra_static_parsers + static_parsers)