9
9
10
10
"""
11
11
12
- from json import dump , load
12
+ from json import JSONDecodeError , dump , load
13
13
from os .path import abspath
14
+ from traceback import format_exc
14
15
15
16
from core .icons import Icons
16
17
18
+ ACCEPT_ENCODING : tuple [str ] = ("ascii" , "utf-8" , "utf-16" , "utf-32" )
19
+
17
20
class Config :
18
- ACCEPT_ENCODING : tuple [str ] = ("ascii" , "utf-8" , "utf-16" , "utf-32" )
21
+ """ Configuration manager object for the program.
22
+
23
+ This class handles the loading, saving, and manipulation of a configuration file
24
+ used by the program. It allows setting and retrieving parameters like CLI color usage,
25
+ character encoding, and splash screen visibility.
26
+
27
+ Attributes:
28
+ loaded (bool): Indicates whether the configuration was successfully loaded at initialization.
29
+
30
+ Private Attributes:
31
+ __colors (bool): Whether colored output is enabled in the CLI.
32
+ __encoding (str): Encoding used for reading/writing the configuration file.
33
+ __path (str): Absolute path to the JSON configuration file.
34
+ __splash (bool): Whether the splash screen is enabled at startup.
35
+
36
+ Methods:
37
+ getColors() -> bool:
38
+ Returns the current state of CLI color output.
39
+
40
+ getEncoding() -> str:
41
+ Returns the currently set encoding.
42
+
43
+ getSplash() -> bool:
44
+ Returns whether the splash screen is enabled.
45
+
46
+ setColors(colors: bool = False) -> bool:
47
+ Updates the CLI color state and saves the configuration.
48
+
49
+ setEncoding(encoding: str = "utf-8") -> bool:
50
+ Updates the encoding value if it's allowed and saves the configuration.
19
51
52
+ setSplash(splash: bool = True) -> bool:
53
+ Updates the splash screen setting and saves the configuration.
54
+
55
+ Notes:
56
+ - The configuration file must be in JSON format with the keys: "colors", "encoding", and "splash".
57
+ - Accepted encodings are defined in the module-level constant `ACCEPT_ENCODING`.
58
+
59
+ """
60
+
61
+ __colors : bool = False
20
62
__encoding : str = "utf-8"
21
63
__path : str = abspath ("config.json" )
22
64
__splash : bool = True
@@ -25,35 +67,60 @@ def __init__(self):
25
67
self .loaded : bool = self .__load ()
26
68
27
69
def __load (self ) -> bool :
70
+ """ Private method to load the configuration file
71
+
72
+ Returns the loading success statement, e.g. True or False.
73
+
74
+ """
75
+
28
76
try :
29
77
with open (self .__path , "r" , encoding = self .__encoding ) as cfgFile :
30
78
_ = dict [str , str | bool ](load (cfgFile ))
31
79
80
+ self .__colors = bool (_ ["colors" ])
32
81
self .__encoding = str (_ ["encoding" ])
33
82
self .__splash = bool (_ ["splash" ])
34
83
35
- except Exception :
84
+ except (FileNotFoundError ):
85
+ print (f"{ Icons .err } No config file found" )
86
+ print (f"{ Icons .info } Recreate config file with default settings" )
87
+ self .__save ()
88
+
89
+ except (JSONDecodeError , KeyError , Exception ):
36
90
print (f"{ Icons .err } Config file loading failed" )
37
91
return (False )
38
92
39
93
return (True )
40
94
41
95
def __save (self ) -> bool :
96
+ """ Private method to save the current configuration
97
+
98
+ Returns the saving success statement, e.g. True or False.
99
+
100
+ """
101
+
42
102
try :
43
103
with open (self .__path , "w" , encoding = self .__encoding ) as cfgFile :
44
104
_ = dict ({
105
+ "colors" : self .__colors ,
45
106
"encoding" : self .__encoding ,
46
107
"splash" : self .__splash
47
108
})
48
109
49
110
dump (dict (_ ), cfgFile , sort_keys = True , indent = 2 )
50
111
51
- except Exception :
112
+ except ( Exception ) :
52
113
print (f"{ Icons .err } Config file saving failed" )
53
114
return (False )
54
115
55
116
return (True )
56
117
118
+ def getColors (self ) -> bool :
119
+ """ Returns the colors display state, e.g. True or False.
120
+ """
121
+
122
+ return (self .__colors )
123
+
57
124
def getEncoding (self ) -> str :
58
125
""" Returns the encoding state, e.g. "ascii", "utf-8", "utf-16" or "utf-32"
59
126
"""
@@ -62,21 +129,133 @@ def getEncoding(self) -> str:
62
129
63
130
def getSplash (self ) -> bool :
64
131
""" Returns the splash display state, e.g. True or False.
65
- """
132
+ """
66
133
67
134
return (self .__splash )
68
135
136
+ def setColors (self , colors : bool = False ) -> bool :
137
+ """ Apply new colors state display on the whole cli
138
+
139
+ Parameters:
140
+
141
+ colors bool
142
+ the state between True or False
143
+
144
+ Return a bool to validate the updating
145
+
146
+ """
147
+
148
+ self .__colors = bool (colors )
149
+ self .__save ()
150
+
151
+ return (True )
152
+
69
153
def setEncoding (self , encoding : str = "utf-8" ) -> bool :
70
- if (encoding .lower () in self .ACCEPT_ENCODING ):
71
- self .__encoding = encoding
154
+ """ Apply new encoding value on settings
155
+
156
+ Parameters:
157
+
158
+ encoding str
159
+ the string of the new encoding to use
160
+
161
+ Return a bool to validate the updating
162
+
163
+ """
164
+
165
+ if (encoding .lower () in ACCEPT_ENCODING ):
166
+ self .__encoding = str (encoding )
72
167
self .__save ()
73
168
74
169
return (True )
75
170
76
171
return (False )
77
172
78
173
def setSplash (self , splash : bool = True ) -> bool :
79
- self .__splash = splash
174
+ """ Apply new splash state display on main prompt
175
+
176
+ Parameters:
177
+
178
+ splash bool
179
+ the state between True or False
180
+
181
+ Return a bool to validate the updating
182
+
183
+ """
184
+
185
+ self .__splash = bool (splash )
80
186
self .__save ()
81
187
82
188
return (True )
189
+
190
+ def getConfig (cfg : Config , prop : str ) -> bool :
191
+ """ Interface to get a config displayer
192
+
193
+ Parameters:
194
+
195
+ cfg Config
196
+ the config object instance
197
+
198
+ prop str
199
+ the string of property to show
200
+ can be "all" to display whole settings values
201
+
202
+ Return a bool to validate the output
203
+
204
+ """
205
+
206
+ __output = list [str ]([])
207
+ __gets = (
208
+ ("colors" , lambda :cfg .getColors ()),
209
+ ("encode" , lambda :cfg .getEncoding ()),
210
+ ("splash" , lambda :cfg .getSplash ())
211
+ )
212
+
213
+ if (prop == "all" ):
214
+ for r , g in __gets :
215
+ __output .append (f"{ r } : { g ()} " )
216
+
217
+ elif (prop in [ r for r , g in __gets ]):
218
+ for r , g in __gets :
219
+ if (prop == r ):
220
+ __output .append (g ())
221
+
222
+ else :
223
+ __output .append (f"{ Icons .warn } Uknown value was entered !" [1 :- 1 ])
224
+
225
+ print ("\n " .join ([ f" { o } " for o in __output ]), end = "\n " * 2 )
226
+ return (True )
227
+
228
+ def setConfig (cfg : Config , prop : str , val : str ) -> bool :
229
+ """ Interface to set a config property on config object
230
+
231
+ Parameters:
232
+
233
+ cfg Config
234
+ the config object instance
235
+
236
+ prop str
237
+ the string of property to update
238
+
239
+ val str
240
+ the new value of setting prop to update
241
+
242
+ Return a bool to validate the applied setting
243
+
244
+ Raise an Exception if the property doen't know
245
+
246
+ """
247
+
248
+ __isApplied = bool (False )
249
+ __sets = (
250
+ ("colors" , lambda v :cfg .setColors (v .lower () == "true" )),
251
+ ("encode" , lambda v :cfg .setEncoding (v )),
252
+ ("splash" , lambda v :cfg .setSplash (v .lower () == "true" ))
253
+ )
254
+
255
+ for r , s in __sets :
256
+ if (prop == r ):
257
+ __isApplied = s (val )
258
+ print (f'{ Icons .info if (__isApplied ) else Icons .err } new { prop } { "is" if (__isApplied ) else "is not" } applied' )
259
+ return (__isApplied )
260
+
261
+ raise (Exception ("Uknown property !" ))
0 commit comments