modulitiz-micro 2.41.0__py311-none-any.whl → 2.43.0__py311-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.
- modulitiz_micro/ModuloMeteo.py +72 -72
- modulitiz_micro/ModuloSeriale.py +70 -70
- modulitiz_micro/ModuloTarghe.py +47 -46
- modulitiz_micro/database/AbstractDatabaseService.py +13 -13
- modulitiz_micro/database/AbstractSql.py +69 -69
- modulitiz_micro/database/ModuloSqlOracle.py +19 -19
- modulitiz_micro/database/ModuloSqlServer.py +43 -43
- modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -6
- modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -114
- modulitiz_micro/database/mysql/ModuloMysql.py +163 -163
- modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -47
- modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -6
- modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -114
- modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -82
- modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -7
- modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -7
- modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -8
- modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -7
- modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -7
- modulitiz_micro/files/cache/DatabaseCache.py +91 -91
- modulitiz_micro/files/cache/decorators/cacheRam.py +26 -26
- modulitiz_micro/files/git/ModuloGit.py +28 -28
- modulitiz_micro/files/git/decorators/catchAndRaiseGitExceptions.py +19 -19
- modulitiz_micro/files/git/exceptions/EccezioneGit.py +7 -7
- modulitiz_micro/gestionedom/GestioneDom.py +44 -44
- modulitiz_micro/iot/ModuleIotDevice.py +4 -4
- modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -7
- modulitiz_micro/keylogger/ModuloKeylogger.py +73 -73
- modulitiz_micro/rete/ModuloNetworking.py +72 -72
- modulitiz_micro/rete/ModuloOpenVpn.py +15 -15
- modulitiz_micro/rete/email/EmailBean.py +5 -5
- modulitiz_micro/rete/email/ModuloEmail.py +90 -90
- modulitiz_micro/rete/http/ModuloHttp.py +119 -119
- modulitiz_micro/rete/http/ModuloHttpConnectionSafe.py +91 -91
- modulitiz_micro/rete/http/ModuloHttpUtils.py +69 -69
- modulitiz_micro/rete/http/beans/HttpResponseBean.py +5 -5
- modulitiz_micro/rete/http/decorators/catchAndRaiseHttpExceptions.py +22 -22
- modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -73
- modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -8
- modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -35
- modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -267
- modulitiz_micro/rete/ssl/ModuloSsl.py +56 -56
- modulitiz_micro/sistema/ModuloEnvVars.py +34 -34
- modulitiz_micro/sistema/ModuloSystemPipe.py +67 -67
- modulitiz_micro/social/telegram/AbstractModuloTelegram.py +53 -53
- modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -26
- modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -15
- modulitiz_micro/util/scheduler/ModuleScheduler.py +26 -26
- {modulitiz_micro-2.41.0.dist-info → modulitiz_micro-2.43.0.dist-info}/METADATA +59 -66
- modulitiz_micro-2.43.0.dist-info/RECORD +56 -0
- {modulitiz_micro-2.41.0.dist-info → modulitiz_micro-2.43.0.dist-info}/WHEEL +1 -1
- {modulitiz_micro-2.41.0.dist-info → modulitiz_micro-2.43.0.dist-info/licenses}/LICENSE +21 -21
- modulitiz_micro/ModuleEnum.py +0 -8
- modulitiz_micro/ModuloBase64.py +0 -61
- modulitiz_micro/ModuloColorText.py +0 -35
- modulitiz_micro/ModuloDate.py +0 -327
- modulitiz_micro/ModuloFunzioni.py +0 -71
- modulitiz_micro/ModuloListe.py +0 -150
- modulitiz_micro/ModuloNumeri.py +0 -127
- modulitiz_micro/ModuloPyinstaller.py +0 -29
- modulitiz_micro/ModuloStatistiche.py +0 -31
- modulitiz_micro/ModuloStringhe.py +0 -180
- modulitiz_micro/android/ModuloAndroid.py +0 -18
- modulitiz_micro/android/ModuloAndroidAdb.py +0 -48
- modulitiz_micro/android/ModuloAndroidSim.py +0 -130
- modulitiz_micro/android/beans/SmsBean.py +0 -12
- modulitiz_micro/android/enums/AndroidSmsTypeEnum.py +0 -17
- modulitiz_micro/eccezioni/EccezioneBase.py +0 -7
- modulitiz_micro/eccezioni/EccezioneRuntime.py +0 -7
- modulitiz_micro/eccezioni/EccezioneSoNonSupportato.py +0 -7
- modulitiz_micro/files/ModuloFiles.py +0 -173
- modulitiz_micro/files/ModuloLogging.py +0 -69
- modulitiz_micro/files/ModuloZip.py +0 -42
- modulitiz_micro/files/cache/CacheBean.py +0 -5
- modulitiz_micro/files/cache/CacheRam.py +0 -29
- modulitiz_micro/init/AbstractBasicInit.py +0 -27
- modulitiz_micro/init/AbstractInit.py +0 -11
- modulitiz_micro/multithread/ModuloThread.py +0 -26
- modulitiz_micro/multithread/ModuloThreadLogger.py +0 -8
- modulitiz_micro/multithread/ModuloThreadWithCallbackError.py +0 -25
- modulitiz_micro/nlp/ModuloNlp.py +0 -36
- modulitiz_micro/nlp/ModuloNlpDateAndTime.py +0 -59
- modulitiz_micro/sistema/EnvVarsEnum.py +0 -9
- modulitiz_micro/sistema/ModuloSystem.py +0 -298
- modulitiz_micro/util/beans/conf/AbstractBasicConfBean.py +0 -11
- modulitiz_micro/util/beans/conf/AbstractConfBean.py +0 -16
- modulitiz_micro/util/beans/fileconf/AbstractBasicFileConfBean.py +0 -11
- modulitiz_micro/util/beans/fileconf/AbstractFileConfBean.py +0 -13
- modulitiz_micro/util/beans/globalvar/AbstractGlobalVarBean.py +0 -34
- modulitiz_micro/util/decorators/noAwait.py +0 -23
- modulitiz_micro/util/pip/AbstractModuloPip.py +0 -41
- modulitiz_micro/util/pip/ModuloPip.py +0 -49
- modulitiz_micro/util/spooler/AbstractSpooler.py +0 -14
- modulitiz_micro/util/spooler/Spooler.py +0 -18
- modulitiz_micro/util/spooler/beans/QueueBean.py +0 -8
- modulitiz_micro/util/spooler/decorators/spooler.py +0 -49
- modulitiz_micro/util/spooler/eccezioni/EccezioneSpooler.py +0 -7
- modulitiz_micro/util/spooler/eccezioni/EccezioneSpoolerFull.py +0 -7
- modulitiz_micro/util/unittesting/AbstractOverrideTestUtil.py +0 -31
- modulitiz_micro/util/unittesting/AbstractTestUtil.py +0 -11
- modulitiz_micro/util/unittesting/ModuloRunUnitTest.py +0 -25
- modulitiz_micro/util/wheel/ModuloBuildWheel.py +0 -118
- modulitiz_micro/util/wheel/ModuloCheckTestNamingConvention.py +0 -89
- modulitiz_micro/util/wheel/ModuloToml.py +0 -40
- modulitiz_micro/util/wheel/ModuloWheel.py +0 -12
- modulitiz_micro-2.41.0.dist-info/RECORD +0 -109
- {modulitiz_micro-2.41.0.dist-info → modulitiz_micro-2.43.0.dist-info}/top_level.txt +0 -0
@@ -1,298 +0,0 @@
|
|
1
|
-
import getpass
|
2
|
-
import os
|
3
|
-
import platform
|
4
|
-
import signal
|
5
|
-
import subprocess
|
6
|
-
import sys
|
7
|
-
from typing import Callable
|
8
|
-
|
9
|
-
import psutil
|
10
|
-
|
11
|
-
from modulitiz_micro.ModuloColorText import ModuloColorText
|
12
|
-
from modulitiz_micro.ModuloFunzioni import ModuloFunzioni
|
13
|
-
from modulitiz_micro.ModuloListe import ModuloListe
|
14
|
-
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
15
|
-
from modulitiz_micro.eccezioni.EccezioneRuntime import EccezioneRuntime
|
16
|
-
from modulitiz_micro.eccezioni.EccezioneSoNonSupportato import EccezioneSoNonSupportato
|
17
|
-
from modulitiz_micro.sistema.EnvVarsEnum import EnvVarsEnum
|
18
|
-
|
19
|
-
|
20
|
-
class ModuloSystem(object):
|
21
|
-
ESTENSIONI_POTENZIALMENTE_ESEGUIBILI=(".exe",".msi",".cmd",".bat",".vbs")
|
22
|
-
|
23
|
-
CODIFICA_WINDOWS_CMD='cp437'
|
24
|
-
|
25
|
-
CMD_PAUSE=r'''python -c "input('pause:')"'''
|
26
|
-
WINDOWS_PATTERN_ECHO="""echo|set /p="{}" & echo."""
|
27
|
-
|
28
|
-
@classmethod
|
29
|
-
def handleCtrlC(cls,handler:Callable=None):
|
30
|
-
cls.handleEvent(handler, signal.SIGINT)
|
31
|
-
@classmethod
|
32
|
-
def handleEvent(cls,handler:Callable=None,signalType=None):
|
33
|
-
if handler is None:
|
34
|
-
handler=cls.__signalHandler
|
35
|
-
signal.signal(signalType,handler)
|
36
|
-
|
37
|
-
@staticmethod
|
38
|
-
def __signalHandler(_signalType, _frame):
|
39
|
-
print("\nUscita...")
|
40
|
-
sys.exit(0)
|
41
|
-
|
42
|
-
@staticmethod
|
43
|
-
def sendCtrlcProcessChilds(ppid:int):
|
44
|
-
try:
|
45
|
-
parent = psutil.Process(ppid)
|
46
|
-
except psutil.NoSuchProcess:
|
47
|
-
return
|
48
|
-
children = parent.children(recursive=True)
|
49
|
-
for process in children:
|
50
|
-
ModuloSystem.sendCtrlcProcess(process.pid)
|
51
|
-
|
52
|
-
@staticmethod
|
53
|
-
def sendCtrlcProcess(pid:int):
|
54
|
-
if pid<=0:
|
55
|
-
raise EccezioneRuntime("Il pid deve essere maggiore di 0")
|
56
|
-
if ModuloSystem.isWindows():
|
57
|
-
segnale=signal.CTRL_C_EVENT
|
58
|
-
else:
|
59
|
-
segnale=signal.SIGINT
|
60
|
-
os.kill(pid,segnale)
|
61
|
-
|
62
|
-
|
63
|
-
@classmethod
|
64
|
-
def systemCallCallbackOutput(cls,cmd:str, callbackOutput:Callable,codifica:str|None):
|
65
|
-
for riga in cls.systemCallYieldOutput(cmd,codifica):
|
66
|
-
callbackOutput(riga)
|
67
|
-
@classmethod
|
68
|
-
def systemCallPrintOutput(cls,cmd: str,codifica: str|None):
|
69
|
-
for riga in cls.systemCallYieldOutput(cmd,codifica):
|
70
|
-
print(">>> "+riga)
|
71
|
-
|
72
|
-
@classmethod
|
73
|
-
def systemCallPrintOutputColor(cls,cmd: str,codifica: str|None):
|
74
|
-
for riga in cls.systemCallYieldOutput(cmd,codifica):
|
75
|
-
print("%s>>>%s %s"%(ModuloColorText.BLU,ModuloColorText.DEFAULT,riga))
|
76
|
-
|
77
|
-
@classmethod
|
78
|
-
def systemCallYieldOutput(cls,cmd:str, codifica:str|None):
|
79
|
-
if codifica is None:
|
80
|
-
codifica=cls.CODIFICA_WINDOWS_CMD
|
81
|
-
with cls.systemCall(cmd,True) as pipe:
|
82
|
-
# scorro l'output
|
83
|
-
for line in iter(pipe.stdout.readline,b''):
|
84
|
-
rigaDecoded=line.decode(codifica,'replace').rstrip()
|
85
|
-
yield rigaDecoded
|
86
|
-
|
87
|
-
@classmethod
|
88
|
-
def systemCallReturnOutput(cls,cmd: str,codifica: str|None) -> str|None:
|
89
|
-
if codifica is None:
|
90
|
-
codifica=cls.CODIFICA_WINDOWS_CMD
|
91
|
-
with cls.systemCall(cmd,True) as pipe:
|
92
|
-
output=cls.fromPipeToString(pipe,None,codifica)
|
93
|
-
return output
|
94
|
-
|
95
|
-
@classmethod
|
96
|
-
def systemCall(cls,cmd:str, useStdOut:bool)->subprocess.Popen:
|
97
|
-
"""
|
98
|
-
useStdOut se mostrare o meno l'output a schermo
|
99
|
-
"""
|
100
|
-
if useStdOut is True:
|
101
|
-
stdOut=subprocess.PIPE
|
102
|
-
else:
|
103
|
-
stdOut=subprocess.DEVNULL
|
104
|
-
# sistemo variabili ambiente
|
105
|
-
envVars=os.environ
|
106
|
-
if not cls.isWindows():
|
107
|
-
originalCommand=envVars.get("_",None)
|
108
|
-
if originalCommand is not None:
|
109
|
-
originalCommand=os.path.dirname(originalCommand)
|
110
|
-
envVarPath=envVars[EnvVarsEnum.PATH]
|
111
|
-
if originalCommand+":" not in envVarPath or ":"+originalCommand not in envVarPath or ":"+originalCommand+":" not in envVarPath:
|
112
|
-
envVars[EnvVarsEnum.PATH]=originalCommand+":"+envVarPath
|
113
|
-
# se ci sono piu' comandi separati li eseguo insieme
|
114
|
-
righe=ModuloListe.eliminaElementiVuoti(ModuloStringhe.normalizzaEol(cmd).split("\n"))
|
115
|
-
cmdFinal=" && ".join(righe)
|
116
|
-
# creo l'oggetto
|
117
|
-
pipe=subprocess.Popen(cmdFinal,shell=True,
|
118
|
-
stdin=subprocess.PIPE,
|
119
|
-
stdout=stdOut,
|
120
|
-
stderr=subprocess.STDOUT,
|
121
|
-
cwd=os.getcwd(), env=envVars)
|
122
|
-
return pipe
|
123
|
-
|
124
|
-
@classmethod
|
125
|
-
def systemCallWaitAndClose(cls,cmd: str,useStdOut: bool):
|
126
|
-
with cls.systemCall(cmd,useStdOut) as pipe:
|
127
|
-
pipe.wait()
|
128
|
-
|
129
|
-
@classmethod
|
130
|
-
def fromPipeToString(cls,pipe: subprocess.Popen,stdinData:bytes|None,codifica:str|None)->str|None:
|
131
|
-
if codifica is None:
|
132
|
-
codifica=cls.CODIFICA_WINDOWS_CMD
|
133
|
-
# chiedo i dati
|
134
|
-
output=pipe.communicate(stdinData)[0]
|
135
|
-
if output is None:
|
136
|
-
return None
|
137
|
-
output=output.decode(codifica,'replace')
|
138
|
-
return output
|
139
|
-
|
140
|
-
@staticmethod
|
141
|
-
def stdinReadMultipleLines(numLinesEmptyToExit:int=2)->list:
|
142
|
-
countLinesEmpty=0
|
143
|
-
output=[]
|
144
|
-
while True:
|
145
|
-
line=sys.stdin.readline().rstrip("\n")
|
146
|
-
if line=='':
|
147
|
-
countLinesEmpty+=1
|
148
|
-
if countLinesEmpty==numLinesEmptyToExit:
|
149
|
-
break
|
150
|
-
else:
|
151
|
-
countLinesEmpty=0
|
152
|
-
output.append(line)
|
153
|
-
return output
|
154
|
-
|
155
|
-
@classmethod
|
156
|
-
def setTitoloFinestra(cls,titolo:str):
|
157
|
-
if not cls.isWindows():
|
158
|
-
return
|
159
|
-
# preparo il comando
|
160
|
-
cmd="title "+titolo
|
161
|
-
#invio il comando
|
162
|
-
cls.systemCallWaitAndClose(cmd,False)
|
163
|
-
|
164
|
-
|
165
|
-
@staticmethod
|
166
|
-
def pause():
|
167
|
-
input("Premere il tasto INVIO per continuare...")
|
168
|
-
|
169
|
-
@staticmethod
|
170
|
-
def getHostname()->str:
|
171
|
-
return platform.node()
|
172
|
-
@staticmethod
|
173
|
-
def getUsername()->str:
|
174
|
-
return getpass.getuser()
|
175
|
-
|
176
|
-
@staticmethod
|
177
|
-
def getCmdSleep()->str:
|
178
|
-
if ModuloSystem.isWindows():
|
179
|
-
return "timeout "
|
180
|
-
return "sleep "
|
181
|
-
|
182
|
-
@staticmethod
|
183
|
-
def getTempFolder()->str:
|
184
|
-
if ModuloSystem.isWindows():
|
185
|
-
return os.environ[EnvVarsEnum.TMP]
|
186
|
-
return "/tmp"
|
187
|
-
|
188
|
-
@staticmethod
|
189
|
-
def getFolderNull()->str:
|
190
|
-
if ModuloSystem.isWindows():
|
191
|
-
return 'NUL'
|
192
|
-
return "/dev/null"
|
193
|
-
|
194
|
-
@staticmethod
|
195
|
-
def isWindows()->bool:
|
196
|
-
return os.name=='nt'
|
197
|
-
|
198
|
-
@staticmethod
|
199
|
-
def isSystem64bit()->bool:
|
200
|
-
return sys.maxsize > 2**32
|
201
|
-
|
202
|
-
@classmethod
|
203
|
-
def shutdown(cls,delay:int=30):
|
204
|
-
if cls.isWindows():
|
205
|
-
cmd='{} {} && shutdown /p'
|
206
|
-
else:
|
207
|
-
cmd='{} {} && systemctl poweroff'
|
208
|
-
cmd=cmd.format(cls.getCmdSleep(),delay)
|
209
|
-
# in questo caso la pipe deve restare aperta
|
210
|
-
cls.systemCall(cmd,True)
|
211
|
-
@classmethod
|
212
|
-
def reboot(cls,delay:int=30):
|
213
|
-
if cls.isWindows():
|
214
|
-
cmd='{} {} && shutdown /r'
|
215
|
-
else:
|
216
|
-
cmd='{} {} && reboot now'
|
217
|
-
cmd=cmd.format(cls.getCmdSleep(),delay)
|
218
|
-
# in questo caso la pipe deve restare aperta
|
219
|
-
cls.systemCall(cmd,True)
|
220
|
-
|
221
|
-
@staticmethod
|
222
|
-
def findPidByName(nomeExe:str)->int|None:
|
223
|
-
process=ModuloSystem.findProcessByName(nomeExe)
|
224
|
-
if process is None:
|
225
|
-
return None
|
226
|
-
return process.pid
|
227
|
-
|
228
|
-
@staticmethod
|
229
|
-
def findProcessByName(nomeExe:str)->psutil.Process|None:
|
230
|
-
for p in psutil.process_iter():
|
231
|
-
currentName=""
|
232
|
-
currentCmdLine=""
|
233
|
-
currentNomeExe=""
|
234
|
-
try:
|
235
|
-
currentName = p.name()
|
236
|
-
currentCmdLine=" ".join(p.cmdline())
|
237
|
-
currentNomeExe = p.exe()
|
238
|
-
except (psutil.AccessDenied, psutil.ZombieProcess, SystemError):
|
239
|
-
pass
|
240
|
-
except psutil.NoSuchProcess:
|
241
|
-
continue
|
242
|
-
if ModuloStringhe.contains(currentName,nomeExe) or ModuloStringhe.contains(currentCmdLine,nomeExe) or os.path.basename(currentNomeExe) == nomeExe:
|
243
|
-
return p
|
244
|
-
|
245
|
-
@classmethod
|
246
|
-
def isAptPackageInstalled(cls,nome:str)->bool:
|
247
|
-
if cls.isWindows():
|
248
|
-
raise EccezioneSoNonSupportato("Windows non supportato")
|
249
|
-
cmd=fr'''apt list --installed | grep {nome}/'''
|
250
|
-
output=cls.systemCallReturnOutput(cmd,None)
|
251
|
-
righe=ModuloStringhe.normalizzaEol(output).split("\n")
|
252
|
-
righe=ModuloListe.eliminaElementiVuoti(righe)
|
253
|
-
for riga in righe:
|
254
|
-
if riga.startswith(nome):
|
255
|
-
return True
|
256
|
-
return False
|
257
|
-
|
258
|
-
@staticmethod
|
259
|
-
def getNumOfCores()->int:
|
260
|
-
return os.cpu_count()
|
261
|
-
|
262
|
-
@staticmethod
|
263
|
-
def getLoadPerc()->float:
|
264
|
-
"""
|
265
|
-
Restituisce la percentuale di cpu utilizzata dall'ultima chiamata a questa funzione
|
266
|
-
"""
|
267
|
-
return psutil.cpu_percent()
|
268
|
-
|
269
|
-
@classmethod
|
270
|
-
def getLoadAveragesPerc(cls)->list:
|
271
|
-
numCores=cls.getNumOfCores()
|
272
|
-
lista=psutil.getloadavg()
|
273
|
-
return [x/numCores*100 for x in lista]
|
274
|
-
|
275
|
-
@classmethod
|
276
|
-
def getTempCpu(cls)->list[tuple[str,int]]|None:
|
277
|
-
"""
|
278
|
-
funziona solo su linux, ritorna una mappa:
|
279
|
-
nome sensore e valore sensore
|
280
|
-
"""
|
281
|
-
if cls.isWindows():
|
282
|
-
return None
|
283
|
-
sensors=psutil.sensors_temperatures(fahrenheit=False)
|
284
|
-
sensor=ModuloFunzioni.dictGetFirstValue(sensors)
|
285
|
-
lista=[]
|
286
|
-
for valore in sensor:
|
287
|
-
obj:psutil._common.shwtemp=valore
|
288
|
-
lista.append((obj.label,int(obj.current)))
|
289
|
-
return lista
|
290
|
-
|
291
|
-
@staticmethod
|
292
|
-
def getBattery()->tuple|None:
|
293
|
-
battery=psutil.sensors_battery()
|
294
|
-
if battery is None:
|
295
|
-
return None
|
296
|
-
percent=int(battery.percent)
|
297
|
-
isPlugged=battery.power_plugged
|
298
|
-
return percent,isPlugged
|
@@ -1,11 +0,0 @@
|
|
1
|
-
from modulitiz_micro.files.ModuloFiles import ModuloFiles
|
2
|
-
|
3
|
-
from modulitiz_micro.util.beans.conf.AbstractConfBean import AbstractConfBean
|
4
|
-
|
5
|
-
|
6
|
-
class AbstractBasicConfBean(AbstractConfBean):
|
7
|
-
|
8
|
-
def __init__(self,clazz,*args,**kwargs):
|
9
|
-
super().__init__(*args,**kwargs)
|
10
|
-
self.INPUT_FILE_CONF=ModuloFiles.pathJoin(self.CARTELLA_BASE_PROGETTO,"conf.json")
|
11
|
-
self.fileConf=clazz(self.INPUT_FILE_CONF)
|
@@ -1,16 +0,0 @@
|
|
1
|
-
from abc import ABC
|
2
|
-
|
3
|
-
from modulitiz_micro.ModuloPyinstaller import ModuloPyinstaller
|
4
|
-
from modulitiz_micro.files.ModuloFiles import ModuloFiles
|
5
|
-
from modulitiz_micro.sistema.EnvVarsEnum import EnvVarsEnum
|
6
|
-
from modulitiz_micro.sistema.ModuloEnvVars import ModuloEnvVars
|
7
|
-
|
8
|
-
|
9
|
-
class AbstractConfBean(ABC):
|
10
|
-
|
11
|
-
def __init__(self,cartellaBase:str|None,nomeProgetto:str):
|
12
|
-
self.CARTELLA_BASE_PROGETTO:str|None=None
|
13
|
-
if cartellaBase is not None:
|
14
|
-
self.CARTELLA_BASE_PROGETTO=ModuloFiles.pathJoin(cartellaBase,nomeProgetto)
|
15
|
-
self.IS_DEBUG=(ModuloEnvVars.getOrNone(EnvVarsEnum.MODULITIZ_IS_DEBUG)=="1" and not ModuloPyinstaller.isExecutableMode())
|
16
|
-
self.NOME_PROGETTO=nomeProgetto
|
@@ -1,11 +0,0 @@
|
|
1
|
-
from modulitiz_micro.util.beans.fileconf.AbstractFileConfBean import AbstractFileConfBean
|
2
|
-
|
3
|
-
|
4
|
-
class AbstractBasicFileConfBean(AbstractFileConfBean):
|
5
|
-
"""
|
6
|
-
Classe che può essere usata come base per definire la struttura del file di configurazione del programma
|
7
|
-
"""
|
8
|
-
|
9
|
-
def __init__(self,*args,**kwargs):
|
10
|
-
super().__init__(*args,**kwargs)
|
11
|
-
self.percorsoCartellaEsterna=self._diz['percorsoCartellaEsterna']
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
from abc import ABC
|
3
|
-
|
4
|
-
from modulitiz_micro.files.ModuloFiles import ModuloFiles
|
5
|
-
|
6
|
-
|
7
|
-
class AbstractFileConfBean(ABC):
|
8
|
-
"""
|
9
|
-
Classe che può essere usata come base per definire la struttura del file di configurazione del programma
|
10
|
-
"""
|
11
|
-
|
12
|
-
def __init__(self,nomefile:str):
|
13
|
-
self._diz=json.loads(ModuloFiles.readFileText(nomefile,True))
|
@@ -1,34 +0,0 @@
|
|
1
|
-
from abc import ABC
|
2
|
-
from typing import NewType
|
3
|
-
|
4
|
-
from modulitiz_micro.ModuloDate import ModuloDate
|
5
|
-
from modulitiz_micro.files.ModuloLogging import ModuloLogging
|
6
|
-
from modulitiz_micro.sistema.ModuloSystem import ModuloSystem
|
7
|
-
from modulitiz_micro.util.beans.conf.AbstractConfBean import AbstractConfBean
|
8
|
-
|
9
|
-
|
10
|
-
class AbstractGlobalVarBean(ABC):
|
11
|
-
"""
|
12
|
-
Classe da usare come base per definire la struttura di una classe che raggrupperà gli oggetti che verranno usati nel programma
|
13
|
-
"""
|
14
|
-
|
15
|
-
def __init__(self,confBean:NewType("T",AbstractConfBean),projectTitle:str,projectVersion:str,projectStartYear:int,isDebug:bool|None):
|
16
|
-
self.confBean=confBean
|
17
|
-
self.projectTitle=projectTitle
|
18
|
-
self.projectVersion=projectVersion
|
19
|
-
self.projectStartYear=projectStartYear
|
20
|
-
|
21
|
-
self.projectHeader="%s V%s"%(projectTitle,projectVersion)
|
22
|
-
|
23
|
-
if isDebug is None:
|
24
|
-
isDebug=confBean.IS_DEBUG
|
25
|
-
self.logger=ModuloLogging(cartellaBase=confBean.CARTELLA_BASE_PROGETTO,isDebug=isDebug)
|
26
|
-
currentYear=ModuloDate.dateToString(None,"%Y")
|
27
|
-
ModuloSystem.setTitoloFinestra(projectTitle)
|
28
|
-
self.logger.info("""
|
29
|
-
############################################################
|
30
|
-
%s - Since %d - Copyright %s
|
31
|
-
############################################################""",self.projectHeader,projectStartYear,currentYear)
|
32
|
-
self.isRequestedStop=False
|
33
|
-
self.isRequestedExit=False
|
34
|
-
|
@@ -1,23 +0,0 @@
|
|
1
|
-
import asyncio
|
2
|
-
from functools import wraps
|
3
|
-
|
4
|
-
|
5
|
-
def noAwait(funzione):
|
6
|
-
"""
|
7
|
-
Usare questo decorator per evitare di propagare async e await in tutto il codice.
|
8
|
-
Esempio dell'uso:
|
9
|
-
|
10
|
-
@noAwait
|
11
|
-
async def funzione(self):
|
12
|
-
await funzioneAsync()
|
13
|
-
"""
|
14
|
-
|
15
|
-
@wraps(funzione)
|
16
|
-
def wrapped(*args, **kwargs):
|
17
|
-
try:
|
18
|
-
loop=asyncio.get_event_loop_policy().get_event_loop()
|
19
|
-
except RuntimeError:
|
20
|
-
loop=asyncio.new_event_loop()
|
21
|
-
asyncio.set_event_loop(loop)
|
22
|
-
loop.run_until_complete(funzione(*args,**kwargs))
|
23
|
-
return wrapped
|
@@ -1,41 +0,0 @@
|
|
1
|
-
import re
|
2
|
-
from abc import ABC
|
3
|
-
|
4
|
-
from modulitiz_micro.ModuloListe import ModuloListe
|
5
|
-
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
6
|
-
from modulitiz_micro.sistema.ModuloSystem import ModuloSystem
|
7
|
-
|
8
|
-
|
9
|
-
class AbstractModuloPip(ABC):
|
10
|
-
REGEX_VERSION=r"\d+\.\d+\.\d+"
|
11
|
-
_PREFIX_OK="Successfully installed "
|
12
|
-
|
13
|
-
@classmethod
|
14
|
-
def _versionFromFileRequirements(cls,rigaIn:str,args:str) -> list:
|
15
|
-
cmd='pip index versions --pre %s %s'%(rigaIn,args)
|
16
|
-
output=ModuloSystem.systemCallReturnOutput(cmd,None)
|
17
|
-
righe=ModuloListe.eliminaElementiVuoti(ModuloStringhe.normalizzaEol(output).split("\n"))
|
18
|
-
righe=cls._parseResults(righe)
|
19
|
-
result=[]
|
20
|
-
if len(righe)<3:
|
21
|
-
return result
|
22
|
-
|
23
|
-
result.append(cls._search(righe[-2],r"INSTALLED:\s+(%s)"))
|
24
|
-
result.append(cls._search(righe[-1],r"LATEST:\s+(%s)"))
|
25
|
-
return result
|
26
|
-
|
27
|
-
@staticmethod
|
28
|
-
def _parseResults(righe:list)->list:
|
29
|
-
output=[]
|
30
|
-
for riga in righe:
|
31
|
-
riga=riga.strip()
|
32
|
-
if not ModuloStringhe.isEmpty(riga) and not riga.startswith("["):
|
33
|
-
output.append(riga)
|
34
|
-
return output
|
35
|
-
|
36
|
-
@classmethod
|
37
|
-
def _search(cls,riga:str,regex:str)->str|None:
|
38
|
-
ricerca=re.search(regex%(cls.REGEX_VERSION,),riga)
|
39
|
-
if ricerca is None:
|
40
|
-
return None
|
41
|
-
return ricerca.group(1).strip()
|
@@ -1,49 +0,0 @@
|
|
1
|
-
from modulitiz_micro.ModuloListe import ModuloListe
|
2
|
-
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
3
|
-
from modulitiz_micro.files.ModuloFiles import ModuloFiles
|
4
|
-
from modulitiz_micro.sistema.ModuloSystem import ModuloSystem
|
5
|
-
from modulitiz_micro.util.pip.AbstractModuloPip import AbstractModuloPip
|
6
|
-
|
7
|
-
|
8
|
-
class ModuloPip(AbstractModuloPip):
|
9
|
-
|
10
|
-
@classmethod
|
11
|
-
def updateFromFileRequirements(cls,percorsoCartellaDipendenze: str) -> tuple[bool,str]:
|
12
|
-
fileDipendenze=ModuloFiles.pathJoin(percorsoCartellaDipendenze,"requirements.txt")
|
13
|
-
cmd='pip install -U -r "%s"'%(fileDipendenze,)
|
14
|
-
output=ModuloSystem.systemCallReturnOutput(cmd,None)
|
15
|
-
# check output
|
16
|
-
righe=ModuloListe.eliminaElementiVuoti(ModuloStringhe.normalizzaEol(output).split("\n"))
|
17
|
-
ultimeRigheReversed=righe[-10:]
|
18
|
-
ultimeRigheReversed.reverse()
|
19
|
-
isError=False
|
20
|
-
for riga in ultimeRigheReversed:
|
21
|
-
if riga.startswith(cls._PREFIX_OK):
|
22
|
-
elencoModuliAggiornati=riga.replace(cls._PREFIX_OK,"")
|
23
|
-
return True,elencoModuliAggiornati
|
24
|
-
if not isError and (riga.startswith("ERROR:") or riga.startswith("Exception:")):
|
25
|
-
isError=True
|
26
|
-
if isError:
|
27
|
-
msg="Aggiornamento moduli non riuscito:\n{}".format(output[-1000:])
|
28
|
-
return False,msg
|
29
|
-
return True," nessun aggiornamento"
|
30
|
-
|
31
|
-
@classmethod
|
32
|
-
def versionsFromFileRequirements(cls,percorsoCartellaDipendenze: str) -> list:
|
33
|
-
fileDipendenze=ModuloFiles.pathJoin(percorsoCartellaDipendenze,"requirements.txt")
|
34
|
-
if ModuloFiles.getFileSize(fileDipendenze)<=0:
|
35
|
-
return []
|
36
|
-
cont=ModuloStringhe.normalizzaEol(ModuloFiles.readFileText(fileDipendenze,None))
|
37
|
-
righe=ModuloListe.eliminaElementiVuoti(cont.split("\n"))
|
38
|
-
results=[]
|
39
|
-
# memorizzo opzioni
|
40
|
-
argsList=[]
|
41
|
-
for riga in righe:
|
42
|
-
if riga.startswith("-"):
|
43
|
-
argsList.append(riga)
|
44
|
-
args=" ".join(argsList)
|
45
|
-
# elaboro ogni modulo
|
46
|
-
for riga in righe:
|
47
|
-
if not riga.startswith("-"):
|
48
|
-
results.append(cls._versionFromFileRequirements(riga,args))
|
49
|
-
return results
|
@@ -1,14 +0,0 @@
|
|
1
|
-
from abc import ABC
|
2
|
-
|
3
|
-
from modulitiz_micro.util.spooler.beans.QueueBean import QueueBean
|
4
|
-
|
5
|
-
|
6
|
-
class AbstractSpooler(ABC):
|
7
|
-
beans:dict[str,QueueBean]={}
|
8
|
-
|
9
|
-
@classmethod
|
10
|
-
def _areJobsNotDone(cls)->bool:
|
11
|
-
for bean in cls.beans.values():
|
12
|
-
if bean.size>0:
|
13
|
-
return True
|
14
|
-
return False
|
@@ -1,18 +0,0 @@
|
|
1
|
-
import time
|
2
|
-
|
3
|
-
from modulitiz_micro.util.spooler.AbstractSpooler import AbstractSpooler
|
4
|
-
from modulitiz_micro.util.spooler.beans.QueueBean import QueueBean
|
5
|
-
|
6
|
-
|
7
|
-
class Spooler(AbstractSpooler):
|
8
|
-
@staticmethod
|
9
|
-
def increaseSize(bean:QueueBean):
|
10
|
-
bean.size+=1
|
11
|
-
@staticmethod
|
12
|
-
def decreaseSize(bean:QueueBean):
|
13
|
-
bean.size-=1
|
14
|
-
|
15
|
-
@classmethod
|
16
|
-
def waitUntilJobsDone(cls):
|
17
|
-
while cls._areJobsNotDone():
|
18
|
-
time.sleep(0.1)
|
@@ -1,49 +0,0 @@
|
|
1
|
-
from functools import wraps
|
2
|
-
|
3
|
-
from modulitiz_micro.ModuloFunzioni import ModuloFunzioni
|
4
|
-
from modulitiz_micro.util.spooler.Spooler import Spooler
|
5
|
-
from modulitiz_micro.util.spooler.beans.QueueBean import QueueBean
|
6
|
-
from modulitiz_micro.util.spooler.eccezioni.EccezioneSpooler import EccezioneSpooler
|
7
|
-
from modulitiz_micro.util.spooler.eccezioni.EccezioneSpoolerFull import EccezioneSpoolerFull
|
8
|
-
|
9
|
-
|
10
|
-
def spooler(maxSize:int,notifyIfConsecutiveSizeGreaterThan:int=0):
|
11
|
-
"""
|
12
|
-
Usare questo decorator per produrre (creare) la coda di azioni e consumarla (scodare) non appena c'è uno slot libero.
|
13
|
-
:param maxSize: dimensione massima della coda
|
14
|
-
:param notifyIfConsecutiveSizeGreaterThan: cosa fare se la coda è piena:
|
15
|
-
- 0: notifica sempre
|
16
|
-
- >0: notifica solo se maggiore di N
|
17
|
-
"""
|
18
|
-
# controllo parametri di input
|
19
|
-
if notifyIfConsecutiveSizeGreaterThan>maxSize:
|
20
|
-
raise EccezioneSpooler("%d non può essere maggiore di %d"%(notifyIfConsecutiveSizeGreaterThan,maxSize))
|
21
|
-
|
22
|
-
def decorator(funzione):
|
23
|
-
@wraps(funzione)
|
24
|
-
def wrapped(*args,**kwargs):
|
25
|
-
fullPathFunction=ModuloFunzioni.getFullyQualifiedName(funzione)
|
26
|
-
bean=Spooler.beans.get(fullPathFunction,None)
|
27
|
-
if bean is None:
|
28
|
-
bean=QueueBean()
|
29
|
-
Spooler.beans[fullPathFunction]=bean
|
30
|
-
# controllo se ho raggiunto o superato il limite
|
31
|
-
if bean.size>=maxSize:
|
32
|
-
bean.countConsecutiveOverSize+=1
|
33
|
-
if bean.countConsecutiveOverSize>notifyIfConsecutiveSizeGreaterThan:
|
34
|
-
bean.countConsecutiveOverSize=0
|
35
|
-
raise EccezioneSpoolerFull()
|
36
|
-
else:
|
37
|
-
bean.countConsecutiveOverSize=0
|
38
|
-
# chiamo la funzione
|
39
|
-
Spooler.increaseSize(bean)
|
40
|
-
try:
|
41
|
-
with bean.lock:
|
42
|
-
output=funzione(*args,**kwargs)
|
43
|
-
except Exception as e:
|
44
|
-
Spooler.decreaseSize(bean)
|
45
|
-
raise e
|
46
|
-
Spooler.decreaseSize(bean)
|
47
|
-
return output
|
48
|
-
return wrapped
|
49
|
-
return decorator
|
@@ -1,31 +0,0 @@
|
|
1
|
-
from abc import ABC
|
2
|
-
|
3
|
-
from modulitiz_micro.eccezioni.EccezioneRuntime import EccezioneRuntime
|
4
|
-
|
5
|
-
|
6
|
-
class AbstractOverrideTestUtil(ABC):
|
7
|
-
"""
|
8
|
-
Solo le funzioni statiche devono essere revertate
|
9
|
-
"""
|
10
|
-
|
11
|
-
def __init__(self):
|
12
|
-
super().__init__()
|
13
|
-
self._cache={}
|
14
|
-
|
15
|
-
def __enter__(self):
|
16
|
-
self._cache.clear()
|
17
|
-
return self
|
18
|
-
|
19
|
-
def __exit__(self,*args,**kwargs):
|
20
|
-
self._cache.clear()
|
21
|
-
|
22
|
-
@staticmethod
|
23
|
-
def getMockedFunction(throwExc:Exception|None,expectedValue: str|tuple|None):
|
24
|
-
"""
|
25
|
-
Must use only 1 param.
|
26
|
-
"""
|
27
|
-
if throwExc is not None:
|
28
|
-
return lambda *args,**kwargs:(_ for _ in ()).throw(throwExc)
|
29
|
-
elif expectedValue is not None:
|
30
|
-
return lambda *args,**kwargs:expectedValue
|
31
|
-
raise EccezioneRuntime("Use only 1 param")
|
@@ -1,11 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
|
3
|
-
|
4
|
-
class AbstractTestUtil(unittest.TestCase):
|
5
|
-
overrideTestUtil=None
|
6
|
-
|
7
|
-
def __init__(self,*args,**kwargs):
|
8
|
-
super().__init__(*args,**kwargs)
|
9
|
-
logger=type('test',(),{})()
|
10
|
-
logger.exception=logger.error=logger.warning=logger.info=logger.debug=print
|
11
|
-
self.logger=logger
|
@@ -1,25 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import pkgutil
|
3
|
-
import unittest
|
4
|
-
|
5
|
-
|
6
|
-
class ModuloRunUnitTest(object):
|
7
|
-
|
8
|
-
@classmethod
|
9
|
-
def startTests(cls,currentFilePath:str):
|
10
|
-
suite=cls.__createTestSuite(currentFilePath)
|
11
|
-
unittest.TextTestRunner(verbosity=2).run(suite)
|
12
|
-
|
13
|
-
@staticmethod
|
14
|
-
def __createTestSuite(currentFilePath:str)->unittest.TestSuite:
|
15
|
-
paths = [x[0] for x in os.walk(os.path.dirname(currentFilePath))]
|
16
|
-
testLoader=unittest.TestLoader()
|
17
|
-
suite=unittest.TestSuite()
|
18
|
-
for modFinder, modName, _isPkg in pkgutil.walk_packages(paths):
|
19
|
-
spec=modFinder.find_spec(modName)
|
20
|
-
loader=spec.loader
|
21
|
-
module=loader.load_module(modName)
|
22
|
-
# carico ogni test presente in un modulo
|
23
|
-
for tests in testLoader.loadTestsFromModule(module):
|
24
|
-
suite.addTests(tests)
|
25
|
-
return suite
|