view configmix/variables.py @ 30:d70b58b0dfb9

A new variable namespace "OS" with a "cwd" function with new filters "abspath" and "normpath" for some minimal path manipulation
author Franz Glasner <hg@dom66.de>
date Fri, 18 Mar 2016 09:27:14 +0100
parents 0b1292e920af
children 3ee21f868440
line wrap: on
line source

# -*- coding: utf-8 -*-
r"""Variable expansion: namespaces and filters

"""

from __future__ import division, absolute_import, print_function

import os
from functools import wraps

from .compat import PY2, text_to_native_os_str, native_os_str_to_text


__all__ = []


_MARKER = object()


def _envlookup(name, default=_MARKER):
    """Lookup an environment variable"""
    try:
        return native_os_str_to_text(os.environ[name])
    except KeyError:
        if default is _MARKER:
            raise
        else:
            return default


def _oslookup(name, default=_MARKER):
    """Lookup an environment variable"""
    if name == "cwd":
        return native_os_str_to_text(os.getcwd())
    raise KeyError("key %r not found in the namespace" % name)


_varns_registry = {
    "ENV": _envlookup,
    "OS": _oslookup
}


def lookup_varns(name):
    return _varns_registry[_normalized(name)]


_filter_registry = {}


def add_filter(name, fn):
    _filter_registry[_normalized(name)] = fn


def lookup_filter(name):
    return _filter_registry[_normalized(name)]


def filter(name):
    """Decorator for a filter function"""

    def _decorator(f):

        @wraps(f)
        def _f(appconfig, v):
            return f(appconfig, v)

        add_filter(name, _f)
        return _f

    return _decorator


def _normalized(name):
    return name.replace('-', '_')


#
# Some pre-defined filter functions
#
if PY2:

    @filter("urlquote")
    def urlquote(config, v):
        """Replace all special characters in string using the ``%xx`` escape"""
        from urllib import quote
        return quote(v.encode("utf-8"), safe=b"").decode("utf-8")

else:

    @filter("urlquote")
    def urlquote(config, v):
        """Replace all special characters in string using the ``%xx`` escape"""
        from urllib.parse import quote
        return quote(v, safe="")


@filter("saslprep")
def saslprep(config, v):
    """Do a `SASLprep` according to RFC4013 on `v`.

    This is a Stringprep Profile for usernames and passwords

    """
    import passlib.utils
    return passlib.utils.saslprep(v)


@filter("normpath")
def normpath_impl(config, v):
    return os.path.normpath(v)


@filter("abspath")
def abspath_impl(config, v):
    return os.path.abspath(v)