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