zpp_config 1.2.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
zpp_config/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ __version__ = '1.2.0'
2
+ __author__ = 'ZephyrOff (Alexandre Pajak)'
3
+ __descriptor__ = 'Module pour le chargement et la modification de fichier de configuration'
4
+
5
+ from .config import *
zpp_config/config.py ADDED
@@ -0,0 +1,490 @@
1
+ import re
2
+ import ast
3
+ from os.path import isfile, exists
4
+
5
+
6
+ class Config():
7
+ def __init__(self,file,separator=" = ", escape_line="#", auto_create=False, read_only=False):
8
+ self.reg = r'\[[0-9A-Za-z-_ ]*\]'
9
+
10
+ self.separator=separator
11
+ self.escape_line = escape_line
12
+
13
+ self.read_only = read_only
14
+ self.created = False
15
+
16
+ if isfile(file) and exists(file):
17
+ self.file = file
18
+ else:
19
+ if auto_create==False:
20
+ print("Error: File not exists")
21
+ else:
22
+ self.file = file
23
+ with open(self.file, 'a') as f:
24
+ pass
25
+ self.created = True
26
+
27
+ #Str to real type
28
+ def return_data(self, data):
29
+ if data=="true" or data=="True":
30
+ return True
31
+ elif data=="false" or data=="False":
32
+ return False
33
+ else:
34
+ try:
35
+ return ast.literal_eval(data)
36
+ except:
37
+ return data
38
+
39
+
40
+ def indent_line(self,line):
41
+ lineC = line.replace("\t","")
42
+
43
+ return lineC
44
+
45
+
46
+ def list_section(self):
47
+ if hasattr(self,'file'):
48
+ with open(self.file) as f:
49
+ sec_array = []
50
+ for line in f.readlines():
51
+ line = self.indent_line(line.strip())
52
+ if re.match(self.reg,line):
53
+ sec_array.append(line.replace("[","").replace("]",""))
54
+ return sec_array
55
+
56
+
57
+ def load(self,val=None,section=None,default=None):
58
+ lock=False
59
+ ban = False
60
+ data = []
61
+ sec = ''
62
+ dict_data = {}
63
+
64
+ if hasattr(self,'file'):
65
+ if section!=None and section!="" and section not in self.list_section():
66
+ return data
67
+
68
+ with open(self.file) as f:
69
+ for line in f.readlines():
70
+ line = self.indent_line(line.strip())
71
+ if ban==True and line.startswith("[") and line.endswith("]"):
72
+ ban=False
73
+
74
+ if line.startswith(self.escape_line+"[") and line.endswith("]"):
75
+ ban=True
76
+ elif line.startswith(self.escape_line):
77
+ pass
78
+ else:
79
+ if ban==False:
80
+ if section!=None:
81
+ if section!="" and re.match(self.reg,line):
82
+ if lock==False:
83
+ if line=="["+section+"]":
84
+ lock=True
85
+ data = []
86
+ else:
87
+ lock=False
88
+ break
89
+
90
+ else:
91
+ if lock==True:
92
+ if len(line)!=0:
93
+ if val==None:
94
+ data.append(line)
95
+ else:
96
+ line = line.split(self.separator)
97
+ if line[0]==val:
98
+ return self.return_data(line[1])
99
+ elif section=="":
100
+ if len(line)!=0:
101
+ if not line.startswith("[") and not line.endswith("]"):
102
+ if val==None:
103
+ data.append(line)
104
+ else:
105
+ line = line.split(self.separator)
106
+ if line[0]==val:
107
+ return self.return_data(line[1])
108
+ else:
109
+ break
110
+
111
+ elif val!=None:
112
+ if re.match(self.reg,line):
113
+ sec = line.replace("[","").replace("]","")
114
+
115
+ if len(line)!=0:
116
+ line = line.split(self.separator)
117
+ if line[0]==val:
118
+ data.append(sec + self.separator + line[1])
119
+
120
+ else:
121
+ if len(line)!=0:
122
+ if not re.match(self.reg,line):
123
+ line = line.split(self.separator)
124
+ if sec=='' and sec not in dict_data:
125
+ dict_data[sec] = {}
126
+ dict_data[sec][line[0]] = self.return_data(line[1])
127
+ else:
128
+ sec = line.replace("[","").replace("]","")
129
+ if sec not in dict_data.keys():
130
+ dict_data[sec] = {}
131
+
132
+ if val==None and section==None:
133
+ return dict_data
134
+
135
+
136
+ if len(data)!=0:
137
+ for element in data:
138
+ element=element.split(self.separator)
139
+ if len(element)>1:
140
+ dict_data[element[0]] = self.return_data(element[1])
141
+
142
+ if dict_data=={} and default!=None:
143
+ return default
144
+ else:
145
+ return dict_data
146
+
147
+ if data==[] and default!=None:
148
+ return default
149
+ else:
150
+ return data
151
+
152
+ if default!=None:
153
+ return default
154
+
155
+
156
+ def edit(self,line,val,key,temp):
157
+ if len(line)!=0:
158
+ if val!=None:
159
+ lineT = line.split(self.separator)
160
+ if lineT[0]==val:
161
+ self.new_content.append(temp.replace(self.separator+lineT[1], self.separator+str(key)))
162
+ return True
163
+ else:
164
+ self.new_content.append(temp)
165
+ return True
166
+ return False
167
+
168
+
169
+ def change(self,val=None,key=None,section=None):
170
+ if self.read_only==False:
171
+ if val!=None and key!=None:
172
+ if isinstance(key,str) or isinstance(key,list) or isinstance(key,int) or isinstance(key,float) or isinstance(key,bool) or isinstance(key,dict):
173
+ if hasattr(self,'file'):
174
+ with open(self.file) as f:
175
+ self.new_content = []
176
+ lock=False
177
+
178
+ for line in f.readlines():
179
+ temp = line.rstrip()
180
+ line = self.indent_line(line.strip())
181
+ if len(line)!=0:
182
+ if section!=None:
183
+ if section!="" and re.match(self.reg,line):
184
+ if lock==False:
185
+ if line=="["+section+"]":
186
+ lock=True
187
+ else:
188
+ lock=False
189
+
190
+ else:
191
+ if lock==True:
192
+ if self.edit(line,val,key,temp):
193
+ continue
194
+ else:
195
+ if self.edit(line,val,key,temp):
196
+ continue
197
+
198
+ self.new_content.append(temp)
199
+ else:
200
+ self.new_content.append(temp)
201
+
202
+ with open(self.file,"w") as f:
203
+ f.write("\n".join(self.new_content))
204
+ else:
205
+ print("Read-only mode")
206
+
207
+
208
+ def add(self,val=None,key=None,section=None):
209
+ if self.read_only==False:
210
+ exist = True
211
+ new_content=None
212
+ lock=False
213
+
214
+ if key=="":
215
+ key = '""'
216
+
217
+ if hasattr(self,'file'):
218
+ if section!=None and section!="" and section not in self.list_section():
219
+ exist = False
220
+
221
+ if val!=None and val!="" and key!=None and not (isinstance(key,str) or isinstance(key,list) or isinstance(key,int) or isinstance(key,float) or isinstance(key,bool) or isinstance(key,dict)):
222
+ print("Key not supported")
223
+ return
224
+
225
+ with open(self.file) as f:
226
+ if exist==False:
227
+ new_content=f.read()
228
+ if len(new_content):
229
+ if new_content[len(new_content)-1]=="\n":
230
+ new_content+="\n["+section+"]"
231
+ else:
232
+ new_content+="\n\n["+section+"]"
233
+ else:
234
+ new_content="["+section+"]"
235
+
236
+ if val!=None and val!="" and key!=None:
237
+ new_content+="\n"+val+self.separator+str(key)
238
+
239
+ else:
240
+ data = self.load()
241
+ if not len(data):
242
+ data = {"":{}}
243
+ if section!=None:
244
+ se_test = section
245
+ else:
246
+ se_test = ""
247
+
248
+ if val!=None:
249
+ se = data[se_test]
250
+ if val in se.keys():
251
+ print("Key already exist")
252
+ return
253
+
254
+ if val!=None and val!="" and key!=None:
255
+ if section=="" or section==None:
256
+ new_content=val+self.separator+str(key)+"\n"
257
+ new_content+=f.read()
258
+ else:
259
+ new_content = []
260
+ for line in f.readlines():
261
+ line_temp = line.rstrip()
262
+ line = self.indent_line(line.strip())
263
+ if line_temp!="":
264
+ if section!=None:
265
+ if section!="" and re.match(self.reg,line):
266
+ if lock==False:
267
+ if line=="["+section+"]":
268
+ if len(se.keys())==0:
269
+ line_temp+="\n"+val+self.separator+str(key)
270
+ lock=True
271
+ else:
272
+ lock=False
273
+
274
+ else:
275
+ if lock==True:
276
+ if "\t" in line_temp:
277
+ line_temp+="\n"+("\t"*line_temp.count('\t'))+val+self.separator+str(key)
278
+ lock=False
279
+
280
+ new_content.append(line_temp)
281
+
282
+ new_content = "\n".join(new_content)
283
+
284
+ if new_content!=None:
285
+ with open(self.file,'w') as f:
286
+ f.write(new_content)
287
+ else:
288
+ print("Read-only mode")
289
+
290
+
291
+ def delete(self,val=None,section=None):
292
+ if self.read_only==False:
293
+ if hasattr(self,'file'):
294
+ with open(self.file) as f:
295
+ lock=False
296
+ new_content=""
297
+ sec = ""
298
+ ban=False
299
+
300
+ for line in f.readlines():
301
+ lineT = line
302
+ line = self.indent_line(line.strip())
303
+
304
+ if line.startswith("[") and line.endswith("]"):
305
+ ban=False
306
+ sec = line.replace("[","").replace("]","")
307
+
308
+ elif line.startswith(self.escape_line+"[") and line.endswith("]"):
309
+ ban=True
310
+ sec = line.replace(self.escape_line+"[","").replace("]","")
311
+
312
+ if ban!=True:
313
+ if section!=None and section!="":
314
+ if section!="" and re.match(self.reg,line):
315
+ if lock==False:
316
+ if line=="["+section+"]":
317
+ lock=True
318
+ if val!=None:
319
+ new_content+=lineT
320
+ else:
321
+ new_content+=lineT
322
+ else:
323
+ new_content+=lineT
324
+ lock=False
325
+ else:
326
+ if lock==True:
327
+ if val==None:
328
+ pass
329
+ else:
330
+ line = line.split(self.separator)
331
+ if line[0]==val:
332
+ pass
333
+ else:
334
+ new_content+=lineT
335
+ else:
336
+ new_content+=lineT
337
+ else:
338
+ if val!=None and sec=="":
339
+ line = line.split(self.separator)
340
+ if line[0]==val:
341
+ pass
342
+ else:
343
+ new_content+=lineT
344
+ else:
345
+ new_content+=lineT
346
+ else:
347
+ new_content+=lineT
348
+
349
+ if new_content!="":
350
+ with open(self.file,'w') as f:
351
+ f.write(new_content)
352
+ else:
353
+ print("Read-only mode")
354
+
355
+
356
+ def disabled_line(self, section=None):
357
+ dict_data = {}
358
+
359
+ if hasattr(self,'file'):
360
+ with open(self.file) as f:
361
+ ban=False
362
+ sec = ""
363
+
364
+ for line in f.readlines():
365
+ line = self.indent_line(line.strip())
366
+ if len(line)!=0:
367
+ if line.startswith("[") and line.endswith("]"):
368
+ sec = line.replace("[","").replace("]","")
369
+ if ban==True:
370
+ ban=False
371
+
372
+ if line.startswith(self.escape_line+"[") and line.endswith("]"):
373
+ ban=True
374
+ sec = line.replace(self.escape_line+"[","").replace("]","")
375
+
376
+ elif line.startswith(self.escape_line):
377
+ line = line[1:len(line)].split(self.separator)
378
+ if sec not in dict_data.keys():
379
+ dict_data[sec] = {}
380
+ dict_data[sec][line[0]] = self.return_data(line[1])
381
+
382
+ else:
383
+ if ban==True:
384
+ line = line.split(self.separator)
385
+ if sec not in dict_data.keys():
386
+ dict_data[sec] = {}
387
+ dict_data[sec][line[0]] = self.return_data(line[1])
388
+ return dict_data
389
+
390
+ def disable(self,val=None,section=None):
391
+ if self.read_only==False:
392
+ if val!=None:
393
+ if hasattr(self,'file'):
394
+ modified = False
395
+ with open(self.file) as f:
396
+ self.new_content = []
397
+ lock=False
398
+
399
+ for line in f.readlines():
400
+ temp = line.rstrip()
401
+ line = self.indent_line(line.strip())
402
+ if len(line)!=0:
403
+ if section!=None:
404
+ if section!="" and re.match(self.reg,line):
405
+ if lock==False:
406
+ if line=="["+section+"]":
407
+ lock=True
408
+ else:
409
+ lock=False
410
+ else:
411
+ if lock==True:
412
+ lineT = line.split(self.separator)
413
+ if lineT[0]==val:
414
+ modified = True
415
+ self.new_content.append("#"+line)
416
+ else:
417
+ self.new_content.append(line)
418
+ continue
419
+ else:
420
+ lineT = line.split(self.separator)
421
+ if lineT[0]==val:
422
+ modified = True
423
+ self.new_content.append("#"+line)
424
+ else:
425
+ self.new_content.append(line)
426
+ continue
427
+ self.new_content.append(temp)
428
+ else:
429
+ self.new_content.append(temp)
430
+
431
+ if modified:
432
+ with open(self.file,"w") as f:
433
+ f.write("\n".join(self.new_content))
434
+ return True
435
+ return False
436
+ else:
437
+ print("Read-only mode")
438
+ return False
439
+
440
+
441
+ def enable(self,val=None,section=None):
442
+ if self.read_only==False:
443
+ if val!=None:
444
+ val = "#"+val
445
+ if hasattr(self,'file'):
446
+ modified = False
447
+ with open(self.file) as f:
448
+ self.new_content = []
449
+ lock=False
450
+
451
+ for line in f.readlines():
452
+ temp = line.rstrip()
453
+ line = self.indent_line(line.strip())
454
+ if len(line)!=0:
455
+ if section!=None:
456
+ if section!="" and re.match(self.reg,line):
457
+ if lock==False:
458
+ if line=="["+section+"]":
459
+ lock=True
460
+ else:
461
+ lock=False
462
+ else:
463
+ if lock==True:
464
+ lineT = line.split(self.separator)
465
+ if lineT[0]==val:
466
+ modified = True
467
+ self.new_content.append(line[1:])
468
+ else:
469
+ self.new_content.append(line)
470
+ continue
471
+ else:
472
+ lineT = line.split(self.separator)
473
+ if lineT[0]==val:
474
+ modified = True
475
+ self.new_content.append(line[1:])
476
+ else:
477
+ self.new_content.append(line)
478
+ continue
479
+ self.new_content.append(temp)
480
+ else:
481
+ self.new_content.append(temp)
482
+
483
+ if modified:
484
+ with open(self.file,"w") as f:
485
+ f.write("\n".join(self.new_content))
486
+ return True
487
+ return False
488
+ else:
489
+ print("Read-only mode")
490
+ return False
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 ZephyrOff (Alexandre Pajak)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.1
2
+ Name: zpp_config
3
+ Version: 1.2.4
4
+ Summary: Module pour le chargement et la modification de fichier de configuration
5
+ Home-page: https://github.com/ZephyrOff/py-zpp_config
6
+ Author:
7
+ License: MIT License
8
+ Project-URL: Documentation, https://github.com/ZephyrOff/py-zpp_config
9
+ Keywords: config file terminal zephyroff
10
+ Platform: ALL
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: Console
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+
18
+ # zpp-config
19
+ ## Informations
20
+ Librairie pour l'utilisation et la modification de fichier de configuration:<br>
21
+ - Charger un ou plusieurs paramètres
22
+ - Modifier un paramètre existant
23
+ - Ajout un paramètre ou une section
24
+ - Supprimer un paramètre ou une section
25
+ - Lister les sections disponibles
26
+ - Lister les paramètres et/ou sections désactivés
27
+
28
+ Prends en compte les paramètres commentés.<br>
29
+ Compatible avec les fichiers de configuration indentés.<br><br>
30
+ Traduit les paramètres pour les types str, int, float, bool, list, dict
31
+
32
+ ### Prérequis
33
+ - Python 3
34
+ <br>
35
+
36
+ # Installation
37
+ ```console
38
+ pip install zpp_config
39
+ ```
40
+
41
+ # Utilisation
42
+ ### Conseil d'importation du module
43
+ ```python
44
+ from zpp_config import Config
45
+ ```
46
+
47
+ <br>
48
+
49
+ ### Exemple de fichier de config
50
+ ```xml
51
+ [section]
52
+ value1 = key1
53
+ value2 = key2
54
+ value3 = key3
55
+
56
+ [section2]
57
+ value1 = key1
58
+ value2 = key2
59
+ value3 = key3
60
+ ```
61
+
62
+ <br>
63
+
64
+ ### Initialisaton d'un fichier de configuration
65
+ ```python
66
+ c = Config("conf.ini")
67
+ ```
68
+ >En paramètre supplémentaire, nous pouvons mettre:<br/>
69
+ >- separator: Définir le séparateur entre la clé et la valeur dans le fichier. (Par défaut: " = ")
70
+ >- escape_line: Définir le caractère utilisé pour commenter une valeur ou une section. (Par défaut: "#")
71
+ >- auto_create: Créer le fichier de configuration s'il n'existe pas. (Par défaut: "False")
72
+ >- read_only: Ouvrir le fichier de configuration en lecture seule. (Par défaut: "False")
73
+
74
+ <br>
75
+
76
+ ### Chargement de paramètre
77
+
78
+ La fonction renvoie la valeur si un unique paramètre a été trouvé, sinon renvoie un dictionnaire avec les différentes valeurs trouvées (classé par section)
79
+ Renvoie un tableau vide si aucun paramètre n'a été trouvé
80
+
81
+ #### Chargement de tous les paramètres
82
+ ```python
83
+ data = c.load()
84
+ ```
85
+ #### Chargement d'une section du fichier
86
+ ```python
87
+ data = c.load(section='section_name')
88
+ ```
89
+ #### Chargement d'une valeur dans tout le fichier
90
+ ```python
91
+ data = c.load(val='value_name')
92
+ ```
93
+ #### Chargement d'une valeur dans une section spécifique
94
+ ```python
95
+ data = c.load(val='value_name', section='section_name')
96
+ ```
97
+
98
+ >En paramètre supplémentaire, nous pouvons mettre:<br/>
99
+ >- default: Pour initialiser une valeur par défaut si aucun résultat est trouvé
100
+
101
+
102
+ <br>
103
+
104
+ ### Changement de paramètre
105
+ #### Changement d'une valeur dans tout le fichier
106
+ ```python
107
+ c.change(val='value_name', key='key_value')
108
+ ```
109
+
110
+ #### Changement d'une valeur dans une section spécifique
111
+ ```python
112
+ c.change(val='value_name', key='key_value', section='section_name')
113
+ ```
114
+
115
+ <br>
116
+
117
+ ### Ajout de paramètre ou de section
118
+
119
+ Ajoute une section ou un paramètre dans le fichier de configuration.
120
+ Dans le cas de l'ajout d'un paramètre, rajoute la section si elle n'existe pas.
121
+
122
+ #### Ajout d'une section
123
+ ```python
124
+ c.add(section='section_name')
125
+ ```
126
+
127
+ #### Ajout d'un paramètre dans une section
128
+ ```python
129
+ c.add(val='value_name', key='key_value', section='section_name')
130
+ ```
131
+ > Si aucune section est défini, rajoute le paramètre en dehors des sections.
132
+
133
+ <br>
134
+
135
+ ### Suppression de paramètre ou de section
136
+
137
+ #### Suppression d'une section
138
+ ```python
139
+ c.delete(section='section_name')
140
+ ```
141
+
142
+ #### Suppression d'un paramètre dans une section
143
+ ```python
144
+ c.delete(val='value_name', section='section_name')
145
+ ```
146
+ > Si aucune section est défini, recherche le paramètre en dehors des sections.
147
+
148
+ <br>
149
+
150
+ ### Liste des paramètres non pris en compte
151
+
152
+ Retourne la liste des paramètres qui sont non pris en compte dans le fichier de configuration.
153
+
154
+ ```python
155
+ data = c.disabled_line()
156
+ ```
157
+ > Possibilité de préciser la section en utilisant le paramètre section
158
+
159
+ <br>
160
+
161
+ ### Liste les sections disponibles
162
+ ```python
163
+ data = c.list_section()
164
+ ```
@@ -0,0 +1,7 @@
1
+ zpp_config/__init__.py,sha256=fYbK3e8kVMyChmsTKxh3Sipa0P1PVeSmBctW3c86vII,184
2
+ zpp_config/config.py,sha256=LdioFZFd5o-q4GRs6V_TzpwABaXgi20aSxXI6rVQp30,13211
3
+ zpp_config-1.2.4.dist-info/LICENSE,sha256=IN5ZiLY3uHlCdy7WDkFpEPZZYO6hZWelnfxjFcyJ1tc,1106
4
+ zpp_config-1.2.4.dist-info/METADATA,sha256=M9N8RiStdFsqb5mqq24mettuemcXIjEM0k8L0XdEQ_s,4529
5
+ zpp_config-1.2.4.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
6
+ zpp_config-1.2.4.dist-info/top_level.txt,sha256=6dEIAXeo-7VTDVRECIf2Jl3e1icUn_HS6ht6H4QYd9o,11
7
+ zpp_config-1.2.4.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (70.3.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ zpp_config