@@ 6,60 6,57 @@ from typing import Mapping
import requests
from cachecontrol import CacheControl # type: ignore
-request_cache = CacheControl(requests.session())
+REQUEST_CACHE = CacheControl(requests.session())
BASE_URL = "https://api.weather.gov"
-LOCAL = False
class Location:
short_name: str
long_name: str
- forecastUrl: str
- hourlyForecastUrl: str
- alertUrl: str
+ forecast_url: str
+ hourly_forecast_url: str
+ alert_url: str
def __init__(self, short_name: str, long_name: str, latitude: float, longitude: float):
self.short_name = short_name
self.long_name = long_name
+
trunc = lambda f: format(f, '.4f')
- api = f"{BASE_URL}/points/{trunc(latitude)},{trunc(longitude)}"
- if LOCAL:
- with open('point', 'r') as f:
- data = json.load(f)['properties']
- else:
- data = request_cache.get(api).json()['properties']
- self.forecastUrl = data['forecast']
- self.hourlyForecastUrl = data['forecastHourly']
+ url = f"{BASE_URL}/points/{trunc(latitude)},{trunc(longitude)}"
+ data = fetch_json(url, 'point')['properties']
+
+ self.forecast_url = data['forecast']
+ self.hourly_forecast_url = data['forecastHourly']
# TODO really?
- self.alertUrl = data['forecastZone'].replace('/zones/forecast', '/alerts/active/zone')
+ self.alert_url = data['forecastZone'].replace('/zones/forecast', '/alerts/active/zone')
def hourly(self):
- if LOCAL:
- with open('hourly', 'r') as f:
- return json.load(f)
- req = request_cache.get(self.hourlyForecastUrl)
- return req.json()
-
+ return fetch_json(self.hourly_forecast_url, 'hourly')
def forecast(self):
- if LOCAL:
- with open('forecast', 'r') as f:
- return json.load(f)
- req = request_cache.get(self.forecastUrl)
- return req.json()
+ return fetch_json(self.forecast_url, 'forecast')
def alerts(self):
- if LOCAL:
- with open('alerts', 'r') as f:
- return json.load(f)
- req = request_cache.get(self.alertUrl)
- return req.json()
+ return fetch_json(self.alert_url, 'alerts')
+
+
+LOCAL = False
+def fetch_json(url: str, default: str):
+ if LOCAL:
+ with open(default, 'r') as local_data:
+ return json.load(local_data)
+ else:
+ return REQUEST_CACHE.get(url).json()
def read_locations() -> Mapping[str, Location]:
- c = configparser.ConfigParser()
- c.read('locations.ini')
+ conf = configparser.ConfigParser()
+ conf.read('locations.ini')
result = {}
- for s in c.sections():
- result[s] = Location(s, c[s]['long_name'], c[s].getfloat('latitude'), c[s].getfloat('longitude'))
+ for long_name in conf.sections():
+ section = conf[long_name]
+ result[long_name] = Location(long_name,
+ section.get('long_name', long_name),
+ section.getfloat('latitude'),
+ section.getfloat('longitude'))
return result
@@ 3,7 3,7 @@ from typing import Optional
from flask import Flask, render_template
-from location import Location, read_locations
+from location import read_locations
app = Flask(__name__)
@@ 50,7 50,7 @@ def weather(key: Optional[str]):
@app.template_filter('quote')
-def quote(s):
+def quote(s: str):
return f'"{s}"'