diff --git a/NuWeather/config.py b/NuWeather/config.py index 8eb5c06..f3d1ff1 100644 --- a/NuWeather/config.py +++ b/NuWeather/config.py @@ -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') diff --git a/NuWeather/formatter.py b/NuWeather/formatter.py index 8fa9278..8c1a489 100644 --- a/NuWeather/formatter.py +++ b/NuWeather/formatter.py @@ -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): """ diff --git a/NuWeather/test.py b/NuWeather/test.py index c1cff51..6a079be 100644 --- a/NuWeather/test.py +++ b/NuWeather/test.py @@ -102,14 +102,37 @@ 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') - self.assertEqual(func(mi=26, km=42), '26mi/42km') + self.assertEqual(func(mi=123), '123mi / 197.9km') + self.assertEqual(func(km=42.6), '26.5mi / 42.6km') + self.assertEqual(func(mi=26, km=42), '26mi / 42km') 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 ')