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,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
- # check if already logged
40
- if not self.isLogged:
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_nano.ModuloDate import ModuloDate
4
+ from modulitiz_nano.ModuloListe import ModuloListe
5
+ from modulitiz_nano.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
+ # check if already logged
40
+ if not self.isLogged:
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,119 +1,119 @@
1
- import gzip
2
- import json
3
- import logging
4
- import ssl
5
- import urllib
6
- from urllib.parse import urlencode
7
- from urllib.request import Request
8
-
9
- import brotli
10
-
11
- from modulitiz_micro.ModuloBase64 import ModuloBase64
12
- from modulitiz_micro.ModuloStringhe import ModuloStringhe
13
- from modulitiz_micro.eccezioni.EccezioneRuntime import EccezioneRuntime
14
- from modulitiz_micro.files.ModuloLogging import ModuloLogging
15
- from modulitiz_micro.rete.http.ModuloHttpConnectionSafe import ModuloHttpConnectionSafe
16
- from modulitiz_micro.rete.http.beans.HttpResponseBean import HttpResponseBean
17
- from modulitiz_micro.rete.http.decorators.catchAndRaiseHttpExceptions import catchAndRaiseHttpExceptions
18
-
19
-
20
- class ModuloHttp(object):
21
- """
22
- Utility per gestione richieste di rete secondo il protocollo HTTP.
23
- """
24
-
25
- 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"
26
-
27
- 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"
28
- 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"
29
- UA_WINDOWS_FIREFOX="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
30
-
31
- UAS=[UA_MACOS_CHROME,UA_WINDOWS_CHROME,UA_WINDOWS_FIREFOX]
32
-
33
- URL_CERCA_GOOGLE="https://www.google.it/search?q="
34
- # https://ipecho.net/plain removed because it can return either ipv4 or ipv6 depending on your ISP/Internet connection
35
- URLS_GET_IPV4=('https://ipinfo.io/ip','https://api.ipify.org','https://ipv4.seeip.org')
36
-
37
- 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"
38
-
39
- STATUS_OK=200
40
- STATUS_OK_PARTIAL_CONTENT=206
41
-
42
-
43
- def __init__(self,url:str,logger:ModuloLogging|None,useProxy:bool=False):
44
- logging.getLogger("urllib3").propagate=False
45
-
46
- self.__requestObj=Request(url)
47
- self.__logger=logger
48
-
49
- self.setUserAgent(self.UA_WINDOWS_FIREFOX)
50
- self.addHeader('Accept-Encoding','gzip, deflate, br') # questo serve per ridurre la dimensione della risposta
51
- if useProxy:
52
- self.addHeader('Origin','localhost')
53
- self.connectionSafe=ModuloHttpConnectionSafe(self.__logger)
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(ignoreCerts)
61
- return self.connectionSafe.run(retries,0,self.__getOrPost,ignoreCerts)
62
-
63
- def doPost(self, postData:dict, asJson:bool, retries:int,ignoreCerts:bool=False)->HttpResponseBean:
64
- """
65
- Esegue una richiesta di tipo POST
66
- """
67
- if not asJson:
68
- postDataEncoded=urlencode(postData)
69
- else:
70
- postDataEncoded=json.dumps(postData)
71
- self.addHeader("Content-Type","application/json; charset=utf-8")
72
- postDataEncoded=postDataEncoded.encode()
73
- self.__requestObj.data=postDataEncoded
74
- if retries==0:
75
- return self.__getOrPost(ignoreCerts)
76
- return self.connectionSafe.run(retries,0,self.__getOrPost,ignoreCerts)
77
-
78
- @catchAndRaiseHttpExceptions
79
- def __getOrPost(self, ignoreCerts:bool)->HttpResponseBean:
80
- # ignoro certificati
81
- ctx=None
82
- if ignoreCerts:
83
- ctx=ssl.create_default_context()
84
- ctx.check_hostname=False
85
- ctx.verify_mode=ssl.CERT_NONE
86
- # send request
87
- with urllib.request.urlopen(self.__requestObj,context=ctx) as response:
88
- responseBody=response.read()
89
- responseHeaders=response.info()
90
- status=response.status
91
- # se il server manda il contenuto in formato compresso lo decomprimo
92
- contentEncoding=responseHeaders.get('Content-Encoding')
93
- if contentEncoding=="gzip":
94
- responseBody=gzip.decompress(responseBody)
95
- elif contentEncoding=="br":
96
- responseBody=brotli.decompress(responseBody)
97
- elif contentEncoding is not None and contentEncoding!= "deflate":
98
- raise EccezioneRuntime("Codifica '"+contentEncoding+"' non gestita.")
99
- return HttpResponseBean(status,responseBody,responseHeaders)
100
-
101
- # opzioni aggiuntive
102
- def addHeader(self,nome:str,valore):
103
- if ModuloStringhe.isEmpty(valore):
104
- return
105
- self.__requestObj.add_header(nome,valore)
106
-
107
- def setUserAgent(self,userAgent:str=None):
108
- if ModuloStringhe.isEmpty(userAgent):
109
- userAgent=self.UA_ANDROID
110
- else:
111
- userAgent=userAgent.strip()
112
- self.addHeader('User-Agent',userAgent)
113
-
114
- def setDownloadRange(self,inizio:int,fine:int):
115
- self.addHeader('Range',"bytes="+str(inizio)+"-"+str(fine))
116
-
117
- def setAuthenticationBasic(self,username:str,password:str):
118
- authStr=ModuloBase64.codificaStr('%s:%s' % (username, password))
119
- self.addHeader('Authorization',"Basic "+authStr)
1
+ import gzip
2
+ import json
3
+ import logging
4
+ import ssl
5
+ import urllib
6
+ from urllib.parse import urlencode
7
+ from urllib.request import Request
8
+
9
+ import brotli
10
+
11
+ from modulitiz_nano.ModuloBase64 import ModuloBase64
12
+ from modulitiz_nano.ModuloStringhe import ModuloStringhe
13
+ from modulitiz_nano.eccezioni.EccezioneRuntime import EccezioneRuntime
14
+ from modulitiz_nano.files.ModuloLogging import ModuloLogging
15
+ from modulitiz_micro.rete.http.ModuloHttpConnectionSafe import ModuloHttpConnectionSafe
16
+ from modulitiz_micro.rete.http.beans.HttpResponseBean import HttpResponseBean
17
+ from modulitiz_micro.rete.http.decorators.catchAndRaiseHttpExceptions import catchAndRaiseHttpExceptions
18
+
19
+
20
+ class ModuloHttp(object):
21
+ """
22
+ Utility per gestione richieste di rete secondo il protocollo HTTP.
23
+ """
24
+
25
+ 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"
26
+
27
+ 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"
28
+ 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"
29
+ UA_WINDOWS_FIREFOX="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
30
+
31
+ UAS=[UA_MACOS_CHROME,UA_WINDOWS_CHROME,UA_WINDOWS_FIREFOX]
32
+
33
+ URL_CERCA_GOOGLE="https://www.google.it/search?q="
34
+ # https://ipecho.net/plain removed because it can return either ipv4 or ipv6 depending on your ISP/Internet connection
35
+ URLS_GET_IPV4=('https://ipinfo.io/ip','https://api.ipify.org','https://ipv4.seeip.org')
36
+
37
+ 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"
38
+
39
+ STATUS_OK=200
40
+ STATUS_OK_PARTIAL_CONTENT=206
41
+
42
+
43
+ def __init__(self,url:str,logger:ModuloLogging|None,useProxy:bool=False):
44
+ logging.getLogger("urllib3").propagate=False
45
+
46
+ self.__requestObj=Request(url)
47
+ self.__logger=logger
48
+
49
+ self.setUserAgent(self.UA_WINDOWS_FIREFOX)
50
+ self.addHeader('Accept-Encoding','gzip, deflate, br') # questo serve per ridurre la dimensione della risposta
51
+ if useProxy:
52
+ self.addHeader('Origin','localhost')
53
+ self.connectionSafe=ModuloHttpConnectionSafe(self.__logger)
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(ignoreCerts)
61
+ return self.connectionSafe.run(retries,0,self.__getOrPost,ignoreCerts)
62
+
63
+ def doPost(self, postData:dict, asJson:bool, retries:int,ignoreCerts:bool=False)->HttpResponseBean:
64
+ """
65
+ Esegue una richiesta di tipo POST
66
+ """
67
+ if not asJson:
68
+ postDataEncoded=urlencode(postData)
69
+ else:
70
+ postDataEncoded=json.dumps(postData)
71
+ self.addHeader("Content-Type","application/json; charset=utf-8")
72
+ postDataEncoded=postDataEncoded.encode()
73
+ self.__requestObj.data=postDataEncoded
74
+ if retries==0:
75
+ return self.__getOrPost(ignoreCerts)
76
+ return self.connectionSafe.run(retries,0,self.__getOrPost,ignoreCerts)
77
+
78
+ @catchAndRaiseHttpExceptions
79
+ def __getOrPost(self, ignoreCerts:bool)->HttpResponseBean:
80
+ # ignoro certificati
81
+ ctx=None
82
+ if ignoreCerts:
83
+ ctx=ssl.create_default_context()
84
+ ctx.check_hostname=False
85
+ ctx.verify_mode=ssl.CERT_NONE
86
+ # send request
87
+ with urllib.request.urlopen(self.__requestObj,context=ctx) as response:
88
+ responseBody=response.read()
89
+ responseHeaders=response.info()
90
+ status=response.status
91
+ # se il server manda il contenuto in formato compresso lo decomprimo
92
+ contentEncoding=responseHeaders.get('Content-Encoding')
93
+ if contentEncoding=="gzip":
94
+ responseBody=gzip.decompress(responseBody)
95
+ elif contentEncoding=="br":
96
+ responseBody=brotli.decompress(responseBody)
97
+ elif contentEncoding is not None and contentEncoding!= "deflate":
98
+ raise EccezioneRuntime("Codifica '"+contentEncoding+"' non gestita.")
99
+ return HttpResponseBean(status,responseBody,responseHeaders)
100
+
101
+ # opzioni aggiuntive
102
+ def addHeader(self,nome:str,valore):
103
+ if ModuloStringhe.isEmpty(valore):
104
+ return
105
+ self.__requestObj.add_header(nome,valore)
106
+
107
+ def setUserAgent(self,userAgent:str=None):
108
+ if ModuloStringhe.isEmpty(userAgent):
109
+ userAgent=self.UA_ANDROID
110
+ else:
111
+ userAgent=userAgent.strip()
112
+ self.addHeader('User-Agent',userAgent)
113
+
114
+ def setDownloadRange(self,inizio:int,fine:int):
115
+ self.addHeader('Range',"bytes="+str(inizio)+"-"+str(fine))
116
+
117
+ def setAuthenticationBasic(self,username:str,password:str):
118
+ authStr=ModuloBase64.codificaStr('%s:%s' % (username, password))
119
+ 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_nano.ModuloFunzioni import ModuloFunzioni
8
+ from modulitiz_nano.ModuloStringhe import ModuloStringhe
9
+ from modulitiz_micro.eccezioni.http.EccezioneHttpGeneric import EccezioneHttpGeneric
10
+ from modulitiz_nano.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