modulitiz-micro 2.26.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/ModuloBase64.py +61 -0
- modulitiz_micro/ModuloColorText.py +35 -0
- modulitiz_micro/ModuloDate.py +295 -0
- modulitiz_micro/ModuloFunzioni.py +58 -0
- modulitiz_micro/ModuloListe.py +150 -0
- modulitiz_micro/ModuloMeteo.py +72 -0
- modulitiz_micro/ModuloNumeri.py +130 -0
- modulitiz_micro/ModuloPyinstaller.py +29 -0
- modulitiz_micro/ModuloSeriale.py +61 -0
- modulitiz_micro/ModuloStatistiche.py +31 -0
- modulitiz_micro/ModuloStringhe.py +180 -0
- modulitiz_micro/ModuloTarghe.py +46 -0
- modulitiz_micro/android/ModuloAndroid.py +18 -0
- modulitiz_micro/android/ModuloAndroidAdb.py +48 -0
- modulitiz_micro/android/ModuloAndroidSim.py +130 -0
- modulitiz_micro/android/beans/SmsBean.py +12 -0
- modulitiz_micro/android/enums/AndroidSmsTypeEnum.py +17 -0
- modulitiz_micro/database/AbstractDatabaseService.py +13 -0
- modulitiz_micro/database/AbstractSql.py +49 -0
- modulitiz_micro/database/ModuloSqlOracle.py +19 -0
- modulitiz_micro/database/ModuloSqlServer.py +50 -0
- modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -0
- modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -0
- modulitiz_micro/database/mysql/ModuloMysql.py +151 -0
- modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -0
- modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -0
- modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -0
- modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -0
- modulitiz_micro/eccezioni/EccezioneBase.py +7 -0
- modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -0
- modulitiz_micro/eccezioni/EccezioneRuntime.py +7 -0
- modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -0
- modulitiz_micro/eccezioni/EccezioneSoNonSupportato.py +7 -0
- modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -0
- modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -0
- modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -0
- modulitiz_micro/files/ModuloFiles.py +173 -0
- modulitiz_micro/files/ModuloLogging.py +69 -0
- modulitiz_micro/files/ModuloZip.py +42 -0
- modulitiz_micro/files/cache/CacheBean.py +5 -0
- modulitiz_micro/files/cache/CacheRam.py +29 -0
- modulitiz_micro/files/cache/DatabaseCache.py +91 -0
- modulitiz_micro/files/cache/decorators/cacheRam.py +26 -0
- modulitiz_micro/files/git/ModuloGit.py +15 -0
- modulitiz_micro/gestionedom/GestioneDom.py +44 -0
- modulitiz_micro/init/AbstractBasicInit.py +27 -0
- modulitiz_micro/init/AbstractInit.py +11 -0
- modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -0
- modulitiz_micro/keylogger/ModuloKeylogger.py +73 -0
- modulitiz_micro/multithreading/ModuloThread.py +26 -0
- modulitiz_micro/multithreading/ModuloThreadLogger.py +8 -0
- modulitiz_micro/multithreading/ModuloThreadWithCallbackError.py +25 -0
- modulitiz_micro/nlp/ModuloNlp.py +36 -0
- modulitiz_micro/nlp/ModuloNlpDateAndTime.py +59 -0
- modulitiz_micro/rete/ModuloEmail.py +69 -0
- modulitiz_micro/rete/ModuloNetworking.py +64 -0
- modulitiz_micro/rete/ModuloOpenVpn.py +15 -0
- modulitiz_micro/rete/http/ModuloHttp.py +114 -0
- modulitiz_micro/rete/http/ModuloHttpConnectionSafe.py +91 -0
- modulitiz_micro/rete/http/ModuloHttpUtils.py +66 -0
- modulitiz_micro/rete/http/beans/HttpResponseBean.py +5 -0
- modulitiz_micro/rete/http/decorators/catchAndRaiseHttpExceptions.py +22 -0
- modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -0
- modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -0
- modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -0
- modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -0
- modulitiz_micro/rete/ssl/ModuloSsl.py +56 -0
- modulitiz_micro/sistema/EnvVarsEnum.py +9 -0
- modulitiz_micro/sistema/ModuloEnvVars.py +34 -0
- modulitiz_micro/sistema/ModuloSystem.py +298 -0
- modulitiz_micro/sistema/ModuloSystemPipe.py +67 -0
- modulitiz_micro/social/telegram/ModuloTelegram.py +52 -0
- modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -0
- modulitiz_micro/util/beans/conf/AbstractBasicConfBean.py +11 -0
- modulitiz_micro/util/beans/conf/AbstractConfBean.py +16 -0
- modulitiz_micro/util/beans/fileconf/AbstractBasicFileConfBean.py +11 -0
- modulitiz_micro/util/beans/fileconf/AbstractFileConfBean.py +13 -0
- modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -0
- modulitiz_micro/util/beans/globalvar/AbstractGlobalVarBean.py +34 -0
- modulitiz_micro/util/decorators/noAwait.py +23 -0
- modulitiz_micro/util/pip/AbstractModuloPip.py +41 -0
- modulitiz_micro/util/pip/ModuloPip.py +49 -0
- modulitiz_micro/util/scheduler/AbstractScheduler.py +32 -0
- modulitiz_micro/util/spooler/AbstractSpooler.py +14 -0
- modulitiz_micro/util/spooler/Spooler.py +18 -0
- modulitiz_micro/util/spooler/beans/QueueBean.py +8 -0
- modulitiz_micro/util/spooler/decorators/spooler.py +49 -0
- modulitiz_micro/util/spooler/eccezioni/EccezioneSpooler.py +7 -0
- modulitiz_micro/util/spooler/eccezioni/EccezioneSpoolerFull.py +7 -0
- modulitiz_micro/util/unittesting/AbstractOverrideTestUtil.py +18 -0
- modulitiz_micro/util/unittesting/AbstractTestUtil.py +11 -0
- modulitiz_micro/util/unittesting/ModuloRunUnitTest.py +25 -0
- modulitiz_micro/util/wheel/ModuloBuildWheel.py +118 -0
- modulitiz_micro/util/wheel/ModuloToml.py +40 -0
- modulitiz_micro/util/wheel/ModuloWheel.py +12 -0
- modulitiz_micro-2.26.0.dist-info/LICENSE +21 -0
- modulitiz_micro-2.26.0.dist-info/METADATA +63 -0
- modulitiz_micro-2.26.0.dist-info/RECORD +100 -0
- modulitiz_micro-2.26.0.dist-info/WHEEL +5 -0
- modulitiz_micro-2.26.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
import glob
|
2
|
+
import os
|
3
|
+
import shutil
|
4
|
+
|
5
|
+
from modulitiz_micro.ModuloDate import ModuloDate
|
6
|
+
from modulitiz_micro.ModuloListe import ModuloListe
|
7
|
+
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
8
|
+
from modulitiz_micro.eccezioni.EccezioneRuntime import EccezioneRuntime
|
9
|
+
|
10
|
+
|
11
|
+
class ModuloFiles(object):
|
12
|
+
@staticmethod
|
13
|
+
def open(*args,**kwargs):
|
14
|
+
return open(newline="\n",*args,**kwargs)
|
15
|
+
|
16
|
+
@classmethod
|
17
|
+
def readFileBinary(cls,filename:str)->str:
|
18
|
+
"""
|
19
|
+
Convert digital data to binary format
|
20
|
+
Puo' essere usato, ad esempio, per inserire un file di tipo BLOB su sqlite
|
21
|
+
"""
|
22
|
+
return cls.readFile(filename,'rb',None)
|
23
|
+
@classmethod
|
24
|
+
def readFileText(cls,filename:str,useUtf8:bool|None)->str:
|
25
|
+
return cls.readFile(filename,'rt',useUtf8)
|
26
|
+
@staticmethod
|
27
|
+
def readFile(filename:str,mode:str,useUtf8:bool|None):
|
28
|
+
codifica=None
|
29
|
+
if useUtf8 is not None:
|
30
|
+
if useUtf8 is True:
|
31
|
+
codifica=ModuloStringhe.CODIFICA_UTF8
|
32
|
+
else:
|
33
|
+
codifica='latin-1'
|
34
|
+
with open(filename,mode,encoding=codifica) as fp:
|
35
|
+
cont=fp.read()
|
36
|
+
return cont
|
37
|
+
|
38
|
+
@staticmethod
|
39
|
+
def getFileSize(nomefile:str)->int:
|
40
|
+
"""
|
41
|
+
Se non trova nessun file ritorna -1
|
42
|
+
"""
|
43
|
+
try:
|
44
|
+
statinfo=os.stat(nomefile)
|
45
|
+
return statinfo.st_size
|
46
|
+
except FileNotFoundError:
|
47
|
+
return -1
|
48
|
+
|
49
|
+
@classmethod
|
50
|
+
def getFolderSize(cls, path:str)->int:
|
51
|
+
if not os.path.exists(path) or os.path.isfile(path):
|
52
|
+
return -1
|
53
|
+
count=0
|
54
|
+
for root,cartelle,filenames in os.walk(path):
|
55
|
+
for filename in filenames:
|
56
|
+
count+=cls.getFileSize(os.path.join(root,filename))
|
57
|
+
return count
|
58
|
+
|
59
|
+
@staticmethod
|
60
|
+
def getTimestampUtcUltimaModifica(nomefile:str)->int:
|
61
|
+
return int(os.path.getmtime(nomefile))
|
62
|
+
|
63
|
+
@staticmethod
|
64
|
+
def normalizzaSlashPath(percorso:str)->str:
|
65
|
+
percorso=os.path.normpath(percorso)
|
66
|
+
return percorso.replace("\\","/")
|
67
|
+
|
68
|
+
@classmethod
|
69
|
+
def pathJoin(cls,path1:str|None,path2:str|None)->str|None:
|
70
|
+
if ModuloStringhe.isEmpty(path1):
|
71
|
+
return path2
|
72
|
+
if ModuloStringhe.isEmpty(path2):
|
73
|
+
return path1
|
74
|
+
# normalizzazione
|
75
|
+
path1=cls.normalizzaSlashPath(path1)
|
76
|
+
path2=cls.normalizzaSlashPath(path2)
|
77
|
+
# concatenazione
|
78
|
+
path=os.path.join(path1,path2)
|
79
|
+
path=cls.normalizzaSlashPath(path)
|
80
|
+
return path
|
81
|
+
|
82
|
+
@classmethod
|
83
|
+
def pathAbsToRel(cls,percorso:str,root:str):
|
84
|
+
percorso=percorso.replace(root,"")
|
85
|
+
percorso=cls.normalizzaSlashPath(percorso)
|
86
|
+
if percorso.startswith("/"):
|
87
|
+
percorso=percorso[1:]
|
88
|
+
return percorso
|
89
|
+
|
90
|
+
@staticmethod
|
91
|
+
def normalizzaPercorsoLocale(percorso:str):
|
92
|
+
percorso=os.path.normpath(os.path.abspath(percorso))
|
93
|
+
return percorso
|
94
|
+
@classmethod
|
95
|
+
def normalizzaPercorsoRemoto(cls,percorso:str):
|
96
|
+
return cls.normalizzaSlashPath(percorso)
|
97
|
+
|
98
|
+
@classmethod
|
99
|
+
def rinominaConTimestamp(cls,nomefile:str):
|
100
|
+
nomefileSenzaEstensione,ext=cls.getNomefileEdEstensione(nomefile)
|
101
|
+
nomefileNew=nomefileSenzaEstensione+"_"+ModuloDate.dateToString(None, ModuloDate.FORMATO_DATA_ORA_NOMEFILE)+ext
|
102
|
+
os.rename(nomefile,nomefileNew)
|
103
|
+
|
104
|
+
@staticmethod
|
105
|
+
def sposta(sourceFilename:str,destFilename:str):
|
106
|
+
shutil.move(sourceFilename,destFilename)
|
107
|
+
|
108
|
+
@staticmethod
|
109
|
+
def copia(sourceFilename:str,destFilename:str):
|
110
|
+
try:
|
111
|
+
shutil.copy2(sourceFilename,destFilename)
|
112
|
+
except Exception:
|
113
|
+
raise EccezioneRuntime("Errore copia file "+sourceFilename+" in "+destFilename)
|
114
|
+
|
115
|
+
@classmethod
|
116
|
+
def eliminaContenutoCartella(cls,percorso:str):
|
117
|
+
"""
|
118
|
+
elimina tutto il contenuto di una cartella ma non la cartella
|
119
|
+
"""
|
120
|
+
for root,cartelle,nomefiles in os.walk(percorso):
|
121
|
+
for nomefile in nomefiles:
|
122
|
+
os.unlink(cls.pathJoin(root, nomefile))
|
123
|
+
for cartella in cartelle:
|
124
|
+
shutil.rmtree(cls.pathJoin(root, cartella))
|
125
|
+
|
126
|
+
@staticmethod
|
127
|
+
def deleteByPattern(pattern:str):
|
128
|
+
filesDaElim=glob.glob(pattern)
|
129
|
+
for fileDaElim in filesDaElim:
|
130
|
+
os.remove(fileDaElim)
|
131
|
+
|
132
|
+
@staticmethod
|
133
|
+
def getNomefileEdEstensione(nomefile:str)->tuple:
|
134
|
+
arr=nomefile.split(".")
|
135
|
+
nomefileSenzaEstensione=".".join(arr[0:-1])
|
136
|
+
ext="."+arr[-1]
|
137
|
+
return nomefileSenzaEstensione,ext
|
138
|
+
|
139
|
+
@classmethod
|
140
|
+
def walk(cls,root:str,excludeFiles:list|tuple,excludeDirs:list|tuple,minByteSize:int|None,maxByteSize:int|None):
|
141
|
+
"""
|
142
|
+
Questa funzione e' uguale a os.walk() ma restituisce anche il path relativo oltre a quello assoluto.
|
143
|
+
"""
|
144
|
+
root=cls.normalizzaPercorsoLocale(root)
|
145
|
+
for result in os.walk(root):
|
146
|
+
yield from cls.__walk(root,excludeFiles,excludeDirs,minByteSize,maxByteSize,result)
|
147
|
+
|
148
|
+
@classmethod
|
149
|
+
def __walk(cls,root: str,excludeFiles: list|tuple,excludeDirs: list|tuple,minByteSize: int|None,maxByteSize: int|None,
|
150
|
+
result:tuple[str, list[str], list[str]]):
|
151
|
+
percorso,cartelle,nomefiles=result
|
152
|
+
percorsoRel=cls.pathAbsToRel(percorso,root)
|
153
|
+
# elaboro i file
|
154
|
+
for index,nomefile in enumerate(nomefiles):
|
155
|
+
nomefileRelPath=cls.pathJoin(percorsoRel,nomefile)
|
156
|
+
# escludo i file che sono nella blacklist
|
157
|
+
if nomefileRelPath in excludeFiles:
|
158
|
+
nomefiles[index]=""
|
159
|
+
continue
|
160
|
+
# controllo dimensione file
|
161
|
+
if maxByteSize is not None or minByteSize is not None:
|
162
|
+
bytesFile=cls.getFileSize(cls.pathJoin(root,nomefileRelPath))
|
163
|
+
if(maxByteSize is not None and bytesFile>maxByteSize) or (minByteSize is not None and bytesFile<minByteSize):
|
164
|
+
nomefiles[index]=""
|
165
|
+
nomefiles=ModuloListe.eliminaElementiVuoti(nomefiles)
|
166
|
+
#elaboro le cartelle
|
167
|
+
for index,cartella in enumerate(cartelle):
|
168
|
+
cartellaRelPath=cls.normalizzaPercorsoRemoto(cls.pathJoin(percorsoRel,cartella))
|
169
|
+
#escludo le cartelle che sono nella blacklist
|
170
|
+
if cartellaRelPath in excludeDirs:
|
171
|
+
cartelle[index]=""
|
172
|
+
cartelle=ModuloListe.eliminaElementiVuoti(cartelle)
|
173
|
+
yield percorsoRel,percorso,cartelle,nomefiles
|
@@ -0,0 +1,69 @@
|
|
1
|
+
import logging
|
2
|
+
import os
|
3
|
+
import sys
|
4
|
+
|
5
|
+
from modulitiz_micro.ModuloDate import ModuloDate
|
6
|
+
from modulitiz_micro.files.ModuloFiles import ModuloFiles
|
7
|
+
|
8
|
+
|
9
|
+
class ModuloLogging(logging.Logger):
|
10
|
+
CARTELLA_LOG="logs"
|
11
|
+
NOMEFILE_PREFIX="log"
|
12
|
+
NOMEFILE_EXT=".txt"
|
13
|
+
# dimensione massima del file di log in byte
|
14
|
+
MAX_FILE_SIZE=10*1024*1024
|
15
|
+
|
16
|
+
def __init__(self,nomefileFullPath:str|None=None,cartellaBase:str|None=None,isDebug:bool=False):
|
17
|
+
super().__init__("modulitiz")
|
18
|
+
logFormatterConsole = self.__getOutputFormatter(False)
|
19
|
+
logLevel=logging.INFO if not isDebug else logging.DEBUG
|
20
|
+
# imposto livello
|
21
|
+
self.setLevel(logLevel)
|
22
|
+
# creo console logger
|
23
|
+
consoleHandler=logging.StreamHandler(sys.stdout)
|
24
|
+
consoleHandler.setLevel(logLevel)
|
25
|
+
consoleHandler.setFormatter(logFormatterConsole)
|
26
|
+
self.addHandler(consoleHandler)
|
27
|
+
# creo file logger
|
28
|
+
self.__addFileHandler(nomefileFullPath,cartellaBase,isDebug)
|
29
|
+
|
30
|
+
def close(self):
|
31
|
+
self.handlers.clear()
|
32
|
+
|
33
|
+
@staticmethod
|
34
|
+
def exceptionToString(eccezione)->str:
|
35
|
+
formatter=logging.Formatter()
|
36
|
+
lastEccezione=sys.exc_info()
|
37
|
+
try:
|
38
|
+
msg=formatter.formatException(eccezione)
|
39
|
+
except TypeError:
|
40
|
+
msg=formatter.formatException(lastEccezione)
|
41
|
+
return msg
|
42
|
+
|
43
|
+
@staticmethod
|
44
|
+
def __getOutputFormatter(isDebug:bool)->logging.Formatter:
|
45
|
+
formato='%(asctime)s '+('[%(filename)s:%(lineno)s]\t' if isDebug is True else '')+'[%(levelname)s]\t%(message)s'
|
46
|
+
return logging.Formatter(formato)
|
47
|
+
|
48
|
+
def __addFileHandler(self,nomefileFullPath:str|None,cartellaBase:str|None,isDebug:bool):
|
49
|
+
# controllo se loggare anche su file
|
50
|
+
if nomefileFullPath is None and cartellaBase is None:
|
51
|
+
return
|
52
|
+
# controllo che la cartella dei log esista
|
53
|
+
if cartellaBase is None:
|
54
|
+
cartellaBase=self.CARTELLA_LOG
|
55
|
+
else:
|
56
|
+
cartellaBase=ModuloFiles.pathJoin(cartellaBase,self.CARTELLA_LOG)
|
57
|
+
if not os.path.exists(cartellaBase):
|
58
|
+
os.makedirs(cartellaBase,exist_ok=True)
|
59
|
+
|
60
|
+
# creo il nome del file
|
61
|
+
if nomefileFullPath is None:
|
62
|
+
nomefileFullPath=ModuloFiles.pathJoin(cartellaBase,self.NOMEFILE_PREFIX+self.NOMEFILE_EXT)
|
63
|
+
# se il file e' troppo grande ne creo uno nuovo
|
64
|
+
if ModuloFiles.getFileSize(nomefileFullPath)>=self.MAX_FILE_SIZE:
|
65
|
+
os.rename(nomefileFullPath,nomefileFullPath+"_"+ModuloDate.dateToString(None,ModuloDate.FORMATO_DATA_ORA_NOMEFILE))
|
66
|
+
# file handler
|
67
|
+
fileHandler=logging.FileHandler(nomefileFullPath)
|
68
|
+
fileHandler.setFormatter(self.__getOutputFormatter(isDebug))
|
69
|
+
self.addHandler(fileHandler)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import os
|
2
|
+
import zipfile
|
3
|
+
|
4
|
+
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
5
|
+
from modulitiz_micro.files.ModuloFiles import ModuloFiles
|
6
|
+
|
7
|
+
|
8
|
+
class ModuloZip(object):
|
9
|
+
|
10
|
+
@classmethod
|
11
|
+
def zip(cls,dirIn: str,fileOut: str,includeRootDir: bool):
|
12
|
+
fh=zipfile.ZipFile(fileOut,'w',zipfile.ZIP_DEFLATED)
|
13
|
+
if not os.path.isfile(dirIn):
|
14
|
+
cls.__fromFolder(fh,dirIn,includeRootDir)
|
15
|
+
else:
|
16
|
+
fh.write(dirIn)
|
17
|
+
fh.close()
|
18
|
+
|
19
|
+
@staticmethod
|
20
|
+
def unzip(fileIn: str,dirOut: str|None = None):
|
21
|
+
if dirOut is None:
|
22
|
+
dirOut="./"
|
23
|
+
elif dirOut=="":
|
24
|
+
dirOut=fileIn.split("/")[-1].split(".")[0]
|
25
|
+
zipRef=zipfile.ZipFile(fileIn,'r')
|
26
|
+
zipRef.extractall(dirOut)
|
27
|
+
zipRef.close()
|
28
|
+
|
29
|
+
@staticmethod
|
30
|
+
def __fromFolder(fh,dirIn: str,includeRootDir: bool):
|
31
|
+
pathOutRootRel=os.path.basename(dirIn) if includeRootDir else ""
|
32
|
+
for pathRel,pathAbs,cartelle,nomefiles in ModuloFiles.walk(dirIn,(),(),None,None):
|
33
|
+
# controllo se devo scrivere anche la cartella principale
|
34
|
+
if not ModuloStringhe.isEmpty(pathOutRootRel):
|
35
|
+
pathOutRel=ModuloFiles.pathJoin(pathOutRootRel,pathRel)
|
36
|
+
fh.write(pathAbs,pathOutRel)
|
37
|
+
else:
|
38
|
+
pathOutRel=pathRel
|
39
|
+
for nomefile in nomefiles:
|
40
|
+
percorsoFile=ModuloFiles.pathJoin(pathAbs,nomefile)
|
41
|
+
percorsoFileRel=ModuloFiles.pathJoin(pathOutRel,nomefile)
|
42
|
+
fh.write(percorsoFile,percorsoFileRel)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from modulitiz_micro.ModuloDate import ModuloDate
|
2
|
+
from modulitiz_micro.ModuloListe import ModuloListe
|
3
|
+
from modulitiz_micro.files.cache.CacheBean import CacheBean
|
4
|
+
|
5
|
+
|
6
|
+
class CacheRam(object):
|
7
|
+
def __init__(self):
|
8
|
+
self.__mappa={}
|
9
|
+
|
10
|
+
def get(self,tipo: str,chiave: str,minsBeforeExpiry: int|None) -> CacheBean|None:
|
11
|
+
# controllo se esiste in ram
|
12
|
+
bean: CacheBean=ModuloListe.collectionSafeGet(self.__mappa,tipo,chiave)
|
13
|
+
if bean is None:
|
14
|
+
return None
|
15
|
+
# controllo se non e' scaduto
|
16
|
+
if minsBeforeExpiry is not None and ModuloDate.now()>ModuloDate.plusMinusMinutes(bean.dataLastUpdate,minsBeforeExpiry):
|
17
|
+
del self.__mappa[tipo][chiave]
|
18
|
+
return None
|
19
|
+
return bean
|
20
|
+
|
21
|
+
def insertOrUpdate(self,tipo: str,chiave: str,valore):
|
22
|
+
if tipo not in self.__mappa:
|
23
|
+
self.__mappa[tipo]={}
|
24
|
+
if chiave not in self.__mappa[tipo]:
|
25
|
+
self.__mappa[tipo][chiave]={}
|
26
|
+
self.__mappa[tipo][chiave]=CacheBean(valore,ModuloDate.now())
|
27
|
+
|
28
|
+
def clear(self):
|
29
|
+
self.__mappa.clear()
|
@@ -0,0 +1,91 @@
|
|
1
|
+
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
2
|
+
from modulitiz_micro.database.sqlite.ModuloSQLite import AbstractSqlite
|
3
|
+
|
4
|
+
|
5
|
+
class DatabaseCache(AbstractSqlite):
|
6
|
+
|
7
|
+
# costruttore
|
8
|
+
def __init__(self,*args,**kwargs):
|
9
|
+
super().__init__(*args,**kwargs)
|
10
|
+
|
11
|
+
# metodi
|
12
|
+
def schema(self):
|
13
|
+
sql="""
|
14
|
+
CREATE TABLE tb_cache(
|
15
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
16
|
+
type TEXT NOT NULL,
|
17
|
+
key TEXT NULL,
|
18
|
+
valore TEXT NOT NULL,
|
19
|
+
data_insert TIMESTAMP NOT NULL
|
20
|
+
);
|
21
|
+
CREATE UNIQUE INDEX IX_tb_cache__type_key ON tb_cache(type,key);
|
22
|
+
|
23
|
+
"""
|
24
|
+
|
25
|
+
return sql
|
26
|
+
|
27
|
+
def insertBasicTables(self):
|
28
|
+
return
|
29
|
+
|
30
|
+
|
31
|
+
#############################################################################################################################
|
32
|
+
def select_cache_valore_by_entries(self,tipo,chiave):
|
33
|
+
results=self.select_cache_by_entries(tipo, chiave)
|
34
|
+
if results is None:
|
35
|
+
return
|
36
|
+
return results[0]['valore']
|
37
|
+
|
38
|
+
def select_cache_by_entries(self,tipo,chiave):
|
39
|
+
with self.__query_cache_by_entries(tipo, chiave,False) as cursoreDb:
|
40
|
+
results=cursoreDb.fetchall()
|
41
|
+
if len(results)==0:
|
42
|
+
return
|
43
|
+
return results
|
44
|
+
|
45
|
+
def count_cache_by_entries(self,tipo,chiave)->int:
|
46
|
+
cursoreDb=self.__query_cache_by_entries(tipo, chiave,True)
|
47
|
+
return self.count(cursoreDb)
|
48
|
+
|
49
|
+
def __query_cache_by_entries(self,tipo,chiave,isCount):
|
50
|
+
add_chiave=ModuloStringhe.isEmpty(chiave) is False
|
51
|
+
sql="SELECT "+("COUNT(*) AS conta" if isCount is True else "*")+"""
|
52
|
+
FROM tb_cache
|
53
|
+
WHERE type=:tipo
|
54
|
+
"""+("AND key=:chiave" if add_chiave is True else "")+"""
|
55
|
+
;
|
56
|
+
"""
|
57
|
+
params={'tipo':tipo}
|
58
|
+
if add_chiave is True:
|
59
|
+
params['chiave']=chiave
|
60
|
+
|
61
|
+
cursoreDb=self.initCursore()
|
62
|
+
cursoreDb.execute(sql,params)
|
63
|
+
return cursoreDb
|
64
|
+
|
65
|
+
def insert_cache(self,tipo,chiave,valore):
|
66
|
+
sql="""
|
67
|
+
INSERT INTO tb_cache(
|
68
|
+
type,key,valore,data_insert
|
69
|
+
) VALUES (
|
70
|
+
:tipo,:chiave,:valore,"""+self.DATE_TIME_NOW+"""
|
71
|
+
);
|
72
|
+
"""
|
73
|
+
cursoreDb=self.initCursore()
|
74
|
+
cursoreDb.execute(sql,{
|
75
|
+
'tipo':tipo,'chiave':chiave,'valore':valore
|
76
|
+
})
|
77
|
+
return cursoreDb
|
78
|
+
|
79
|
+
def update_cache_valore(self,tipo,chiave,valore):
|
80
|
+
sql="""
|
81
|
+
UPDATE tb_cache
|
82
|
+
SET valore=:valore,data_insert="""+self.DATE_TIME_NOW+"""
|
83
|
+
WHERE type=:tipo AND key=:chiave
|
84
|
+
;
|
85
|
+
"""
|
86
|
+
cursoreDb=self.initCursore()
|
87
|
+
cursoreDb.execute(sql,{
|
88
|
+
'valore':valore,'tipo':tipo,'chiave':chiave
|
89
|
+
})
|
90
|
+
return cursoreDb
|
91
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
from functools import wraps
|
2
|
+
|
3
|
+
from cachetools import TTLCache
|
4
|
+
from cachetools import cached
|
5
|
+
|
6
|
+
from modulitiz_micro.ModuloNumeri import ModuloNumeri
|
7
|
+
|
8
|
+
|
9
|
+
def cacheRam(minsBeforeExpiry: int|float|None):
|
10
|
+
"""
|
11
|
+
Usare questo decorator per mettere in cache delle informazioni.
|
12
|
+
Alla base usa una libreria di terze parti.
|
13
|
+
:param minsBeforeExpiry: se null mantiene i dati in memoria per 1 giorno
|
14
|
+
"""
|
15
|
+
|
16
|
+
__secsBeforeExpiry=24*3600 if minsBeforeExpiry is None else ModuloNumeri.decimalNumbersTruncate(minsBeforeExpiry*60,2)
|
17
|
+
__cache=cached(TTLCache(20,__secsBeforeExpiry))
|
18
|
+
|
19
|
+
def decorator(funzione):
|
20
|
+
__funzione=__cache(funzione)
|
21
|
+
|
22
|
+
@wraps(funzione)
|
23
|
+
def wrapped(*args,**kwargs):
|
24
|
+
return __funzione(*args,**kwargs)
|
25
|
+
return wrapped
|
26
|
+
return decorator
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import git
|
2
|
+
|
3
|
+
|
4
|
+
class ModuloGit(object):
|
5
|
+
def __init__(self, repoPath:str):
|
6
|
+
self.inner=git.Repo(repoPath)
|
7
|
+
|
8
|
+
def getWorkingCopyRevision(self)->str:
|
9
|
+
return self.inner.head.object.hexsha
|
10
|
+
|
11
|
+
def getRemoteRevision(self)->str:
|
12
|
+
return self.inner.remotes[0].fetch()[0].ref.object.hexsha
|
13
|
+
|
14
|
+
def update(self)->str:
|
15
|
+
return self.inner.remotes[0].pull()[0].ref.object.hexsha
|
@@ -0,0 +1,44 @@
|
|
1
|
+
from bs4 import BeautifulSoup
|
2
|
+
|
3
|
+
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
4
|
+
from modulitiz_micro.files.ModuloFiles import ModuloFiles
|
5
|
+
|
6
|
+
|
7
|
+
class GestioneDom(object):
|
8
|
+
def __init__(self, percorsoNomefile: str | None, htmlString:str):
|
9
|
+
if percorsoNomefile is not None:
|
10
|
+
self.percorsoNomefile=percorsoNomefile
|
11
|
+
htmlString=ModuloFiles.readFileText(percorsoNomefile, True)
|
12
|
+
self.htmlString=htmlString
|
13
|
+
self.dom=self.__createObj()
|
14
|
+
|
15
|
+
@staticmethod
|
16
|
+
def innerHTML(tag):
|
17
|
+
"""
|
18
|
+
dato in input un tag html della classe BeautifulSoup, restituisce il codice html all'interno di questo tag
|
19
|
+
"""
|
20
|
+
return "".join([str(x) for x in tag.contents])
|
21
|
+
|
22
|
+
def selector(self,cssSelector:str):
|
23
|
+
"""
|
24
|
+
estrae tutti gli elementi che corrispondono al css selector
|
25
|
+
"""
|
26
|
+
elementi=self.dom.select(cssSelector)
|
27
|
+
return elementi
|
28
|
+
|
29
|
+
@staticmethod
|
30
|
+
def getAttributeValue(tag, nomeAttr:str):
|
31
|
+
oldValue=tag.attrs[nomeAttr]
|
32
|
+
return oldValue
|
33
|
+
@staticmethod
|
34
|
+
def setAttributeValue(tag, nomeAttr:str, value):
|
35
|
+
tag.attrs[nomeAttr]=value
|
36
|
+
return tag
|
37
|
+
|
38
|
+
def save(self):
|
39
|
+
htmlOut=str(self.dom).encode(ModuloStringhe.CODIFICA_UTF8)
|
40
|
+
with ModuloFiles.open(self.percorsoNomefile, "wb") as file:
|
41
|
+
file.write(htmlOut)
|
42
|
+
|
43
|
+
def __createObj(self)->BeautifulSoup:
|
44
|
+
return BeautifulSoup(self.htmlString, features="html.parser")
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from abc import ABC
|
2
|
+
from abc import abstractmethod
|
3
|
+
|
4
|
+
from modulitiz_micro.init.AbstractInit import AbstractInit
|
5
|
+
|
6
|
+
|
7
|
+
class AbstractBasicInit(AbstractInit,ABC):
|
8
|
+
@classmethod
|
9
|
+
@abstractmethod
|
10
|
+
def getCartellaBase(cls)->str:
|
11
|
+
"""
|
12
|
+
Ricavo la cartella dell'archivio del progetto attuale.
|
13
|
+
"""
|
14
|
+
|
15
|
+
@classmethod
|
16
|
+
@abstractmethod
|
17
|
+
def getProjectRoot(cls,nome: str) -> str:
|
18
|
+
"""
|
19
|
+
Restituisce il percorso assoluto di un progetto.
|
20
|
+
"""
|
21
|
+
|
22
|
+
@classmethod
|
23
|
+
@abstractmethod
|
24
|
+
def getProjectsRoot(cls) -> str:
|
25
|
+
"""
|
26
|
+
Restituisce il percorso assoluto dei progetti.
|
27
|
+
"""
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import threading
|
2
|
+
import time
|
3
|
+
from typing import Callable
|
4
|
+
|
5
|
+
from modulitiz_micro.sistema.ModuloSystem import ModuloSystem
|
6
|
+
|
7
|
+
if ModuloSystem.isWindows():
|
8
|
+
from pynput.keyboard import Key, Listener
|
9
|
+
|
10
|
+
|
11
|
+
class ModuloKeylogger(object):
|
12
|
+
IS_AVAILABLE=ModuloSystem.isWindows()
|
13
|
+
EXIT_KEY=None
|
14
|
+
EXIT_KEY_2=None
|
15
|
+
if IS_AVAILABLE:
|
16
|
+
EXIT_KEY=Key.pause
|
17
|
+
EXIT_KEY_2=Key.menu
|
18
|
+
|
19
|
+
__lastKeyPressed=None
|
20
|
+
__numKeyPressed=0
|
21
|
+
__callbackOnKeyPress=None
|
22
|
+
|
23
|
+
@staticmethod
|
24
|
+
def getTasto(key):
|
25
|
+
try:
|
26
|
+
tasto=key.char
|
27
|
+
except AttributeError:
|
28
|
+
tasto=key
|
29
|
+
if tasto is None:
|
30
|
+
return str(key.vk)
|
31
|
+
return str(tasto).replace("Key.","")
|
32
|
+
|
33
|
+
@classmethod
|
34
|
+
def start(cls,callbackOnKeyPress:Callable,runNewProcess:bool):
|
35
|
+
"""
|
36
|
+
Se la liberia non e' disponibile non verra' caricata, ad esempio se usi la cli
|
37
|
+
"""
|
38
|
+
# controllo se e' disponibile
|
39
|
+
if not cls.IS_AVAILABLE:
|
40
|
+
return
|
41
|
+
# lancio gli handler
|
42
|
+
cls.__callbackOnKeyPress=callbackOnKeyPress
|
43
|
+
if runNewProcess is True:
|
44
|
+
processo=threading.Thread(target=cls.__tStartListening,args=(cls.__onKeyPressHandler,cls.__onKeyReleaseHandler),daemon=True)
|
45
|
+
processo.start()
|
46
|
+
return
|
47
|
+
cls.__startListening(cls.__onKeyPressHandler,cls.__onKeyReleaseHandler)
|
48
|
+
|
49
|
+
@staticmethod
|
50
|
+
def __startListening(onKeyPressHandler,onKeyReleaseHandler):
|
51
|
+
with Listener(on_press=onKeyPressHandler,on_release=onKeyReleaseHandler) as listener:
|
52
|
+
listener.join()
|
53
|
+
@classmethod
|
54
|
+
def __tStartListening(cls,onKeyPressHandler,onKeyReleaseHandler):
|
55
|
+
cls.__startListening(onKeyPressHandler,onKeyReleaseHandler)
|
56
|
+
while True:
|
57
|
+
time.sleep(1)
|
58
|
+
|
59
|
+
#
|
60
|
+
#key handlers
|
61
|
+
#
|
62
|
+
@classmethod
|
63
|
+
def __onKeyPressHandler(cls,key):
|
64
|
+
if cls.__lastKeyPressed==key:
|
65
|
+
return
|
66
|
+
cls.__callbackOnKeyPress(key,cls.__numKeyPressed)
|
67
|
+
|
68
|
+
cls.__lastKeyPressed=key
|
69
|
+
cls.__numKeyPressed+=1
|
70
|
+
@classmethod
|
71
|
+
def __onKeyReleaseHandler(cls,key):
|
72
|
+
cls.__lastKeyPressed=None
|
73
|
+
cls.__numKeyPressed-=1
|