From 6810e193bba2e3a0828f885202ddcb5c8a7a7540 Mon Sep 17 00:00:00 2001 From: miro Date: Thu, 7 Nov 2024 08:54:06 +0000 Subject: [PATCH 1/2] feat: list join util --- .../res/text/az/word_connectors.json | 4 + .../res/text/ca/word_connectors.json | 4 + .../res/text/{cs-cz => cs}/noise_words.list | 0 .../res/text/cs/word_connectors.json | 4 + .../res/text/da/word_connectors.json | 4 + .../res/text/{de-de => de}/noise_words.list | 0 .../res/text/de/word_connectors.json | 4 + .../res/text/{en-us => en}/noise_words.list | 0 .../res/text/en/word_connectors.json | 4 + .../res/text/fa/word_connectors.json | 4 + .../res/text/pl/word_connectors.json | 4 + .../res/text/{ru-ru => ru}/noise_words.list | 0 .../res/text/sl/word_connectors.json | 4 + .../res/text/uk/word_connectors.json | 4 + ovos_workshop/skills/common_query_skill.py | 13 ++-- ovos_workshop/skills/ovos.py | 76 ++++++++++++++++++- 16 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 ovos_workshop/res/text/az/word_connectors.json create mode 100644 ovos_workshop/res/text/ca/word_connectors.json rename ovos_workshop/res/text/{cs-cz => cs}/noise_words.list (100%) create mode 100644 ovos_workshop/res/text/cs/word_connectors.json create mode 100644 ovos_workshop/res/text/da/word_connectors.json rename ovos_workshop/res/text/{de-de => de}/noise_words.list (100%) create mode 100644 ovos_workshop/res/text/de/word_connectors.json rename ovos_workshop/res/text/{en-us => en}/noise_words.list (100%) create mode 100644 ovos_workshop/res/text/en/word_connectors.json create mode 100644 ovos_workshop/res/text/fa/word_connectors.json create mode 100644 ovos_workshop/res/text/pl/word_connectors.json rename ovos_workshop/res/text/{ru-ru => ru}/noise_words.list (100%) create mode 100644 ovos_workshop/res/text/sl/word_connectors.json create mode 100644 ovos_workshop/res/text/uk/word_connectors.json diff --git a/ovos_workshop/res/text/az/word_connectors.json b/ovos_workshop/res/text/az/word_connectors.json new file mode 100644 index 00000000..5afe5040 --- /dev/null +++ b/ovos_workshop/res/text/az/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "və", + "or": "ya" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/ca/word_connectors.json b/ovos_workshop/res/text/ca/word_connectors.json new file mode 100644 index 00000000..198b8823 --- /dev/null +++ b/ovos_workshop/res/text/ca/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "i", + "or": "o" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/cs-cz/noise_words.list b/ovos_workshop/res/text/cs/noise_words.list similarity index 100% rename from ovos_workshop/res/text/cs-cz/noise_words.list rename to ovos_workshop/res/text/cs/noise_words.list diff --git a/ovos_workshop/res/text/cs/word_connectors.json b/ovos_workshop/res/text/cs/word_connectors.json new file mode 100644 index 00000000..bbb3da2f --- /dev/null +++ b/ovos_workshop/res/text/cs/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "a", + "or": "nebo" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/da/word_connectors.json b/ovos_workshop/res/text/da/word_connectors.json new file mode 100644 index 00000000..2ef585e2 --- /dev/null +++ b/ovos_workshop/res/text/da/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "og", + "or": "eller" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/de-de/noise_words.list b/ovos_workshop/res/text/de/noise_words.list similarity index 100% rename from ovos_workshop/res/text/de-de/noise_words.list rename to ovos_workshop/res/text/de/noise_words.list diff --git a/ovos_workshop/res/text/de/word_connectors.json b/ovos_workshop/res/text/de/word_connectors.json new file mode 100644 index 00000000..087c7de5 --- /dev/null +++ b/ovos_workshop/res/text/de/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "und", + "or": "oder" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/en-us/noise_words.list b/ovos_workshop/res/text/en/noise_words.list similarity index 100% rename from ovos_workshop/res/text/en-us/noise_words.list rename to ovos_workshop/res/text/en/noise_words.list diff --git a/ovos_workshop/res/text/en/word_connectors.json b/ovos_workshop/res/text/en/word_connectors.json new file mode 100644 index 00000000..d1823a01 --- /dev/null +++ b/ovos_workshop/res/text/en/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "and", + "or": "or" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/fa/word_connectors.json b/ovos_workshop/res/text/fa/word_connectors.json new file mode 100644 index 00000000..793097a4 --- /dev/null +++ b/ovos_workshop/res/text/fa/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "و", + "or": "یا" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/pl/word_connectors.json b/ovos_workshop/res/text/pl/word_connectors.json new file mode 100644 index 00000000..f91e2382 --- /dev/null +++ b/ovos_workshop/res/text/pl/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "oraz", + "or": "lub" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/ru-ru/noise_words.list b/ovos_workshop/res/text/ru/noise_words.list similarity index 100% rename from ovos_workshop/res/text/ru-ru/noise_words.list rename to ovos_workshop/res/text/ru/noise_words.list diff --git a/ovos_workshop/res/text/sl/word_connectors.json b/ovos_workshop/res/text/sl/word_connectors.json new file mode 100644 index 00000000..20588c81 --- /dev/null +++ b/ovos_workshop/res/text/sl/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "in", + "or": "ali" +} \ No newline at end of file diff --git a/ovos_workshop/res/text/uk/word_connectors.json b/ovos_workshop/res/text/uk/word_connectors.json new file mode 100644 index 00000000..3c890bee --- /dev/null +++ b/ovos_workshop/res/text/uk/word_connectors.json @@ -0,0 +1,4 @@ +{ + "and": "та", + "or": "або" +} \ No newline at end of file diff --git a/ovos_workshop/skills/common_query_skill.py b/ovos_workshop/skills/common_query_skill.py index e5123f42..6839b5e4 100644 --- a/ovos_workshop/skills/common_query_skill.py +++ b/ovos_workshop/skills/common_query_skill.py @@ -67,8 +67,9 @@ def __init__(self, *args, **kwargs): } super().__init__(*args, **kwargs) - noise_words_filepath = f"text/{self.lang}/noise_words.list" - default_res = f"{dirname(dirname(__file__))}/res/text/{self.lang}" \ + lang = self.lang.split("-")[0] + noise_words_filepath = f"text/{lang}/noise_words.list" + default_res = f"{dirname(dirname(__file__))}/res/text/{lang}" \ f"/noise_words.list" noise_words_filename = \ resolve_resource_file(noise_words_filepath, @@ -79,7 +80,7 @@ def __init__(self, *args, **kwargs): if noise_words_filename: with open(noise_words_filename) as f: translated_noise_words = f.read().strip() - self._translated_noise_words[self.lang] = \ + self._translated_noise_words[lang] = \ translated_noise_words.split() @property @@ -89,13 +90,13 @@ def translated_noise_words(self) -> List[str]: """ log_deprecation("self.translated_noise_words will become a " "private variable", "0.1.0") - return self._translated_noise_words.get(self.lang, []) + return self._translated_noise_words.get(self.lang.split("-")[0], []) @translated_noise_words.setter def translated_noise_words(self, val: List[str]): log_deprecation("self.translated_noise_words will become a " "private variable", "0.1.0") - self._translated_noise_words[self.lang] = val + self._translated_noise_words[self.lang.split("-")[0]] = val def bind(self, bus): """Overrides the default bind method of MycroftSkill. @@ -179,7 +180,7 @@ def remove_noise(self, phrase: str, lang: str = None) -> str: @param lang: language of `phrase`, else defaults to `self.lang` @return: cleaned `phrase` with extra words removed """ - lang = lang or self.lang + lang = (lang or self.lang).split("-")[0] phrase = ' ' + phrase + ' ' for word in self._translated_noise_words.get(lang, []): mtch = ' ' + word + ' ' diff --git a/ovos_workshop/skills/ovos.py b/ovos_workshop/skills/ovos.py index 29267e3d..06c89eb1 100644 --- a/ovos_workshop/skills/ovos.py +++ b/ovos_workshop/skills/ovos.py @@ -2064,7 +2064,7 @@ def ask_selection(self, options: List[str], dialog: str = '', number = pronounce_number(idx + 1, self.lang) self.speak(f"{number}, {opt}", wait=True) else: - opt_str = join_list(options, "or", lang=self.lang) + "?" + opt_str = join_word_list(options, "or", sep=",", lang=self.lang) + "?" self.speak(opt_str, wait=True) resp = self.get_response(dialog=dialog, data=data) @@ -2502,3 +2502,77 @@ def __init__(self, skill: OVOSSkill): ui_directories = get_ui_directories(skill.root_dir) GUIInterface.__init__(self, skill_id=skill_id, bus=bus, config=config, ui_directories=ui_directories) + + +def _get_and_word(lang): + """ Helper to get word translations + + Args: + lang (str, optional): an optional BCP-47 language code, if omitted + the default language will be used. + + Returns: + str: translated version of resource name + """ + res_file = f"{dirname(dirname(__file__))}/res/text/{lang}" \ + f"/word_connectors.json" + if not os.path.isfile(res_file): + LOG.warning(f"untranslated file: {res_file}") + return ", " + with open(res_file) as f: + w = json.load(f)["and"] + return w + +def _get_or_word(lang): + """ Helper to get word translations + + Args: + lang (str, optional): an optional BCP-47 language code, if omitted + the default language will be used. + + Returns: + str: translated version of resource name + """ + res_file = f"{dirname(dirname(__file__))}/res/text/{lang}" \ + f"/word_connectors.json" + if not os.path.isfile(res_file): + LOG.warning(f"untranslated file: {res_file}") + return ", " + with open(res_file) as f: + w = json.load(f)["or"] + return w + + +def join_word_list(items: List[str], connector: str, sep: str, lang:str) -> str: + """ Join a list into a phrase using the given connector word + + Examples: + join_word_list([1,2,3], "or") -> "1, 2 or 3" + join_word_list([1,2,3], "and") -> "1, 2 and 3" + join_word_list([1,2,3], "and", ";") -> "1; 2 and 3" + + Args: + items (array): items to be joined + connector (str): connecting word (resource name), like "and" or "or" + sep (str, optional): separator character, default = "," + lang (str, optional): an optional BCP-47 language code, if omitted + the default language will be used. + Returns: + str: the connected list phrase + """ + cons = { + "and": _get_and_word, + "or": _get_or_word + } + if not items: + return "" + if len(items) == 1: + return str(items[0]) + + if not sep: + sep = ", " + else: + sep += " " + return (sep.join(str(item) for item in items[:-1]) + + " " + cons[connector](lang) + + " " + items[-1]) From 949989f2956eae1c6ffab7d7a9961d1c10c05421 Mon Sep 17 00:00:00 2001 From: miro Date: Thu, 7 Nov 2024 09:17:17 +0000 Subject: [PATCH 2/2] feat: list join util --- ovos_workshop/skills/ovos.py | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/ovos_workshop/skills/ovos.py b/ovos_workshop/skills/ovos.py index 06c89eb1..ad6e07c6 100644 --- a/ovos_workshop/skills/ovos.py +++ b/ovos_workshop/skills/ovos.py @@ -1,4 +1,5 @@ import datetime +import json import os import re import sys @@ -420,7 +421,8 @@ def settings(self, val: dict): """ Update settings specific to this skill """ - LOG.warning("Skills are not supposed to override self.settings, expect breakage! Set individual dict keys instead") + LOG.warning( + "Skills are not supposed to override self.settings, expect breakage! Set individual dict keys instead") assert isinstance(val, dict) # init method if self._settings is None: @@ -2504,7 +2506,7 @@ def __init__(self, skill: OVOSSkill): ui_directories=ui_directories) -def _get_and_word(lang): +def _get_word(lang, connector): """ Helper to get word translations Args: @@ -2520,30 +2522,11 @@ def _get_and_word(lang): LOG.warning(f"untranslated file: {res_file}") return ", " with open(res_file) as f: - w = json.load(f)["and"] - return w - -def _get_or_word(lang): - """ Helper to get word translations - - Args: - lang (str, optional): an optional BCP-47 language code, if omitted - the default language will be used. - - Returns: - str: translated version of resource name - """ - res_file = f"{dirname(dirname(__file__))}/res/text/{lang}" \ - f"/word_connectors.json" - if not os.path.isfile(res_file): - LOG.warning(f"untranslated file: {res_file}") - return ", " - with open(res_file) as f: - w = json.load(f)["or"] + w = json.load(f)[connector] return w -def join_word_list(items: List[str], connector: str, sep: str, lang:str) -> str: +def join_word_list(items: List[str], connector: str, sep: str, lang: str) -> str: """ Join a list into a phrase using the given connector word Examples: @@ -2561,8 +2544,8 @@ def join_word_list(items: List[str], connector: str, sep: str, lang:str) -> str: str: the connected list phrase """ cons = { - "and": _get_and_word, - "or": _get_or_word + "and": _get_word(lang, "and"), + "or": _get_word(lang, "or") } if not items: return "" @@ -2574,5 +2557,5 @@ def join_word_list(items: List[str], connector: str, sep: str, lang:str) -> str: else: sep += " " return (sep.join(str(item) for item in items[:-1]) + - " " + cons[connector](lang) + + " " + cons[connector] + " " + items[-1])