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, unicode_literals 9 10import codecs 11import re 12import sys 13 14if sys.version_info[0] == 3: 15 str_type = str 16else: 17 str_type = basestring 18 19class DotProperties: 20 r'''A thin representation of a key=value .properties file.''' 21 22 def __init__(self, file=None): 23 self._properties = {} 24 if file: 25 self.update(file) 26 27 def update(self, file): 28 '''Updates properties from a file name or file-like object. 29 30 Ignores empty lines and comment lines.''' 31 32 if isinstance(file, str_type): 33 f = codecs.open(file, 'r', 'utf-8') 34 else: 35 f = file 36 37 for l in f.readlines(): 38 line = l.strip() 39 if not line or line.startswith('#'): 40 continue 41 (k, v) = re.split('\s*=\s*', line, 1) 42 self._properties[k] = v 43 44 def get(self, key, default=None): 45 return self._properties.get(key, default) 46 47 def get_list(self, prefix): 48 '''Turns {'list.0':'foo', 'list.1':'bar'} into ['foo', 'bar']. 49 50 Returns [] to indicate an empty or missing list.''' 51 52 if not prefix.endswith('.'): 53 prefix = prefix + '.' 54 indexes = [] 55 for k, v in self._properties.iteritems(): 56 if not k.startswith(prefix): 57 continue 58 key = k[len(prefix):] 59 if '.' in key: 60 # We have something like list.sublist.0. 61 continue 62 indexes.append(int(key)) 63 return [self._properties[prefix + str(index)] for index in sorted(indexes)] 64 65 def get_dict(self, prefix, required_keys=[]): 66 '''Turns {'foo.title':'title', ...} into {'title':'title', ...}. 67 68 If |required_keys| is present, it must be an iterable of required key 69 names. If a required key is not present, ValueError is thrown. 70 71 Returns {} to indicate an empty or missing dict.''' 72 73 if not prefix.endswith('.'): 74 prefix = prefix + '.' 75 76 D = dict((k[len(prefix):], v) for k, v in self._properties.iteritems() 77 if k.startswith(prefix) and '.' not in k[len(prefix):]) 78 79 for required_key in required_keys: 80 if not required_key in D: 81 raise ValueError('Required key %s not present' % required_key) 82 83 return D 84