ya2 · news · projects · code · about

more cleaning
[pmachines.git] / ya2 / dictfile.py
CommitLineData
8ee66edd
FC
1import sys
2from logging import info
3from os import makedirs
4from os.path import dirname
addec9c9 5from collections.abc import Mapping
8ee66edd
FC
6from configparser import ConfigParser
7from json import load, dumps
53ddf3c3 8from ya2.gameobject import GameObject
b3bd2e45 9from ya2.lib.p3d.p3d import LibP3d
8ee66edd
FC
10
11
12class DctFile(GameObject):
13
14 def __init__(self, fpath, default_dct=None, persistent=True):
15 GameObject.__init__(self)
16 default_dct = default_dct or {}
17 if sys.platform == 'darwin' and LibP3d.runtime():
18 fpath = dirname(__file__) + '/' + fpath
19 self.fpath = fpath
20 self.persistent = persistent
21 try:
22 #with open(fpath) as json: fdct = load(json)
23 config = ConfigParser()
24 config.read(fpath)
25 fdct = {section: dict(config.items(section)) for section in config.sections()}
26 fdct = self.__typed_dct(fdct)
27 self.dct = self.__add_default(default_dct, fdct)
28 except IOError: self.dct = default_dct
29
30 @staticmethod
31 def __typed_dct(dct):
32 def convert_single_val(val):
33 try: return int(val)
34 except ValueError:
35 try: return float(val)
36 except ValueError:
37 if not val or val[0] != '[':
38 return val
39 else:
40 raise ValueError
41 def converted(val):
42 try: return convert_single_val(val)
43 except ValueError:
44 return [elm.strip() for elm in val[1:-1].split(',')]
45 new_dct = {}
46 for section, sec_dct in dct.items():
47 for key, val in sec_dct.items():
48 if section not in new_dct:
49 new_dct[section] = {}
50 new_dct[section][key] = converted(val)
51 return new_dct
52
53 @staticmethod
54 def __add_default(dct, upd):
55 for key, val in upd.items():
56 if isinstance(val, Mapping):
57 dct[key] = DctFile.__add_default(dct.get(key, {}), val)
58 else: dct[key] = upd[key]
59 return dct
60
61 @staticmethod
62 def deepupdate(dct, new_dct):
63 for key, val in new_dct.items():
64 if isinstance(val, Mapping):
65 dct[key] = DctFile.deepupdate(dct.get(key, {}), val)
66 else: dct[key] = val
67 return dct
68
69 def store(self):
70 info('storing %s' % self.fpath)
71 if not self.persistent: return
72 #json_str = dumps(self.dct, sort_keys=True, indent=4,
73 # separators=(',', ': '))
74 #with open(self.fpath, 'w') as json: json.write(json_str)
75 fdct = {}
76 for section, sec_dct in self.dct.items():
77 if section not in fdct:
78 fdct[section] = {}
79 for key, val in sec_dct.items():
80 if type(val) == list:
81 fdct[section][key] = '[%s]' % ', '.join(val)
82 else:
83 fdct[section][key] = val
84 config = ConfigParser()
85 for key in self.dct:
86 config[key] = fdct[key]
87 if dirname(self.fpath):
88 makedirs(dirname(self.fpath), exist_ok=True)
89 with open(self.fpath, 'w') as ini_file:
90 config.write(ini_file)
91
92 def __getitem__(self, arg): return self.dct[arg]
93
94 def __setitem__(self, arg, val): self.dct[arg] = val
95
96 def __delitem__(self, arg): del self.dct[arg]