mirix commited on
Commit
40fc494
·
verified ·
1 Parent(s): 5886896

Delete weather_app.py

Browse files
Files changed (1) hide show
  1. weather_app.py +0 -444
weather_app.py DELETED
@@ -1,444 +0,0 @@
1
- import os
2
- import json
3
- import pathlib
4
- import mimetypes
5
- import gpxpy
6
- import pandas as pd
7
- import gradio as gr
8
- from datetime import datetime, timedelta
9
-
10
- import pytz
11
- from sunrisesunset import SunriseSunset
12
- from timezonefinder import TimezoneFinder
13
- tf = TimezoneFinder()
14
- from beaufort_scale.beaufort_scale import beaufort_scale_ms
15
-
16
- from wordsegment import load, segment
17
- load()
18
-
19
- import srtm
20
- elevation_data = srtm.get_data()
21
-
22
- import requests
23
-
24
- from geopy.geocoders import Nominatim
25
- geolocator = Nominatim(user_agent='FreeLetzWeather')
26
-
27
- from apscheduler.schedulers.background import BackgroundScheduler
28
-
29
- ### Default variables ###
30
-
31
- # Met no weather forecast API
32
- url = 'https://api.met.no/weatherapi/locationforecast/2.0/complete'
33
- headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'}
34
-
35
- # Weather icons URL
36
- icon_url = 'https://raw.githubusercontent.com/metno/weathericons/89e3173756248b4696b9b10677b66c4ef435db53/weather/svg/'
37
-
38
- # Custom CSS
39
- css = '''
40
- #button {background: DarkGoldenrod;}
41
- .buttons {color: white;}
42
- #table {height: 1080px;}
43
- .tables {height: 1080px;}
44
-
45
- .required-dropdown input:focus {
46
- color: white;
47
- background-color: DarkGoldenrod;
48
- box-shadow: 0 0 0 12px DarkGoldenrod;
49
- }
50
- '''
51
- # Default coordinates
52
- params = {'lat': 49.6108, 'lon': 6.1326, 'altitude': 310}
53
- lat=params['lat']
54
- lon=params['lon']
55
- altitude=params['altitude']
56
-
57
- # Default GPX if none is uploaded
58
- #directory = os.path.dirname(os.path.abspath(__file__))
59
- gpx_file = os.path.join(os.getcwd(), 'default_gpx.gpx')
60
- gpx_path = pathlib.Path(gpx_file)
61
-
62
- '''
63
- # Default dates
64
- #forecast_days = 3
65
- today = datetime.today()
66
- day_read = today.strftime('%A %-d %B')
67
- day_print = '<h2>' + day_read + '</h2>'
68
- dates_read = [(today + timedelta(days=x)).strftime('%A %-d %B %Y') for x in range(forecast_days)]
69
- dates_filt = [(today + timedelta(days=x)).strftime('%Y-%m-%d') for x in range(forecast_days)]
70
- dates_dict = dict(zip(dates_read, dates_filt))
71
- dates_list = list(dates_dict.keys())
72
- '''
73
-
74
- ### Functions ###
75
-
76
- # Pluviometry to natural language
77
- def rain_intensity(precipt):
78
- if precipt >= 50:
79
- rain = 'Extreme rain'
80
- elif 50 < precipt <= 16:
81
- rain = 'Very heavy rain'
82
- elif 4 <= precipt < 16:
83
- rain = 'Heavy rain'
84
- elif 1 <= precipt < 4:
85
- rain = 'Moderate rain'
86
- elif 0.25 <= precipt < 1:
87
- rain = 'Light rain'
88
- elif 0 < precipt < 0.25:
89
- rain = 'Light drizzle'
90
- else:
91
- rain = ''
92
- return rain
93
-
94
- # Generate dates for which the forecast is available
95
- # (today plus 10 days ahead)
96
-
97
- '''
98
- def gen_dates():
99
-
100
- global dates_dict
101
- global dates_list
102
- global day_read
103
- global today
104
-
105
- today = datetime.today()
106
- day_read = today.strftime('%A %-d %B')
107
- dates_read = [(today + timedelta(days=x)).strftime('%A %-d %B %Y') for x in range(forecast_days)]
108
- dates_filt = [(today + timedelta(days=x)).strftime('%Y-%m-%d') for x in range(forecast_days)]
109
- dates_dict = dict(zip(dates_read, dates_filt))
110
- dates_list = list(dates_dict.keys())
111
- return dates_dict
112
- '''
113
-
114
- def gen_dates():
115
-
116
- global dates_filt
117
- global dates_dict
118
- global dates_list
119
- global day_read
120
- global today
121
-
122
- today = datetime.today()
123
- day_read = today.strftime('%A %-d %B')
124
-
125
- resp = requests.get(url=url, headers=headers, params=params)
126
- data = resp.json()
127
-
128
- dates_aval = []
129
- for d in data['properties']['timeseries']:
130
- if 'next_1_hours' in d['data']:
131
- date = datetime.strptime(d['time'], '%Y-%m-%dT%H:%M:%SZ')
132
- dates_aval.append(date.date())
133
-
134
- dates_aval = sorted(set(dates_aval))
135
-
136
- if len(dates_aval) > 3:
137
- dates_aval = dates_aval[:3]
138
-
139
- dates_read = [x.strftime('%A %-d %B %Y') for x in dates_aval]
140
- dates_filt = [x.strftime('%Y-%m-%d') for x in dates_aval]
141
-
142
-
143
- dates_dict = dict(zip(dates_read, dates_filt))
144
- dates_list = list(dates_dict.keys())
145
-
146
- return dates_dict
147
-
148
- def gen_dates_list():
149
-
150
- global dates_filt
151
- global dates_dict
152
- global dates_list
153
- global day_read
154
- global today
155
-
156
- today = datetime.today()
157
- day_read = today.strftime('%A %-d %B')
158
-
159
- resp = requests.get(url=url, headers=headers, params=params)
160
- data = resp.json()
161
-
162
- dates_aval = []
163
- for d in data['properties']['timeseries']:
164
- if 'next_1_hours' in d['data']:
165
- date = datetime.strptime(d['time'], '%Y-%m-%dT%H:%M:%SZ')
166
- dates_aval.append(date.date())
167
-
168
- dates_aval = sorted(set(dates_aval))
169
-
170
- if len(dates_aval) > 3:
171
- dates_aval = dates_aval[:3]
172
-
173
- dates_read = [x.strftime('%A %-d %B %Y') for x in dates_aval]
174
- dates_filt = [x.strftime('%Y-%m-%d') for x in dates_aval]
175
-
176
-
177
- dates_dict = dict(zip(dates_read, dates_filt))
178
- dates_list = list(dates_dict.keys())
179
-
180
- return dates_list
181
-
182
- def gen_dropdown():
183
-
184
- global dates_filt
185
- global dates_dict
186
- global dates_list
187
- global day_read
188
- global today
189
-
190
- today = datetime.today()
191
- day_read = today.strftime('%A %-d %B')
192
-
193
- resp = requests.get(url=url, headers=headers, params=params)
194
- data = resp.json()
195
-
196
- dates_aval = []
197
- for d in data['properties']['timeseries']:
198
- if 'next_1_hours' in d['data']:
199
- date = datetime.strptime(d['time'], '%Y-%m-%dT%H:%M:%SZ')
200
- dates_aval.append(date.date())
201
-
202
- dates_aval = sorted(set(dates_aval))
203
-
204
- if len(dates_aval) > 3:
205
- dates_aval = dates_aval[:3]
206
-
207
- dates_read = [x.strftime('%A %-d %B %Y') for x in dates_aval]
208
- dates_filt = [x.strftime('%Y-%m-%d') for x in dates_aval]
209
-
210
-
211
- dates_dict = dict(zip(dates_read, dates_filt))
212
- dates_list = list(dates_dict.keys())
213
-
214
- dates = gr.Dropdown(choices=dates_list, label='2. Pick up the date of your hike', value=dates_list[0], interactive=True, elem_classes='required-dropdown')
215
-
216
- return dates
217
-
218
- # Default dates
219
- #forecast_days = 3
220
- today = datetime.today()
221
- day_read = today.strftime('%A %-d %B')
222
- day_print = '<h2>' + day_read + '</h2>'
223
- dates_dict = gen_dates()
224
- dates_list = list(dates_dict.keys())
225
- dates_read = list(dates_dict.keys())
226
- dates_filt = list(dates_dict.values())
227
-
228
- def sunrise_sunset(lat, lon, day):
229
-
230
- tz = tf.timezone_at(lng=lon, lat=lat)
231
- zone = pytz.timezone(tz)
232
-
233
- dt = day.astimezone(zone)
234
-
235
- rs = SunriseSunset(dt, lat=lat, lon=lon, zenith='official')
236
- rise_time, set_time = rs.sun_rise_set
237
-
238
- sunrise = rise_time.strftime('%H:%M')
239
- sunset = set_time.strftime('%H:%M')
240
-
241
- sunrise_icon = '<img style="float: left;" width="24px" src=' + icon_url + 'clearsky_day.svg>'
242
- sunset_icon = '<img style="float: left;" width="24px" src=' + icon_url + 'clearsky_night.svg>'
243
-
244
- sunrise = '<h6>' + sunrise_icon + ' Sunrise ' + sunrise + '</h6>'
245
- sunset = '<h6>' + sunset_icon + ' Sunset ' + sunset + '</h6>'
246
-
247
- return sunrise, sunset
248
-
249
- sunrise, sunset = sunrise_sunset(lat, lon, today)
250
-
251
- # Download the JSON and filter it per date
252
- def json_parser(date):
253
-
254
- global dfs
255
- #global dates_dict
256
- #global dates_list
257
-
258
- #dates_dict = gen_dates()
259
- #dates_list = list(dates_dict.keys())
260
- resp = requests.get(url=url, headers=headers, params=params)
261
- data = resp.json()
262
-
263
- day = date
264
-
265
- dict_weather = {'Time': [], 'Weather': [], 'Weather outline': [], 'Temp (°C)': [], 'Rain (mm/h)': [], 'Rain level': [], 'Wind (m/s)': [], 'Wind level': [] }
266
-
267
-
268
- #av_dates = []
269
- for d in data['properties']['timeseries']:
270
- date = datetime.strptime(d['time'], '%Y-%m-%dT%H:%M:%SZ')
271
- date_read = date.strftime('%Y-%m-%d')
272
- #av_dates.append(date.date())
273
-
274
- if date_read == day:
275
- dict_weather['Time'].append(date.strftime('%H'))
276
- weather = d['data']['next_1_hours']['summary']['symbol_code']
277
- icon_path = '<img style="float: left; padding: 0; margin: -6px; display: block;" width=32px; src=' + icon_url + weather + '.svg>'
278
- dict_weather['Weather'].append(icon_path)
279
- weather_read = ' '.join(segment(weather.replace('_', '')))
280
- dict_weather['Weather outline'].append(weather_read)
281
- temp = d['data']['instant']['details']['air_temperature']
282
- dict_weather['Temp (°C)'].append(str(int(round(temp, 0))) + '°')
283
- rain = d['data']['next_1_hours']['details']['precipitation_amount']
284
- dict_weather['Rain (mm/h)'].append(rain)
285
- dict_weather['Rain level'].append(rain_intensity(rain))
286
- wind = d['data']['instant']['details']['wind_speed']
287
- dict_weather['Wind (m/s)'].append(wind)
288
- dict_weather['Wind level'].append(beaufort_scale_ms(wind, language='en'))
289
-
290
- df = pd.DataFrame(dict_weather)
291
-
292
- df['Weather outline'] = df['Weather outline'].str.capitalize().str.replace(' night','').str.replace(' day','')
293
- df[['Rain (mm/h)', 'Wind (m/s)']] = df[['Rain (mm/h)', 'Wind (m/s)']].round(1).replace({0:''}).astype(str)
294
-
295
- #df.to_csv('weather.csv', index=False)
296
-
297
- dfs = df.style.set_properties(**{'border': '0px'})
298
-
299
- return dfs
300
-
301
- dfs = json_parser(dates_filt[0])
302
-
303
- # Extract coordinates and location from GPX file
304
- # gpx_name = '1. Click the upload GPX button to begin'
305
- def coor_gpx(gpx):
306
-
307
- global gpx_name
308
- global params
309
- global lat
310
- global lon
311
- global altitude
312
- global location
313
- global dates_dict
314
- global dates_list
315
- global day_read
316
-
317
- dates_dict = gen_dates()
318
- dates_list = list(dates_dict.keys())
319
- day_read = dates_list[0]
320
- date_filt = datetime.strptime(day_read, '%A %d %B %Y')
321
- date_filt = date_filt.strftime('%Y-%m-%d')
322
- day_print = '<h2>' + day_read + '</h2>'
323
-
324
- #if mimetypes.guess_type(gpx.name)[0] in ['application/gpx+xml', 'application/xml']:
325
- try:
326
- with open(gpx.name) as f:
327
- gpx_parsed = gpxpy.parse(f)
328
- # Convert to a dataframe one point at a time.
329
- points = []
330
- for track in gpx_parsed.tracks:
331
- for segment in track.segments:
332
- for p in segment.points:
333
- points.append({
334
- 'lat': p.latitude,
335
- 'lon': p.longitude,
336
- 'altitude': p.elevation,
337
- })
338
- df_gpx = pd.DataFrame.from_records(points)
339
- #df_gpx = pd.read_xml(gpx.name, xpath=".//doc:trkseg/doc:trkpt", namespaces={"doc": "http://www.topografix.com/GPX/1/1"})
340
- params = df_gpx.iloc[-1].to_dict()
341
- lat = params['lat']
342
- lon = params['lon']
343
-
344
- if params['altitude'] == None:
345
- params['altitude'] = int(round(elevation_data.get_elevation(lat, lon), 0))
346
- else:
347
- params['altitude'] = int(round(params['altitude'], 0))
348
-
349
- #params['altitude'] = int(round(params['altitude'], 0))
350
- altitude = params['altitude']
351
-
352
- location = geolocator.reverse('{}, {}'.format(lat, lon), zoom=14)
353
-
354
- gpx_name = 'You have uploaded <b style="color: #004170;">' + os.path.basename(gpx.name) + '</b>'
355
- location = '<p style="color: #004170">' + str(location) + '</p>'
356
-
357
- sunrise, sunset = sunrise_sunset(lat, lon, datetime.strptime(day_read, '%A %d %B %Y'))
358
-
359
- dates = gr.Dropdown(choices=dates_list, label='2. Next, pick up the date of your hike', value=dates_list[0], interactive=True, elem_classes='required-dropdown')
360
-
361
- dfs = json_parser(date_filt)
362
-
363
- return gpx_name, location, dates, day_print, sunrise, sunset, dfs
364
-
365
- except:
366
- sunrise, sunset = sunrise_sunset(lat, lon, today)
367
- dfs = json_parser(dates_filt[0])
368
- gpx_name = '<b style="color: firebrick;">ERROR: Not a valid GPX file. Upload another file.</b>'
369
- return gpx_name, location, dates_list, day_print, sunrise, sunset, dfs
370
- #else:
371
- # sunrise, sunset = sunrise_sunset(lat, lon, today)
372
- # dfs = json_parser(dates_filt[0])
373
- # gpx_name = '<b style="color: firebrick;">ERROR: Not a valid GPX file. Upload another file.</b>'
374
- # return gpx_name, location, dates_list, day_print, sunrise, sunset, dfs
375
-
376
- coor_gpx(gpx_path)
377
-
378
- # Choose a date from the dropdown menu
379
- def date_chooser(day):
380
- global day_read
381
- global sunrise
382
- global sunset
383
- global sunrise_icon
384
- global sunset_icon
385
- global dates_dict
386
- global dates_list
387
-
388
- dates_dict = gen_dates()
389
- dates_list = list(dates_dict.keys())
390
-
391
- day_read = day
392
- day_print = '<h2>' + day_read + '</h2>'
393
-
394
- date = datetime.strptime(day, '%A %d %B %Y')
395
-
396
- index = dates_list.index(day)
397
-
398
- sunrise, sunset = sunrise_sunset(lat, lon, date)
399
-
400
- date_filt = date.strftime('%Y-%m-%d')
401
- dfs = json_parser(date_filt)
402
-
403
- dates = gr.Dropdown(choices=dates_list, label='2. Next, pick up the date of your hike', value=dates_list[index], interactive=True, elem_classes='required-dropdown')
404
-
405
- return day_print, sunrise, sunset, dfs, dates
406
-
407
- ### Gradio app ###
408
- with gr.Blocks(theme='ParityError/Interstellar', css=css, fill_height=True) as demo:
409
- with gr.Column():
410
- with gr.Row():
411
- gr.HTML('<h1 style="color: DarkGoldenrod">Freedom Luxembourg<br><h3 style="color: #004170">The Weather for Hikers</h3></h1>')
412
- with gr.Column():
413
- upload_gpx = gr.UploadButton(label='1. Upload your GPX track', file_count='single', size='lg', file_types=['.gpx', '.GPX'], elem_id='button', elem_classes='buttons', interactive=True)
414
- file_name = gr.HTML('<h6>' + gpx_name + '</h6>')
415
- dates = gr.Dropdown(choices=gen_dates_list(), label='2. Pick up the date of your hike', value=dates_list[0], interactive=True, elem_classes='required-dropdown')
416
- gr.HTML('<h1><br></h1>')
417
- with gr.Row():
418
- choosen_date = gr.HTML(day_print)
419
- loc = gr.HTML('<p style="color: #004170">' + str(location) + '</p>')
420
- sunrise = gr.HTML(sunrise)
421
- sunset = gr.HTML(sunset)
422
- table = gr.DataFrame(dfs, max_height=1000, type='pandas', headers=None, line_breaks=False, interactive=False, wrap=True, visible=True, render=True,
423
- elem_id='table', elem_classes='tables',
424
- datatype=['str', 'html', 'str', 'str', 'str', 'str', 'str', 'str'],
425
- )
426
- gr.HTML('<center>Freedom Luxembourg<br><a style="color: DarkGoldenrod; font-style: italic; text-decoration: none" href="https://www.freeletz.lu/freeletz/" target="_blank">freeletz.lu</a></center>')
427
- gr.HTML('<center>Powered by the <a style="color: #004170; text-decoration: none" href="https://api.met.no/weatherapi/locationforecast/2.0/documentation" target="_blank">Norwegian Meteorological Institute</a> API</center>')
428
- #demo.load(fn=date_chooser, inputs=dates, outputs=[choosen_date, sunrise, sunset, table, dates])
429
- upload_gpx.upload(fn=coor_gpx, inputs=upload_gpx, outputs=[file_name, loc, dates, choosen_date, sunrise, sunset, table])
430
- demo.load(gen_dropdown, None, dates)
431
- dates.input(fn=date_chooser, inputs=dates, outputs=[choosen_date, sunrise, sunset, table, dates])
432
-
433
-
434
- def restart_app():
435
- demo.close()
436
- port = int(os.environ.get('PORT', 7860))
437
- demo.launch(server_name="0.0.0.0", server_port=port)
438
-
439
- scheduler = BackgroundScheduler({'apscheduler.timezone': 'Europe/Luxembourg'})
440
- scheduler.add_job(func=restart_app, trigger='cron', hour='00', minute='01')
441
- scheduler.start()
442
-
443
- port = int(os.environ.get('PORT', 7860))
444
- demo.launch(server_name="0.0.0.0", server_port=port)