DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (df59b74d33d7)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

# This file contains utility functions for reading .properties files, like
# region.properties.

from __future__ import absolute_import, print_function, unicode_literals

import codecs
import re
import six
import sys

if sys.version_info[0] == 3:
    str_type = str
else:
    str_type = basestring


class DotProperties:
    r'''A thin representation of a key=value .properties file.'''

    def __init__(self, file=None):
        self._properties = {}
        if file:
            self.update(file)

    def update(self, file):
        '''Updates properties from a file name or file-like object.

        Ignores empty lines and comment lines.'''

        if isinstance(file, str_type):
            f = codecs.open(file, 'r', 'utf-8')
        else:
            f = file

        for l in f.readlines():
            line = l.strip()
            if not line or line.startswith('#'):
                continue
            (k, v) = re.split('\s*=\s*', line, 1)
            self._properties[k] = v

    def get(self, key, default=None):
        return self._properties.get(key, default)

    def get_list(self, prefix):
        '''Turns {'list.0':'foo', 'list.1':'bar'} into ['foo', 'bar'].

        Returns [] to indicate an empty or missing list.'''

        if not prefix.endswith('.'):
            prefix = prefix + '.'
        indexes = []
        for k, v in six.iteritems(self._properties):
            if not k.startswith(prefix):
                continue
            key = k[len(prefix):]
            if '.' in key:
                # We have something like list.sublist.0.
                continue
            indexes.append(int(key))
        return [self._properties[prefix + str(index)] for index in sorted(indexes)]

    def get_dict(self, prefix, required_keys=[]):
        '''Turns {'foo.title':'title', ...} into {'title':'title', ...}.

        If ``|required_keys|`` is present, it must be an iterable of required key
        names.  If a required key is not present, ValueError is thrown.

        Returns {} to indicate an empty or missing dict.'''

        if not prefix.endswith('.'):
            prefix = prefix + '.'

        D = dict((k[len(prefix):], v) for k, v
                 in six.iteritems(self._properties)
                 if k.startswith(prefix) and '.' not in k[len(prefix):])

        for required_key in required_keys:
            if required_key not in D:
                raise ValueError('Required key %s not present' % required_key)

        return D