modulitiz-micro 2.41.0__py311-none-any.whl → 2.42.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.
Files changed (107) hide show
  1. modulitiz_micro/ModuloMeteo.py +72 -72
  2. modulitiz_micro/ModuloSeriale.py +70 -70
  3. modulitiz_micro/ModuloTarghe.py +47 -46
  4. modulitiz_micro/database/AbstractDatabaseService.py +13 -13
  5. modulitiz_micro/database/AbstractSql.py +69 -69
  6. modulitiz_micro/database/ModuloSqlOracle.py +19 -19
  7. modulitiz_micro/database/ModuloSqlServer.py +43 -43
  8. modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -6
  9. modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -114
  10. modulitiz_micro/database/mysql/ModuloMysql.py +163 -163
  11. modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -47
  12. modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -6
  13. modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -114
  14. modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -82
  15. modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -7
  16. modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -7
  17. modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -8
  18. modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -7
  19. modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -7
  20. modulitiz_micro/files/cache/DatabaseCache.py +91 -91
  21. modulitiz_micro/files/cache/decorators/cacheRam.py +26 -26
  22. modulitiz_micro/files/git/ModuloGit.py +28 -28
  23. modulitiz_micro/files/git/decorators/catchAndRaiseGitExceptions.py +19 -19
  24. modulitiz_micro/files/git/exceptions/EccezioneGit.py +7 -7
  25. modulitiz_micro/gestionedom/GestioneDom.py +44 -44
  26. modulitiz_micro/iot/ModuleIotDevice.py +4 -4
  27. modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -7
  28. modulitiz_micro/keylogger/ModuloKeylogger.py +73 -73
  29. modulitiz_micro/rete/ModuloNetworking.py +72 -72
  30. modulitiz_micro/rete/ModuloOpenVpn.py +15 -15
  31. modulitiz_micro/rete/email/EmailBean.py +5 -5
  32. modulitiz_micro/rete/email/ModuloEmail.py +90 -90
  33. modulitiz_micro/rete/http/ModuloHttp.py +119 -119
  34. modulitiz_micro/rete/http/ModuloHttpConnectionSafe.py +91 -91
  35. modulitiz_micro/rete/http/ModuloHttpUtils.py +69 -69
  36. modulitiz_micro/rete/http/beans/HttpResponseBean.py +5 -5
  37. modulitiz_micro/rete/http/decorators/catchAndRaiseHttpExceptions.py +22 -22
  38. modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -73
  39. modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -8
  40. modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -35
  41. modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -267
  42. modulitiz_micro/rete/ssl/ModuloSsl.py +56 -56
  43. modulitiz_micro/sistema/ModuloEnvVars.py +34 -34
  44. modulitiz_micro/sistema/ModuloSystemPipe.py +67 -67
  45. modulitiz_micro/social/telegram/AbstractModuloTelegram.py +53 -53
  46. modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -26
  47. modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -15
  48. modulitiz_micro/util/scheduler/ModuleScheduler.py +26 -26
  49. {modulitiz_micro-2.41.0.dist-info → modulitiz_micro-2.42.0.dist-info}/METADATA +58 -66
  50. modulitiz_micro-2.42.0.dist-info/RECORD +56 -0
  51. {modulitiz_micro-2.41.0.dist-info → modulitiz_micro-2.42.0.dist-info}/WHEEL +1 -1
  52. {modulitiz_micro-2.41.0.dist-info → modulitiz_micro-2.42.0.dist-info/licenses}/LICENSE +21 -21
  53. modulitiz_micro/ModuleEnum.py +0 -8
  54. modulitiz_micro/ModuloBase64.py +0 -61
  55. modulitiz_micro/ModuloColorText.py +0 -35
  56. modulitiz_micro/ModuloDate.py +0 -327
  57. modulitiz_micro/ModuloFunzioni.py +0 -71
  58. modulitiz_micro/ModuloListe.py +0 -150
  59. modulitiz_micro/ModuloNumeri.py +0 -127
  60. modulitiz_micro/ModuloPyinstaller.py +0 -29
  61. modulitiz_micro/ModuloStatistiche.py +0 -31
  62. modulitiz_micro/ModuloStringhe.py +0 -180
  63. modulitiz_micro/android/ModuloAndroid.py +0 -18
  64. modulitiz_micro/android/ModuloAndroidAdb.py +0 -48
  65. modulitiz_micro/android/ModuloAndroidSim.py +0 -130
  66. modulitiz_micro/android/beans/SmsBean.py +0 -12
  67. modulitiz_micro/android/enums/AndroidSmsTypeEnum.py +0 -17
  68. modulitiz_micro/eccezioni/EccezioneBase.py +0 -7
  69. modulitiz_micro/eccezioni/EccezioneRuntime.py +0 -7
  70. modulitiz_micro/eccezioni/EccezioneSoNonSupportato.py +0 -7
  71. modulitiz_micro/files/ModuloFiles.py +0 -173
  72. modulitiz_micro/files/ModuloLogging.py +0 -69
  73. modulitiz_micro/files/ModuloZip.py +0 -42
  74. modulitiz_micro/files/cache/CacheBean.py +0 -5
  75. modulitiz_micro/files/cache/CacheRam.py +0 -29
  76. modulitiz_micro/init/AbstractBasicInit.py +0 -27
  77. modulitiz_micro/init/AbstractInit.py +0 -11
  78. modulitiz_micro/multithread/ModuloThread.py +0 -26
  79. modulitiz_micro/multithread/ModuloThreadLogger.py +0 -8
  80. modulitiz_micro/multithread/ModuloThreadWithCallbackError.py +0 -25
  81. modulitiz_micro/nlp/ModuloNlp.py +0 -36
  82. modulitiz_micro/nlp/ModuloNlpDateAndTime.py +0 -59
  83. modulitiz_micro/sistema/EnvVarsEnum.py +0 -9
  84. modulitiz_micro/sistema/ModuloSystem.py +0 -298
  85. modulitiz_micro/util/beans/conf/AbstractBasicConfBean.py +0 -11
  86. modulitiz_micro/util/beans/conf/AbstractConfBean.py +0 -16
  87. modulitiz_micro/util/beans/fileconf/AbstractBasicFileConfBean.py +0 -11
  88. modulitiz_micro/util/beans/fileconf/AbstractFileConfBean.py +0 -13
  89. modulitiz_micro/util/beans/globalvar/AbstractGlobalVarBean.py +0 -34
  90. modulitiz_micro/util/decorators/noAwait.py +0 -23
  91. modulitiz_micro/util/pip/AbstractModuloPip.py +0 -41
  92. modulitiz_micro/util/pip/ModuloPip.py +0 -49
  93. modulitiz_micro/util/spooler/AbstractSpooler.py +0 -14
  94. modulitiz_micro/util/spooler/Spooler.py +0 -18
  95. modulitiz_micro/util/spooler/beans/QueueBean.py +0 -8
  96. modulitiz_micro/util/spooler/decorators/spooler.py +0 -49
  97. modulitiz_micro/util/spooler/eccezioni/EccezioneSpooler.py +0 -7
  98. modulitiz_micro/util/spooler/eccezioni/EccezioneSpoolerFull.py +0 -7
  99. modulitiz_micro/util/unittesting/AbstractOverrideTestUtil.py +0 -31
  100. modulitiz_micro/util/unittesting/AbstractTestUtil.py +0 -11
  101. modulitiz_micro/util/unittesting/ModuloRunUnitTest.py +0 -25
  102. modulitiz_micro/util/wheel/ModuloBuildWheel.py +0 -118
  103. modulitiz_micro/util/wheel/ModuloCheckTestNamingConvention.py +0 -89
  104. modulitiz_micro/util/wheel/ModuloToml.py +0 -40
  105. modulitiz_micro/util/wheel/ModuloWheel.py +0 -12
  106. modulitiz_micro-2.41.0.dist-info/RECORD +0 -109
  107. {modulitiz_micro-2.41.0.dist-info → modulitiz_micro-2.42.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,8 +0,0 @@
1
- import threading
2
-
3
-
4
- class QueueBean(object):
5
- def __init__(self):
6
- self.lock=threading.Lock()
7
- self.size=0
8
- self.countConsecutiveOverSize=0
@@ -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,7 +0,0 @@
1
- from modulitiz_micro.eccezioni.EccezioneBase import EccezioneBase
2
-
3
-
4
- class EccezioneSpooler(EccezioneBase):
5
-
6
- def __init__(self,msg:str):
7
- super().__init__(msg)
@@ -1,7 +0,0 @@
1
- from modulitiz_micro.util.spooler.eccezioni.EccezioneSpooler import EccezioneSpooler
2
-
3
-
4
- class EccezioneSpoolerFull(EccezioneSpooler):
5
-
6
- def __init__(self):
7
- super().__init__("Spooler pieno")
@@ -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