forked from chigkim/VOLlama
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Settings.py
109 lines (94 loc) · 3.5 KB
/
Settings.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
from cryptography.fernet import Fernet
import appdirs
import os
import json
import threading
def encrypt(key, value):
# Convert the string representation of the key back to bytes
key_bytes = key.encode()
cipher_suite = Fernet(key_bytes)
# Encrypt the value, which is then encoded to a string for easy handling
encrypted_value = cipher_suite.encrypt(value.encode()).decode()
return encrypted_value
def decrypt(key, encrypted_value):
key_bytes = key.encode()
encrypted_value_bytes = encrypted_value.encode()
cipher_suite = Fernet(key_bytes)
decrypted_value = cipher_suite.decrypt(encrypted_value_bytes).decode()
return decrypted_value
class DotDict:
def __init__(self, dictionary=None, parent=None):
self.__dict__["_parent"] = parent # Reference to the SettingsManager for autosave.
if dictionary is None:
dictionary = {}
for key, value in dictionary.items():
# Directly assign the value without converting it to DotDict.
self.__dict__[key] = value
def __setattr__(self, key, value):
# Directly assign the value without checking for dict type to convert.
self.__dict__[key] = value
if "_parent" in self.__dict__ and self._parent:
self._parent.save_settings()
def to_dict(self):
dict_ = {}
for key, value in self.__dict__.items():
if key == "_parent":
continue # Skip the parent reference when converting to dict.
# Directly assign the value without converting from DotDict to dict.
dict_[key] = value
return dict_
class SettingsManager:
_instance = None
_lock = threading.Lock()
def __new__(cls):
with cls._lock:
if cls._instance is None:
cls._instance = super(SettingsManager, cls).__new__(cls)
cls._instance._initialized = False
return cls._instance
def __init__(self):
if self._initialized: return
self._initialized = True
self.app_name = 'VOLlama'
self.company_name = None
self.config_dir = appdirs.user_config_dir(self.app_name, self.company_name)
self.settings_file_path = os.path.join(self.config_dir, 'settings.json')
os.makedirs(self.config_dir, exist_ok=True)
self.settings = self.load_settings() # Then attempt to load settings, or initialize with defaults if loading fails.
def save_settings(self):
settings_dict = self.settings.to_dict()
for key, value in settings_dict.items():
if "key" in key and value:
settings_dict[key] = encrypt(settings_dict['secret'], value)
with open(self.settings_file_path, 'w') as file:
json.dump(settings_dict, file, indent='\t')
def load_settings(self):
p = os.path.join(os.path.dirname(__file__), "default-parameters.json")
default_dict = json.load(open(p))
try:
with open(self.settings_file_path, 'r') as file:
settings_dict = json.load(file)
except FileNotFoundError:
settings_dict = default_dict
# Ensure all default settings are present, add missing ones
for key, value in default_dict.items():
if key not in settings_dict:
settings_dict[key] = value
if "secret" not in settings_dict:
secret = Fernet.generate_key().decode()
settings_dict['secret'] = secret
else: secret = settings_dict['secret']
for key, value in settings_dict.items():
if "key" in key and value:
settings_dict[key] = decrypt(secret, value)
self.settings = DotDict(settings_dict, parent=self)
self.save_settings() # Save settings, ensuring any additions are persisted
return self.settings
@property
def settings(self):
return self._settings
@settings.setter
def settings(self, value):
self._settings = value
self.save_settings()
settings = SettingsManager().settings