NuWeather: implement configurable unit display for distance and speed

This is implemented as two new options using simple templates: plugins.nuweather.units.distance and plugins.nuweather.units.speed

Closes #101.
Closes #97.
This commit is contained in:
James Lu 2022-05-24 13:27:18 -07:00
parent cb49620a2d
commit 05b15b0111
3 changed files with 59 additions and 10 deletions

View File

@ -59,6 +59,23 @@ conf.registerChannelValue(NuWeather.units, 'temperature',
NuWeatherTemperatureDisplayMode('F/C', _("""Determines how temperatures will be displayed.
F/C means show "50F/10C", C means display only Celsius, and so on.""")))
class NuWeatherDistanceDisplayMode(registry.String):
"""Value must contain one of $mi, $km, or $m"""
def setValue(self, v):
if any(x in v for x in ('$mi', '$km', '$mi')):
registry.String.setValue(self, v)
else:
self.error()
conf.registerChannelValue(NuWeather.units, 'distance',
NuWeatherDistanceDisplayMode('$mi / $km', _("""Determines how distance values will be displayed.
The following template variables are supported, and at least one must be included:
$mi = miles, $km = kilometers, $m = meters.""")))
conf.registerChannelValue(NuWeather.units, 'speed',
NuWeatherDistanceDisplayMode('$mi / $km', _("""Determines how speed values will be displayed.
The following template variables are supported, and at least one must be included:
$mi = mph, $km = km/h, $m = m/s.""")))
# List of supported backends for weather & geocode. This is reused by plugin.py
BACKENDS = ('openweathermap', 'darksky', 'weatherstack')
GEOCODE_BACKENDS = ('nominatim', 'googlemaps', 'opencage', 'weatherstack')

View File

@ -182,8 +182,8 @@ def format_distance(mi=None, km=None, speed=False):
"""Formats distance or speed values in miles and kilometers"""
if mi is None and km is None:
return _('N/A')
elif mi == 0 or km == 0:
return '0' # Don't bother with 2 units if the value is 0
if mi == 0 or km == 0:
return '0' # Don't bother with multiple units if the value is 0
if mi is None:
mi = round(km / 1.609, 1)
@ -191,9 +191,18 @@ def format_distance(mi=None, km=None, speed=False):
km = round(mi * 1.609, 1)
if speed:
return _('%smph/%skph') % (mi, km)
m = f'{round(km / 3.6, 1)}m/s'
mi = f'{mi}mph'
km = f'{km}km/h'
displaymode = _registryValue('units.speed', channel=_channel_context)
else:
return _('%smi/%skm') % (mi, km)
m = f'{round(km * 1000, 1)}m'
mi = f'{mi}mi'
km = f'{km}km'
displaymode = _registryValue('units.distance', channel=_channel_context)
return string.Template(displaymode).safe_substitute(
{'mi': mi, 'km': km, 'm': m}
)
def format_percentage(value):
"""

View File

@ -102,7 +102,7 @@ class NuWeatherFormatterTestCase(unittest.TestCase):
with conf.supybot.plugins.NuWeather.units.temperature.context('F'):
self.assertEqual(func(f=72), '\x030872.0F\x03')
def test_format_distance_speed(self):
def test_format_distance(self):
func = formatter.format_distance
self.assertEqual(func(mi=123), '123mi / 197.9km')
self.assertEqual(func(km=42.6), '26.5mi / 42.6km')
@ -110,6 +110,29 @@ class NuWeatherFormatterTestCase(unittest.TestCase):
self.assertEqual(func(mi=0), '0') # special case
self.assertEqual(func(), 'N/A')
def test_format_distance_speed(self):
func = lambda *args, **kwargs: formatter.format_distance(*args, speed=True, **kwargs)
self.assertEqual(func(mi=123), '123mph / 197.9km/h')
self.assertEqual(func(km=42.6), '26.5mph / 42.6km/h')
self.assertEqual(func(mi=26, km=42), '26mph / 42km/h')
self.assertEqual(func(mi=0), '0') # special case
self.assertEqual(func(), 'N/A')
def test_format_distance_displaymode(self):
func = formatter.format_distance
with conf.supybot.plugins.NuWeather.units.distance.context('$mi / $km / $m'):
self.assertEqual(func(mi=123), '123mi / 197.9km / 197900.0m')
self.assertEqual(func(km=42.6), '26.5mi / 42.6km / 42600.0m')
with conf.supybot.plugins.NuWeather.units.distance.context('$m/$km'):
self.assertEqual(func(km=2), '2000m/2km')
def test_format_distance_speed_displaymode(self):
func = lambda *args, **kwargs: formatter.format_distance(*args, speed=True, **kwargs)
with conf.supybot.plugins.NuWeather.units.speed.context('$mi / $km / $m'):
self.assertEqual(func(mi=123), '123mph / 197.9km/h / 55.0m/s')
with conf.supybot.plugins.NuWeather.units.speed.context('$m / $km'):
self.assertEqual(func(km=2), '0.6m/s / 2km/h')
def test_format_default(self):
data = {'location': "Narnia",
'poweredby': 'Dummy',
@ -137,8 +160,8 @@ class NuWeatherFormatterTestCase(unittest.TestCase):
self.assertEqual(formatter.format_weather(data),
'\x02Narnia\x02 :: Sunny \x030780.0F/26.7C\x03 (Humidity: 80%) | '
'\x02Feels like:\x02 \x030785.0F/29.4C\x03 | '
'\x02Wind\x02: 12mph/19.3kph NNE | '
'\x02Wind gust\x02: 20mph/32.2kph | '
'\x02Wind\x02: 12mph / 19.3km/h NNE | '
'\x02Wind gust\x02: 20mph / 32.2km/h | '
'\x02Today\x02: Cloudy. High \x0304100.0F/37.8C\x03. Low \x030360.0F/15.6C\x03. | '
'\x02Tomorrow\x02: Light rain. High \x030870.0F/21.1C\x03. Low \x030955.0F/12.8C\x03. | '
'Powered by \x02Dummy\x02 <http://dummy.invalid/api/>')