def register_path(config, spec, discovery=False, indexes=[], request_type=None): """ Add a skin path to the current configuration state. If ``discovery`` is enabled, the path will automatically be monitored for changes. The ``indexes`` argument is an optional list of view registrations with the provided names. The ``request_type`` option decides the request type for which to make the registration. """ package_name, path = resolve_asset_spec(spec) if package_name is not None: path = pkg_resources.resource_filename(package_name, path) else: path = caller_path(path) directive = Skins(config, path, discovery, request_type) for index in indexes: directive.view(config, index) for action in directive(): config.action(*action) return directive
def __init__( self, root_dir, cache_max_age=3600, package_name=None, use_subpath=False, index='index.html', reload=False, content_encodings=(), ): # package_name is for bw compat; it is preferred to pass in a # package-relative path as root_dir # (e.g. ``anotherpackage:foo/static``). self.cache_max_age = cache_max_age if package_name is None: package_name = caller_package().__name__ package_name, docroot = resolve_asset_spec(root_dir, package_name) self.use_subpath = use_subpath self.package_name = package_name self.docroot = docroot self.norm_docroot = normcase(normpath(docroot)) self.index = index self.reload = reload self.content_encodings = _compile_content_encodings(content_encodings) self.filemap = {}
def get_template(self, uri): """Fetch a template from the cache, or check the filesystem for it In addition to the basic filesystem lookup, this subclass will use pkg_resource to load a file using the asset specification syntax. """ isabs = os.path.isabs(uri) if (not isabs) and (':' in uri): # Windows can't cope with colons in filenames, so we replace the # colon with a dollar sign in the filename mako uses to actually # store the generated python code in the mako module_directory or # in the temporary location of mako's modules adjusted = uri.replace(':', '$') try: if self.filesystem_checks: return self._check(adjusted, self._collection[adjusted]) else: return self._collection[adjusted] except KeyError: pname, path = resolve_asset_spec(uri) srcfile = abspath_from_asset_spec(path, pname) if os.path.isfile(srcfile): return self._load(srcfile, adjusted) raise exceptions.TopLevelLookupException( "Can not locate template for uri %r" % uri) return TemplateLookup.get_template(self, uri)
def __call__(self, value, system): package, filename = resolve_asset_spec(self.info.name) template = os.path.join(package_path(self.info.package), filename) template_fh = open(template) template_stream = template_fh.read() template_fh.close() return pystache.render(template_stream, value)
def config_defaults(configurator, config, files=['config.yml']): ''' Reads and extends/creates configuration from yaml source. .. note:: If exists, this method extends config with defaults, so it will not override existing values, merely add those, that were not defined already! :param pyramid.config.Configurator configurator: pyramid's app configurator :param string config: yaml file locations :param list files: list of files to include from location ''' # getting spec path package_name, filename = resolve_asset_spec(config) if not package_name: path = filename else: __import__(package_name) package = sys.modules[package_name] path = os.path.join(package_path(package), filename) config = ConfigManager(files=[os.path.join(path, f) for f in files]) # we could use this method both for creating and extending. Hence the checks to not override if not 'config' in configurator.registry: configurator.registry['config'] = config else: config.merge(configurator.registry['config']) configurator.registry['config'] = config
def __init__(self, template_name=None): pkg = caller_package(level=3) if template_name: _, template_name = resolve_asset_spec( template_name, pkg.__name__) template_name = '%s:%s' % (_, template_name) self.template_name = template_name self.exposed = True
def __call__(self, value, system): """Render the template.""" pkg, name = resolve_asset_spec(self.info.name) pkg_path = package_path(self.info.package) tpl_path = os.path.join(pkg_path, name) tpl_dir = os.path.split(tpl_path)[0] renderer = pystache.Renderer(search_dirs=[tpl_dir, pkg_path]) return renderer.render_path(tpl_path, value)
def _asset_to_fixture(asset: str) -> Path: """Translate :term:`asset` to absolute fixture path.""" package_name, file_name = resolve_asset_spec(asset) if package_name: package = __import__(package_name) path = Path(package_path(package), file_name) else: path = Path(file_name) if not path.is_dir(): msg = 'This is not a directory {}'.format(asset) raise ConfigurationError(details=msg) return path
def __init__(self, root_dir, cache_max_age=3600, package_name=None): # package_name is for bw compat; it is preferred to pass in a # package-relative path as root_dir # (e.g. ``anotherpackage:foo/static``). caller_package_name = caller_package().__name__ package_name = package_name or caller_package_name package_name, root_dir = resolve_asset_spec(root_dir, package_name) if package_name is None: app = StaticURLParser(root_dir, cache_max_age=cache_max_age) else: app = PackageURLParser( package_name, root_dir, cache_max_age=cache_max_age) self.app = app
def __init__(self, root_dir, cache_max_age=3600, package_name=None): # package_name is for bw compat; it is preferred to pass in a # package-relative path as root_dir # (e.g. ``anotherpackage:foo/static``). if package_name is None: package_name = caller_package().__name__ package_name, root_dir = resolve_asset_spec(root_dir, package_name) if package_name is None: app = StaticURLParser(root_dir, cache_max_age=cache_max_age) else: app = PackageURLParser( package_name, root_dir, cache_max_age=cache_max_age) self.app = app
def _translation_template_path(self, spec): # pylint:disable=no-self-use """ Calculate path to translation template file. :param str spec: either full path, or package related path """ # resolving possible asset spec to path (pyramid way): package_name, filename = resolve_asset_spec(spec) if package_name is None: # absolute filename return os.path.abspath(filename) __import__(package_name) package = sys.modules[package_name] return os.path.abspath(os.path.join(package_path(package), filename))
def __init__(self, root_dir, cache_max_age=3600, package_name=None, use_subpath=False, index="index.html"): # package_name is for bw compat; it is preferred to pass in a # package-relative path as root_dir # (e.g. ``anotherpackage:foo/static``). self.cache_max_age = cache_max_age if package_name is None: package_name = caller_package().__name__ package_name, docroot = resolve_asset_spec(root_dir, package_name) self.use_subpath = use_subpath self.package_name = package_name self.docroot = docroot self.norm_docroot = normcase(normpath(docroot)) self.index = index
def _translation_template_path(self, spec): ''' calculates path to translation template file :param str spec: either full path, or package related path ''' # resolving possible asset spec to path (pyramid way): package_name, filename = resolve_asset_spec(spec) if package_name is None: # absolute filename return os.path.abspath(filename) else: __import__(package_name) package = sys.modules[package_name] return os.path.abspath(os.path.join(package_path(package), filename))
def prod_fullfile_app(): """Configure the Pyramid application. We need to be sure that we get full path to pass always, no matter where this test is being run. """ package_name, filename = resolve_asset_spec('tests:config') __import__(package_name) package = sys.modules[package_name] path = os.path.join(package_path(package), filename) # Configure redirect routes config = config_factory(**{'env': 'prod', 'yml.location': path}) # Add routes for change_password, change_username, app = TestApp(config.make_wsgi_app()) return App(app, config)
def destination_path(request): ''' Returns absolute path of the translation destination :param pyramid.request.Request request: a request object :returns: A combined translation destination path :rtype: str ''' package_name, filename = resolve_asset_spec(request.config.localize.translation.destination) if package_name is None: # absolute filename directory = filename else: __import__(package_name) package = sys.modules[package_name] directory = os.path.join(package_path(package), filename) return directory
def destination_path(request): """ Return absolute path of the translation destination. :param pyramid.request.Request request: a request object :returns: A combined translation destination path :rtype: str """ package_name, filename = resolve_asset_spec( request.registry['config'].localize.translation.destination) if package_name is None: # absolute filename directory = filename else: __import__(package_name) package = sys.modules[package_name] directory = os.path.join(package_path(package), filename) return directory
def _load_file(self, rule, name): name, ext = os.path.splitext(name) if ext: search_exts = [ext] else: search_exts = ['.scss', '.sass'] dirname, name = os.path.split(name) seen_paths = [] # search_path is an assetspec # relpath is relative to the parent # dirname is from the import statement # name is the file itself for search_path in self.search_paths: for relpath in [rule.source_file.parent_dir]: # for basepath in [rule.source_file.parent_dir]: full_path = os.path.join(search_path, relpath, dirname) if full_path in seen_paths: continue seen_paths.append(full_path) for prefix, suffix in product(('_', ''), search_exts): full_filename = os.path.join( full_path, prefix + name + suffix) pname, filename = resolve_asset_spec(full_filename) if resource_exists(pname, filename): content = resource_string(pname, filename).decode('utf-8') return (filename, os.path.join(relpath, dirname), content, seen_paths) return None, None, None, seen_paths
def _translate_config_path(location): """ Translate location into fullpath according asset specification. Might be package:path for package related paths, or simply path :param str location: resource location :returns: fullpath :rtype: str """ # getting spec path package_name, filename = resolve_asset_spec(location.strip()) if not package_name: path = filename else: package = __import__(package_name) path = os.path.join(package_path(package), filename) return path
def __init__(self, root_dir, cache_max_age=3600, package_name=None, use_subpath=False, index='index.html', cachebust_match=None): # package_name is for bw compat; it is preferred to pass in a # package-relative path as root_dir # (e.g. ``anotherpackage:foo/static``). self.cache_max_age = cache_max_age if package_name is None: package_name = caller_package().__name__ package_name, docroot = resolve_asset_spec(root_dir, package_name) self.use_subpath = use_subpath self.package_name = package_name self.docroot = docroot self.norm_docroot = normcase(normpath(docroot)) self.index = index self.cachebust_match = cachebust_match
def get_template(self, uri): """Fetch a template from the cache, or check the filesystem for it In addition to the basic filesystem lookup, this subclass will use pkg_resource to load a file using the asset specification syntax. """ isabs = os.path.isabs(uri) if (not isabs) and (':' in uri): try: if self.filesystem_checks: return self._check(uri, self._collection[uri]) else: return self._collection[uri] except KeyError: pname, path = resolve_asset_spec(uri) srcfile = abspath_from_asset_spec(path, pname) if os.path.isfile(srcfile): return self._load(srcfile, uri) raise exceptions.TopLevelLookupException( "Can not locate template for uri %r" % uri) return TemplateLookup.get_template(self, uri)
def register_path(config, spec, discovery=False, indexes=[], request_type=None): """ Add a skin path to the current configuration state. If ``discovery`` is enabled, the path will automatically be monitored for changes. The ``indexes`` argument is an optional list of view registrations with the provided names. The ``request_type`` option decides the request type for which to make the registration. """ package_name, path = resolve_asset_spec(spec) if package_name is not None: path = pkg_resources.resource_filename(package_name, path) else: path = caller_path(path) if package_name is None: # absolute filename package = config.package else: __import__(package_name) package = sys.modules[package_name] context = ConfigurationMachine() context.registry = config.registry context.autocommit = False context.package = package context.route_prefix = getattr(config, 'route_prefix', None) directive = skins(context, path, discovery, request_type) for index in indexes: directive.view(config, index) for action in directive(): config.action(*action)
def _split_spec(self, path_or_spec): return resolve_asset_spec(path_or_spec, self.package_name)
def _make_spec(self, path_or_spec): package, filename = resolve_asset_spec(path_or_spec, self.package_name) if package is None: return filename # absolute filename return '%s:%s' % (package, filename)
def __init__(self, *args, **kwargs): gzip_path = kwargs.pop('gzip_path') super(gzip_static_view, self).__init__(*args, **kwargs) package_name, self.gzip_docroot = resolve_asset_spec(gzip_path, self.package_name) self.norm_gzip_docroot = normcase(normpath(self.gzip_docroot))
def load_zcml(self, spec='configure.zcml', lock=threading.Lock(), features=()): """ Load configuration from a :term:`ZCML` file into the current configuration state. The ``spec`` argument is an absolute filename, a relative filename, or a :term:`asset specification`, defaulting to ``configure.zcml`` (relative to the package of the method's caller). The ``features`` argument can be any iterable of strings. These are useful for conditionally including or excluding parts of a :term:`ZCML` file. """ package_name, filename = resolve_asset_spec(spec, self.package_name) if package_name is None: # absolute filename package = self.package else: __import__(package_name) package = sys.modules[package_name] # To avoid breaking people's expectations of how ZCML works, we # cannot autocommit ZCML actions incrementally. If we commit actions # incrementally, configuration outcome will be controlled purely by # ZCML directive execution order, which isn't what anyone who uses # ZCML expects. So we don't autocommit each ZCML directive action # while parsing is happening, but we do make sure to commit right # after parsing if autocommit it True. context = ConfigurationMachine() for feature in features: context.provideFeature(feature) context.registry = self.registry context.autocommit = False context.package = package context.route_prefix = getattr(self, 'route_prefix', None) context.introspection = getattr(self, 'introspection', True) context.config_class = self.__class__ registerCommonDirectives(context) self.manager.push({'registry': self.registry, 'request': None}) lock.acquire() try: # old_action_state will be None for Pyramid 1.0 and 1.1, but # not for 1.2 old_action_state = getattr(self.registry, 'action_state', None) if old_action_state is not None: # For Pyramid 1.2+, we need to assign a temporary action state to # the registry, because the configurator actions must populate # the context's action list (instead of the registry action # state's action list) in order for includeOverrides to work # properly. from pyramid.config import ActionState self.registry.action_state = ActionState() self.registry.action_state.actions = context.actions xmlconfig.file(filename, package, context=context, execute=False) finally: if old_action_state is not None: # if we reassigned the action state, restore the old one (1.2 only) self.registry.action_state = old_action_state lock.release() self.manager.pop() self._ctx.actions.extend(context.actions) if self.autocommit: self.commit() return self.registry
def load_zcml(self, spec='configure.zcml', lock=threading.Lock(), features=()): """ Load configuration from a :term:`ZCML` file into the current configuration state. The ``spec`` argument is an absolute filename, a relative filename, or a :term:`asset specification`, defaulting to ``configure.zcml`` (relative to the package of the method's caller). The ``features`` argument can be any iterable of strings. These are useful for conditionally including or excluding parts of a :term:`ZCML` file. """ package_name, filename = resolve_asset_spec(spec, self.package_name) if package_name is None: # absolute filename package = self.package else: __import__(package_name) package = sys.modules[package_name] # To avoid breaking people's expectations of how ZCML works, we # cannot autocommit ZCML actions incrementally. If we commit actions # incrementally, configuration outcome will be controlled purely by # ZCML directive execution order, which isn't what anyone who uses # ZCML expects. So we don't autocommit each ZCML directive action # while parsing is happening, but we do make sure to commit right # after parsing if autocommit it True. context = ConfigurationMachine() for feature in features: context.provideFeature(feature) context.registry = self.registry context.autocommit = False context.package = package context.route_prefix = getattr(self, 'route_prefix', None) context.introspection = getattr(self, 'introspection', True) context.config_class = self.__class__ registerCommonDirectives(context) self.manager.push({'registry':self.registry, 'request':None}) lock.acquire() try: # old_action_state will be None for Pyramid 1.0 and 1.1, but # not for 1.2 old_action_state = getattr(self.registry, 'action_state', None) if old_action_state is not None: # For Pyramid 1.2+, we need to assign a temporary action state to # the registry, because the configurator actions must populate # the context's action list (instead of the registry action # state's action list) in order for includeOverrides to work # properly. from pyramid.config import ActionState self.registry.action_state = ActionState() self.registry.action_state.actions = context.actions xmlconfig.file(filename, package, context=context, execute=False) finally: if old_action_state is not None: # if we reassigned the action state, restore the old one (1.2 only) self.registry.action_state = old_action_state lock.release() self.manager.pop() self._ctx.actions.extend(context.actions) if self.autocommit: self.commit() return self.registry
def __call__(self, value, system): """Render the template.""" pkg, name = resolve_asset_spec(self.info.name) tpl = os.path.join(package_path(self.info.package), name) return pystache.render(open(tpl, 'r').read(), value)
"""Tests conftest file.""" import os import sys import pytest from pyramid.asset import resolve_asset_spec from pyramid.path import package_path from pytest_pyramid import factories package_name, filename = resolve_asset_spec('tests:config') __import__(package_name) package = sys.modules[package_name] full_path = os.path.join(package_path(package), filename) @pytest.fixture(scope='function', params=['tests:config', 'tests:config/config.yaml', full_path]) def base_config(request): """Basic config parametrized for different configuration location.""" return factories.pyramid_config({ 'yaml.location': request.param, 'pyramid.includes': ['tzf.pyramid_yml'] })(request) @pytest.fixture(scope='function', params=['tests:config', 'tests:config/config.yaml', full_path]) def prod_config(request): """Basic with env set parametrized for different configuration location.""" return factories.pyramid_config({
def notfound_view(request): package, filename = resolve_asset_spec('pylonsprojectjp:static/404.html', request.registry.__name__) path = resource_filename(package, filename) return FileResponse(path)