mirror of
https://github.com/jlu5/SupyPlugins.git
synced 2025-04-30 15:31:11 -05:00
NuWeather: add Google Maps backend (#79)
This commit is contained in:
parent
ff044013ca
commit
f76614c10c
@ -60,15 +60,24 @@ conf.registerChannelValue(NuWeather.units, 'temperature',
|
|||||||
F/C means show "50F/10C", C means display only Celsius, and so on.""")))
|
F/C means show "50F/10C", C means display only Celsius, and so on.""")))
|
||||||
|
|
||||||
BACKENDS = ('darksky', 'apixu')
|
BACKENDS = ('darksky', 'apixu')
|
||||||
|
GEOCODE_BACKENDS = ('nominatim', 'googlemaps')
|
||||||
class NuWeatherBackend(registry.OnlySomeStrings):
|
class NuWeatherBackend(registry.OnlySomeStrings):
|
||||||
validStrings = BACKENDS
|
validStrings = BACKENDS
|
||||||
|
class NuWeatherGeocode(registry.OnlySomeStrings):
|
||||||
|
validStrings = GEOCODE_BACKENDS
|
||||||
|
|
||||||
conf.registerChannelValue(NuWeather, 'defaultBackend',
|
conf.registerChannelValue(NuWeather, 'defaultBackend',
|
||||||
NuWeatherBackend(BACKENDS[0], _("""Determines the default weather backend.""")))
|
NuWeatherBackend(BACKENDS[0], _("""Determines the default weather backend.""")))
|
||||||
|
|
||||||
|
conf.registerChannelValue(NuWeather, 'geocodeBackend',
|
||||||
|
NuWeatherGeocode(GEOCODE_BACKENDS[0], _("""Determines the default geocode backend.""")))
|
||||||
|
|
||||||
for backend in BACKENDS:
|
for backend in BACKENDS:
|
||||||
conf.registerGlobalValue(NuWeather.apikeys, backend,
|
conf.registerGlobalValue(NuWeather.apikeys, backend,
|
||||||
registry.String("", _("""Sets the API key for %s.""") % backend, private=True))
|
registry.String("", _("""Sets the API key for %s.""") % backend, private=True))
|
||||||
|
for backend in GEOCODE_BACKENDS:
|
||||||
|
conf.registerGlobalValue(NuWeather.apikeys, backend,
|
||||||
|
registry.String("", _("""Sets the API key for %s.""") % backend, private=True))
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_FORMAT = ('\x02$location\x02 :: $c__condition $c__temperature '
|
DEFAULT_FORMAT = ('\x02$location\x02 :: $c__condition $c__temperature '
|
||||||
|
@ -48,7 +48,7 @@ except ImportError:
|
|||||||
pendulum = None
|
pendulum = None
|
||||||
log.warning('NuWeather: pendulum is not installed; extended forecasts will not be formatted properly')
|
log.warning('NuWeather: pendulum is not installed; extended forecasts will not be formatted properly')
|
||||||
|
|
||||||
from .config import BACKENDS, DEFAULT_FORMAT, DEFAULT_FORECAST_FORMAT
|
from .config import BACKENDS, GEOCODE_BACKENDS, DEFAULT_FORMAT, DEFAULT_FORECAST_FORMAT
|
||||||
from .local import accountsdb
|
from .local import accountsdb
|
||||||
|
|
||||||
HEADERS = {
|
HEADERS = {
|
||||||
@ -255,9 +255,6 @@ class NuWeather(callbacks.Plugin):
|
|||||||
|
|
||||||
def _nominatim_geocode(self, location):
|
def _nominatim_geocode(self, location):
|
||||||
location = location.lower()
|
location = location.lower()
|
||||||
if location in self.geocode_db:
|
|
||||||
self.log.debug('NuWeather: using cached latlon %s for location %s', self.geocode_db[location], location)
|
|
||||||
return self.geocode_db[location]
|
|
||||||
|
|
||||||
url = 'https://nominatim.openstreetmap.org/search/%s?format=jsonv2' % utils.web.urlquote(location)
|
url = 'https://nominatim.openstreetmap.org/search/%s?format=jsonv2' % utils.web.urlquote(location)
|
||||||
self.log.debug('NuWeather: using url %s (geocoding)', url)
|
self.log.debug('NuWeather: using url %s (geocoding)', url)
|
||||||
@ -265,7 +262,7 @@ class NuWeather(callbacks.Plugin):
|
|||||||
f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
|
f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
|
||||||
data = json.loads(f)
|
data = json.loads(f)
|
||||||
if not data:
|
if not data:
|
||||||
raise callbacks.Error("Unknown location %s." % location)
|
raise callbacks.Error("Unknown location %s from OSM/Nominatim" % location)
|
||||||
|
|
||||||
data = data[0]
|
data = data[0]
|
||||||
# Limit location verbosity to 3 divisions (e.g. City, Province/State, Country)
|
# Limit location verbosity to 3 divisions (e.g. City, Province/State, Country)
|
||||||
@ -279,14 +276,50 @@ class NuWeather(callbacks.Plugin):
|
|||||||
lat = data['lat']
|
lat = data['lat']
|
||||||
lon = data['lon']
|
lon = data['lon']
|
||||||
osm_id = data.get('osm_id')
|
osm_id = data.get('osm_id')
|
||||||
self.log.debug('NuWeather: saving %s,%s (osm_id %s, %s) for location %s', lat, lon, osm_id, display_name, location)
|
self.log.debug('NuWeather: saving %s,%s (osm_id %s, %s) for location %s from OSM/Nominatim', lat, lon, osm_id, display_name, location)
|
||||||
|
|
||||||
result = (lat, lon, display_name, osm_id)
|
result = (lat, lon, display_name, osm_id, "OSM/Nominatim")
|
||||||
self.geocode_db[location] = result # Cache result persistently
|
self.geocode_db[location] = result # Cache result persistently
|
||||||
return result
|
return result
|
||||||
|
|
||||||
_geocode = _nominatim_geocode # Maybe we'll add more backends for this in the future?
|
def _googlemaps_geocode(self, location):
|
||||||
_geocode.backend = "OSM/Nominatim"
|
location = location.lower()
|
||||||
|
apikey = self.registryValue('apikeys.googlemaps')
|
||||||
|
if not apikey:
|
||||||
|
raise callbacks.Error("No Google Geocode API key.", Raise=True)
|
||||||
|
url = "https://maps.googleapis.com/maps/api/geocode/json?address={0}&key={1}".format(utils.web.urlquote(location), apikey)
|
||||||
|
self.log.debug('NuWeather: using url %s (geocoding)', url)
|
||||||
|
# Custom User agent & caching are required for Nominatim per https://operations.osmfoundation.org/policies/nominatim/
|
||||||
|
f = utils.web.getUrl(url, headers=HEADERS).decode('utf-8')
|
||||||
|
data = json.loads(f)
|
||||||
|
if data['status'] != "OK":
|
||||||
|
raise callbacks.Error("{0} from GoogleMaps for location {1}".format(data['status'], location))
|
||||||
|
data = data['results'][0]
|
||||||
|
lat = data['geometry']['location']['lat']
|
||||||
|
lon = data['geometry']['location']['lng']
|
||||||
|
display_name = data['formatted_address']
|
||||||
|
place_id = data['place_id']
|
||||||
|
self.log.debug('NuWeather: saving %s,%s (place_id %s, %s) for location %s from GoogleMaps', lat, lon, place_id, display_name, location)
|
||||||
|
result = (lat, lon, display_name, place_id, "GoogleMaps")
|
||||||
|
self.geocode_db[location] = result # Cache result persistently
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _geocode (self, location):
|
||||||
|
geocode_backend = self.registryValue('geocodeBackend', dynamic.msg.args[0])
|
||||||
|
if geocode_backend not in GEOCODE_BACKENDS:
|
||||||
|
irc.error(_("Unknown geocode backend %s. Valid ones are: %s") % (geocode_backend, ', '.join(GEOCODE_BACKENDS)), Raise=True)
|
||||||
|
|
||||||
|
if location in self.geocode_db:
|
||||||
|
self.log.debug('NuWeather: using cached latlon %s for location %s', self.geocode_db[location], location)
|
||||||
|
if len(self.geocode_db[location]) > 4:
|
||||||
|
return self.geocode_db[location]
|
||||||
|
else:
|
||||||
|
self.geocode_db[location].append("OSM/Nominatim")
|
||||||
|
return self.geocode_db[location]
|
||||||
|
|
||||||
|
backend_func = getattr(self, '_%s_geocode' % geocode_backend)
|
||||||
|
result = backend_func(location)
|
||||||
|
return result
|
||||||
|
|
||||||
def _format(self, data, forecast=False):
|
def _format(self, data, forecast=False):
|
||||||
"""
|
"""
|
||||||
@ -363,7 +396,7 @@ class NuWeather(callbacks.Plugin):
|
|||||||
if not latlon:
|
if not latlon:
|
||||||
raise callbacks.Error("Unknown location %s." % location)
|
raise callbacks.Error("Unknown location %s." % location)
|
||||||
|
|
||||||
lat, lon, display_name, geocodeid = latlon
|
lat, lon, display_name, geocodeid, geocode_backend = latlon
|
||||||
|
|
||||||
# Request US units - this is reflected (mi, mph) and processed in our output format as needed
|
# Request US units - this is reflected (mi, mph) and processed in our output format as needed
|
||||||
url = 'https://api.darksky.net/forecast/%s/%s,%s?units=us&exclude=minutely' % (apikey, lat, lon)
|
url = 'https://api.darksky.net/forecast/%s/%s,%s?units=us&exclude=minutely' % (apikey, lat, lon)
|
||||||
@ -377,7 +410,7 @@ class NuWeather(callbacks.Plugin):
|
|||||||
# N.B. Dark Sky docs tell to not expect any values to exist except the timestamp attached to the response
|
# N.B. Dark Sky docs tell to not expect any values to exist except the timestamp attached to the response
|
||||||
return {
|
return {
|
||||||
'location': display_name,
|
'location': display_name,
|
||||||
'poweredby': 'Dark\xa0Sky+' + self._geocode.backend,
|
'poweredby': 'DarkSky+' + geocode_backend,
|
||||||
'url': 'https://darksky.net/forecast/%s,%s' % (lat, lon),
|
'url': 'https://darksky.net/forecast/%s,%s' % (lat, lon),
|
||||||
'current': {
|
'current': {
|
||||||
'condition': currentdata.get('summary', 'N/A'),
|
'condition': currentdata.get('summary', 'N/A'),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user