open file with encoding (python 2/3 supported)
[rainbowstream.git] / rainbowstream / config.py
1 import json
2 import re
3 import os
4 import os.path
5 from io import open
6 from collections import OrderedDict
7
8 # Regular expression for comments in config file
9 comment_re = re.compile(
10 '(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?',
11 re.DOTALL | re.MULTILINE
12 )
13
14 # Config dictionary
15 c = {}
16
17
18 def fixup(adict, k, v):
19 """
20 Fix up a key in json format
21 """
22 for key in adict.keys():
23 if key == k:
24 adict[key] = v
25 elif isinstance(adict[key], dict):
26 fixup(adict[key], k, v)
27
28
29 def load_config(filepath):
30 """
31 Load config from filepath
32 """
33 with open(filepath, encoding='utf-8') as f:
34 content = ''.join(f.readlines())
35 match = comment_re.search(content)
36 while match:
37 content = content[:match.start()] + content[match.end():]
38 match = comment_re.search(content)
39 return json.loads(content, object_pairs_hook=OrderedDict)
40
41
42 def get_all_config():
43 """
44 Get all config
45 """
46 path = os.path.expanduser("~") + os.sep + '.rainbow_config.json'
47 data = load_config(path)
48 # Hard to set from prompt
49 data.pop('ONLY_LIST', None)
50 data.pop('IGNORE_LIST', None)
51 data.pop('FORMAT', None)
52 return data
53
54
55 def get_default_config(key):
56 """
57 Get default value of a config key
58 """
59 path = os.path.dirname(
60 __file__) + '/colorset/config'
61 try:
62 data = load_config(path)
63 except:
64 raise Exception('No such config key.')
65 return data[key]
66
67
68 def get_config(key):
69 """
70 Get current value of a config key
71 """
72 return c[key]
73
74
75 def set_config(key, value):
76 """
77 Set a config key with specific value
78 """
79 # Modify value
80 if value.isdigit():
81 value = int(value)
82 elif value.lower() == 'true':
83 value = True
84 elif value.lower() == 'false':
85 value = False
86 # Fix up
87 path = os.path.expanduser("~") + os.sep + '.rainbow_config.json'
88 data = {}
89 try:
90 data = load_config(path)
91 except:
92 pass
93 # Update global config
94 c[key] = value
95 # Update config file
96 if key in data:
97 fixup(data, key, value)
98 else:
99 data[key] = value
100 # Save
101 with open(path, 'w', encoding='utf-8') as out:
102 json.dump(data, out, indent=4)
103 os.system('chmod 777 ' + path)
104
105
106 def delete_config(key):
107 """
108 Delete a config key
109 """
110 path = os.path.expanduser("~") + os.sep + '.rainbow_config.json'
111 data = load_config(path)
112 # Drop key
113 if key in data and key in c:
114 data.pop(key)
115 c.pop(key)
116 try:
117 data[key] = c[key] = get_default_config(key)
118 except:
119 pass
120 else:
121 raise Exception('No such config key.')
122 # Save
123 with open(path, 'w', encoding='utf-8') as out:
124 json.dump(data, out, indent=4)
125 os.system('chmod 777 ' + path)
126
127
128 def reload_config():
129 """
130 Reload config
131 """
132 rainbow_config = os.path.expanduser("~") + os.sep + '.rainbow_config.json'
133 try:
134 data = load_config(rainbow_config)
135 for d in data:
136 c[d] = data[d]
137 except:
138 print('It seems that ~/.rainbow_config.json has wrong format :(')
139
140
141 def init_config():
142 """
143 Init configuration
144 """
145 # Load the initial config
146 config = os.path.dirname(
147 __file__) + '/colorset/config'
148 try:
149 data = load_config(config)
150 for d in data:
151 c[d] = data[d]
152 except:
153 pass
154 # Load user's config
155 rainbow_config = os.path.expanduser("~") + os.sep + '.rainbow_config.json'
156 try:
157 data = load_config(rainbow_config)
158 for d in data:
159 c[d] = data[d]
160 except:
161 pass
162 # Load default theme
163 theme_file = os.path.dirname(
164 __file__) + '/colorset/' + c['THEME'] + '.json'
165 try:
166 data = load_config(theme_file)
167 for d in data:
168 c[d] = data[d]
169 except:
170 pass
171
172
173 # Init config
174 init_config()