modulitiz-micro 2.45.0__py311-none-any.whl → 2.46.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 (64) hide show
  1. modulitiz_micro/ModuloSeriale.py +70 -70
  2. modulitiz_micro/ModuloTarghe.py +47 -47
  3. modulitiz_micro/database/AbstractDatabaseService.py +13 -13
  4. modulitiz_micro/database/AbstractSql.py +69 -69
  5. modulitiz_micro/database/ModuloSqlOracle.py +19 -19
  6. modulitiz_micro/database/ModuloSqlServer.py +43 -43
  7. modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -6
  8. modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -114
  9. modulitiz_micro/database/mysql/ModuloMysql.py +163 -163
  10. modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -47
  11. modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -6
  12. modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -114
  13. modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -82
  14. modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -7
  15. modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -7
  16. modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -8
  17. modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -7
  18. modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -7
  19. modulitiz_micro/files/cache/DatabaseCache.py +91 -91
  20. modulitiz_micro/files/cache/decorators/cacheRam.py +26 -26
  21. modulitiz_micro/files/git/ModuloGit.py +28 -28
  22. modulitiz_micro/files/git/decorators/catchAndRaiseGitExceptions.py +19 -19
  23. modulitiz_micro/files/git/exceptions/EccezioneGit.py +7 -7
  24. modulitiz_micro/gestionedom/GestioneDom.py +44 -44
  25. modulitiz_micro/iot/ModuleIotDevice.py +62 -62
  26. modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -7
  27. modulitiz_micro/keylogger/ModuloKeylogger.py +73 -73
  28. modulitiz_micro/rete/ModuleAndroidTVRemote.py +107 -0
  29. modulitiz_micro/rete/ModuloNetworking.py +67 -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/http/huawei/fusionsolar/ModuleHuaweiFusionSolar.py +84 -84
  39. modulitiz_micro/rete/http/huawei/fusionsolar/beans/TokenBean.py +28 -28
  40. modulitiz_micro/rete/http/huawei/fusionsolar/beans/device/DeviceBean.py +6 -6
  41. modulitiz_micro/rete/http/huawei/fusionsolar/beans/device/DeviceDataBattery.py +22 -22
  42. modulitiz_micro/rete/http/huawei/fusionsolar/beans/device/DeviceDataPowerSensor.py +49 -49
  43. modulitiz_micro/rete/http/huawei/fusionsolar/enums/DevTypeIdEnum.py +21 -21
  44. modulitiz_micro/rete/http/huawei/fusionsolar/exceptions/ExceptionTooManyLogins.py +7 -7
  45. modulitiz_micro/rete/http/huawei/fusionsolar/service/AbstractHuaweiFusionSolar.py +72 -72
  46. modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -73
  47. modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -8
  48. modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -35
  49. modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -267
  50. modulitiz_micro/rete/ssl/ModuloSsl.py +56 -56
  51. modulitiz_micro/sistema/ModuloEnvVars.py +34 -34
  52. modulitiz_micro/sistema/ModuloSystemPipe.py +67 -67
  53. modulitiz_micro/social/telegram/AbstractModuloTelegram.py +53 -53
  54. modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -26
  55. modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -15
  56. modulitiz_micro/util/scheduler/ModuleScheduler.py +26 -26
  57. modulitiz_micro/weather/AbstractModuleWeather.py +31 -31
  58. modulitiz_micro/weather/ModuleWeather.py +62 -62
  59. {modulitiz_micro-2.45.0.dist-info → modulitiz_micro-2.46.0.dist-info}/METADATA +59 -59
  60. modulitiz_micro-2.46.0.dist-info/RECORD +67 -0
  61. {modulitiz_micro-2.45.0.dist-info → modulitiz_micro-2.46.0.dist-info}/licenses/LICENSE +21 -21
  62. modulitiz_micro-2.45.0.dist-info/RECORD +0 -66
  63. {modulitiz_micro-2.45.0.dist-info → modulitiz_micro-2.46.0.dist-info}/WHEEL +0 -0
  64. {modulitiz_micro-2.45.0.dist-info → modulitiz_micro-2.46.0.dist-info}/top_level.txt +0 -0
@@ -1,34 +1,34 @@
1
- import os
2
-
3
- from modulitiz_nano.sistema.ModuloSystem import ModuloSystem
4
-
5
-
6
- class ModuloEnvVars(object):
7
-
8
- @classmethod
9
- def add(cls,nomeVar:str,valore:str,addFirst:bool):
10
- if not ModuloSystem.isWindows():
11
- separatore=":"
12
- else:
13
- separatore=";"
14
- nomeVar=nomeVar.upper()
15
- if not cls.exist(nomeVar):
16
- cls.setOrReplace(nomeVar,valore)
17
- return
18
- if addFirst:
19
- cls.setOrReplace(nomeVar,valore+separatore+os.environ[nomeVar])
20
- else:
21
- if not os.environ[nomeVar].endswith(separatore):
22
- os.environ[nomeVar]+=separatore
23
- os.environ[nomeVar]+=valore
24
- @staticmethod
25
- def setOrReplace(nomeVar:str,valore:str):
26
- os.environ[nomeVar]=valore
27
-
28
- @staticmethod
29
- def getOrNone(nomeVar:str)->str|None:
30
- return os.environ.get(nomeVar,None)
31
-
32
- @staticmethod
33
- def exist(nomeVar:str)->bool:
34
- return nomeVar in os.environ
1
+ import os
2
+
3
+ from modulitiz_nano.sistema.ModuloSystem import ModuloSystem
4
+
5
+
6
+ class ModuloEnvVars(object):
7
+
8
+ @classmethod
9
+ def add(cls,nomeVar:str,valore:str,addFirst:bool):
10
+ if not ModuloSystem.isWindows():
11
+ separatore=":"
12
+ else:
13
+ separatore=";"
14
+ nomeVar=nomeVar.upper()
15
+ if not cls.exist(nomeVar):
16
+ cls.setOrReplace(nomeVar,valore)
17
+ return
18
+ if addFirst:
19
+ cls.setOrReplace(nomeVar,valore+separatore+os.environ[nomeVar])
20
+ else:
21
+ if not os.environ[nomeVar].endswith(separatore):
22
+ os.environ[nomeVar]+=separatore
23
+ os.environ[nomeVar]+=valore
24
+ @staticmethod
25
+ def setOrReplace(nomeVar:str,valore:str):
26
+ os.environ[nomeVar]=valore
27
+
28
+ @staticmethod
29
+ def getOrNone(nomeVar:str)->str|None:
30
+ return os.environ.get(nomeVar,None)
31
+
32
+ @staticmethod
33
+ def exist(nomeVar:str)->bool:
34
+ return nomeVar in os.environ
@@ -1,67 +1,67 @@
1
- import multiprocessing
2
- import queue
3
- import subprocess
4
- import threading
5
- import time
6
-
7
- import psutil
8
-
9
- from modulitiz_nano.files.ModuloLogging import ModuloLogging
10
- from modulitiz_nano.multithread.ModuloThread import ModuloThread
11
- from modulitiz_nano.sistema.ModuloSystem import ModuloSystem
12
-
13
-
14
- class ModuloSystemPipe(object):
15
-
16
- @classmethod
17
- def read(cls,logger: ModuloLogging,pipe: subprocess.Popen,timeout:int|float) -> str|None:
18
- event=threading.Event()
19
- q=multiprocessing.Queue()
20
- ModuloThread.startDaemon(logger,cls.__read,(pipe,q,event))
21
-
22
- output=""
23
- pauseInterval=0.1
24
- contaTimeout=0
25
- continua=True
26
- while continua:
27
- outputBefore=output
28
- try:
29
- output+=q.get_nowait()
30
- except queue.Empty:
31
- pass
32
- continua=(output=="" or output!=outputBefore)
33
- if continua:
34
- if output=="":
35
- contaTimeout+=pauseInterval
36
- else:
37
- contaTimeout=0
38
- time.sleep(pauseInterval)
39
- else:
40
- if contaTimeout<=timeout:
41
- time.sleep(pauseInterval)
42
- continua=True
43
- contaTimeout+=pauseInterval
44
- event.set()
45
- return output.rstrip()
46
-
47
- @staticmethod
48
- def __read(pipe: subprocess.Popen,q: multiprocessing.Queue,event: threading.Event):
49
- chunk=pipe.stdout.readline()
50
- while chunk:
51
- q.put_nowait(chunk.decode())
52
- if event.is_set():
53
- return
54
- chunk=pipe.stdout.readline()
55
-
56
- @staticmethod
57
- def closeAndCheck(process:psutil.Process|subprocess.Popen,alias:str,timeout:int,callbackError,callbackSuccess):
58
- ModuloSystem.sendCtrlcProcess(process.pid)
59
- try:
60
- exitCode=process.wait(timeout)
61
- except subprocess.TimeoutExpired:
62
- callbackError(alias+" non terminato correttamente nel tempo utile")
63
- return
64
- if exitCode is None or exitCode==0:
65
- callbackSuccess(alias+" terminato con successo")
66
- return
67
- callbackError(alias+" non terminato correttamente, esito=%s"%(exitCode,))
1
+ import multiprocessing
2
+ import queue
3
+ import subprocess
4
+ import threading
5
+ import time
6
+
7
+ import psutil
8
+
9
+ from modulitiz_nano.files.ModuloLogging import ModuloLogging
10
+ from modulitiz_nano.multithread.ModuloThread import ModuloThread
11
+ from modulitiz_nano.sistema.ModuloSystem import ModuloSystem
12
+
13
+
14
+ class ModuloSystemPipe(object):
15
+
16
+ @classmethod
17
+ def read(cls,logger: ModuloLogging,pipe: subprocess.Popen,timeout:int|float) -> str|None:
18
+ event=threading.Event()
19
+ q=multiprocessing.Queue()
20
+ ModuloThread.startDaemon(logger,cls.__read,(pipe,q,event))
21
+
22
+ output=""
23
+ pauseInterval=0.1
24
+ contaTimeout=0
25
+ continua=True
26
+ while continua:
27
+ outputBefore=output
28
+ try:
29
+ output+=q.get_nowait()
30
+ except queue.Empty:
31
+ pass
32
+ continua=(output=="" or output!=outputBefore)
33
+ if continua:
34
+ if output=="":
35
+ contaTimeout+=pauseInterval
36
+ else:
37
+ contaTimeout=0
38
+ time.sleep(pauseInterval)
39
+ else:
40
+ if contaTimeout<=timeout:
41
+ time.sleep(pauseInterval)
42
+ continua=True
43
+ contaTimeout+=pauseInterval
44
+ event.set()
45
+ return output.rstrip()
46
+
47
+ @staticmethod
48
+ def __read(pipe: subprocess.Popen,q: multiprocessing.Queue,event: threading.Event):
49
+ chunk=pipe.stdout.readline()
50
+ while chunk:
51
+ q.put_nowait(chunk.decode())
52
+ if event.is_set():
53
+ return
54
+ chunk=pipe.stdout.readline()
55
+
56
+ @staticmethod
57
+ def closeAndCheck(process:psutil.Process|subprocess.Popen,alias:str,timeout:int,callbackError,callbackSuccess):
58
+ ModuloSystem.sendCtrlcProcess(process.pid)
59
+ try:
60
+ exitCode=process.wait(timeout)
61
+ except subprocess.TimeoutExpired:
62
+ callbackError(alias+" non terminato correttamente nel tempo utile")
63
+ return
64
+ if exitCode is None or exitCode==0:
65
+ callbackSuccess(alias+" terminato con successo")
66
+ return
67
+ callbackError(alias+" non terminato correttamente, esito=%s"%(exitCode,))
@@ -1,53 +1,53 @@
1
- from abc import ABC
2
- from abc import abstractmethod
3
-
4
- from telethon import TelegramClient
5
-
6
- from modulitiz_nano.ModuloStringhe import ModuloStringhe
7
- from modulitiz_nano.util.decorators.noAwait import noAwait
8
-
9
-
10
- class AbstractModuloTelegram(ABC):
11
- def __init__(self,apiId:int,apiHash:str,nomefileSessione:str,phoneNumWithCountryCode:str):
12
- self.apiId=apiId
13
- self.apiHash=apiHash
14
- self.nomefileSessione=nomefileSessione
15
- self.phoneNumWithCountryCode=phoneNumWithCountryCode
16
-
17
- self.client:TelegramClient|None = None
18
-
19
- @noAwait
20
- async def connect(self):
21
- self.client = TelegramClient(self.nomefileSessione, self.apiId, self.apiHash)
22
- await self.client.connect()
23
- # se il client non e' autorizzato richiedo la verifica
24
- if await self.client.is_user_authorized():
25
- return
26
- await self.client.send_code_request(self.phoneNumWithCountryCode)
27
- await self.client.sign_in(self.phoneNumWithCountryCode, self.getVerificationCodefromUser())
28
-
29
- def sendMessageWithConnectAndClose(self,username: str|None,msg: str):
30
- """
31
- Apre la connessione, invia il messaggio e chiude la connessione.
32
- :param username: il nome utente del destinatario a cui mandare il messaggio
33
- :param msg: il testo del messaggio da inviare
34
- """
35
- if ModuloStringhe.isEmpty(username):
36
- return
37
- self.connect()
38
- self.sendMessage(username,msg)
39
- self.close()
40
-
41
- @noAwait
42
- async def sendMessage(self,username:str,msg:str):
43
- await self.client.send_message(username, msg, parse_mode='html')
44
-
45
- def close(self):
46
- self.client.disconnect()
47
-
48
- @staticmethod
49
- @abstractmethod
50
- def getVerificationCodefromUser()->str:
51
- """
52
- Deve ritornare una stringa che corrisponde al codice di verifica inserito dall'utente.
53
- """
1
+ from abc import ABC
2
+ from abc import abstractmethod
3
+
4
+ from telethon import TelegramClient
5
+
6
+ from modulitiz_nano.ModuloStringhe import ModuloStringhe
7
+ from modulitiz_nano.util.decorators.noAwait import noAwait
8
+
9
+
10
+ class AbstractModuloTelegram(ABC):
11
+ def __init__(self,apiId:int,apiHash:str,nomefileSessione:str,phoneNumWithCountryCode:str):
12
+ self.apiId=apiId
13
+ self.apiHash=apiHash
14
+ self.nomefileSessione=nomefileSessione
15
+ self.phoneNumWithCountryCode=phoneNumWithCountryCode
16
+
17
+ self.client:TelegramClient|None = None
18
+
19
+ @noAwait
20
+ async def connect(self):
21
+ self.client = TelegramClient(self.nomefileSessione, self.apiId, self.apiHash)
22
+ await self.client.connect()
23
+ # se il client non e' autorizzato richiedo la verifica
24
+ if await self.client.is_user_authorized():
25
+ return
26
+ await self.client.send_code_request(self.phoneNumWithCountryCode)
27
+ await self.client.sign_in(self.phoneNumWithCountryCode, self.getVerificationCodefromUser())
28
+
29
+ def sendMessageWithConnectAndClose(self,username: str|None,msg: str):
30
+ """
31
+ Apre la connessione, invia il messaggio e chiude la connessione.
32
+ :param username: il nome utente del destinatario a cui mandare il messaggio
33
+ :param msg: il testo del messaggio da inviare
34
+ """
35
+ if ModuloStringhe.isEmpty(username):
36
+ return
37
+ self.connect()
38
+ self.sendMessage(username,msg)
39
+ self.close()
40
+
41
+ @noAwait
42
+ async def sendMessage(self,username:str,msg:str):
43
+ await self.client.send_message(username, msg, parse_mode='html')
44
+
45
+ def close(self):
46
+ self.client.disconnect()
47
+
48
+ @staticmethod
49
+ @abstractmethod
50
+ def getVerificationCodefromUser()->str:
51
+ """
52
+ Deve ritornare una stringa che corrisponde al codice di verifica inserito dall'utente.
53
+ """
@@ -1,26 +1,26 @@
1
- from modulitiz_micro.social.telegram.AbstractModuloTelegram import AbstractModuloTelegram
2
-
3
-
4
- class ModuloTelegramSimple(AbstractModuloTelegram):
5
- """
6
- Utility di gestione semplice per il sistema di messaggistica istantanea Telegram.
7
- """
8
-
9
- def __init__(self,usernameDestinatario:str|None,*args,**kwargs):
10
- super().__init__(*args,**kwargs)
11
- self.usernameDestinatario=usernameDestinatario
12
-
13
- @staticmethod
14
- def getVerificationCodefromUser()->str:
15
- """
16
- Specifica in che modo chiedere all'utente il codice di verifica,
17
- viene chiesto solo la prima volta che ci si collega.
18
- """
19
- return input('Inserisci il codice di verifica: ')
20
-
21
- def sendMessageDefaultDestinatario(self,msg:str):
22
- """
23
- Invia il messaggio al destinatario di default specificato nella creazione di quest'oggetto.
24
- :param msg: il testo del messaggio da inviare
25
- """
26
- super().sendMessageWithConnectAndClose(self.usernameDestinatario,msg)
1
+ from modulitiz_micro.social.telegram.AbstractModuloTelegram import AbstractModuloTelegram
2
+
3
+
4
+ class ModuloTelegramSimple(AbstractModuloTelegram):
5
+ """
6
+ Utility di gestione semplice per il sistema di messaggistica istantanea Telegram.
7
+ """
8
+
9
+ def __init__(self,usernameDestinatario:str|None,*args,**kwargs):
10
+ super().__init__(*args,**kwargs)
11
+ self.usernameDestinatario=usernameDestinatario
12
+
13
+ @staticmethod
14
+ def getVerificationCodefromUser()->str:
15
+ """
16
+ Specifica in che modo chiedere all'utente il codice di verifica,
17
+ viene chiesto solo la prima volta che ci si collega.
18
+ """
19
+ return input('Inserisci il codice di verifica: ')
20
+
21
+ def sendMessageDefaultDestinatario(self,msg:str):
22
+ """
23
+ Invia il messaggio al destinatario di default specificato nella creazione di quest'oggetto.
24
+ :param msg: il testo del messaggio da inviare
25
+ """
26
+ super().sendMessageWithConnectAndClose(self.usernameDestinatario,msg)
@@ -1,15 +1,15 @@
1
- from modulitiz_micro.rete.ntp.ModuloNtpIt import ModuloNtpIt
2
-
3
- from modulitiz_nano.util.beans.globalvar.AbstractGlobalVarBean import AbstractGlobalVarBean
4
-
5
-
6
- class AbstractBasicGlobalVarBean(AbstractGlobalVarBean):
7
- """
8
- Classe da usare come base per definire la struttura di una classe che raggrupperà gli oggetti che verranno usati nel programma
9
- """
10
-
11
- def __init__(self,useNtp:bool,*args,**kwargs):
12
- super().__init__(*args,**kwargs)
13
- if useNtp:
14
- self.moduloNtp=ModuloNtpIt(self.logger)
15
-
1
+ from modulitiz_micro.rete.ntp.ModuloNtpIt import ModuloNtpIt
2
+
3
+ from modulitiz_nano.util.beans.globalvar.AbstractGlobalVarBean import AbstractGlobalVarBean
4
+
5
+
6
+ class AbstractBasicGlobalVarBean(AbstractGlobalVarBean):
7
+ """
8
+ Classe da usare come base per definire la struttura di una classe che raggrupperà gli oggetti che verranno usati nel programma
9
+ """
10
+
11
+ def __init__(self,useNtp:bool,*args,**kwargs):
12
+ super().__init__(*args,**kwargs)
13
+ if useNtp:
14
+ self.moduloNtp=ModuloNtpIt(self.logger)
15
+
@@ -1,26 +1,26 @@
1
- import schedule
2
-
3
- from modulitiz_nano.ModuloListe import ModuloListe
4
-
5
-
6
- class ModuleScheduler(object):
7
- @staticmethod
8
- def cancelJobByTag(tag:str):
9
- schedule.clear(tag)
10
-
11
- @classmethod
12
- def rescheduleJob(cls,tag:str,timeStr:str)->schedule.Job|None:
13
- # recupero il job
14
- jobs=schedule.get_jobs(tag)
15
- if ModuloListe.isEmpty(jobs):
16
- return None
17
- job=jobs[0]
18
- # cambio l'orario
19
- job.at(timeStr)
20
- # cancello quello vecchio
21
- cls.cancelJobByTag(tag)
22
- # lo aggiungo alla lista
23
- job.scheduler.jobs.append(job)
24
- # lo rischedulo
25
- job._schedule_next_run()
26
- return job
1
+ import schedule
2
+
3
+ from modulitiz_nano.ModuloListe import ModuloListe
4
+
5
+
6
+ class ModuleScheduler(object):
7
+ @staticmethod
8
+ def cancelJobByTag(tag:str):
9
+ schedule.clear(tag)
10
+
11
+ @classmethod
12
+ def rescheduleJob(cls,tag:str,timeStr:str)->schedule.Job|None:
13
+ # recupero il job
14
+ jobs=schedule.get_jobs(tag)
15
+ if ModuloListe.isEmpty(jobs):
16
+ return None
17
+ job=jobs[0]
18
+ # cambio l'orario
19
+ job.at(timeStr)
20
+ # cancello quello vecchio
21
+ cls.cancelJobByTag(tag)
22
+ # lo aggiungo alla lista
23
+ job.scheduler.jobs.append(job)
24
+ # lo rischedulo
25
+ job._schedule_next_run()
26
+ return job
@@ -1,31 +1,31 @@
1
- import json
2
- from abc import ABC
3
-
4
- from modulitiz_micro.eccezioni.http.EccezioneHttpGeneric import EccezioneHttpGeneric
5
- from modulitiz_micro.rete.http.ModuloHttp import ModuloHttp
6
- from modulitiz_micro.rete.http.ModuloHttpUtils import ModuloHttpUtils
7
- from modulitiz_nano.files.ModuloLogging import ModuloLogging
8
-
9
-
10
- class AbstractModuleWeather(ABC):
11
- OPTIONS="lang=it&units=metric"
12
- KEY="appid=e28cd365c35c12e3ed8f2d84e04398c9"
13
-
14
- __BASE_URL="https://api.openweathermap.org"
15
- URL_CURRENT=__BASE_URL+f"/data/2.5/weather?{OPTIONS}&{KEY}&q="
16
- URL_FORECAST=__BASE_URL+f"/data/2.5/forecast?{OPTIONS}&{KEY}&q="
17
-
18
- def __init__(self,logger:ModuloLogging):
19
- self._logger=logger
20
-
21
- def _makeForecastRequest(self,baseUrl:str,city:str,codState:str):
22
- return self._makeGenericRequest(baseUrl,city, codState)['list']
23
-
24
- def _makeGenericRequest(self,baseUrl:str,city:str,codState:str):
25
- url=baseUrl+ModuloHttpUtils.encodeUrl(city+","+codState)
26
- http=ModuloHttp(url,self._logger,False)
27
- try:
28
- response=http.doGet(0,False)
29
- except EccezioneHttpGeneric:
30
- return None
31
- return json.loads(response.responseBody)
1
+ import json
2
+ from abc import ABC
3
+
4
+ from modulitiz_micro.eccezioni.http.EccezioneHttpGeneric import EccezioneHttpGeneric
5
+ from modulitiz_micro.rete.http.ModuloHttp import ModuloHttp
6
+ from modulitiz_micro.rete.http.ModuloHttpUtils import ModuloHttpUtils
7
+ from modulitiz_nano.files.ModuloLogging import ModuloLogging
8
+
9
+
10
+ class AbstractModuleWeather(ABC):
11
+ OPTIONS="lang=it&units=metric"
12
+ KEY="appid=e28cd365c35c12e3ed8f2d84e04398c9"
13
+
14
+ __BASE_URL="https://api.openweathermap.org"
15
+ URL_CURRENT=__BASE_URL+f"/data/2.5/weather?{OPTIONS}&{KEY}&q="
16
+ URL_FORECAST=__BASE_URL+f"/data/2.5/forecast?{OPTIONS}&{KEY}&q="
17
+
18
+ def __init__(self,logger:ModuloLogging):
19
+ self._logger=logger
20
+
21
+ def _makeForecastRequest(self,baseUrl:str,city:str,codState:str):
22
+ return self._makeGenericRequest(baseUrl,city, codState)['list']
23
+
24
+ def _makeGenericRequest(self,baseUrl:str,city:str,codState:str):
25
+ url=baseUrl+ModuloHttpUtils.encodeUrl(city+","+codState)
26
+ http=ModuloHttp(url,self._logger,False)
27
+ try:
28
+ response=http.doGet(0,False)
29
+ except EccezioneHttpGeneric:
30
+ return None
31
+ return json.loads(response.responseBody)
@@ -1,62 +1,62 @@
1
- from modulitiz_micro.weather.AbstractModuleWeather import AbstractModuleWeather
2
- from modulitiz_nano.ModuloDate import ModuloDate
3
- from modulitiz_nano.ModuloListe import ModuloListe
4
-
5
-
6
- class ModuleWeather(AbstractModuleWeather):
7
- """
8
- Utility for current weather and forecasts.
9
- """
10
- OPTIONS="lang=it&units=metric"
11
- KEY="appid=e28cd365c35c12e3ed8f2d84e04398c9"
12
-
13
- __BASE_URL="https://api.openweathermap.org"
14
- URL_CURRENT=__BASE_URL+f"/data/2.5/weather?{OPTIONS}&{KEY}&q="
15
- URL_FORECAST=__BASE_URL+f"/data/2.5/forecast?{OPTIONS}&{KEY}&q="
16
-
17
- def __init__(self,*args,**kwargs):
18
- super().__init__(*args,**kwargs)
19
-
20
- def getCurrent(self,city:str,codState:str)-> dict:
21
- return self._makeGenericRequest(self.URL_CURRENT,city,codState)
22
-
23
- def getForecastRainUntilTomorrow(self,city:str,codState:str)-> list|None:
24
- """
25
- Chiede le previsioni fino al giorno dopo e mostra solo i risultati che dicono che pioverà.
26
- """
27
- now=ModuloDate.now()
28
- tomorrow=ModuloDate.setEndOfDay(ModuloDate.plusMinusDays(now,1))
29
- hoursDiff=ModuloDate.hoursDiff(tomorrow, now)
30
- elements=self.__getForecasts(city, codState,True,None,hoursDiff)
31
- if elements is None:
32
- return None
33
- # filter elements
34
- results=[]
35
- for elem in elements:
36
- if ModuloListe.collectionSafeGet(elem,'rain') is not None:
37
- results.append(elem)
38
- return results
39
-
40
- def __getForecasts(self,city:str,codState:str,includeFirstForecast:bool,stepHours: int|None,maxHours:int)-> list|None:
41
- results=self._makeForecastRequest(self.URL_FORECAST,city,codState)
42
- maxLista=len(results)
43
- # calculate indexes
44
- if maxHours is not None:
45
- maxInd=int(maxHours/3)+1
46
- if maxInd>=maxLista:
47
- maxInd=maxLista-1
48
- else:
49
- maxInd=maxLista-1
50
- if stepHours is None:
51
- step=1
52
- else:
53
- step=int(stepHours/3)
54
- inds=list(range(4,maxInd,step))
55
- if includeFirstForecast:
56
- inds.insert(0,1)
57
- # process json
58
- output=[]
59
- for ind in inds:
60
- elem=results[ind]
61
- output.append(elem)
62
- return output
1
+ from modulitiz_micro.weather.AbstractModuleWeather import AbstractModuleWeather
2
+ from modulitiz_nano.ModuloDate import ModuloDate
3
+ from modulitiz_nano.ModuloListe import ModuloListe
4
+
5
+
6
+ class ModuleWeather(AbstractModuleWeather):
7
+ """
8
+ Utility for current weather and forecasts.
9
+ """
10
+ OPTIONS="lang=it&units=metric"
11
+ KEY="appid=e28cd365c35c12e3ed8f2d84e04398c9"
12
+
13
+ __BASE_URL="https://api.openweathermap.org"
14
+ URL_CURRENT=__BASE_URL+f"/data/2.5/weather?{OPTIONS}&{KEY}&q="
15
+ URL_FORECAST=__BASE_URL+f"/data/2.5/forecast?{OPTIONS}&{KEY}&q="
16
+
17
+ def __init__(self,*args,**kwargs):
18
+ super().__init__(*args,**kwargs)
19
+
20
+ def getCurrent(self,city:str,codState:str)-> dict:
21
+ return self._makeGenericRequest(self.URL_CURRENT,city,codState)
22
+
23
+ def getForecastRainUntilTomorrow(self,city:str,codState:str)-> list|None:
24
+ """
25
+ Chiede le previsioni fino al giorno dopo e mostra solo i risultati che dicono che pioverà.
26
+ """
27
+ now=ModuloDate.now()
28
+ tomorrow=ModuloDate.setEndOfDay(ModuloDate.plusMinusDays(now,1))
29
+ hoursDiff=ModuloDate.hoursDiff(tomorrow, now)
30
+ elements=self.__getForecasts(city, codState,True,None,hoursDiff)
31
+ if elements is None:
32
+ return None
33
+ # filter elements
34
+ results=[]
35
+ for elem in elements:
36
+ if ModuloListe.collectionSafeGet(elem,'rain') is not None:
37
+ results.append(elem)
38
+ return results
39
+
40
+ def __getForecasts(self,city:str,codState:str,includeFirstForecast:bool,stepHours: int|None,maxHours:int)-> list|None:
41
+ results=self._makeForecastRequest(self.URL_FORECAST,city,codState)
42
+ maxLista=len(results)
43
+ # calculate indexes
44
+ if maxHours is not None:
45
+ maxInd=int(maxHours/3)+1
46
+ if maxInd>=maxLista:
47
+ maxInd=maxLista-1
48
+ else:
49
+ maxInd=maxLista-1
50
+ if stepHours is None:
51
+ step=1
52
+ else:
53
+ step=int(stepHours/3)
54
+ inds=list(range(4,maxInd,step))
55
+ if includeFirstForecast:
56
+ inds.insert(0,1)
57
+ # process json
58
+ output=[]
59
+ for ind in inds:
60
+ elem=results[ind]
61
+ output.append(elem)
62
+ return output