Adding localization mechanism for strings embedded in mycroft-core code (#717)

* Adding localization mechanism for strings embedded in mycroft-core code

Added mycroft.dialog.get() function.  This behaves much like the localization
mechanism for dialogs in Skills.  So you can do things like this:

   lang = "en-us"
   str = mycroft.dialog.get("how are you", lang)

Which will look in mycroft/res/text for the dialog file containing strings to
use as templates for the actual output.  This depends on the language being
currently used.  When operating in English this would be:

   mycroft/res/text/en-us/how are you.dialog

This function will pick a random line from that file to assign to str.

A more advanced use is to embed placeholders in the strings within the
template file.

   lang = "en-us"
   ctx = {"time" : "noon"}
   str = mycroft.dialog.get("current time", lang, ctx)

And the random template line picked was "the current time is {{time}} ", then
the output would be:

   "the current time is noon"
pull/748/head
Steve Penrod 2017-05-03 12:25:17 -07:00 committed by Art McGee
parent 07ffe301c5
commit faa3070f3c
5 changed files with 63 additions and 22 deletions

View File

@ -25,6 +25,7 @@ from pyee import EventEmitter
from requests import HTTPError
from requests.exceptions import ConnectionError
import mycroft.dialog
from mycroft.client.speech.local_recognizer import LocalRecognizer
from mycroft.client.speech.mic import MutableMicrophone, ResponsiveRecognizer
from mycroft.configuration import ConfigurationManager
@ -109,7 +110,7 @@ class AudioConsumer(Thread):
self.metrics):
SessionManager.touch()
self.state.sleeping = False
self.__speak("I'm awake.")
self.__speak(mycroft.dialog.get("i am awake", self.stt.lang))
self.metrics.increment("mycroft.wakeup")
@staticmethod
@ -141,7 +142,8 @@ class AudioConsumer(Thread):
LOG.error("Could not request Speech Recognition {0}".format(e))
except ConnectionError as e:
LOG.error("Connection Error: {0}".format(e))
self.__speak("Mycroft seems not to be connected to the Internet")
self.__speak(mycroft.dialog.get("not connected to the internet",
self.stt.lang))
except HTTPError as e:
if e.response.status_code == 401:
text = "pair my device"
@ -149,7 +151,8 @@ class AudioConsumer(Thread):
except Exception as e:
LOG.error(e)
LOG.error("Speech Recognition could not understand audio")
self.__speak("Sorry, I didn't catch that")
self.__speak(mycroft.dialog.get("i didn't catch that",
self.stt.lang))
if text:
# STT succeeded, send the transcribed speech on for processing
payload = {

View File

@ -19,7 +19,7 @@
import pystache
import os
import random
from mycroft.util import log
from mycroft.util import log, resolve_resource_file
__author__ = 'seanfitz'
logger = log.getLogger(__name__)
@ -40,11 +40,9 @@ class MustacheDialogRenderer(object):
"""
Load a template by file name into the templates cache.
:param template_name: a unique identifier for a group of templates.
:param filename: a fully qualified filename of a mustache template.
:return:
Args:
template_name (str): a unique identifier for a group of templates
filename (str): a fully qualified filename of a mustache template.
"""
with open(filename, 'r') as f:
for line in f:
@ -56,20 +54,20 @@ class MustacheDialogRenderer(object):
def render(self, template_name, context={}, index=None):
"""
Given a template name, pick a template and render it with the provided
context.
Given a template name, pick a template and render it using the context
:param template_name: the name of a template group.
Args:
template_name (str): the name of a template group.
context (dict): dictionary representing values to be rendered
index (int): optional, the specific index in the collection of
templates
:param context: dictionary representing values to be rendered
Returns:
str: the rendered string
:param index: optional, the specific index in the collection of
templates
:raises NotImplementedError: if no template can be found identified by
template_name
:return:
Raises:
NotImplementedError: if no template can be found identified by
template_name
"""
if template_name not in self.templates:
raise NotImplementedError("Template not found: %s" % template_name)
@ -92,9 +90,11 @@ class DialogLoader(object):
"""
Load all dialog files within the specified directory.
:param dialog_dir: directory that contains dialog files
Args:
dialog_dir (str): directory that contains dialog files
:return: a loaded instance of a dialog renderer
Returns:
a loaded instance of a dialog renderer
"""
if not os.path.exists(dialog_dir) or not os.path.isdir(dialog_dir):
logger.warn("No dialog found: " + dialog_dir)
@ -108,3 +108,31 @@ class DialogLoader(object):
dialog_entry_name, os.path.join(dialog_dir, f))
return self.__renderer
def get(phrase, lang, context=None):
"""
Looks up a resource file for the given phrase. If no file
is found, the requested phrase is returned as the string.
This will use the default language for translations.
Args:
phrase (str): resource phrase to retrieve/translate
lang (str): the language to use
context (dict): values to be inserted into the string
Returns:
str: a randomized and/or translated version of the phrase
"""
filename = "text/"+lang.lower()+"/"+phrase+".dialog"
template = resolve_resource_file(filename)
if not template:
logger.debug("Resource file not found: " + filename)
return phrase
stache = MustacheDialogRenderer()
stache.load_template_file("template", template)
if not context:
context = {}
return stache.render("template", context)

View File

@ -0,0 +1,2 @@
I am awake
I'm awake now

View File

@ -0,0 +1,4 @@
Sorry, I didn't catch that
I afraid I couldn't understand that
Can you say that again?
Can you please repeat that?

View File

@ -0,0 +1,4 @@
It seems I'm not connected to the Internet
I don't seem to be connected to the internet
I can't reach the internet right now
I'm unable to reach the internet