mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-26 12:49:24 +01:00
Geography: Add 'localtime' command
This commit is contained in:
parent
36ade18319
commit
93a407a9ac
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from supybot import utils, plugins, ircutils, callbacks
|
from supybot import conf, utils, plugins, ircutils, callbacks
|
||||||
from supybot.commands import *
|
from supybot.commands import *
|
||||||
from supybot.i18n import PluginInternationalization
|
from supybot.i18n import PluginInternationalization
|
||||||
|
|
||||||
@ -40,6 +40,27 @@ from . import wikidata
|
|||||||
_ = PluginInternationalization("Geography")
|
_ = PluginInternationalization("Geography")
|
||||||
|
|
||||||
|
|
||||||
|
def timezone_from_uri(irc, uri):
|
||||||
|
try:
|
||||||
|
return wikidata.timezone_from_uri(uri)
|
||||||
|
except utils.time.UnknownTimeZone as e:
|
||||||
|
irc.error(
|
||||||
|
format(_("Could not understand timezone: %s"), e.args[0]),
|
||||||
|
Raise=True,
|
||||||
|
)
|
||||||
|
except utils.time.MissingTimezoneLibrary:
|
||||||
|
irc.error(
|
||||||
|
_(
|
||||||
|
"Timezone-related commands are not available. "
|
||||||
|
"Your administrator need to either upgrade Python to "
|
||||||
|
"version 3.9 or greater, or install pytz."
|
||||||
|
),
|
||||||
|
Raise=True,
|
||||||
|
)
|
||||||
|
except utils.time.TimezoneException as e:
|
||||||
|
irc.error(e.args[0], Raise=True)
|
||||||
|
|
||||||
|
|
||||||
class Geography(callbacks.Plugin):
|
class Geography(callbacks.Plugin):
|
||||||
"""Provides geography facts, such as timezones.
|
"""Provides geography facts, such as timezones.
|
||||||
|
|
||||||
@ -49,6 +70,38 @@ class Geography(callbacks.Plugin):
|
|||||||
|
|
||||||
threaded = True
|
threaded = True
|
||||||
|
|
||||||
|
@wrap(["text"])
|
||||||
|
def localtime(self, irc, msg, args, query):
|
||||||
|
"""<location name to search>
|
||||||
|
|
||||||
|
Returns the current used in the given location. For example,
|
||||||
|
the name could be "Paris" or "Paris, France". The response is
|
||||||
|
formatted according to supybot.reply.format.time
|
||||||
|
This uses data from Wikidata and Nominatim."""
|
||||||
|
osmids = nominatim.search_osmids(query)
|
||||||
|
if not osmids:
|
||||||
|
irc.error(_("Could not find the location"), Raise=True)
|
||||||
|
|
||||||
|
for osmid in osmids:
|
||||||
|
uri = wikidata.uri_from_osmid(osmid)
|
||||||
|
if not uri:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Get the timezone object (and handle various errors)
|
||||||
|
timezone = timezone_from_uri(irc, uri)
|
||||||
|
|
||||||
|
# Get the local time
|
||||||
|
now = datetime.datetime.now(tz=timezone)
|
||||||
|
|
||||||
|
format_ = conf.supybot.reply.format.time.getSpecific(
|
||||||
|
channel=msg.channel, network=irc.network
|
||||||
|
)()
|
||||||
|
|
||||||
|
# Return it
|
||||||
|
irc.reply(now.strftime(format_))
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
@wrap(["text"])
|
@wrap(["text"])
|
||||||
def timezone(self, irc, msg, args, query):
|
def timezone(self, irc, msg, args, query):
|
||||||
"""<location name to search>
|
"""<location name to search>
|
||||||
@ -68,24 +121,7 @@ class Geography(callbacks.Plugin):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Get the timezone object (and handle various errors)
|
# Get the timezone object (and handle various errors)
|
||||||
try:
|
timezone = timezone_from_uri(irc, uri)
|
||||||
timezone = wikidata.timezone_from_uri(uri)
|
|
||||||
except utils.time.UnknownTimeZone as e:
|
|
||||||
irc.error(
|
|
||||||
format(_("Could not understand timezone: %s"), e.args[0]),
|
|
||||||
Raise=True,
|
|
||||||
)
|
|
||||||
except utils.time.MissingTimezoneLibrary:
|
|
||||||
irc.error(
|
|
||||||
_(
|
|
||||||
"Timezone-related commands are not available. "
|
|
||||||
"Your administrator need to either upgrade Python to "
|
|
||||||
"version 3.9 or greater, or install pytz."
|
|
||||||
),
|
|
||||||
Raise=True,
|
|
||||||
)
|
|
||||||
except utils.time.TimezoneException as e:
|
|
||||||
irc.error(e.args[0], Raise=True)
|
|
||||||
|
|
||||||
# Extract a human-friendly name, depending on the type of
|
# Extract a human-friendly name, depending on the type of
|
||||||
# the timezone object:
|
# the timezone object:
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
###
|
###
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import functools
|
||||||
import contextlib
|
import contextlib
|
||||||
from unittest import skipIf
|
from unittest import skipIf
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
@ -50,31 +51,38 @@ from . import wikidata
|
|||||||
from . import nominatim
|
from . import nominatim
|
||||||
|
|
||||||
|
|
||||||
class GeographyTestCase(PluginTestCase):
|
def mock(f):
|
||||||
|
@functools.wraps(f)
|
||||||
|
def newf(self):
|
||||||
|
with patch.object(wikidata, "uri_from_osmid", return_value="foo"):
|
||||||
|
with patch.object(nominatim, "search_osmids", return_value=[42]):
|
||||||
|
f(self)
|
||||||
|
|
||||||
|
return newf
|
||||||
|
|
||||||
|
|
||||||
|
class GeographyTimezoneTestCase(PluginTestCase):
|
||||||
plugins = ("Geography",)
|
plugins = ("Geography",)
|
||||||
|
|
||||||
@skipIf(not pytz, "pytz is not available")
|
@skipIf(not pytz, "pytz is not available")
|
||||||
@patch.object(nominatim, "search_osmids", return_value=[42])
|
@mock
|
||||||
@patch.object(wikidata, "uri_from_osmid", return_value="foo")
|
def testTimezonePytz(self):
|
||||||
def testTimezonePytz(self, _, __):
|
|
||||||
tz = pytz.timezone("Europe/Paris")
|
tz = pytz.timezone("Europe/Paris")
|
||||||
|
|
||||||
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
||||||
self.assertResponse("timezone Foo Bar", "Europe/Paris")
|
self.assertResponse("timezone Foo Bar", "Europe/Paris")
|
||||||
|
|
||||||
@skipIf(not zoneinfo, "Python is older than 3.9")
|
@skipIf(not zoneinfo, "Python is older than 3.9")
|
||||||
@patch.object(nominatim, "search_osmids", return_value=[42])
|
@mock
|
||||||
@patch.object(wikidata, "uri_from_osmid", return_value="foo")
|
def testTimezoneZoneinfo(self):
|
||||||
def testTimezoneZoneinfo(self, _, __):
|
|
||||||
tz = zoneinfo.ZoneInfo("Europe/Paris")
|
tz = zoneinfo.ZoneInfo("Europe/Paris")
|
||||||
|
|
||||||
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
||||||
self.assertResponse("timezone Foo Bar", "Europe/Paris")
|
self.assertResponse("timezone Foo Bar", "Europe/Paris")
|
||||||
|
|
||||||
@skipIf(not zoneinfo, "Python is older than 3.9")
|
@skipIf(not zoneinfo, "Python is older than 3.9")
|
||||||
@patch.object(nominatim, "search_osmids", return_value=[42])
|
@mock
|
||||||
@patch.object(wikidata, "uri_from_osmid", return_value="foo")
|
def testTimezoneAbsolute(self):
|
||||||
def testTimezoneAbsolute(self, _, __):
|
|
||||||
tz = datetime.timezone(datetime.timedelta(hours=4))
|
tz = datetime.timezone(datetime.timedelta(hours=4))
|
||||||
|
|
||||||
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
||||||
@ -91,6 +99,44 @@ class GeographyTestCase(PluginTestCase):
|
|||||||
self.assertResponse("timezone Saint-Denis, La Réunion", "UTC+04:00")
|
self.assertResponse("timezone Saint-Denis, La Réunion", "UTC+04:00")
|
||||||
|
|
||||||
|
|
||||||
|
class GeographyLocaltimeTestCase(PluginTestCase):
|
||||||
|
plugins = ("Geography",)
|
||||||
|
|
||||||
|
@skipIf(not pytz, "pytz is not available")
|
||||||
|
@mock
|
||||||
|
def testLocaltimePytz(self):
|
||||||
|
tz = pytz.timezone("Europe/Paris")
|
||||||
|
|
||||||
|
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
||||||
|
self.assertRegexp("localtime Foo Bar", r".*\+0[12]00$")
|
||||||
|
|
||||||
|
@skipIf(not zoneinfo, "Python is older than 3.9")
|
||||||
|
@mock
|
||||||
|
def testLocaltimeZoneinfo(self):
|
||||||
|
tz = zoneinfo.ZoneInfo("Europe/Paris")
|
||||||
|
|
||||||
|
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
||||||
|
self.assertRegexp("localtime Foo Bar", r".*\+0[12]00$")
|
||||||
|
|
||||||
|
@skipIf(not zoneinfo, "Python is older than 3.9")
|
||||||
|
@mock
|
||||||
|
def testLocaltimeAbsolute(self):
|
||||||
|
tz = datetime.timezone(datetime.timedelta(hours=4))
|
||||||
|
|
||||||
|
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
||||||
|
self.assertRegexp("localtime Foo Bar", r".*\+0400$")
|
||||||
|
|
||||||
|
tz = datetime.timezone(datetime.timedelta(hours=4, minutes=30))
|
||||||
|
|
||||||
|
with patch.object(wikidata, "timezone_from_uri", return_value=tz):
|
||||||
|
self.assertRegexp("localtime Foo Bar", r".*\+0430$")
|
||||||
|
|
||||||
|
@skipIf(not network, "Network test")
|
||||||
|
def testLocaltimeIntegration(self):
|
||||||
|
self.assertRegexp("localtime Metz, France", r".*\+0[12]00$")
|
||||||
|
self.assertRegexp("localtime Saint-Denis, La Réunion", r".*\+0400$")
|
||||||
|
|
||||||
|
|
||||||
class GeographyWikidataTestCase(SupyTestCase):
|
class GeographyWikidataTestCase(SupyTestCase):
|
||||||
@skipIf(not network, "Network test")
|
@skipIf(not network, "Network test")
|
||||||
def testOsmidToTimezone(self):
|
def testOsmidToTimezone(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user