modulitiz-micro 2.31.0__py311-none-any.whl → 2.32.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 (105) hide show
  1. modulitiz_micro/ModuloBase64.py +61 -61
  2. modulitiz_micro/ModuloColorText.py +35 -35
  3. modulitiz_micro/ModuloDate.py +295 -295
  4. modulitiz_micro/ModuloFunzioni.py +70 -58
  5. modulitiz_micro/ModuloListe.py +150 -150
  6. modulitiz_micro/ModuloMeteo.py +72 -72
  7. modulitiz_micro/ModuloNumeri.py +130 -130
  8. modulitiz_micro/ModuloPyinstaller.py +29 -29
  9. modulitiz_micro/ModuloSeriale.py +61 -61
  10. modulitiz_micro/ModuloStatistiche.py +31 -31
  11. modulitiz_micro/ModuloStringhe.py +180 -180
  12. modulitiz_micro/ModuloTarghe.py +46 -46
  13. modulitiz_micro/android/ModuloAndroid.py +18 -18
  14. modulitiz_micro/android/ModuloAndroidAdb.py +48 -48
  15. modulitiz_micro/android/ModuloAndroidSim.py +130 -130
  16. modulitiz_micro/android/beans/SmsBean.py +12 -12
  17. modulitiz_micro/android/enums/AndroidSmsTypeEnum.py +17 -17
  18. modulitiz_micro/database/AbstractDatabaseService.py +13 -13
  19. modulitiz_micro/database/AbstractSql.py +69 -69
  20. modulitiz_micro/database/ModuloSqlOracle.py +19 -19
  21. modulitiz_micro/database/ModuloSqlServer.py +43 -43
  22. modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -6
  23. modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -114
  24. modulitiz_micro/database/mysql/ModuloMysql.py +163 -163
  25. modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -47
  26. modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -6
  27. modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -114
  28. modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -82
  29. modulitiz_micro/eccezioni/EccezioneBase.py +7 -7
  30. modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -7
  31. modulitiz_micro/eccezioni/EccezioneRuntime.py +7 -7
  32. modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -7
  33. modulitiz_micro/eccezioni/EccezioneSoNonSupportato.py +7 -7
  34. modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -8
  35. modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -7
  36. modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -7
  37. modulitiz_micro/files/ModuloFiles.py +173 -173
  38. modulitiz_micro/files/ModuloLogging.py +69 -69
  39. modulitiz_micro/files/ModuloZip.py +42 -42
  40. modulitiz_micro/files/cache/CacheBean.py +5 -5
  41. modulitiz_micro/files/cache/CacheRam.py +29 -29
  42. modulitiz_micro/files/cache/DatabaseCache.py +91 -91
  43. modulitiz_micro/files/cache/decorators/cacheRam.py +26 -26
  44. modulitiz_micro/files/git/ModuloGit.py +20 -20
  45. modulitiz_micro/files/git/decorators/catchAndRaiseGitExceptions.py +19 -19
  46. modulitiz_micro/files/git/exceptions/EccezioneGit.py +7 -7
  47. modulitiz_micro/gestionedom/GestioneDom.py +44 -44
  48. modulitiz_micro/init/AbstractBasicInit.py +27 -27
  49. modulitiz_micro/init/AbstractInit.py +11 -11
  50. modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -7
  51. modulitiz_micro/keylogger/ModuloKeylogger.py +73 -73
  52. modulitiz_micro/{multithreading → multithread}/ModuloThread.py +26 -26
  53. modulitiz_micro/{multithreading → multithread}/ModuloThreadLogger.py +8 -8
  54. modulitiz_micro/{multithreading → multithread}/ModuloThreadWithCallbackError.py +25 -25
  55. modulitiz_micro/nlp/ModuloNlp.py +36 -36
  56. modulitiz_micro/nlp/ModuloNlpDateAndTime.py +59 -59
  57. modulitiz_micro/rete/ModuloNetworking.py +67 -67
  58. modulitiz_micro/rete/ModuloOpenVpn.py +15 -15
  59. modulitiz_micro/rete/email/EmailBean.py +5 -5
  60. modulitiz_micro/rete/email/ModuloEmail.py +90 -90
  61. modulitiz_micro/rete/http/ModuloHttp.py +115 -115
  62. modulitiz_micro/rete/http/ModuloHttpConnectionSafe.py +91 -91
  63. modulitiz_micro/rete/http/ModuloHttpUtils.py +69 -69
  64. modulitiz_micro/rete/http/beans/HttpResponseBean.py +5 -5
  65. modulitiz_micro/rete/http/decorators/catchAndRaiseHttpExceptions.py +22 -22
  66. modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -73
  67. modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -8
  68. modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -35
  69. modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -267
  70. modulitiz_micro/rete/ssl/ModuloSsl.py +56 -56
  71. modulitiz_micro/sistema/EnvVarsEnum.py +9 -9
  72. modulitiz_micro/sistema/ModuloEnvVars.py +34 -34
  73. modulitiz_micro/sistema/ModuloSystem.py +298 -298
  74. modulitiz_micro/sistema/ModuloSystemPipe.py +67 -67
  75. modulitiz_micro/social/telegram/ModuloTelegram.py +52 -52
  76. modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -26
  77. modulitiz_micro/util/beans/conf/AbstractBasicConfBean.py +11 -11
  78. modulitiz_micro/util/beans/conf/AbstractConfBean.py +16 -16
  79. modulitiz_micro/util/beans/fileconf/AbstractBasicFileConfBean.py +11 -11
  80. modulitiz_micro/util/beans/fileconf/AbstractFileConfBean.py +13 -13
  81. modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -15
  82. modulitiz_micro/util/beans/globalvar/AbstractGlobalVarBean.py +34 -34
  83. modulitiz_micro/util/decorators/noAwait.py +23 -23
  84. modulitiz_micro/util/pip/AbstractModuloPip.py +41 -41
  85. modulitiz_micro/util/pip/ModuloPip.py +49 -49
  86. modulitiz_micro/util/scheduler/AbstractScheduler.py +32 -32
  87. modulitiz_micro/util/spooler/AbstractSpooler.py +14 -14
  88. modulitiz_micro/util/spooler/Spooler.py +18 -18
  89. modulitiz_micro/util/spooler/beans/QueueBean.py +8 -8
  90. modulitiz_micro/util/spooler/decorators/spooler.py +49 -49
  91. modulitiz_micro/util/spooler/eccezioni/EccezioneSpooler.py +7 -7
  92. modulitiz_micro/util/spooler/eccezioni/EccezioneSpoolerFull.py +7 -7
  93. modulitiz_micro/util/unittesting/AbstractOverrideTestUtil.py +31 -31
  94. modulitiz_micro/util/unittesting/AbstractTestUtil.py +11 -11
  95. modulitiz_micro/util/unittesting/ModuloRunUnitTest.py +25 -25
  96. modulitiz_micro/util/wheel/ModuloBuildWheel.py +131 -121
  97. modulitiz_micro/util/wheel/ModuloCheckTestNamingConvention.py +86 -0
  98. modulitiz_micro/util/wheel/ModuloToml.py +40 -40
  99. modulitiz_micro/util/wheel/ModuloWheel.py +12 -12
  100. {modulitiz_micro-2.31.0.dist-info → modulitiz_micro-2.32.0.dist-info}/LICENSE +21 -21
  101. {modulitiz_micro-2.31.0.dist-info → modulitiz_micro-2.32.0.dist-info}/METADATA +64 -64
  102. modulitiz_micro-2.32.0.dist-info/RECORD +104 -0
  103. modulitiz_micro-2.31.0.dist-info/RECORD +0 -103
  104. {modulitiz_micro-2.31.0.dist-info → modulitiz_micro-2.32.0.dist-info}/WHEEL +0 -0
  105. {modulitiz_micro-2.31.0.dist-info → modulitiz_micro-2.32.0.dist-info}/top_level.txt +0 -0
@@ -1,90 +1,90 @@
1
- import smtplib
2
-
3
- from modulitiz_micro.ModuloDate import ModuloDate
4
- from modulitiz_micro.ModuloListe import ModuloListe
5
- from modulitiz_micro.ModuloStringhe import ModuloStringhe
6
-
7
-
8
- class ModuloEmail(object):
9
- SERVER_GOOGLE_INVIO=('smtp.gmail.com',smtplib.SMTP_SSL_PORT)
10
- SERVER_VIRGILIO_INVIO=('out.virgilio.it',smtplib.SMTP_SSL_PORT)
11
-
12
- def __init__(self,credenzialiServer:tuple,user:str|None,password:str|None,isDebug:bool=False):
13
- self.credenzialiServer=credenzialiServer
14
- self.isDebug=isDebug
15
- self.connEmail=None
16
- self.user=user
17
- self.password=password
18
- self.isLogged=False
19
-
20
- def login(self,user:str|None=None,password:str|None=None):
21
- if self.isLogged:
22
- return
23
- # controllo se usare le credenziali dei parametri o quelle della classe
24
- if user is not None:
25
- self.user=user
26
- if password is not None:
27
- self.password=password
28
- # mi collego
29
- self.connEmail=smtplib.SMTP_SSL(*self.credenzialiServer)
30
- if self.isDebug:
31
- self.connEmail.set_debuglevel(1)
32
- # se serve setto l'autenticazione
33
- if self.user is not None and self.password is not None:
34
- self.connEmail.login(self.user,self.password)
35
- self.isLogged=True
36
-
37
- def sendWithLoginAndClose(self,destinatari:str|list|tuple, oggetto:str, messaggio:str,
38
- isHtml:bool)->dict:
39
- # controllo se gia' loggato
40
- if self.isLogged is False:
41
- self.login(self.user,self.password)
42
- # invio email
43
- try:
44
- errors=self.send(None,destinatari,oggetto,messaggio,isHtml)
45
- except Exception as ex:
46
- self.close()
47
- raise ex
48
- # chiudo la connessione
49
- self.close()
50
- return errors
51
-
52
- def send(self, mittente:str|None,destinatari:str|list|tuple, oggetto:str, messaggio:str,
53
- isHtml:bool, dataInvio=ModuloDate.now(), cc=None, ccn=None)->dict:
54
- # controllo i parametri
55
- dataInvio=ModuloDate.dateToString(dataInvio)
56
- if isinstance(destinatari, str):
57
- destinatari=[destinatari]
58
- if mittente is None:
59
- mittente=self.user
60
- domain=self.user.split("@")[-1]
61
- messageId=f"{ModuloDate.getSecs()}@{domain}"
62
- # creo il messaggio
63
- message=f"""Date: {dataInvio}
64
- From: {mittente}
65
- Subject: {oggetto}
66
- To: {", ".join(destinatari)}
67
- Message-ID: <{messageId}>
68
- """
69
- if not ModuloListe.isEmpty(cc):
70
- message+=("Cc: "+", ".join(cc))+"\n"
71
- if not ModuloListe.isEmpty(ccn):
72
- message+=("Bcc: "+", ".join(ccn))+"\n"
73
- message+="Content-Type: text/html;\n"
74
- # converto il messaggio in formato html
75
- if not isHtml:
76
- messaggio=ModuloStringhe.normalizzaEol(messaggio).replace("\n","<br/>\n")
77
- messaggio=messaggio.encode(ModuloStringhe.CODIFICA_ASCII,"xmlcharrefreplace").decode(ModuloStringhe.CODIFICA_UTF8)
78
- message+="\n"+messaggio
79
- # invio la mail
80
- try:
81
- return self.connEmail.sendmail(mittente,destinatari,message)
82
- except smtplib.SMTPServerDisconnected as ex:
83
- return {"":str(ex)}
84
-
85
- def close(self):
86
- if self.connEmail is None:
87
- return
88
- self.connEmail.quit()
89
- self.connEmail=None
90
- self.isLogged=False
1
+ import smtplib
2
+
3
+ from modulitiz_micro.ModuloDate import ModuloDate
4
+ from modulitiz_micro.ModuloListe import ModuloListe
5
+ from modulitiz_micro.ModuloStringhe import ModuloStringhe
6
+
7
+
8
+ class ModuloEmail(object):
9
+ SERVER_GOOGLE_INVIO=('smtp.gmail.com',smtplib.SMTP_SSL_PORT)
10
+ SERVER_VIRGILIO_INVIO=('out.virgilio.it',smtplib.SMTP_SSL_PORT)
11
+
12
+ def __init__(self,credenzialiServer:tuple,user:str|None,password:str|None,isDebug:bool=False):
13
+ self.credenzialiServer=credenzialiServer
14
+ self.isDebug=isDebug
15
+ self.connEmail=None
16
+ self.user=user
17
+ self.password=password
18
+ self.isLogged=False
19
+
20
+ def login(self,user:str|None=None,password:str|None=None):
21
+ if self.isLogged:
22
+ return
23
+ # controllo se usare le credenziali dei parametri o quelle della classe
24
+ if user is not None:
25
+ self.user=user
26
+ if password is not None:
27
+ self.password=password
28
+ # mi collego
29
+ self.connEmail=smtplib.SMTP_SSL(*self.credenzialiServer)
30
+ if self.isDebug:
31
+ self.connEmail.set_debuglevel(1)
32
+ # se serve setto l'autenticazione
33
+ if self.user is not None and self.password is not None:
34
+ self.connEmail.login(self.user,self.password)
35
+ self.isLogged=True
36
+
37
+ def sendWithLoginAndClose(self,destinatari:str|list|tuple, oggetto:str, messaggio:str,
38
+ isHtml:bool)->dict:
39
+ # controllo se gia' loggato
40
+ if self.isLogged is False:
41
+ self.login(self.user,self.password)
42
+ # invio email
43
+ try:
44
+ errors=self.send(None,destinatari,oggetto,messaggio,isHtml)
45
+ except Exception as ex:
46
+ self.close()
47
+ raise ex
48
+ # chiudo la connessione
49
+ self.close()
50
+ return errors
51
+
52
+ def send(self, mittente:str|None,destinatari:str|list|tuple, oggetto:str, messaggio:str,
53
+ isHtml:bool, dataInvio=ModuloDate.now(), cc=None, ccn=None)->dict:
54
+ # controllo i parametri
55
+ dataInvio=ModuloDate.dateToString(dataInvio)
56
+ if isinstance(destinatari, str):
57
+ destinatari=[destinatari]
58
+ if mittente is None:
59
+ mittente=self.user
60
+ domain=self.user.split("@")[-1]
61
+ messageId=f"{ModuloDate.getSecs()}@{domain}"
62
+ # creo il messaggio
63
+ message=f"""Date: {dataInvio}
64
+ From: {mittente}
65
+ Subject: {oggetto}
66
+ To: {", ".join(destinatari)}
67
+ Message-ID: <{messageId}>
68
+ """
69
+ if not ModuloListe.isEmpty(cc):
70
+ message+=("Cc: "+", ".join(cc))+"\n"
71
+ if not ModuloListe.isEmpty(ccn):
72
+ message+=("Bcc: "+", ".join(ccn))+"\n"
73
+ message+="Content-Type: text/html;\n"
74
+ # converto il messaggio in formato html
75
+ if not isHtml:
76
+ messaggio=ModuloStringhe.normalizzaEol(messaggio).replace("\n","<br/>\n")
77
+ messaggio=messaggio.encode(ModuloStringhe.CODIFICA_ASCII,"xmlcharrefreplace").decode(ModuloStringhe.CODIFICA_UTF8)
78
+ message+="\n"+messaggio
79
+ # invio la mail
80
+ try:
81
+ return self.connEmail.sendmail(mittente,destinatari,message)
82
+ except smtplib.SMTPServerDisconnected as ex:
83
+ return {"":str(ex)}
84
+
85
+ def close(self):
86
+ if self.connEmail is None:
87
+ return
88
+ self.connEmail.quit()
89
+ self.connEmail=None
90
+ self.isLogged=False
@@ -1,115 +1,115 @@
1
- import gzip
2
- import logging
3
- import ssl
4
- import urllib
5
- from urllib.parse import urlencode
6
- from urllib.request import Request
7
-
8
- import brotli
9
-
10
- from modulitiz_micro.ModuloBase64 import ModuloBase64
11
- from modulitiz_micro.ModuloStringhe import ModuloStringhe
12
- from modulitiz_micro.eccezioni.EccezioneRuntime import EccezioneRuntime
13
- from modulitiz_micro.files.ModuloLogging import ModuloLogging
14
- from modulitiz_micro.rete.http.ModuloHttpConnectionSafe import ModuloHttpConnectionSafe
15
- from modulitiz_micro.rete.http.beans.HttpResponseBean import HttpResponseBean
16
- from modulitiz_micro.rete.http.decorators.catchAndRaiseHttpExceptions import catchAndRaiseHttpExceptions
17
-
18
-
19
- class ModuloHttp(object):
20
- """
21
- Utility per gestione richieste di rete secondo il protocollo HTTP.
22
- """
23
-
24
- UA_ANDROID="Mozilla/5.0 (Linux; Android 12.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Mobile Safari/537.36"
25
-
26
- UA_MACOS_CHROME="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
27
- UA_WINDOWS_CHROME="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
28
- UA_WINDOWS_FIREFOX="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
29
-
30
- UAS=[UA_MACOS_CHROME,UA_WINDOWS_CHROME,UA_WINDOWS_FIREFOX]
31
-
32
- URL_CERCA_GOOGLE="https://www.google.it/search?q="
33
- # https://ipecho.net/plain removed because it can return either ipv4 or ipv6 depending on your ISP/Internet connection
34
- URLS_GET_IPV4=('https://ipinfo.io/ip','https://api.ipify.org','https://ipv4.seeip.org')
35
-
36
- REGEX_IPV4_ADDRESS=r"\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b"
37
-
38
- STATUS_OK=200
39
- STATUS_OK_PARTIAL_CONTENT=206
40
-
41
-
42
- def __init__(self,url:str,logger:ModuloLogging|None,useProxy:bool=False):
43
- logging.getLogger("urllib3").propagate=False
44
-
45
- self.__requestObj=Request(url)
46
- self.__logger=logger
47
-
48
- self.setUserAgent(self.UA_WINDOWS_FIREFOX)
49
- self.addHeader('Accept-Encoding','gzip, deflate, br') # questo serve per ridurre la dimensione della risposta
50
- if useProxy is True:
51
- self.addHeader('Origin','localhost')
52
- self.connectionSafe=ModuloHttpConnectionSafe(self.__logger)
53
- self.postData=None
54
-
55
- def doGet(self,retries:int,ignoreCerts:bool=False)->HttpResponseBean:
56
- """
57
- Esegue una richiesta di tipo GET
58
- """
59
- if retries==0:
60
- return self.__getOrPost(True,ignoreCerts)
61
- return self.connectionSafe.run(retries,0,self.__getOrPost,True,ignoreCerts)
62
-
63
- def doPost(self, postData:dict, retries:int,ignoreCerts:bool=False)->HttpResponseBean:
64
- """
65
- Esegue una richiesta di tipo POST
66
- """
67
- self.postData=postData
68
- if retries==0:
69
- return self.__getOrPost(False,ignoreCerts)
70
- return self.connectionSafe.run(retries,0,self.__getOrPost,False,ignoreCerts)
71
-
72
- @catchAndRaiseHttpExceptions
73
- def __getOrPost(self, isGet:bool,ignoreCerts:bool)->HttpResponseBean:
74
- if not isGet:
75
- postData=urlencode(self.postData).encode()
76
- self.__requestObj.data=postData
77
- # ignoro certificati
78
- ctx=None
79
- if ignoreCerts:
80
- ctx=ssl.create_default_context()
81
- ctx.check_hostname=False
82
- ctx.verify_mode=ssl.CERT_NONE
83
- with urllib.request.urlopen(self.__requestObj,context=ctx) as response:
84
- responseBody=response.read()
85
- responseHeaders=response.info()
86
- status=response.status
87
- # se il server manda il contenuto in formato compresso lo decomprimo
88
- contentEncoding=responseHeaders.get('Content-Encoding')
89
- if contentEncoding=="gzip":
90
- responseBody=gzip.decompress(responseBody)
91
- elif contentEncoding=="br":
92
- responseBody=brotli.decompress(responseBody)
93
- elif contentEncoding is not None and contentEncoding!= "deflate":
94
- raise EccezioneRuntime("Codifica '"+contentEncoding+"' non gestita.")
95
- return HttpResponseBean(status,responseBody,responseHeaders)
96
-
97
- # opzioni aggiuntive
98
- def addHeader(self,nome:str,valore):
99
- if ModuloStringhe.isEmpty(valore):
100
- return
101
- self.__requestObj.add_header(nome,valore)
102
-
103
- def setUserAgent(self,userAgent:str=None):
104
- if ModuloStringhe.isEmpty(userAgent):
105
- userAgent=self.UA_ANDROID
106
- else:
107
- userAgent=userAgent.strip()
108
- self.addHeader('User-Agent',userAgent)
109
-
110
- def setDownloadRange(self,inizio:int,fine:int):
111
- self.addHeader('Range',"bytes="+str(inizio)+"-"+str(fine))
112
-
113
- def setAuthenticationBasic(self,username:str,password:str):
114
- authStr=ModuloBase64.codificaStr('%s:%s' % (username, password))
115
- self.addHeader('Authorization',"Basic "+authStr)
1
+ import gzip
2
+ import logging
3
+ import ssl
4
+ import urllib
5
+ from urllib.parse import urlencode
6
+ from urllib.request import Request
7
+
8
+ import brotli
9
+
10
+ from modulitiz_micro.ModuloBase64 import ModuloBase64
11
+ from modulitiz_micro.ModuloStringhe import ModuloStringhe
12
+ from modulitiz_micro.eccezioni.EccezioneRuntime import EccezioneRuntime
13
+ from modulitiz_micro.files.ModuloLogging import ModuloLogging
14
+ from modulitiz_micro.rete.http.ModuloHttpConnectionSafe import ModuloHttpConnectionSafe
15
+ from modulitiz_micro.rete.http.beans.HttpResponseBean import HttpResponseBean
16
+ from modulitiz_micro.rete.http.decorators.catchAndRaiseHttpExceptions import catchAndRaiseHttpExceptions
17
+
18
+
19
+ class ModuloHttp(object):
20
+ """
21
+ Utility per gestione richieste di rete secondo il protocollo HTTP.
22
+ """
23
+
24
+ UA_ANDROID="Mozilla/5.0 (Linux; Android 12.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Mobile Safari/537.36"
25
+
26
+ UA_MACOS_CHROME="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
27
+ UA_WINDOWS_CHROME="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
28
+ UA_WINDOWS_FIREFOX="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
29
+
30
+ UAS=[UA_MACOS_CHROME,UA_WINDOWS_CHROME,UA_WINDOWS_FIREFOX]
31
+
32
+ URL_CERCA_GOOGLE="https://www.google.it/search?q="
33
+ # https://ipecho.net/plain removed because it can return either ipv4 or ipv6 depending on your ISP/Internet connection
34
+ URLS_GET_IPV4=('https://ipinfo.io/ip','https://api.ipify.org','https://ipv4.seeip.org')
35
+
36
+ REGEX_IPV4_ADDRESS=r"\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b"
37
+
38
+ STATUS_OK=200
39
+ STATUS_OK_PARTIAL_CONTENT=206
40
+
41
+
42
+ def __init__(self,url:str,logger:ModuloLogging|None,useProxy:bool=False):
43
+ logging.getLogger("urllib3").propagate=False
44
+
45
+ self.__requestObj=Request(url)
46
+ self.__logger=logger
47
+
48
+ self.setUserAgent(self.UA_WINDOWS_FIREFOX)
49
+ self.addHeader('Accept-Encoding','gzip, deflate, br') # questo serve per ridurre la dimensione della risposta
50
+ if useProxy is True:
51
+ self.addHeader('Origin','localhost')
52
+ self.connectionSafe=ModuloHttpConnectionSafe(self.__logger)
53
+ self.postData=None
54
+
55
+ def doGet(self,retries:int,ignoreCerts:bool=False)->HttpResponseBean:
56
+ """
57
+ Esegue una richiesta di tipo GET
58
+ """
59
+ if retries==0:
60
+ return self.__getOrPost(True,ignoreCerts)
61
+ return self.connectionSafe.run(retries,0,self.__getOrPost,True,ignoreCerts)
62
+
63
+ def doPost(self, postData:dict, retries:int,ignoreCerts:bool=False)->HttpResponseBean:
64
+ """
65
+ Esegue una richiesta di tipo POST
66
+ """
67
+ self.postData=postData
68
+ if retries==0:
69
+ return self.__getOrPost(False,ignoreCerts)
70
+ return self.connectionSafe.run(retries,0,self.__getOrPost,False,ignoreCerts)
71
+
72
+ @catchAndRaiseHttpExceptions
73
+ def __getOrPost(self, isGet:bool,ignoreCerts:bool)->HttpResponseBean:
74
+ if not isGet:
75
+ postData=urlencode(self.postData).encode()
76
+ self.__requestObj.data=postData
77
+ # ignoro certificati
78
+ ctx=None
79
+ if ignoreCerts:
80
+ ctx=ssl.create_default_context()
81
+ ctx.check_hostname=False
82
+ ctx.verify_mode=ssl.CERT_NONE
83
+ with urllib.request.urlopen(self.__requestObj,context=ctx) as response:
84
+ responseBody=response.read()
85
+ responseHeaders=response.info()
86
+ status=response.status
87
+ # se il server manda il contenuto in formato compresso lo decomprimo
88
+ contentEncoding=responseHeaders.get('Content-Encoding')
89
+ if contentEncoding=="gzip":
90
+ responseBody=gzip.decompress(responseBody)
91
+ elif contentEncoding=="br":
92
+ responseBody=brotli.decompress(responseBody)
93
+ elif contentEncoding is not None and contentEncoding!= "deflate":
94
+ raise EccezioneRuntime("Codifica '"+contentEncoding+"' non gestita.")
95
+ return HttpResponseBean(status,responseBody,responseHeaders)
96
+
97
+ # opzioni aggiuntive
98
+ def addHeader(self,nome:str,valore):
99
+ if ModuloStringhe.isEmpty(valore):
100
+ return
101
+ self.__requestObj.add_header(nome,valore)
102
+
103
+ def setUserAgent(self,userAgent:str=None):
104
+ if ModuloStringhe.isEmpty(userAgent):
105
+ userAgent=self.UA_ANDROID
106
+ else:
107
+ userAgent=userAgent.strip()
108
+ self.addHeader('User-Agent',userAgent)
109
+
110
+ def setDownloadRange(self,inizio:int,fine:int):
111
+ self.addHeader('Range',"bytes="+str(inizio)+"-"+str(fine))
112
+
113
+ def setAuthenticationBasic(self,username:str,password:str):
114
+ authStr=ModuloBase64.codificaStr('%s:%s' % (username, password))
115
+ self.addHeader('Authorization',"Basic "+authStr)
@@ -1,91 +1,91 @@
1
- import socket
2
- import time
3
- from urllib.error import URLError
4
-
5
- import requests
6
-
7
- from modulitiz_micro.ModuloFunzioni import ModuloFunzioni
8
- from modulitiz_micro.ModuloStringhe import ModuloStringhe
9
- from modulitiz_micro.eccezioni.http.EccezioneHttpGeneric import EccezioneHttpGeneric
10
- from modulitiz_micro.files.ModuloLogging import ModuloLogging
11
-
12
-
13
- class ModuloHttpConnectionSafe(object):
14
- """
15
- Utility che serve per gestire eventuali errori di rete e riprova a fare la richiesta in caso di errore
16
- """
17
-
18
- def __init__(self,logger: ModuloLogging|None):
19
- self.__logger=logger
20
-
21
- self.isLoggerEnabled=self.__logger is not None
22
- self.contaTentativi=0
23
- self.nomeFunzChiamanti=[]
24
- self.msgFunzChiamanti=None
25
-
26
- def run(self, retries:int,retriesBeforeNotify: int, funzione, *args,**kwargs):
27
- """
28
- se 'retries' e' = -1 allora continua a provare all'infinito
29
- se 'retriesBeforeNotify' e' = 0 allora in caso di errore di rete notifica subito
30
- """
31
- ritorno = None
32
- while self._buildIf(self.contaTentativi,retries):
33
- try:
34
- ritorno = funzione(*args,**kwargs)
35
- self.contaTentativi = -1
36
- except (EccezioneHttpGeneric,ConnectionError, TimeoutError, URLError,
37
- requests.exceptions.ConnectionError, socket.gaierror) as ex:
38
- # controllo il tipo di errore
39
- ModuloHttpConnectionSafe.__checkCodeExc(ex)
40
- # gestisco l'assenza di connessione
41
- self.contaTentativi += 1
42
- # scrivo un messaggio di avviso
43
- if retriesBeforeNotify == 0 or self.contaTentativi >= retriesBeforeNotify:
44
- self.__buildMsgAndNotify()
45
- ModuloHttpConnectionSafe.__dynamicPauseOrRaiseExc(self.contaTentativi, ex)
46
- self.contaTentativi=0
47
- self.nomeFunzChiamanti.clear()
48
- return ritorno
49
-
50
- @staticmethod
51
- def _buildIf(contaTentativi:int,retries:int)->bool:
52
- return contaTentativi >= 0 and (retries==-1 or contaTentativi<retries)
53
-
54
- def __buildMsgAndNotify(self):
55
- if not self.nomeFunzChiamanti:
56
- self.msgFunzChiamanti="Errore di connessione nella funzione "+ModuloFunzioni.getFunctionName(1)+"()"
57
- i=0
58
- while -1<i<2:
59
- nomeFunz = ModuloFunzioni.getFunctionName(i+2)
60
- if not ModuloStringhe.isEmpty(nomeFunz):
61
- self.msgFunzChiamanti += f", chiamata da {nomeFunz}()"
62
- i+=1
63
- else:
64
- i=-1
65
- msg=self.msgFunzChiamanti+f"; tentativo numero: {self.contaTentativi}"
66
- if self.isLoggerEnabled:
67
- self.__logger.error(msg)
68
- else:
69
- print(msg)
70
-
71
- @staticmethod
72
- def __checkCodeExc(ex: Exception):
73
- try:
74
- codiceErrore = ex.code
75
- except AttributeError:
76
- codiceErrore = 0
77
- if codiceErrore in (404, 500):
78
- raise ex
79
-
80
- @staticmethod
81
- def __dynamicPauseOrRaiseExc(contaTentativi: int, ex: Exception):
82
- if 0 < contaTentativi <= 20:
83
- time.sleep(10)
84
- elif 20 < contaTentativi <= 30:
85
- time.sleep(60)
86
- elif 20 < contaTentativi <= 50:
87
- time.sleep(60 * 2)
88
- elif 50 < contaTentativi <= 100:
89
- time.sleep(60 * 5)
90
- else:
91
- raise ex
1
+ import socket
2
+ import time
3
+ from urllib.error import URLError
4
+
5
+ import requests
6
+
7
+ from modulitiz_micro.ModuloFunzioni import ModuloFunzioni
8
+ from modulitiz_micro.ModuloStringhe import ModuloStringhe
9
+ from modulitiz_micro.eccezioni.http.EccezioneHttpGeneric import EccezioneHttpGeneric
10
+ from modulitiz_micro.files.ModuloLogging import ModuloLogging
11
+
12
+
13
+ class ModuloHttpConnectionSafe(object):
14
+ """
15
+ Utility che serve per gestire eventuali errori di rete e riprova a fare la richiesta in caso di errore
16
+ """
17
+
18
+ def __init__(self,logger: ModuloLogging|None):
19
+ self.__logger=logger
20
+
21
+ self.isLoggerEnabled=self.__logger is not None
22
+ self.contaTentativi=0
23
+ self.nomeFunzChiamanti=[]
24
+ self.msgFunzChiamanti=None
25
+
26
+ def run(self, retries:int,retriesBeforeNotify: int, funzione, *args,**kwargs):
27
+ """
28
+ se 'retries' e' = -1 allora continua a provare all'infinito
29
+ se 'retriesBeforeNotify' e' = 0 allora in caso di errore di rete notifica subito
30
+ """
31
+ ritorno = None
32
+ while self._buildIf(self.contaTentativi,retries):
33
+ try:
34
+ ritorno = funzione(*args,**kwargs)
35
+ self.contaTentativi = -1
36
+ except (EccezioneHttpGeneric,ConnectionError, TimeoutError, URLError,
37
+ requests.exceptions.ConnectionError, socket.gaierror) as ex:
38
+ # controllo il tipo di errore
39
+ ModuloHttpConnectionSafe.__checkCodeExc(ex)
40
+ # gestisco l'assenza di connessione
41
+ self.contaTentativi += 1
42
+ # scrivo un messaggio di avviso
43
+ if retriesBeforeNotify == 0 or self.contaTentativi >= retriesBeforeNotify:
44
+ self.__buildMsgAndNotify()
45
+ ModuloHttpConnectionSafe.__dynamicPauseOrRaiseExc(self.contaTentativi, ex)
46
+ self.contaTentativi=0
47
+ self.nomeFunzChiamanti.clear()
48
+ return ritorno
49
+
50
+ @staticmethod
51
+ def _buildIf(contaTentativi:int,retries:int)->bool:
52
+ return contaTentativi >= 0 and (retries==-1 or contaTentativi<retries)
53
+
54
+ def __buildMsgAndNotify(self):
55
+ if not self.nomeFunzChiamanti:
56
+ self.msgFunzChiamanti="Errore di connessione nella funzione "+ModuloFunzioni.getFunctionName(1)+"()"
57
+ i=0
58
+ while -1<i<2:
59
+ nomeFunz = ModuloFunzioni.getFunctionName(i+2)
60
+ if not ModuloStringhe.isEmpty(nomeFunz):
61
+ self.msgFunzChiamanti += f", chiamata da {nomeFunz}()"
62
+ i+=1
63
+ else:
64
+ i=-1
65
+ msg=self.msgFunzChiamanti+f"; tentativo numero: {self.contaTentativi}"
66
+ if self.isLoggerEnabled:
67
+ self.__logger.error(msg)
68
+ else:
69
+ print(msg)
70
+
71
+ @staticmethod
72
+ def __checkCodeExc(ex: Exception):
73
+ try:
74
+ codiceErrore = ex.code
75
+ except AttributeError:
76
+ codiceErrore = 0
77
+ if codiceErrore in (404, 500):
78
+ raise ex
79
+
80
+ @staticmethod
81
+ def __dynamicPauseOrRaiseExc(contaTentativi: int, ex: Exception):
82
+ if 0 < contaTentativi <= 20:
83
+ time.sleep(10)
84
+ elif 20 < contaTentativi <= 30:
85
+ time.sleep(60)
86
+ elif 20 < contaTentativi <= 50:
87
+ time.sleep(60 * 2)
88
+ elif 50 < contaTentativi <= 100:
89
+ time.sleep(60 * 5)
90
+ else:
91
+ raise ex