1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab 4 5# Copyright (c) 2014-2020 Kevin B. Hendricks, and Doug Massay 6# Copyright (c) 2014 John Schember 7# All rights reserved. 8# 9# Redistribution and use in source and binary forms, with or without modification, 10# are permitted provided that the following conditions are met: 11# 12# 1. Redistributions of source code must retain the above copyright notice, this list of 13# conditions and the following disclaimer. 14# 15# 2. Redistributions in binary form must reproduce the above copyright notice, this list 16# of conditions and the following disclaimer in the documentation and/or other materials 17# provided with the distribution. 18# 19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 22# SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 24# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 27# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29import os 30import json 31from collections import OrderedDict 32 33class JSONPrefs(dict): 34 35 EXTENSION = '.json' 36 37 # json file in user plugin directory. 38 def __init__(self, plugin_dir, plugin_name): 39 dict.__init__(self) 40 self.defaults = OrderedDict() 41 pfolder = os.path.join(os.path.dirname(plugin_dir), "plugins_prefs", plugin_name) 42 # in a plugins_prefs dir (/plugin_name subdir just to be safe) 43 self.file_path = os.path.join(pfolder, '{0}{1}'.format(plugin_name, self.EXTENSION)) 44 self.file_path = os.path.abspath(self.file_path) 45 self.refresh() 46 47 def refresh(self, clear_current=True): 48 d = OrderedDict() 49 if os.path.exists(self.file_path): 50 with open(self.file_path, 'r', encoding='utf-8') as f: 51 try: 52 d = json.load(f) 53 except SystemError: 54 pass 55 except Exception: 56 import traceback 57 traceback.print_exc() 58 d = OrderedDict() 59 if clear_current: 60 self.clear() 61 self.update(d) 62 63 def __getitem__(self, key): 64 try: 65 return dict.__getitem__(self, key) 66 except KeyError: 67 return self.defaults[key] 68 69 def get(self, key, default=None): 70 try: 71 return dict.__getitem__(self, key) 72 except KeyError: 73 return self.defaults.get(key, default) 74 75 def __setitem__(self, key, val): 76 dict.__setitem__(self, key, val) 77 78 def set(self, key, val): 79 self.__setitem__(key, val) 80 81 def __delitem__(self, key): 82 try: 83 dict.__delitem__(self, key) 84 except KeyError: 85 pass # ignore missing keys 86 except Exception: 87 import traceback 88 traceback.print_exc() 89 90 def _commit(self): 91 if hasattr(self, 'file_path') and self.file_path and len(self): 92 dpath = os.path.dirname(self.file_path) 93 if not os.path.exists(dpath): 94 os.makedirs(dpath, 0o700) 95 with open(self.file_path, 'w', encoding='utf-8') as f: 96 return json.dump(self, f, indent=2, ensure_ascii=False) 97