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.
Files changed (100) hide show
  1. modulitiz_micro/ModuloBase64.py +61 -0
  2. modulitiz_micro/ModuloColorText.py +35 -0
  3. modulitiz_micro/ModuloDate.py +295 -0
  4. modulitiz_micro/ModuloFunzioni.py +58 -0
  5. modulitiz_micro/ModuloListe.py +150 -0
  6. modulitiz_micro/ModuloMeteo.py +72 -0
  7. modulitiz_micro/ModuloNumeri.py +130 -0
  8. modulitiz_micro/ModuloPyinstaller.py +29 -0
  9. modulitiz_micro/ModuloSeriale.py +61 -0
  10. modulitiz_micro/ModuloStatistiche.py +31 -0
  11. modulitiz_micro/ModuloStringhe.py +180 -0
  12. modulitiz_micro/ModuloTarghe.py +46 -0
  13. modulitiz_micro/android/ModuloAndroid.py +18 -0
  14. modulitiz_micro/android/ModuloAndroidAdb.py +48 -0
  15. modulitiz_micro/android/ModuloAndroidSim.py +130 -0
  16. modulitiz_micro/android/beans/SmsBean.py +12 -0
  17. modulitiz_micro/android/enums/AndroidSmsTypeEnum.py +17 -0
  18. modulitiz_micro/database/AbstractDatabaseService.py +13 -0
  19. modulitiz_micro/database/AbstractSql.py +49 -0
  20. modulitiz_micro/database/ModuloSqlOracle.py +19 -0
  21. modulitiz_micro/database/ModuloSqlServer.py +50 -0
  22. modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -0
  23. modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -0
  24. modulitiz_micro/database/mysql/ModuloMysql.py +151 -0
  25. modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -0
  26. modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -0
  27. modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -0
  28. modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -0
  29. modulitiz_micro/eccezioni/EccezioneBase.py +7 -0
  30. modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -0
  31. modulitiz_micro/eccezioni/EccezioneRuntime.py +7 -0
  32. modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -0
  33. modulitiz_micro/eccezioni/EccezioneSoNonSupportato.py +7 -0
  34. modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -0
  35. modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -0
  36. modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -0
  37. modulitiz_micro/files/ModuloFiles.py +173 -0
  38. modulitiz_micro/files/ModuloLogging.py +69 -0
  39. modulitiz_micro/files/ModuloZip.py +42 -0
  40. modulitiz_micro/files/cache/CacheBean.py +5 -0
  41. modulitiz_micro/files/cache/CacheRam.py +29 -0
  42. modulitiz_micro/files/cache/DatabaseCache.py +91 -0
  43. modulitiz_micro/files/cache/decorators/cacheRam.py +26 -0
  44. modulitiz_micro/files/git/ModuloGit.py +15 -0
  45. modulitiz_micro/gestionedom/GestioneDom.py +44 -0
  46. modulitiz_micro/init/AbstractBasicInit.py +27 -0
  47. modulitiz_micro/init/AbstractInit.py +11 -0
  48. modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -0
  49. modulitiz_micro/keylogger/ModuloKeylogger.py +73 -0
  50. modulitiz_micro/multithreading/ModuloThread.py +26 -0
  51. modulitiz_micro/multithreading/ModuloThreadLogger.py +8 -0
  52. modulitiz_micro/multithreading/ModuloThreadWithCallbackError.py +25 -0
  53. modulitiz_micro/nlp/ModuloNlp.py +36 -0
  54. modulitiz_micro/nlp/ModuloNlpDateAndTime.py +59 -0
  55. modulitiz_micro/rete/ModuloEmail.py +69 -0
  56. modulitiz_micro/rete/ModuloNetworking.py +64 -0
  57. modulitiz_micro/rete/ModuloOpenVpn.py +15 -0
  58. modulitiz_micro/rete/http/ModuloHttp.py +114 -0
  59. modulitiz_micro/rete/http/ModuloHttpConnectionSafe.py +91 -0
  60. modulitiz_micro/rete/http/ModuloHttpUtils.py +66 -0
  61. modulitiz_micro/rete/http/beans/HttpResponseBean.py +5 -0
  62. modulitiz_micro/rete/http/decorators/catchAndRaiseHttpExceptions.py +22 -0
  63. modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -0
  64. modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -0
  65. modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -0
  66. modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -0
  67. modulitiz_micro/rete/ssl/ModuloSsl.py +56 -0
  68. modulitiz_micro/sistema/EnvVarsEnum.py +9 -0
  69. modulitiz_micro/sistema/ModuloEnvVars.py +34 -0
  70. modulitiz_micro/sistema/ModuloSystem.py +298 -0
  71. modulitiz_micro/sistema/ModuloSystemPipe.py +67 -0
  72. modulitiz_micro/social/telegram/ModuloTelegram.py +52 -0
  73. modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -0
  74. modulitiz_micro/util/beans/conf/AbstractBasicConfBean.py +11 -0
  75. modulitiz_micro/util/beans/conf/AbstractConfBean.py +16 -0
  76. modulitiz_micro/util/beans/fileconf/AbstractBasicFileConfBean.py +11 -0
  77. modulitiz_micro/util/beans/fileconf/AbstractFileConfBean.py +13 -0
  78. modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -0
  79. modulitiz_micro/util/beans/globalvar/AbstractGlobalVarBean.py +34 -0
  80. modulitiz_micro/util/decorators/noAwait.py +23 -0
  81. modulitiz_micro/util/pip/AbstractModuloPip.py +41 -0
  82. modulitiz_micro/util/pip/ModuloPip.py +49 -0
  83. modulitiz_micro/util/scheduler/AbstractScheduler.py +32 -0
  84. modulitiz_micro/util/spooler/AbstractSpooler.py +14 -0
  85. modulitiz_micro/util/spooler/Spooler.py +18 -0
  86. modulitiz_micro/util/spooler/beans/QueueBean.py +8 -0
  87. modulitiz_micro/util/spooler/decorators/spooler.py +49 -0
  88. modulitiz_micro/util/spooler/eccezioni/EccezioneSpooler.py +7 -0
  89. modulitiz_micro/util/spooler/eccezioni/EccezioneSpoolerFull.py +7 -0
  90. modulitiz_micro/util/unittesting/AbstractOverrideTestUtil.py +18 -0
  91. modulitiz_micro/util/unittesting/AbstractTestUtil.py +11 -0
  92. modulitiz_micro/util/unittesting/ModuloRunUnitTest.py +25 -0
  93. modulitiz_micro/util/wheel/ModuloBuildWheel.py +118 -0
  94. modulitiz_micro/util/wheel/ModuloToml.py +40 -0
  95. modulitiz_micro/util/wheel/ModuloWheel.py +12 -0
  96. modulitiz_micro-2.26.0.dist-info/LICENSE +21 -0
  97. modulitiz_micro-2.26.0.dist-info/METADATA +63 -0
  98. modulitiz_micro-2.26.0.dist-info/RECORD +100 -0
  99. modulitiz_micro-2.26.0.dist-info/WHEEL +5 -0
  100. modulitiz_micro-2.26.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,7 @@
1
+ class EccezioneRuntime(RuntimeError):
2
+
3
+ def __init__(self,*args,**kwargs):
4
+ super().__init__(*args)
5
+
6
+ def getMessage(self)->str:
7
+ return " ".join(self.args)
@@ -0,0 +1,7 @@
1
+ from modulitiz_micro.eccezioni.EccezioneBase import EccezioneBase
2
+
3
+
4
+ class EccezioneScheduler(EccezioneBase):
5
+
6
+ def __init__(self,*args,**kwargs):
7
+ super().__init__(*args,**kwargs)
@@ -0,0 +1,7 @@
1
+ from modulitiz_micro.eccezioni.EccezioneBase import EccezioneBase
2
+
3
+
4
+ class EccezioneSoNonSupportato(EccezioneBase):
5
+
6
+ def __init__(self,*args,**kwargs):
7
+ super().__init__(*args,**kwargs)
@@ -0,0 +1,8 @@
1
+ from modulitiz_micro.eccezioni.EccezioneBase import EccezioneBase
2
+
3
+
4
+ class EccezioneHttp(EccezioneBase):
5
+
6
+ def __init__(self,httpCode:int|None,*args,**kwargs):
7
+ super().__init__(*args,**kwargs)
8
+ self.httpCode=httpCode
@@ -0,0 +1,7 @@
1
+ from modulitiz_micro.eccezioni.http.EccezioneHttp import EccezioneHttp
2
+
3
+
4
+ class EccezioneHttp404(EccezioneHttp):
5
+
6
+ def __init__(self,):
7
+ super().__init__(404)
@@ -0,0 +1,7 @@
1
+ from modulitiz_micro.eccezioni.http.EccezioneHttp import EccezioneHttp
2
+
3
+
4
+ class EccezioneHttpGeneric(EccezioneHttp):
5
+
6
+ def __init__(self):
7
+ super().__init__(None)
@@ -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,5 @@
1
+ class CacheBean(object):
2
+ def __init__(self,valore,dataLastUpdate):
3
+ self.valore=valore
4
+ self.dataLastUpdate=dataLastUpdate
5
+
@@ -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,11 @@
1
+ from abc import ABC
2
+ from abc import abstractmethod
3
+
4
+
5
+ class AbstractInit(ABC):
6
+ @staticmethod
7
+ @abstractmethod
8
+ def getCartellaScriptCorrente(cls)->str:
9
+ """
10
+ Come recuperare la cartella dello script corrente.
11
+ """
@@ -0,0 +1,7 @@
1
+ from modulitiz_micro.eccezioni.EccezioneBase import EccezioneBase
2
+
3
+
4
+ class EccezioneKeyLogger(EccezioneBase):
5
+
6
+ def __init__(self):
7
+ super().__init__("Ricevuto comando da tastiera di chiusura programma")
@@ -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