Beispiel #1
0
def parse_settings_file(path, section='app', interpolation=None, meta_settings=True, **kwargs):
    """Parse settings from the .ini file at ``path``.

    ``path`` can be a file system path or an asset path. ``section``
    specifies which [section] to get settings from.

    By default, some extra metadata will be added to the settings parsed
    from a file. These are the file name the settings were loaded from
    (__file__), the base file names of any extended files (__base__ and
    __bases__), and the environment indicated by the file's base name
    (env). Use ``meta_settings=False`` to disable this.

    ``kwargs`` are the keyword args for :func:`parse_settings`.

    """
    file_name = abs_path(path)
    file_dir = os.path.dirname(file_name)
    defaults = {'__dir__': file_dir}
    if interpolation is None:
        interpolation = configparser.ExtendedInterpolation()
    parser = configparser.ConfigParser(defaults=defaults, interpolation=interpolation)

    with open(file_name) as fp:
        parser.read_file(fp)

    try:
        settings = dict(parser[section])
    except KeyError:
        raise ValueError('Settings file has no [{}] section'.format(section))

    settings = parse_settings(settings, **kwargs)
    required = kwargs.pop('required', None)

    if meta_settings:
        settings['__file__'] = file_name
        settings['__base__'] = None
        settings['__bases__'] = ()
        if 'env' not in settings:
            env = os.path.basename(file_name)
            env = os.path.splitext(env)[0]
            settings['env'] = env

    extends = settings.pop('extends', None)
    if extends:
        if not is_asset_path(extends):
            extends = os.path.join(file_dir, extends)
        base_file_name = abs_path(extends)
        base_settings = parse_settings_file(
            base_file_name, section, interpolation, meta_settings, **kwargs)
        if meta_settings:
            settings['__base__'] = base_file_name
            settings['__bases__'] = (base_file_name,)
            settings['__bases__'] += base_settings['__bases__']
        base_settings.update(settings)
        settings = base_settings

    if required:
        check_required(settings, required)

    return settings
Beispiel #2
0
    def mount_static_directory(self, prefix, directory, remote=False,
                               index_page=None):
        """Mount a local or remote static directory.

        ``prefix`` is an alias referring to ``directory``.

        If ``directory`` is just a path, it should be a local directory.
        Requests to ``/{prefix}/{path}`` will look in this directory for
        the file indicated by ``path``.

        If ``directory`` refers to a remote location (i.e., it starts
        with ``http://`` or ``https://``), URLs generated via
        ``reqeust.static_url`` and ``request.static_path`` will point
        to the remote directory.

        ``remote`` can also be specified explicitly. In this context,
        "remote" means not served by the application itself. E.g., you
        might be mapping an alias in Nginx to a local directory.

        .. note:: It's best to always use
                  :meth:`tangled.web.request.Request.static_url`
                  :meth:`tangled.web.request.Request.static_path`
                  to generate static URLs.

        """
        prefix = tuple(prefix.strip('/').split('/'))
        if remote or re.match(r'https?://', directory):
            directory = RemoteDirectory(directory)
        else:
            directory = abs_path(directory)
            directory = LocalDirectory(directory, index_page=index_page)
        self.register('static_directory', directory, prefix)
Beispiel #3
0
    def mount_static_directory(self,
                               prefix,
                               directory,
                               remote=False,
                               index_page=None):
        """Mount a local or remote static directory.

        ``prefix`` is an alias referring to ``directory``.

        If ``directory`` is just a path, it should be a local directory.
        Requests to ``/{prefix}/{path}`` will look in this directory for
        the file indicated by ``path``.

        If ``directory`` refers to a remote location (i.e., it starts
        with ``http://`` or ``https://``), URLs generated via
        ``reqeust.static_url`` and ``request.static_path`` will point
        to the remote directory.

        ``remote`` can also be specified explicitly. In this context,
        "remote" means not served by the application itself. E.g., you
        might be mapping an alias in Nginx to a local directory.

        .. note:: It's best to always use
                  :meth:`tangled.web.request.Request.static_url`
                  :meth:`tangled.web.request.Request.static_path`
                  to generate static URLs.

        """
        prefix = tuple(prefix.strip('/').split('/'))
        if remote or re.match(r'https?://', directory):
            directory = RemoteDirectory(directory)
        else:
            directory = abs_path(directory)
            directory = LocalDirectory(directory, index_page=index_page)
        self.register('static_directory', directory, prefix)
Beispiel #4
0
def on_application_created(event):
    app = event.app
    production = app.settings.get('env') == 'production'

    if production:
        base_docs_dir = abs_path(app.settings['docs_dir'])
        for name in os.listdir(base_docs_dir):
            docs_dir = os.path.join(base_docs_dir, name)
            if os.path.isdir(docs_dir):
                prefix = posixpath.join('docs', name)
                app.mount_static_directory(
                    prefix, docs_dir, remote=True, index_page='index.html')
    else:
        src_dir = abs_path(app.settings['src_dir'])
        for name in os.listdir(src_dir):
            if name.startswith('tangled'):
                repo_dir = os.path.join(src_dir, name)
                docs_dir = os.path.join(repo_dir, 'docs/_build')
                if os.path.exists(docs_dir):
                    prefix = posixpath.join('docs', name)
                    app.mount_static_directory(
                        prefix, docs_dir, remote=False,
                        index_page='index.html')
Beispiel #5
0
 def test_abs_path_for_asset(self):
     path = util.abs_path('tangled.util:x/y')
     self.assertTrue(os.path.isabs(path))
     expected = os.path.join(os.path.dirname(util.__file__), 'x/y')
     self.assertTrue(path.endswith('/tangled/tangled/x/y'))
     self.assertEqual(path, expected)
Beispiel #6
0
 def test_abs_path_for_abs_path(self):
     path = util.abs_path('/x/y/z')
     self.assertEqual(path, '/x/y/z')
Beispiel #7
0
 def test_abs_path_for_rel_path(self):
     cwd = os.path.dirname(os.getcwd())
     path = util.abs_path('..')
     self.assertTrue(os.path.isabs(path))
     self.assertEqual(path, cwd)
Beispiel #8
0
 def test_abs_path_for_asset(self):
     path = util.abs_path('tangled.util:x/y')
     self.assertTrue(os.path.isabs(path))
     expected = os.path.join(os.path.dirname(util.__file__), 'x/y')
     self.assertTrue(path.endswith('/tangled/tangled/util/x/y'))
     self.assertEqual(path, expected)
Beispiel #9
0
 def test_abs_path_for_abs_path(self):
     path = util.abs_path('/x/y/z')
     self.assertEqual(path, '/x/y/z')
Beispiel #10
0
 def test_abs_path_for_rel_path(self):
     cwd = os.path.dirname(os.getcwd())
     path = util.abs_path('..')
     self.assertTrue(os.path.isabs(path))
     self.assertEqual(path, cwd)
Beispiel #11
0
def as_abs_path(v):
    v = v.strip()
    if not v:
        return None
    return abs_path(v)
Beispiel #12
0
def parse_settings_file(path,
                        section='app',
                        interpolation=None,
                        meta_settings=True,
                        **kwargs):
    """Parse settings from the .ini file at ``path``.

    ``path`` can be a file system path or an asset path. ``section``
    specifies which [section] to get settings from.

    By default, some extra metadata will be added to the settings parsed
    from a file. These are the file name the settings were loaded from
    (__file__), the base file names of any extended files (__base__ and
    __bases__), and the environment indicated by the file's base name
    (env). Use ``meta_settings=False`` to disable this.

    ``kwargs`` are the keyword args for :func:`parse_settings`.

    """
    file_name = abs_path(path)
    file_dir = os.path.dirname(file_name)
    defaults = {'__dir__': json.dumps(file_dir)}
    if interpolation is None:
        interpolation = configparser.ExtendedInterpolation()
    parser = configparser.ConfigParser(defaults=defaults,
                                       delimiters='=',
                                       interpolation=interpolation)

    with open(file_name) as fp:
        parser.read_file(fp)

    try:
        settings = dict(parser[section])
    except KeyError:
        raise ValueError('Settings file has no [{}] section'.format(section))

    try:
        settings = parse_settings(settings, **kwargs)
    except ValueError as exc:
        file_name = os.path.relpath(file_name, os.getcwd())
        message = '{exc} in {file_name}'.format_map(locals())
        raise ValueError(message) from None

    required = kwargs.pop('required', None)

    if meta_settings:
        settings['__file__'] = file_name
        settings['__base__'] = None
        settings['__bases__'] = ()
        if 'env' not in settings:
            env = os.path.basename(file_name)
            env = os.path.splitext(env)[0]
            settings['env'] = env

    extends = settings.pop('extends', None)
    if extends:
        if not is_asset_path(extends):
            extends = os.path.join(file_dir, extends)
        base_file_name = abs_path(extends)
        base_settings = parse_settings_file(base_file_name, section,
                                            interpolation, meta_settings,
                                            **kwargs)
        if meta_settings:
            settings['__base__'] = base_file_name
            settings['__bases__'] = (base_file_name, )
            settings['__bases__'] += base_settings['__bases__']
        base_settings.update(settings)
        settings = base_settings

    if required:
        check_required(settings, required)

    return settings
Beispiel #13
0
 def test_lookup_abs_path(self):
     lookup = create_lookup({})
     lookup.get_template(abs_path('tangled.mako.tests:templates/test.mako'))