1
1
#!/usr/bin/env python3
2
2
3
+ import asyncio
4
+ from logging import currentframe
3
5
from lib .run import Runner , Caller
6
+ from lib .asynclib import make_async
4
7
import sys
5
8
import os
6
9
import json
7
- from typing import Dict , Tuple
10
+ from typing import Dict , Tuple , List
8
11
from datetime import datetime
12
+ from datetime import timedelta
9
13
import csv
10
14
11
- def get_weather_csv ():
15
+ def get_weather_csv () -> List [ Dict [ str , str ]] :
12
16
csv_path = '/etc/ohmyoled/ecIcons_utf8.csv'
13
17
return list (csv .DictReader (open (csv_path )))
14
- def build_weather_icons ():
18
+
19
+ def build_weather_icons () -> str :
15
20
csv = get_weather_csv ()
16
21
icon = {}
17
22
for icn in csv :
18
23
icon .update ({icn ["OWMCode" ]: WeatherIcon (icn ['OWMCode' ], icn ['Description' ], icn ['fontcode' ], icn ['font' ])})
19
24
return icon
20
25
21
26
class WeatherIcon ():
22
- def __init__ (self , owm_id , description , fontcode , font ) -> None :
27
+ def __init__ (self , owm_id : str , description : str , fontcode : str , font : str ) -> None :
23
28
self .owm_id = owm_id
24
29
self .description = description
25
30
self .fontcode = fontcode
26
31
self .font = font
27
32
28
33
@property
29
- def get_owm_id (self ):
34
+ def get_owm_id (self ) -> str :
30
35
return self .owm_id
31
36
@property
32
- def get_description (self ):
37
+ def get_description (self ) -> str :
33
38
return self .description
34
39
@property
35
- def get_fontcode (self ):
40
+ def get_fontcode (self ) -> str :
36
41
return self .fontcode
37
42
@property
38
- def get_font (self ):
43
+ def get_font (self ) -> str :
39
44
return self .font
40
45
41
46
@@ -46,14 +51,14 @@ class WeatherApi(Runner):
46
51
To parse the config file and
47
52
Run Data
48
53
"""
49
- def __init__ (self , config ):
54
+ def __init__ (self , config ) -> None :
50
55
super ().__init__ (config )
51
56
self .weather = self .config ['weather' ]
52
57
try :
53
58
if "open_weather_token" in self .config ['basic' ]:
54
- self .token = self .config ['basic' ].get ('open_weather_token' )
59
+ self .token : str = self .config ['basic' ].get ('open_weather_token' )
55
60
else :
56
- self .token = os .environ ['WEATHERTOKEN' ]
61
+ self .token : str = os .environ ['WEATHERTOKEN' ]
57
62
except KeyError :
58
63
self .logger .critical ("No Weather Token" )
59
64
sys .exit ("No Weather Token" )
@@ -80,7 +85,7 @@ async def get_long_and_lat(self, location: str=None, zipcode: int=None) -> Tuple
80
85
self .logger .debug ("Getting Lat and Long" )
81
86
try :
82
87
if location :
83
- self .logger .debug ("Getting Longitude and Latitude" )
88
+ self .logger .debug ("Computing Longitude and Latitude" )
84
89
url = f'http://api.openweathermap.org/data/2.5/weather?q={ location } &appid={ self .token } '
85
90
response = await self .get_data (url )
86
91
lon = response .get ('coord' ).get ('lon' )
@@ -91,7 +96,9 @@ async def get_long_and_lat(self, location: str=None, zipcode: int=None) -> Tuple
91
96
except Exception as e :
92
97
self .logger .critical (e )
93
98
sys .exit ("No City Found" )
94
- def get_current_location (self ):
99
+
100
+ @make_async
101
+ def get_current_location (self ) -> Dict [str , str ]:
95
102
url = 'http://ipinfo.io/json'
96
103
response = self .run_non_async_request (url )
97
104
return response .json ()
@@ -100,32 +107,26 @@ async def url_builder(self, location=None, zipcode=None, current_location=False)
100
107
"""
101
108
Builds Url to poll the Api
102
109
"""
103
- self .logger .debug ("Building url..." )
110
+ self .logger .debug ("Building Weather url..." )
104
111
if current_location :
105
- ip_json = self .get_current_location ()
112
+ ip_json : Dict [ str , str ] = await self .get_current_location ()
106
113
lon , lat = ip_json ['loc' ].split (',' )[1 ], ip_json ['loc' ].split (',' )[0 ]
107
114
url = f"https://api.openweathermap.org/data/2.5/onecall?lat={ lat } &lon={ lon } &appid={ self .token } &units={ self .weather .get ('format' )} "
108
115
elif location :
109
116
lon , lat = await self .get_long_and_lat (location )
110
117
url = f"https://api.openweathermap.org/data/2.5/onecall?lat={ lat } &lon={ lon } &appid={ self .token } &units={ self .weather .get ('format' )} "
111
118
else :
112
- ip_json = self .get_current_location ()
119
+ ip_json = await self .get_current_location ()
113
120
lon , lat = ip_json ['loc' ].split (',' )[1 ], ip_json ['loc' ].split (',' )[0 ]
114
121
url = f"https://api.openweathermap.org/data/2.5/onecall?lat={ lat } &lon={ lon } &appid={ self .token } &units={ self .weather .get ('format' )} "
115
122
return url
116
123
117
- async def run (self ):
118
- """
119
- Get Args
120
- parse args
121
- Build URL
122
- make request
123
- return Json
124
- """
125
- self .logger .info ("Using to get Weather" )
124
+ async def run (self ) -> Dict :
125
+ self .logger .info ("Running Api for Weather" )
126
126
args = await self .parse_args ()
127
127
api_data = await self .get_data (args )
128
- api_data ['name' ] = self .get_current_location ()['city' ]
128
+ current_data = await self .get_current_location ()
129
+ api_data ['name' ] = current_data ['city' ]
129
130
return api_data
130
131
131
132
class Weather (Caller ):
@@ -180,89 +181,89 @@ def __repr__(self) -> str:
180
181
return f"Weather(\n { joined_attrs } )"
181
182
182
183
@property
183
- def get_wind_speed (self ):
184
+ def get_wind_speed (self ) -> int :
184
185
return self ._wind_speed
185
186
186
- def set_wind_speed (self , speed ) :
187
+ def set_wind_speed (self , speed : int ) -> None :
187
188
self ._wind_speed = speed
188
189
189
190
@property
190
- def get_daily (self ):
191
+ def get_daily (self ) -> Dict [ str , str ] :
191
192
return self ._daily
192
193
193
194
@property
194
- def get_wind_deg (self ):
195
+ def get_wind_deg (self ) -> int :
195
196
return self ._wind_deg
196
197
197
198
@property
198
- def get_precipitation (self ):
199
- return self ._pop
199
+ def get_precipitation (self ) -> int :
200
+ return self ._pop * 100
200
201
201
202
@property
202
- def get_uv (self ):
203
+ def get_uv (self ) -> int :
203
204
return self ._uv
204
205
205
- def set_place (self , place ) :
206
+ def set_place (self , place : str ) -> None :
206
207
self ._place = place
207
208
208
209
@property
209
- def get_place (self ):
210
+ def get_place (self ) -> str :
210
211
return self ._place
211
212
212
- def set_weather (self , weather ) :
213
+ def set_weather (self , weather : Dict [ str , str ]) -> None :
213
214
self ._weather = weather
214
215
215
216
@property
216
- def get_weather (self ):
217
+ def get_weather (self ) -> Dict [ str , str ] :
217
218
return self ._weather
218
219
219
- def set_conditions (self , conditions ) :
220
+ def set_conditions (self , conditions : str ) -> None :
220
221
self ._conditions = conditions
221
222
222
223
@property
223
- def get_conditions (self ):
224
+ def get_conditions (self ) -> str :
224
225
return self ._conditions
225
226
226
- def set_weather_icon (self , icon ) :
227
+ def set_weather_icon (self , icon : str ) -> None :
227
228
self ._weather_icon = icon
228
229
229
230
@property
230
- def get_weather_icon (self ):
231
+ def get_weather_icon (self ) -> str :
231
232
return self ._weather_icon
232
233
233
- def set_temp (self , temp ) :
234
+ def set_temp (self , temp : int ) -> None :
234
235
self ._temp = temp
235
236
236
237
@property
237
- def get_temp (self ):
238
+ def get_temp (self ) -> int :
238
239
return self ._temp
239
240
240
- def set_feels_like (self , feels ):
241
+ def set_feels_like (self , feels : int ):
241
242
self ._feels_like = feels
242
243
243
244
@property
244
- def get_feels_like (self ):
245
+ def get_feels_like (self ) -> int :
245
246
return self ._feels_like
246
247
247
- def set_min_temp (self , temp ) :
248
+ def set_min_temp (self , temp : int ) -> None :
248
249
self ._min_temp = temp
249
250
250
251
@property
251
- def get_min_temp (self ):
252
+ def get_min_temp (self ) -> int :
252
253
return self ._min_temp
253
254
254
- def set_max_temp (self , temp ) :
255
+ def set_max_temp (self , temp : int ) -> None :
255
256
self ._max_temp = temp
256
257
257
258
@property
258
- def get_max_temp (self ):
259
+ def get_max_temp (self ) -> int :
259
260
return self ._max_temp
260
261
261
- def set_humidity (self , humidity ) :
262
+ def set_humidity (self , humidity : int ) -> None :
262
263
self ._humidity = humidity
263
264
264
265
@property
265
- def get_humidity (self ):
266
+ def get_humidity (self ) -> None :
266
267
return self ._humidity
267
268
268
269
def set_wind (self , wind : Dict ) -> None :
@@ -272,14 +273,14 @@ def set_wind(self, wind: Dict) -> None:
272
273
def get_wind (self ) -> Dict :
273
274
return self ._wind
274
275
275
- def set_time (self , time ) -> None :
276
+ def set_time (self , time : int ) -> None :
276
277
self ._time = datetime .fromtimestamp (time )
277
278
278
279
@property
279
280
def get_time (self ) -> datetime :
280
281
return self ._time
281
282
282
- def set_sunrise (self , time ) -> None :
283
+ def set_sunrise (self , time : int ) -> None :
283
284
self ._sunrise = datetime .fromtimestamp (time )
284
285
285
286
@property
@@ -293,5 +294,5 @@ def set_sunset(self, time) -> None:
293
294
def get_sunset (self ) -> datetime :
294
295
return self ._sunset
295
296
296
- def calculate_duration_of_daylight (self ):
297
+ def calculate_duration_of_daylight (self ) -> timedelta :
297
298
return self ._sunset - self ._time
0 commit comments