Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improved localization #52

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 66 additions & 19 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ class OWMApi(Api):

def __init__(self):
super(OWMApi, self).__init__("owm")
self.lang = "en"
self.owmLang = "en"
forslund marked this conversation as resolved.
Show resolved Hide resolved
self.observation = ObservationParser()
self.forecast = ForecastParser()

def build_query(self, params):
params.get("query").update({"lang": self.lang})
params.get("query").update({"lang": self.owmLang})
return params.get("query")

def get_data(self, response):
Expand Down Expand Up @@ -111,6 +111,9 @@ def to_forecast(self, data, interval):
return Forecaster(forecast)
else:
return None

def set_OWM_language(self, lang):
self.owmLang = lang


class WeatherSkill(MycroftSkill):
Expand All @@ -132,7 +135,6 @@ def __init__(self):

# Use Mycroft proxy if no private key provided
key = self.config.get('api_key')

# TODO: Remove lat,lon parameters from the OWMApi()
# methods and implement _at_coords() versions
# instead to make the interfaces compatible
Expand All @@ -143,7 +145,9 @@ def __init__(self):
# else:
# self.owm = OWMApi()
self.owm = OWMApi()

if self.owm:
self.owm.set_OWM_language(lang=self.__get_OWM_language(self.lang))

# Handle: what is the weather like?
@intent_handler(IntentBuilder("").require(
"Weather").optionally("Location").build())
Expand All @@ -152,13 +156,12 @@ def handle_current_weather(self, message):
# Get a date from requests like "weather for next Tuesday"
today = extract_datetime(" ")[0]
when, _ = extract_datetime(
message.data.get('utterance'), lang=self.lang)
message.data.get('utterance'), lang=self.lang)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra space at the end.

if today != when:
LOG.info("Doing a forecast" + str(today) + " " + str(when))
return self.handle_forecast(message)

report = self.__initialize_report(message)

# Get current conditions
currentWeather = self.owm.weather_at_place(
report['full_location'], report['lat'],
Expand All @@ -167,7 +170,7 @@ def handle_current_weather(self, message):
report['condition'] = condition
report['temp'] = self.__get_temperature(currentWeather, 'temp')
report['icon'] = currentWeather.get_weather_icon_name()

domcross marked this conversation as resolved.
Show resolved Hide resolved
# Get forecast for the day
# can get 'min', 'max', 'eve', 'morn', 'night', 'day'
# Set time to 12 instead of 00 to accomodate for timezones
Expand All @@ -194,6 +197,7 @@ def handle_forecast(self, message):
report = self.__initialize_report(message)

# Get a date from spoken request
LOG.debug("lang %s" % self.lang)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a critical thing but I think it's better to use the new style 'lang {}'.format(self.lang) instead of the old % notation.

when = extract_datetime(message.data.get('utterance'),
lang=self.lang)[0]

Expand Down Expand Up @@ -428,7 +432,7 @@ def handle_sunrise(self, message):

dtSunriseUTC = datetime.fromtimestamp(weather.get_sunrise_time())
dtLocal = self.__to_Local(dtSunriseUTC)
self.speak(nice_time(dtLocal, use_ampm=True))
self.speak(self.__nice_time(dtLocal, lang=self.lang, use_ampm=True))

# Handle: When is the sunset?
@intent_handler(IntentBuilder("").require(
Expand Down Expand Up @@ -457,7 +461,7 @@ def handle_sunset(self, message):

dtSunriseUTC = datetime.fromtimestamp(weather.get_sunset_time())
dtLocal = self.__to_Local(dtSunriseUTC)
self.speak(nice_time(dtLocal, use_ampm=True))
self.speak(self.__nice_time(dtLocal, lang=self.lang, use_ampm=True))

def __get_location(self, message):
# Attempt to extract a location from the spoken phrase. If none
Expand Down Expand Up @@ -576,9 +580,25 @@ def __api_error(self, e):
def __to_day(self, when):
# TODO: This will be a compatibility wrapper for
# mycroft.util.format.relative_day(when)
if self.lang =='sv-se':
LOG.debug("lang %s" % self.lang)
if self.lang.lower().startswith("sv"):
days = ['Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag',
'Lördag', 'Söndag']
elif self.lang.lower().startswith("de"):
days = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag',
'Samstag', 'Sonntag']
elif self.lang.lower().startswith("es"):
days = ['Lunes', 'Martes', u'Miércoles',
'Jueves', 'Viernes', u'Sábado', 'Domingo']
elif self.lang.lower().startswith("fr"):
days = ["Lundi", "Mardi", "Mercredi",
"Jeudi", "Vendredi", "Samedi", "Dimanche"]
elif self.lang.lower().startswith("it"):
days = ['Lunedi', 'Martedi', 'Mercoledi',
'Giovedi', 'Venerdi', 'Sabato', 'Domenica']
elif self.lang.lower().startswith("pt"):
days = ['Segunda', 'Terca', 'Quarta',
'Quinta', 'Sexta', 'Sabado', 'Domingo']
else:
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
'Saturday', 'Sunday']
Expand Down Expand Up @@ -607,17 +627,44 @@ def __to_Local(self, when):

def __translate(self, condition, future=False, data=None):
if future:
# Convert things like "sky is clear" to a future tense
try:
if (condition + ".future") in self.dialog_renderer.templates:
return self.dialog_renderer.render(condition + ".future", data)
except BaseException:
return condition

if condition in self.dialog_renderer.templates:
return self.dialog_renderer.render(condition, data)
else:
try:
return self.dialog_renderer.render(condition, data)
except BaseException:
return condition

return condition

"""
OWM supports 31 languages, see https://openweathermap.org/current#multi

If Mycroft's language setting is supported by OWM,
then use it - or use 'en' otherwise
"""
def __get_OWM_language(self, lang):
owmLang = 'en'
owmMulti = ['ar','bg','ca','cz','de','el','en','fa','fi','fr','gl',
'hr','hu','it','ja','kr','la','lt','mk','nl','pl','pt',
'ro','ru','se','sk','sl','es','tr','ua','vi']

lang = lang.lower()
LOG.debug("lang %s" % lang)
if lang == 'zh_zn' or lang == 'zh_tw':
owmLang = lang
elif lang[0:2] in owmMulti:
owmLang = lang[0:2]
LOG.debug("lang: %s owmLang: %s" % (lang, owmLang))
return owmLang
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this will work 100% accurately.

for swedish the language code in mycroft is sv-se which will not work with the lang[0:2].

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went through the lang codes in OWM and most will work.

Maybe you could add special handling for the ones that doesn't work:

ISO	OWM	Language
sv-* 	se	Swedish
cs-cz	cz	Czech
ko-kr	kr	Korean
lv-lv	la	Latvian
uk-ua	ua	Ukrainan


"""
compatibility wrapper for nice_time
"""
def __nice_time(self, dt, lang="en-us", speech=True, use_24hour=False,
use_ampm=False):
nt_supported_languages = ['en','it','fr','de']
if not (lang[0:2] in nt_supported_languages):
lang = "en-us"
return nice_time(dt, lang, speech, use_24hour, use_ampm)

def create_skill():
return WeatherSkill()
File renamed without changes.
2 changes: 1 addition & 1 deletion dialog/de-de/forecast.local.weather.dialog
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{{day}} wird es {{condition}}, mit maximal {{temp_max}} und minimal {{temp_min}} Grad
{{day}} wird es höchstens {{temp_max}} und minimal {{temp_min}} Grad, bei {{condition}} Bedingungen
Die Temperaturen für {{day}}'s sind maximal {{temp_max}} und minimal {{temp_min}} Grad
Die Temperaturen für {{day}} sind maximal {{temp_max}} und minimal {{temp_min}} Grad
1 change: 1 addition & 0 deletions dialog/de-de/meters per second.dialog
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Meter pro Sekunde
File renamed without changes.
2 changes: 2 additions & 0 deletions dialog/de-de/no precipitation expected.dialog
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Es wird kein Niederschlag vorhergesagt
Niederschlag wird nicht erwartet
2 changes: 2 additions & 0 deletions dialog/de-de/precipitation expected.dialog
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{{modifier}} {{precip}} wird am {{day}} erwartet
Die Vorhersage für {{day}}: {{modifier}} {{precip}}