Source

slipper / slipper / config.py

Full commit
def repo_map_from_config(config):
    """Convert INI-style configuration to a useful repository map.

    `config` is a dictionary whose keys and values correspond to an
    INI file::

        >>> config = {
        ...     'slipper.DEFAULT.cache_dir': '/path/to/cache/dir',
        ...     'slipper.repo1.local_dir': '/path/to/repo1',
        ...     'slipper.repo1.hgweb_url': 'http://path.to/repo1',
        ...     'slipper.repo2.local_dir': '/path/to/repo2',
        ...     'slipper.repo2.hgweb_url': 'http://path.to/repo2',
        ...     'slipper.repo2.rst_extension': '.txt',
        ...     }

    Returns a dictionary whose keys are the names of each repository,
    and whose values are objects with the following string keys:

    - ``cache_dir``
    - ``rst_extension``
    - ``local_dir``
    - ``hgweb_url``

    ::

        >>> repo_map = repo_map_from_config(config)
        >>> sorted(repo_map.keys())
        ['repo1', 'repo2']
    """
    config = config.copy()
    # Find default information.
    default = RepositoryInfo(
        cache_dir = config.pop('slipper.DEFAULT.cache_dir', None),
        colorize = ColorizeInfo(config.pop('slipper.DEFAULT.colorize', '')),
        rst_extension = config.pop('slipper.DEFAULT.rst_extension', '.rst'),
        stylesheet_path = config.pop('slipper.DEFAULT.stylesheet_path', None),
        local_dir = None,
        hgweb_url = None,
        )
    # Build the repository map.
    repo_map = {}
    for key, value in config.iteritems():
        keyparts = key.split('.')
        if len(keyparts) != 3 or keyparts[0] != 'slipper':
            # Not a configuration item we care about.
            continue
        _, repo_name, config_key = keyparts
        config = repo_map.setdefault(repo_name, default.copy())
        if config_key == 'colorize':
            value = ColorizeInfo(value)
        setattr(config, config_key, value)
    # Done.
    return repo_map


class ColorizeInfo(object):
    
    def __init__(self, colorize_string):
        # Split by comma.
        parts = [part.strip() for part in colorize_string.split(',')]
        # Remove blanks and split by spaces.
        parts = [part.split() for part in parts if part]
        # Turn into dictionary.
        self.ext_info = dict((part[0], part[1:]) for part in parts)
        
    def colorize_info(self, path):
        """Return a dictionary based on `path` that contains the following
        keys, or `None` if the file should not be colorized.
        
        - `original_ext`: Original extension to use to find the file to
          colorize.
        - `original_path`: The path that should be accessed to retrieve the
          file to colorize.
        - `lexer`: The name of the Pygments lexer to use.
        - `variant`: The name of the Pygments renderer variant to use, or 
          None if not specified.
        """
        for extension in self.ext_info:
            if path.endswith(extension):
                parts = self.ext_info[extension]
                info = dict(
                    original_ext = parts[0],
                    lexer = parts[1],
                    )
                if len(parts) == 3:
                    info['variant'] = parts[2]
                else:
                    info['variant'] = None
                path_without_ext = path[:len(path)-len(extension)]
                info['original_path'] = (
                    path_without_ext + info['original_ext'])
                return info
        return None
        

class RepositoryInfo(object):

    def __init__(self, **kw):
        self.__dict__.update(kw)

    def copy(self):
        return RepositoryInfo(**self.__dict__)