iniUts 1.3.2__tar.gz → 2.0.1__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iniUts
3
- Version: 1.3.2
3
+ Version: 2.0.1
4
4
  Summary: Ini file manipulator
5
5
  Home-page:
6
6
  Author: Melque Lima
@@ -0,0 +1,235 @@
1
+ import configparser as cp
2
+ from dataclasses import dataclass
3
+ from datetime import datetime
4
+ import re
5
+ import os
6
+ import types
7
+ from iniUts.secret import decrypt, encrypt
8
+
9
+ class envar():
10
+ def __init__(self,key:str,default:str=None):
11
+ self.key = key
12
+ self.default = default
13
+
14
+ def get_value(self):
15
+ if self.default != None:
16
+ return os.getenv(self.key,self.default)
17
+ else:
18
+ value = os.getenv(self.key)
19
+ if not value:
20
+ raise Exception(f"envar '{self.key}' not found!")
21
+ return value
22
+
23
+
24
+ def save(self):
25
+ ini = self.__INIUTS__
26
+ types_to_str = [str,int,float,bool]
27
+ is_str = lambda t: any([t == x for x in types_to_str])
28
+
29
+
30
+ for k,t in self.__annotations__.items():
31
+ if k in self.__ENVARS__: continue
32
+
33
+ if is_str(t):
34
+ value = str(getattr(self,k))
35
+ elif t == tuple:
36
+ value = getattr(self,k)
37
+ delimiter = ini.delimiters[f"{str(self)}_{k}"]
38
+ value = delimiter.join(value)
39
+ elif t == datetime:
40
+ value = getattr(self,k)
41
+ dateFormat = ini.dateFormats[f"{str(self)}_{k}"]
42
+ value = value.strftime(dateFormat)
43
+
44
+ if k in self.__CRYPTED_KEYS__:
45
+ k = "&_" + k
46
+ value = encrypt(value,ini.encryption_key)
47
+
48
+ if not ini.in_prd and k in ini.cp_dev.getKeys(self.__SECTION__):
49
+ ini.cp_dev.write(self.__SECTION__,k,value)
50
+ else:
51
+ ini.cp_prd.write(self.__SECTION__,k,value)
52
+
53
+
54
+ class iniCp:
55
+ config_parser = None
56
+
57
+ def __init__(self,ini_file,encoding=None):
58
+ self.ini_file = ini_file
59
+ self.encoding = encoding
60
+ self.read_ini()
61
+
62
+ def read_ini(self):
63
+ config = cp.RawConfigParser(allow_no_value=True,comment_prefixes=("##"))
64
+ config.optionxform = str
65
+ if self.encoding:
66
+ with open(self.ini_file, 'r', encoding=self.encoding) as f:
67
+ config.read_string(f.read())
68
+ else:
69
+ config.read(self.ini_file)
70
+
71
+ self.config_parser = config
72
+
73
+ def write(self,section,key,value):
74
+ if not section in self.config_parser.sections():
75
+ self.config_parser[section] = {}
76
+ self.config_parser[section][key] = value
77
+ self.config_parser.write(open(self.ini_file, 'w',encoding=self.encoding))
78
+
79
+ def read(self,section,key):
80
+ if not section in self.config_parser.sections():
81
+ raise Exception("Section not found!")
82
+ if not key in self.config_parser[section]:
83
+ raise Exception("Key not found!")
84
+ return self.config_parser[section][key]
85
+
86
+ def getSections(self):
87
+ return list(self.config_parser.sections())
88
+
89
+ def getKeys(self,section):
90
+ if not section in self.config_parser.sections():
91
+ raise Exception("Section not found!")
92
+
93
+ return list(self.config_parser[section])
94
+
95
+ def section2Dict(self,section):
96
+ dc = dict(self.config_parser[section])
97
+
98
+ return {x:(y or None) for x,y in dc.items()}
99
+
100
+ def __iter__(self):
101
+ sections = self.getSections()
102
+ for sect in sections:
103
+ # Retorna uma tupla (chave, valor) para cada iteração
104
+ yield sect, self.section2Dict(sect)
105
+
106
+
107
+
108
+
109
+
110
+ class IniUts():
111
+ delimiters = {}
112
+ dateFormats = {}
113
+
114
+ def __init__(self,ini_prd,ini_dev=None,in_prd=True,encryption_key=None,encoding=None):
115
+ self.cp_prd = iniCp(ini_prd,encoding=encoding)
116
+ self.cp_dev = iniCp(ini_dev,encoding=encoding) if ini_dev else None
117
+ self.in_prd = in_prd
118
+ self.encryption_key = encryption_key
119
+ self.checkKeys()
120
+
121
+ def refresh(self):
122
+ self.cp_prd = iniCp(self.cp_prd.ini_file,encoding=self.cp_prd.encoding)
123
+ self.cp_dev = iniCp(self.cp_dev.ini_file,encoding=self.cp_dev.encoding) if self.cp_dev else None
124
+
125
+
126
+ #TODAS AS CHAVES DE DEV DEVE CONTER EM PRD
127
+ def checkKeys(self):
128
+ if self.cp_dev:
129
+ # VALIDA AS SESSOES
130
+ sections_dev = self.cp_dev.getSections()
131
+ sections_prd = self.cp_prd.getSections()
132
+ not_sections_in_prd = set(sections_dev) - set(sections_prd)
133
+ if not_sections_in_prd:
134
+ raise Exception(f"could not find {not_sections_in_prd} section at production file, dev ini file must contain same sections as in production ini file")
135
+
136
+ #VALIDA AS CHAVES
137
+ for sect in sections_dev:
138
+ keys_dev = self.cp_dev.getKeys(sect)
139
+ keys_prd = self.cp_prd.getKeys(sect)
140
+ not_keys_in_prd = set(keys_dev) - set(keys_prd)
141
+ if not_keys_in_prd:
142
+ raise Exception(f"could not find {not_keys_in_prd} keys in section '{sect}' at production file, dev ini file must contain same sections as in production ini file")
143
+
144
+
145
+
146
+ def format_data(self,dtClass,k,v):
147
+ cls = dtClass.__annotations__[k]
148
+ if k in dtClass.__CRYPTED_KEYS__:
149
+ v = decrypt(v,self.encryption_key)
150
+
151
+ if cls == tuple:
152
+ name = f"{str(dtClass)}_{k}"
153
+ if not name in self.delimiters:
154
+ isFormatDefined = k in [x for x in dir(dtClass) if not re.search("__.*__", x)]
155
+ delimiter = getattr(dtClass,k) or ',' if isFormatDefined else ','
156
+ self.delimiters[name]=delimiter
157
+ a = 2
158
+
159
+ v = tuple(v.split(self.delimiters[name]))
160
+ elif cls == datetime:
161
+ name = f"{str(dtClass)}_{k}"
162
+ if not name in self.dateFormats:
163
+ isFormatDefined = k in [x for x in dir(dtClass) if not re.search("__.*__", x)]
164
+ delimiter = getattr(dtClass,k) if isFormatDefined else '%Y-%m-%d'
165
+ self.dateFormats[name]=delimiter
166
+ a = 2
167
+
168
+ v = datetime.strptime(v,self.dateFormats[name])
169
+ elif cls == bool:
170
+ val = v.strip().lower()
171
+ v = True if val and val in ['true','1','y'] else False
172
+ v = False if val in ['false','','0','n'] else True
173
+
174
+ else:
175
+ v = cls(v)
176
+ return v
177
+
178
+ #COLOCA TODOS COMO NONE INICIALMENTE
179
+ def setup_initial_values(self,dtClass):
180
+ for k in dtClass.__annotations__:
181
+ if not hasattr(dtClass, k):
182
+ setattr(dtClass, k, None)
183
+ return dtClass
184
+
185
+
186
+ def section2DataClass(self,section,dtClass,skip_missing=False,empty_as_null=False):
187
+ dtClass = self.setup_initial_values(dtClass)
188
+
189
+ dtClass.save = types.MethodType(save, dtClass)
190
+ dtClass.__SECTION__ = section
191
+ dtClass.__ENVARS__ = [x for x in dtClass.__annotations__ if isinstance(getattr(dtClass,x),envar)]
192
+ dtClass.__INIUTS__ = self
193
+ dtClass.__CRYPTED_KEYS__ = [ x.replace("&_","") for x in self.cp_prd.getKeys(section) if "&_" in x ]
194
+ dict_prd = { k.replace("&_",""):v for k,v in self.cp_prd.section2Dict(section).items() }
195
+ dict_dev = { k.replace("&_",""):v for k,v in self.cp_dev.section2Dict(section).items() } if self.cp_dev and section in self.cp_dev.getSections() else {}
196
+ #ENCRIPTA VARIAVEIS INICIAIS
197
+ for k in dtClass.__CRYPTED_KEYS__:
198
+ # ENCRIPTA VARIAVEIS INICIAIS NO ARQUIVO DE DEV
199
+ if self.cp_dev:
200
+ if k in dict_dev.keys() and dict_dev[k] and dict_dev[k].startswith('&_'):
201
+ cripted_value = encrypt(dict_dev[k].replace('&_',''),self.encryption_key)
202
+ dict_dev[k] = cripted_value
203
+ self.cp_dev.write(section,"&_" + k,cripted_value)
204
+
205
+ # ENCRIPTA VARIAVEIS INICIAIS NO ARQUIVO DE PRD
206
+ if k in dict_prd.keys() and dict_prd[k] and dict_prd[k].startswith('&_'):
207
+ cripted_value = encrypt(dict_prd[k].replace('&_',''),self.encryption_key)
208
+ dict_prd[k] = cripted_value
209
+ self.cp_prd.write(section,"&_" + k,cripted_value)
210
+
211
+ for key in dtClass.__annotations__:
212
+ if key in dtClass.__ENVARS__:
213
+ v = getattr(dtClass,key).get_value()
214
+ v = self.format_data(dtClass,key,v)
215
+ setattr(dtClass, key, v)
216
+ continue
217
+ if key in dict_prd.keys():
218
+ if key in dict_dev.keys() and not self.in_prd:
219
+ v = dict_dev.get(key)
220
+ else:
221
+ v = dict_prd.get(key)
222
+ v = self.format_data(dtClass,key,v)
223
+ setattr(dtClass, key, v)
224
+ continue
225
+ raise Exception(f"Cound not find '{key}' key at section '{section}' in ini file")
226
+
227
+ def link(self,section,skip_missing=False,empty_as_null=False):
228
+ def wrap(function):
229
+ self.section2DataClass(section,function,skip_missing,empty_as_null)
230
+ return function
231
+ return wrap
232
+
233
+
234
+
235
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iniUts
3
- Version: 1.3.2
3
+ Version: 2.0.1
4
4
  Summary: Ini file manipulator
5
5
  Home-page:
6
6
  Author: Melque Lima
@@ -7,7 +7,7 @@ from iniUts import *
7
7
  load_dotenv()
8
8
 
9
9
  ini = IniUts('prd_config.ini')
10
- ini = IniUts('prd_config.ini','dev_config.ini',in_prd=True,encription_key="asdoajhsdoiuayhsoidhasoidhalijksdhaioshdioaws")
10
+ ini = IniUts('prd_config.ini','dev_config.ini',in_prd=True,encryption_key="asdoajhsdoiuayhsoidhasoidhalijksdhaioshdioaws")
11
11
 
12
12
  #TODAS AS CHAVES DE DEV DEVE CONTER EM PRD
13
13
 
@@ -10,7 +10,7 @@ classifiers = [
10
10
 
11
11
  setup(
12
12
  name='iniUts',
13
- version='1.3.2',
13
+ version='2.0.1',
14
14
  description='Ini file manipulator',
15
15
  long_description=open('README.md').read() + '\n\n' + open('CHANGELOG.txt').read(),
16
16
  long_description_content_type='text/markdown',
@@ -1,262 +0,0 @@
1
- import configparser as cp
2
- from dataclasses import dataclass
3
- from datetime import datetime
4
- import re
5
- import os
6
- import types
7
- from iniUts.secret import decrypt, encrypt
8
-
9
- class envar():
10
- def __init__(self,key:str,default:str=None):
11
- self.key = key
12
- self.default = default
13
-
14
- def get_value(self):
15
- if self.default != None:
16
- return os.getenv(self.key,self.default)
17
- else:
18
- value = os.getenv(self.key)
19
- if not value:
20
- raise Exception(f"envar '{self.key}' not found!")
21
- return value
22
-
23
-
24
- def save(self):
25
- ini = self.__INIUTS__
26
- types_to_str = [str,int,float,bool]
27
- is_str = lambda t: any([t == x for x in types_to_str])
28
-
29
- iniProd = IniUts(ini.prd_file)
30
- iniDev = IniUts(ini.dev_file) if ini.dev_file else None
31
-
32
-
33
- for k,t in self.__annotations__.items():
34
- if k in self.__ENVARS__: continue
35
-
36
- if is_str(t):
37
- value = str(getattr(self,k))
38
- elif t == tuple:
39
- value = getattr(self,k)
40
- delimiter = ini.delimiters[f"{str(self)}_{k}"]
41
- value = delimiter.join(value)
42
- elif t == datetime:
43
- value = getattr(self,k)
44
- dateFormat = ini.dateFormats[f"{str(self)}_{k}"]
45
- value = value.strftime(dateFormat)
46
-
47
- if k in self.__CRYPTED_KEYS__:
48
- k = "&_" + k
49
- value = encrypt(value,ini.encryption_key)
50
-
51
- if not ini.in_prd and k in iniDev.getKeys(self.__SECTION__):
52
- iniDev.write(self.__SECTION__,k,value)
53
- else:
54
- iniProd.write(self.__SECTION__,k,value)
55
-
56
-
57
- class IniUts():
58
- def __init__(self,ini_prd,ini_dev=None,in_prd=True,encryption_key=None):
59
- self.prd_file = ini_prd
60
- self.dev_file = ini_dev
61
- self.in_prd = in_prd
62
- self.encryption_key = encryption_key
63
- self.delimiters = {}
64
- self.dateFormats = {}
65
- self.dev_sections = []
66
- self.checkKeys()
67
-
68
- #TODAS AS CHAVES DE DEV DEVE CONTER EM PRD
69
- def checkKeys(self):
70
- if self.dev_file:
71
- # VALIDA AS SESSOES
72
- sections_dev = self.getSections(_file=self.dev_file)
73
- sections_prd = self.getSections()
74
- not_sections_in_prd = set(sections_dev) - set(sections_prd)
75
- if not_sections_in_prd:
76
- raise Exception(f"could not find {not_sections_in_prd} section at production file, dev ini file must contain same sections as in production ini file")
77
-
78
- #VALIDA AS CHAVES
79
- for sect in sections_dev:
80
- keys_dev = self.getKeys(sect,_file=self.dev_file)
81
- keys_prd = self.getKeys(sect)
82
- not_keys_in_prd = set(keys_dev) - set(keys_prd)
83
- if not_keys_in_prd:
84
- raise Exception(f"could not find {not_keys_in_prd} keys in section '{sect}' at production file, dev ini file must contain same sections as in production ini file")
85
-
86
- self.dev_sections = self.getSections(_file=self.dev_file)
87
-
88
- def write(self,section,key,value):
89
- _file = self.dev_file if not self.in_prd and section in self.dev_sections else self.prd_file
90
- config = cp.RawConfigParser()
91
- config.optionxform = str
92
- config.read(_file)
93
- if not section in config.sections():
94
- config[section] = {}
95
- config[section][key] = ""
96
- config.write(open(_file, 'w'))
97
- config[section][key] = value
98
- config.write(open(_file, 'w'))
99
-
100
- def read(self,section,key):
101
- _file = self.dev_file if not self.in_prd and section in self.dev_sections else self.prd_file
102
- config = cp.RawConfigParser()
103
- config.optionxform = str
104
- config.read(_file)
105
- if not section in config.sections():
106
- raise Exception("Section not found!")
107
- if not key in config[section]:
108
- raise Exception("Key not found!")
109
- return config[section][key]
110
-
111
- def getSections(self,_file=None):
112
- _file = _file if _file else self.prd_file
113
- config = cp.RawConfigParser()
114
- config.optionxform = str
115
- config.read(_file)
116
- return [k for k in config.sections()]
117
-
118
- def getKeys(self,section,_file=None):
119
- _file = _file if _file else self.prd_file
120
- config = cp.RawConfigParser()
121
- config.optionxform = str
122
- config.read(_file)
123
- if not section in config.sections():
124
- raise Exception("Section not found!")
125
-
126
- return [k for k in config[section]]
127
-
128
- def to_dict(self):
129
- sections = self.getSections()
130
- result = {}
131
- for sect in sections:
132
- result[sect] = self.Section2Dict(sect)
133
- return result
134
-
135
- def Section2Dict(self,section,empty_as_null=False,fileIni=None):
136
- _file = self.dev_file if not self.in_prd and section in self.dev_sections else self.prd_file
137
- config = cp.RawConfigParser(allow_no_value=True)
138
- config.optionxform = str
139
- config.read(fileIni if fileIni else _file)
140
-
141
- dc = dict(config[section])
142
- return dc if not empty_as_null else {x:(y or None) for x,y in dc.items()}
143
-
144
- def format_data(self,dtClass,k,v):
145
- cls = dtClass.__annotations__[k]
146
- if k in dtClass.__CRYPTED_KEYS__:
147
- v = decrypt(v,self.encryption_key)
148
-
149
- if cls == tuple:
150
- name = f"{str(dtClass)}_{k}"
151
- if not name in self.delimiters:
152
- isFormatDefined = k in [x for x in dir(dtClass) if not re.search("__.*__", x)]
153
- delimiter = getattr(dtClass,k) if isFormatDefined else ','
154
- self.delimiters[name]=delimiter
155
- a = 2
156
-
157
- v = tuple(v.split(self.delimiters[name]))
158
- elif cls == datetime:
159
- name = f"{str(dtClass)}_{k}"
160
- if not name in self.dateFormats:
161
- isFormatDefined = k in [x for x in dir(dtClass) if not re.search("__.*__", x)]
162
- delimiter = getattr(dtClass,k) if isFormatDefined else '%Y-%m-%d'
163
- self.dateFormats[name]=delimiter
164
- a = 2
165
-
166
- v = datetime.strptime(v,self.dateFormats[name])
167
- elif cls == bool:
168
- val = v.strip().lower()
169
- v = True if val and val in ['true','1','y'] else False
170
- v = False if val in ['false','','0','n'] else True
171
-
172
- else:
173
- v = cls(v)
174
- return v
175
-
176
- def setup_initial_values(self,dtClass):
177
- for k in dtClass.__annotations__:
178
- if not hasattr(dtClass, k):
179
- setattr(dtClass, k, None)
180
- return dtClass
181
-
182
- def section2DataClass(self,section,dtClass,skip_missing=False,empty_as_null=False):
183
- dt = self.Section2Dict(section,empty_as_null=empty_as_null)
184
- dt2 = self.Section2Dict(section,empty_as_null=empty_as_null,fileIni=self.prd_file)
185
-
186
- dtClass = self.setup_initial_values(dtClass)
187
-
188
- dtClass.save = types.MethodType(save, dtClass)
189
- dtClass.__SECTION__ = section
190
- dtClass.__ENVARS__ = []
191
- dtClass.__INIUTS__ = self
192
- dtClass.__CRYPTED_KEYS__ = [ x.replace("&_","") for x in dt2 if "&_" in x ]
193
- dt2 = { x.replace("&_",""):dt2[x] for x in dt2 }
194
- dt = { x.replace("&_",""):dt[x] for x in dt }
195
-
196
- #ENCRIPTA VARIAVEIS INICIAIS
197
- for k in dtClass.__CRYPTED_KEYS__:
198
- # ENCRIPTA VARIAVEIS INICIAIS NO ARQUIVO DE DEV
199
- if k in dt.keys() and dt[k].startswith('&_') and not self.in_prd:
200
- dt[k] = encrypt(dt[k].replace('&_',''),self.encryption_key)
201
- IniUts(self.dev_file).write(section,"&_" + k,dt[k])
202
-
203
- # ENCRIPTA VARIAVEIS INICIAIS NO ARQUIVO DE PRD
204
- if k in dt2.keys() and dt2[k].startswith('&_'):
205
- dt2[k] = encrypt(dt2[k].replace('&_',''),self.encryption_key)
206
- IniUts(self.prd_file).write(section,"&_" + k,dt2[k])
207
-
208
-
209
-
210
- #VALIDA AS KEYS NO INI DE DEV
211
- for k, v in dt.items():
212
- if not k in dtClass.__annotations__:
213
- if not skip_missing:
214
- raise Exception(f"please create the key '{k}' in data class object")
215
- else:
216
- continue
217
- v = self.format_data(dtClass,k,v)
218
- setattr(dtClass, k, v)
219
-
220
- class_keys = [x for x in dtClass.__annotations__ if getattr(dtClass,x) != envar]
221
-
222
- MissingKeysFromClass = lambda x:list(set(class_keys) - set(x.keys()))
223
-
224
- #VERIFICA SE AS KEYS NAO ENCONTRADAS ESTAO NO ARQUIVO DE PRD:
225
- if not self.in_prd:
226
- for k in MissingKeysFromClass(dt):
227
- if not k in dt2.keys():
228
- if isinstance(getattr(dtClass,k),envar):
229
- v = getattr(dtClass,k).get_value()
230
- setattr(dtClass, k, v)
231
- dtClass.__ENVARS__.append(k)
232
- continue
233
- if not skip_missing:
234
- raise Exception(f"Cound not find '{k}' keys at section '{section}' in ini file")
235
- continue
236
- v = self.format_data(dtClass,k,dt2[k])
237
- setattr(dtClass, k, v)
238
- else:
239
- for k in MissingKeysFromClass(dt):
240
- if isinstance(getattr(dtClass,k),envar):
241
- v = getattr(dtClass,k).get_value()
242
- setattr(dtClass, k, v)
243
- dtClass.__ENVARS__.append(k)
244
- continue
245
- if not skip_missing and MissingKeysFromClass(dt):
246
- raise Exception(f"Cound not find '{k}' keys at section '{section}' in ini file")
247
-
248
- def link(self,section,skip_missing=False,empty_as_null=False):
249
- def wrap(function):
250
- self.section2DataClass(section,function,skip_missing,empty_as_null)
251
- return function
252
- return wrap
253
-
254
-
255
-
256
-
257
-
258
-
259
-
260
-
261
-
262
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes