1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this file, 3# You can obtain one at http://mozilla.org/MPL/2.0/. 4 5# This file contains utility functions for reading .properties files, like 6# region.properties. 7 8from __future__ import absolute_import, print_function, unicode_literals 9 10import codecs 11import re 12import six 13import sys 14 15if sys.version_info[0] == 3: 16 str_type = str 17else: 18 str_type = basestring 19 20 21class DotProperties: 22 r"""A thin representation of a key=value .properties file.""" 23 24 def __init__(self, file=None): 25 self._properties = {} 26 if file: 27 self.update(file) 28 29 def update(self, file): 30 """Updates properties from a file name or file-like object. 31 32 Ignores empty lines and comment lines.""" 33 34 if isinstance(file, str_type): 35 f = codecs.open(file, "r", "utf-8") 36 else: 37 f = file 38 39 for l in f.readlines(): 40 line = l.strip() 41 if not line or line.startswith("#"): 42 continue 43 (k, v) = re.split("\s*=\s*", line, 1) 44 self._properties[k] = v 45 46 def get(self, key, default=None): 47 return self._properties.get(key, default) 48 49 def get_list(self, prefix): 50 """Turns {'list.0':'foo', 'list.1':'bar'} into ['foo', 'bar']. 51 52 Returns [] to indicate an empty or missing list.""" 53 54 if not prefix.endswith("."): 55 prefix = prefix + "." 56 indexes = [] 57 for k, v in six.iteritems(self._properties): 58 if not k.startswith(prefix): 59 continue 60 key = k[len(prefix) :] 61 if "." in key: 62 # We have something like list.sublist.0. 63 continue 64 indexes.append(int(key)) 65 return [self._properties[prefix + str(index)] for index in sorted(indexes)] 66 67 def get_dict(self, prefix, required_keys=[]): 68 """Turns {'foo.title':'title', ...} into {'title':'title', ...}. 69 70 If ``|required_keys|`` is present, it must be an iterable of required key 71 names. If a required key is not present, ValueError is thrown. 72 73 Returns {} to indicate an empty or missing dict.""" 74 75 if not prefix.endswith("."): 76 prefix = prefix + "." 77 78 D = dict( 79 (k[len(prefix) :], v) 80 for k, v in six.iteritems(self._properties) 81 if k.startswith(prefix) and "." not in k[len(prefix) :] 82 ) 83 84 for required_key in required_keys: 85 if required_key not in D: 86 raise ValueError("Required key %s not present" % required_key) 87 88 return D 89