iniUts 1.3.1__tar.gz → 2.0.0__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.1
3
+ Version: 2.0.0
4
4
  Summary: Ini file manipulator
5
5
  Home-page:
6
6
  Author: Melque Lima
@@ -0,0 +1,232 @@
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
+
122
+ #TODAS AS CHAVES DE DEV DEVE CONTER EM PRD
123
+ def checkKeys(self):
124
+ if self.cp_dev:
125
+ # VALIDA AS SESSOES
126
+ sections_dev = self.cp_dev.getSections()
127
+ sections_prd = self.cp_prd.getSections()
128
+ not_sections_in_prd = set(sections_dev) - set(sections_prd)
129
+ if not_sections_in_prd:
130
+ 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")
131
+
132
+ #VALIDA AS CHAVES
133
+ for sect in sections_dev:
134
+ keys_dev = self.cp_dev.getKeys(sect)
135
+ keys_prd = self.cp_prd.getKeys(sect)
136
+ not_keys_in_prd = set(keys_dev) - set(keys_prd)
137
+ if not_keys_in_prd:
138
+ 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")
139
+
140
+
141
+
142
+ def format_data(self,dtClass,k,v):
143
+ cls = dtClass.__annotations__[k]
144
+ if k in dtClass.__CRYPTED_KEYS__:
145
+ v = decrypt(v,self.encryption_key)
146
+
147
+ if cls == tuple:
148
+ name = f"{str(dtClass)}_{k}"
149
+ if not name in self.delimiters:
150
+ isFormatDefined = k in [x for x in dir(dtClass) if not re.search("__.*__", x)]
151
+ delimiter = getattr(dtClass,k) or ',' if isFormatDefined else ','
152
+ self.delimiters[name]=delimiter
153
+ a = 2
154
+
155
+ v = tuple(v.split(self.delimiters[name]))
156
+ elif cls == datetime:
157
+ name = f"{str(dtClass)}_{k}"
158
+ if not name in self.dateFormats:
159
+ isFormatDefined = k in [x for x in dir(dtClass) if not re.search("__.*__", x)]
160
+ delimiter = getattr(dtClass,k) if isFormatDefined else '%Y-%m-%d'
161
+ self.dateFormats[name]=delimiter
162
+ a = 2
163
+
164
+ v = datetime.strptime(v,self.dateFormats[name])
165
+ elif cls == bool:
166
+ val = v.strip().lower()
167
+ v = True if val and val in ['true','1','y'] else False
168
+ v = False if val in ['false','','0','n'] else True
169
+
170
+ else:
171
+ v = cls(v)
172
+ return v
173
+
174
+ #COLOCA TODOS COMO NONE INICIALMENTE
175
+ def setup_initial_values(self,dtClass):
176
+ for k in dtClass.__annotations__:
177
+ if not hasattr(dtClass, k):
178
+ setattr(dtClass, k, None)
179
+ return dtClass
180
+
181
+
182
+ def section2DataClass(self,section,dtClass,skip_missing=False,empty_as_null=False):
183
+ dtClass = self.setup_initial_values(dtClass)
184
+
185
+ dtClass.save = types.MethodType(save, dtClass)
186
+ dtClass.__SECTION__ = section
187
+ dtClass.__ENVARS__ = [x for x in dtClass.__annotations__ if isinstance(getattr(dtClass,x),envar)]
188
+ dtClass.__INIUTS__ = self
189
+ dtClass.__CRYPTED_KEYS__ = [ x.replace("&_","") for x in self.cp_prd.getKeys(section) if "&_" in x ]
190
+ dict_prd = { k.replace("&_",""):v for k,v in self.cp_prd.section2Dict(section).items() }
191
+ dict_dev = { k.replace("&_",""):v for k,v in self.cp_dev.section2Dict(section).items() } if section in self.cp_dev.getSections() else {}
192
+
193
+ #ENCRIPTA VARIAVEIS INICIAIS
194
+ for k in dtClass.__CRYPTED_KEYS__:
195
+ # ENCRIPTA VARIAVEIS INICIAIS NO ARQUIVO DE DEV
196
+ if self.cp_dev:
197
+ if k in dict_dev.keys() and dict_dev[k] and dict_dev[k].startswith('&_'):
198
+ cripted_value = encrypt(dict_dev[k].replace('&_',''),self.encryption_key)
199
+ dict_dev[k] = cripted_value
200
+ self.cp_dev.write(section,"&_" + k,cripted_value)
201
+
202
+ # ENCRIPTA VARIAVEIS INICIAIS NO ARQUIVO DE PRD
203
+ if k in dict_prd.keys() and dict_prd[k] and dict_prd[k].startswith('&_'):
204
+ cripted_value = encrypt(dict_prd[k].replace('&_',''),self.encryption_key)
205
+ dict_prd[k] = cripted_value
206
+ self.cp_prd.write(section,"&_" + k,cripted_value)
207
+
208
+ for key in dtClass.__annotations__:
209
+ if key in dtClass.__ENVARS__:
210
+ v = getattr(dtClass,key).get_value()
211
+ v = self.format_data(dtClass,key,v)
212
+ setattr(dtClass, key, v)
213
+ continue
214
+ if key in dict_prd.keys():
215
+ if key in dict_dev.keys() and not self.in_prd:
216
+ v = dict_dev.get(key)
217
+ else:
218
+ v = dict_prd.get(key)
219
+ v = self.format_data(dtClass,key,v)
220
+ setattr(dtClass, key, v)
221
+ continue
222
+ raise Exception(f"Cound not find '{key}' key at section '{section}' in ini file")
223
+
224
+ def link(self,section,skip_missing=False,empty_as_null=False):
225
+ def wrap(function):
226
+ self.section2DataClass(section,function,skip_missing,empty_as_null)
227
+ return function
228
+ return wrap
229
+
230
+
231
+
232
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iniUts
3
- Version: 1.3.1
3
+ Version: 2.0.0
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.1',
13
+ version='2.0.0',
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 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.encription_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,encription_key=None):
59
- self.prd_file = ini_prd
60
- self.dev_file = ini_dev
61
- self.in_prd = in_prd
62
- self.encription_key = encription_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.encription_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.encription_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.encription_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