zpp_config 1.0.0__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,6 @@
1
+ __version__ = '1.0.0'
2
+ __author__ = 'ZephyrOff (Alexandre Pajak)'
3
+ __descriptor__ = 'Module pour le chargement et la modification de fichier de configuration'
4
+ __lastupdate__ = '01/06/2022'
5
+
6
+ from .config import *
zpp_config/config.py ADDED
@@ -0,0 +1,417 @@
1
+ ####################################################################
2
+ #/ Nom du projet: py-zpp_config /#
3
+ #/ Nom du fichier: config.py /#
4
+ #/ Type de fichier: fichier principal /#
5
+ #/ Fichier annexe: /#
6
+ #/ /#
7
+ #/ Auteur: ZephyrOff (Alexandre Pajak) /#
8
+ #/ Version: 1.0 /#
9
+ #/ Description: Module pour le chargement et la modification /#
10
+ #/ de fichier de configuration /#
11
+ #/ Date: 01/06/2022 /#
12
+ ####################################################################
13
+
14
+ import re
15
+ import ast
16
+ from os.path import isfile, exists
17
+
18
+
19
+ class Config():
20
+ def __init__(self,file,separator=" = ", escape_line="#", auto_create=False, read_only=False):
21
+ self.reg = r'\[[0-9A-Za-z-_ ]*\]'
22
+
23
+ self.separator=separator
24
+ self.escape_line = escape_line
25
+
26
+ self.read_only = read_only
27
+
28
+ if isfile(file) and exists(file):
29
+ self.file = file
30
+ else:
31
+ if auto_create==False:
32
+ print("Error: File not exists")
33
+ else:
34
+ with open(file,'w') as f:
35
+ self.file = file
36
+
37
+ #Str to real type
38
+ def return_data(self, data):
39
+ if data=="true" or data=="True":
40
+ return True
41
+ elif data=="false" or data=="False":
42
+ return False
43
+ else:
44
+ try:
45
+ return ast.literal_eval(data)
46
+ except:
47
+ return data
48
+
49
+
50
+ def indent_line(self,line):
51
+ lineC = line.replace("\t","")
52
+ line = ""
53
+ l = ""
54
+ for i, char in enumerate(lineC):
55
+ if (char=="'" and lineC.count("'")%2==0) or (char=='"' and lineC.count('"')%2==0):
56
+ if l==char:
57
+ l=""
58
+ else:
59
+ l=char
60
+ else:
61
+ if len(l)==0 and i+1<len(lineC) and lineC[i]==" " and lineC[i+1]==" ":
62
+ pass
63
+ else:
64
+ line+=char
65
+ return line
66
+
67
+
68
+ def list_section(self):
69
+ if hasattr(self,'file'):
70
+ with open(self.file) as f:
71
+ sec_array = []
72
+ for line in f.readlines():
73
+ line = self.indent_line(line.strip())
74
+ if re.match(self.reg,line):
75
+ sec_array.append(line.replace("[","").replace("]",""))
76
+ return sec_array
77
+
78
+
79
+ def load(self,val=None,section=None):
80
+ lock=False
81
+ ban = False
82
+ data = []
83
+ sec = ''
84
+ dict_data = {}
85
+
86
+ if hasattr(self,'file'):
87
+ if section!=None and section!="" and section not in self.list_section():
88
+ return data
89
+
90
+ with open(self.file) as f:
91
+ for line in f.readlines():
92
+ line = self.indent_line(line.strip())
93
+ if ban==True and line.startswith("[") and line.endswith("]"):
94
+ ban=False
95
+
96
+ if line.startswith(self.escape_line+"[") and line.endswith("]"):
97
+ ban=True
98
+ elif line.startswith(self.escape_line):
99
+ pass
100
+ else:
101
+ if ban==False:
102
+ if section!=None:
103
+ if section!="" and re.match(self.reg,line):
104
+ if lock==False:
105
+ if line=="["+section+"]":
106
+ lock=True
107
+ data = []
108
+ else:
109
+ lock=False
110
+ break
111
+
112
+ else:
113
+ if lock==True:
114
+ if len(line)!=0:
115
+ if val==None:
116
+ data.append(line)
117
+ else:
118
+ line = line.split(self.separator)
119
+ if line[0]==val:
120
+ return self.return_data(line[1])
121
+ elif section=="":
122
+ if len(line)!=0:
123
+ if not line.startswith("[") and not line.endswith("]"):
124
+ if val==None:
125
+ data.append(line)
126
+ else:
127
+ line = line.split(self.separator)
128
+ if line[0]==val:
129
+ return self.return_data(line[1])
130
+ else:
131
+ break
132
+
133
+ elif val!=None:
134
+ if re.match(self.reg,line):
135
+ sec = line.replace("[","").replace("]","")
136
+
137
+ if len(line)!=0:
138
+ line = line.split(self.separator)
139
+ if line[0]==val:
140
+ data.append(sec + self.separator + line[1])
141
+
142
+ else:
143
+ if len(line)!=0:
144
+ if sec not in dict_data.keys():
145
+ dict_data[sec] = {}
146
+ if not re.match(self.reg,line):
147
+ line = line.split(self.separator)
148
+ dict_data[sec][line[0]] = self.return_data(line[1])
149
+ else:
150
+ sec = line.replace("[","").replace("]","")
151
+
152
+ if val==None and section==None:
153
+ return dict_data
154
+
155
+ if len(data)!=0:
156
+ for element in data:
157
+ element=element.split(self.separator)
158
+ dict_data[element[0]] = self.return_data(element[1])
159
+ return dict_data
160
+
161
+ return data
162
+
163
+
164
+ def edit(self,line,val,key,temp):
165
+ if len(line)!=0:
166
+ if val!=None:
167
+ lineT = line.split(self.separator)
168
+ if lineT[0]==val:
169
+ self.new_content.append(temp.replace(self.separator+lineT[1], self.separator+str(key)))
170
+ return True
171
+ else:
172
+ self.new_content.append(temp)
173
+ return True
174
+ return False
175
+
176
+
177
+ def change(self,val=None,key=None,section=None):
178
+ if self.read_only==False:
179
+ if val!=None and key!=None:
180
+ if isinstance(key,str) or isinstance(key,list) or isinstance(key,int) or isinstance(key,float) or isinstance(key,bool) or isinstance(key,dict):
181
+ if hasattr(self,'file'):
182
+ with open(self.file) as f:
183
+ self.new_content = []
184
+ lock=False
185
+
186
+ for line in f.readlines():
187
+ temp = line.rstrip()
188
+ line = self.indent_line(line.strip())
189
+ if len(line)!=0:
190
+ if section!=None:
191
+ if section!="" and re.match(self.reg,line):
192
+ if lock==False:
193
+ if line=="["+section+"]":
194
+ lock=True
195
+ else:
196
+ lock=False
197
+
198
+ else:
199
+ if lock==True:
200
+ if self.edit(line,val,key,temp):
201
+ continue
202
+ else:
203
+ if self.edit(line,val,key,temp):
204
+ continue
205
+
206
+ self.new_content.append(temp)
207
+ else:
208
+ self.new_content.append(temp)
209
+
210
+ with open(self.file,"w") as f:
211
+ f.write("\n".join(self.new_content))
212
+ else:
213
+ print("Read-only mode")
214
+
215
+
216
+ def add(self,val=None,key=None,section=None):
217
+ if self.read_only==False:
218
+ exist = True
219
+ new_content=None
220
+ lock=False
221
+
222
+ if hasattr(self,'file'):
223
+ if section!=None and section!="" and section not in self.list_section():
224
+ exist = False
225
+
226
+ 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)):
227
+ print("Key not supported")
228
+ return
229
+
230
+ with open(self.file) as f:
231
+ if exist==False:
232
+ new_content=f.read()
233
+ if new_content[len(new_content)-1]=="\n":
234
+ new_content+="\n["+section+"]"
235
+ else:
236
+ new_content+="\n\n["+section+"]"
237
+ if val!=None and val!="" and key!=None:
238
+ new_content+="\n"+val+self.separator+str(key)
239
+
240
+ else:
241
+ data = c.load()
242
+ if section!=None:
243
+ se_test = section
244
+ else:
245
+ se_test = ""
246
+
247
+ if val!=None:
248
+ se = data[se_test]
249
+ if val in se.keys():
250
+ print("Key already exist")
251
+ return
252
+
253
+ if val!=None and val!="" and key!=None:
254
+ if section=="" or section==None:
255
+ new_content=val+self.separator+str(key)+"\n"
256
+ new_content+=f.read()
257
+ else:
258
+ new_content = []
259
+ for line in f.readlines():
260
+ line_temp = line.rstrip()
261
+ line = self.indent_line(line.strip())
262
+ if line_temp!="":
263
+ if section!=None:
264
+ if section!="" and re.match(self.reg,line):
265
+ if lock==False:
266
+ if line=="["+section+"]":
267
+ if len(se.keys())==0:
268
+ line_temp+="\n"+val+self.separator+str(key)
269
+ lock=True
270
+ else:
271
+ lock=False
272
+
273
+ else:
274
+ if lock==True:
275
+ if "\t" in line_temp:
276
+ line_temp+="\n"+("\t"*line_temp.count('\t'))+val+self.separator+str(key)
277
+ lock=False
278
+
279
+ new_content.append(line_temp)
280
+
281
+ new_content = "\n".join(new_content)
282
+
283
+ if new_content!=None:
284
+ with open(self.file,'w') as f:
285
+ f.write(new_content)
286
+ else:
287
+ print("Read-only mode")
288
+
289
+
290
+ def delete(self,val=None,section=None):
291
+ if self.read_only==False:
292
+ if hasattr(self,'file'):
293
+ with open(self.file) as f:
294
+ lock=False
295
+ new_content=""
296
+ sec = ""
297
+ ban=False
298
+
299
+ for line in f.readlines():
300
+ lineT = line
301
+ line = self.indent_line(line.strip())
302
+
303
+ if line.startswith("[") and line.endswith("]"):
304
+ ban=False
305
+ sec = line.replace("[","").replace("]","")
306
+
307
+ elif line.startswith(self.escape_line+"[") and line.endswith("]"):
308
+ ban=True
309
+ sec = line.replace(self.escape_line+"[","").replace("]","")
310
+
311
+ if ban!=True:
312
+ if section!=None and section!="":
313
+ if section!="" and re.match(self.reg,line):
314
+ if lock==False:
315
+ if line=="["+section+"]":
316
+ lock=True
317
+ if val!=None:
318
+ new_content+=lineT
319
+ else:
320
+ new_content+=lineT
321
+ else:
322
+ new_content+=lineT
323
+ lock=False
324
+ else:
325
+ if lock==True:
326
+ if val==None:
327
+ pass
328
+ else:
329
+ line = line.split(self.separator)
330
+ if line[0]==val:
331
+ pass
332
+ else:
333
+ new_content+=lineT
334
+ else:
335
+ new_content+=lineT
336
+ else:
337
+ if val!=None and sec=="":
338
+ line = line.split(self.separator)
339
+ if line[0]==val:
340
+ pass
341
+ else:
342
+ new_content+=lineT
343
+ else:
344
+ new_content+=lineT
345
+ else:
346
+ new_content+=lineT
347
+
348
+ if new_content!="":
349
+ with open(self.file,'w') as f:
350
+ f.write(new_content)
351
+ else:
352
+ print("Read-only mode")
353
+
354
+
355
+ def disabled_line(self, section=None):
356
+ dict_data = {}
357
+
358
+ if hasattr(self,'file'):
359
+ with open(self.file) as f:
360
+ ban=False
361
+ sec = ""
362
+
363
+ for line in f.readlines():
364
+ line = self.indent_line(line.strip())
365
+ if len(line)!=0:
366
+ if line.startswith("[") and line.endswith("]"):
367
+ sec = line.replace("[","").replace("]","")
368
+ if ban==True:
369
+ ban=False
370
+
371
+ if line.startswith(self.escape_line+"[") and line.endswith("]"):
372
+ ban=True
373
+ sec = line.replace(self.escape_line+"[","").replace("]","")
374
+
375
+ elif line.startswith(self.escape_line):
376
+ line = line[1:len(line)].split(self.separator)
377
+ if sec not in dict_data.keys():
378
+ dict_data[sec] = {}
379
+ dict_data[sec][line[0]] = self.return_data(line[1])
380
+
381
+ else:
382
+ if ban==True:
383
+ line = line.split(self.separator)
384
+ if sec not in dict_data.keys():
385
+ dict_data[sec] = {}
386
+ dict_data[sec][line[0]] = self.return_data(line[1])
387
+ return dict_data
388
+
389
+
390
+ #c = Config("conf.dat",auto_create=True)
391
+ c = Config("conf.dat",read_only=True)
392
+ #c.add(val="test4",key=5,section="f_section")
393
+ #d = c.list_section()
394
+ #print(d)
395
+ #d = c.load(val="conf",section="second_section")
396
+ #print(d)
397
+ #d = c.load(section='section')
398
+ #print(d)
399
+ #c.change(val="conf",key="NULL",section="second_section")
400
+
401
+ #d = c.load(section='second_section',val='conf')
402
+ #print(d)
403
+ #d = c.disabled_line()
404
+ #print(d)
405
+ #c.delete(section="f_section")
406
+
407
+
408
+ '''
409
+ list_section(self)
410
+ load(self,val=None,section=None)
411
+ change(self,val=None,key=None,section=None)
412
+ add(self,val=None,key=None,section=None)
413
+ delete(self,val=None,section=None)
414
+ disabled_line(self, section=None)
415
+ '''
416
+
417
+ #read-only
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.1
2
+ Name: zpp-config
3
+ Version: 1.0.0
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: ZephyrOff
7
+ Author-email: contact@apajak.fr
8
+ License: MIT
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
+
17
+ # zpp-config
18
+ ## Informations
19
+ Librairie pour l'utilisation et la modification de fichier de configuration:<br>
20
+ - Charger un ou plusieurs paramètres
21
+ - Modifier un paramètre existant
22
+ - Ajout un paramètre ou une section
23
+ - Supprimer un paramètre ou une section
24
+ - Lister les sections disponibles
25
+ - Lister les paramètres et/ou sections désactivés
26
+
27
+ Prends en compte les paramètres commentés.<br>
28
+ Compatible avec les fichiers de configuration indentés.<br><br>
29
+ Traduit les paramètres pour les types str, int, float, bool, list, dict
30
+
31
+ ### Prérequis
32
+ - Python 3
33
+ <br>
34
+
35
+ # Installation
36
+ ```console
37
+ pip install zpp_config
38
+ ```
39
+
40
+ # Utilisation
41
+ ### Conseil d'importation du module
42
+ ```python
43
+ from zpp_config import Config
44
+ ```
45
+
46
+ <br>
47
+
48
+ ### Exemple de fichier de config
49
+ ```xml
50
+ [section]
51
+ value1 = key1
52
+ value2 = key2
53
+ value3 = key3
54
+
55
+ [section2]
56
+ value1 = key1
57
+ value2 = key2
58
+ value3 = key3
59
+ ```
60
+
61
+ <br>
62
+
63
+ ### Initialisaton d'un fichier de configuration
64
+ ```python
65
+ c = Config("conf.ini")
66
+ ```
67
+ >En paramètre supplémentaire, nous pouvons mettre:<br/>
68
+ >- separator: Définir le séparateur entre la clé et la valeur dans le fichier. (Par défaut: " = ")
69
+ >- escape_line: Définir le caractère utilisé pour commenter une valeur ou une section. (Par défaut: "#")
70
+ >- auto_create: Créer le fichier de configuration s'il n'existe pas. (Par défaut: "False")
71
+ >- read_only: Ouvrir le fichier de configuration en lecture seule. (Par défaut: "False")
72
+
73
+ <br>
74
+
75
+ ### Chargement de paramètre
76
+
77
+ 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)
78
+ Renvoie un tableau vide si aucun paramètre n'a été trouvé
79
+
80
+ #### Chargement de tous les paramètres
81
+ ```python
82
+ data = c.load()
83
+ ```
84
+ #### Chargement d'une section du fichier
85
+ ```python
86
+ data = c.load(section='section_name')
87
+ ```
88
+ #### Chargement d'une valeur dans tout le fichier
89
+ ```python
90
+ data = c.load(val='value_name')
91
+ ```
92
+ #### Chargement d'une valeur dans une section spécifique
93
+ ```python
94
+ data = c.load(val='value_name', section='section_name')
95
+ ```
96
+
97
+ <br>
98
+
99
+ ### Changement de paramètre
100
+ #### Changement d'une valeur dans tout le fichier
101
+ ```python
102
+ c.change(val='value_name', key='key_value')
103
+ ```
104
+
105
+ #### Changement d'une valeur dans une section spécifique
106
+ ```python
107
+ c.change(val='value_name', key='key_value', section='section_name')
108
+ ```
109
+
110
+ <br>
111
+
112
+ ### Ajout de paramètre ou de section
113
+
114
+ Ajoute une section ou un paramètre dans le fichier de configuration.
115
+ Dans le cas de l'ajout d'un paramètre, rajoute la section si elle n'existe pas.
116
+
117
+ #### Ajout d'une section
118
+ ```python
119
+ c.add(section='section_name')
120
+ ```
121
+
122
+ #### Ajout d'un paramètre dans une section
123
+ ```python
124
+ c.add(val='value_name', key='key_value', section='section_name')
125
+ ```
126
+ > Si aucune section est défini, rajoute le paramètre en dehors des sections.
127
+
128
+ <br>
129
+
130
+ ### Suppression de paramètre ou de section
131
+
132
+ #### Suppression d'une section
133
+ ```python
134
+ c.delete(section='section_name')
135
+ ```
136
+
137
+ #### Suppression d'un paramètre dans une section
138
+ ```python
139
+ c.delete(val='value_name', section='section_name')
140
+ ```
141
+ > Si aucune section est défini, recherche le paramètre en dehors des sections.
142
+
143
+ <br>
144
+
145
+ ### Liste des paramètres non pris en compte
146
+
147
+ Retourne la liste des paramètres qui sont non pris en compte dans le fichier de configuration.
148
+
149
+ ```python
150
+ data = c.disabled_line()
151
+ ```
152
+ > Possibilité de préciser la section en utilisant le paramètre section
153
+
154
+ <br>
155
+
156
+ ### Liste les sections disponibles
157
+ ```python
158
+ data = c.list_section()
159
+ ```
160
+
@@ -0,0 +1,6 @@
1
+ zpp_config/__init__.py,sha256=Dza4DmamkfxHk3hThVQ2fEBxIE72224lqe23c24822Y,215
2
+ zpp_config/config.py,sha256=PhVqtVUil2Ls4wJCS5ozn7P8XC2stwoyfhcApKn4aEs,11731
3
+ zpp_config-1.0.0.dist-info/METADATA,sha256=c01hibPENXkFzDqzx1UoR0spUXgkcQUE5J5IX6_faIo,4040
4
+ zpp_config-1.0.0.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
5
+ zpp_config-1.0.0.dist-info/top_level.txt,sha256=6dEIAXeo-7VTDVRECIf2Jl3e1icUn_HS6ht6H4QYd9o,11
6
+ zpp_config-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.34.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ zpp_config