-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSettings.py
121 lines (100 loc) · 3.52 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
110
111
112
113
114
115
116
117
118
119
120
121
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