from datetime import datetime, timedelta, timezone import json import os import urllib.parse import urllib.request class DarkSkyAPI: def __init__(self, apikey=None, gps=None, opts={"lang": "fr", "units": "ca"}): self.apikey = apikey or os.environ["DARKSKYAPIKEY"] self.baseurl = "https://api.darksky.net/forecast" self.default_gps = gps or ("GPS" in os.environ and os.environ["GPS"]) or "48.8127,2.3437" self.opts = opts self._cached_file = ".darksky-%s.cache" def get_weather(self, gps=None): if gps is None: gps = self.default_gps # Read the mod time statinfo = None try: statinfo = os.stat(self._cached_file % gps) except: pass if statinfo is None or datetime.fromtimestamp(statinfo.st_mtime, tz=timezone.utc) + timedelta(hours=1) < datetime.now(tz=timezone.utc): # Do the request and save it with urllib.request.urlopen(self.baseurl + "/" + str(self.apikey) + "/" + gps + "?" + "&".join([opt+"="+self.opts[opt] for opt in self.opts])) as f: with open(self._cached_file % gps, 'wb') as fd: fd.write(f.read()) # Retrieve cached data res = {} with open(self._cached_file % gps) as f: res = json.load(f) return res def get_icon(icon, current=False): if icon == "clear-day": return "wi-day-sunny.png" elif icon == "clear-night": return "wi-night-clear.png" elif icon == "rain": if not current: return "wi-day-rain.png" else: return "wi-rain.png" elif icon == "snow": if not current: return "wi-day-snow.png" else: return "wi-snow.png" elif icon == "sleet": if not current: return "wi-day-sleet.png" else: return "wi-sleet.png" elif icon == "wind": if not current: return "wi-day-windy.png" else: return "wi-strong-wind.png" elif icon == "fog": if not current: return "wi-day-fog.png" else: return "wi-fog.png" elif icon == "cloudy": return "wi-cloudy.png" elif icon == "partly-cloudy-day": return "wi-day-cloudy.png" elif icon == "partly-cloudy-night": return "wi-night-partly-cloudy.png" elif icon == "hail": if not current: return "wi-day-hail.png" else: return "wi-hail.png" elif icon == "thunderstorm": if not current: return "wi-day-thunderstorm.png" else: return "wi-thunderstorm.png" elif icon == "tornado": return "wi-tornado.png" else: return "wi-alien.png" def get_moon_icon(self, day=0): moon_phase = self.get_daily()["data"][day]["moonPhase"] if moon_phase <= 0: return "wi-moon-alt-new.png" elif moon_phase <= 0.035: return "wi-moon-alt-waxing-crescent-1.png" elif moon_phase <= 0.071: return "wi-moon-alt-waxing-crescent-2.png" elif moon_phase <= 0.107: return "wi-moon-alt-waxing-crescent-3.png" elif moon_phase <= 0.142: return "wi-moon-alt-waxing-crescent-4.png" elif moon_phase <= 0.178: return "wi-moon-alt-waxing-crescent-5.png" elif moon_phase <= 0.214: return "wi-moon-alt-waxing-crescent-6.png" elif moon_phase <= 0.25: return "wi-moon-alt-first-quarter.png" elif moon_phase <= 0.285: return "wi-moon-alt-waxing-gibbous-1.png" elif moon_phase <= 0.321: return "wi-moon-alt-waxing-gibbous-2.png" elif moon_phase <= 0.357: return "wi-moon-alt-waxing-gibbous-3.png" elif moon_phase <= 0.392: return "wi-moon-alt-waxing-gibbous-4.png" elif moon_phase <= 0.428: return "wi-moon-alt-waxing-gibbous-5.png" elif moon_phase <= 0.464: return "wi-moon-alt-waxing-gibbous-6.png" elif moon_phase <= 0.5: return "wi-moon-alt-full.png" elif moon_phase <= 0.535: return "wi-moon-alt-waning-gibbous-1.png" elif moon_phase <= 0.571: return "wi-moon-alt-waning-gibbous-2.png" elif moon_phase <= 0.607: return "wi-moon-alt-waning-gibbous-3.png" elif moon_phase <= 0.642: return "wi-moon-alt-waning-gibbous-4.png" elif moon_phase <= 0.678: return "wi-moon-alt-waning-gibbous-5.png" elif moon_phase <= 0.714: return "wi-moon-alt-waning-gibbous-6.png" elif moon_phase <= 0.75: return "wi-moon-alt-third-quarter.png" elif moon_phase <= 0.785: return "wi-moon-alt-waning-crescent-1.png" elif moon_phase <= 0.821: return "wi-moon-alt-waning-crescent-2.png" elif moon_phase <= 0.857: return "wi-moon-alt-waning-crescent-3.png" elif moon_phase <= 0.892: return "wi-moon-alt-waning-crescent-4.png" elif moon_phase <= 0.928: return "wi-moon-alt-waning-crescent-5.png" elif moon_phase <= 0.964: return "wi-moon-alt-waning-crescent-6.png" else: return "wi-alien.png" def get_currently(self, *args, **kwargs): return self.get_weather(*args, **kwargs)["currently"] def get_hourly(self, *args, **kwargs): return self.get_weather(*args, **kwargs)["hourly"] def get_daily(self, *args, **kwargs): return self.get_weather(*args, **kwargs)["daily"] def has_alerts(self, *args, **kwargs): return "alerts" in self.get_weather(*args, **kwargs) and len(self.get_weather(*args, **kwargs)["alerts"]) > 0 def get_alerts(self, *args, **kwargs): return self.get_weather(*args, **kwargs)["alerts"] def read_timestamp(self, timestamp, *args, **kwargs): wth = self.get_weather(*args, **kwargs) tz = timezone(timedelta(hours=wth["offset"]), wth["timezone"]) return datetime.fromtimestamp(timestamp, tz=tz) WeatherAPI = DarkSkyAPI if __name__ == '__main__': dsa = DarkSkyAPI() print(dsa.get_currently())