Example #1
0
def _move_config_sections(user_config, local_config):
    """
    Temporary method to handle one-time migration of user_config params to local_config
    Args:
        user_config (NGIConfig): user configuration object
        local_config (NGIConfig): local configuration object
    """
    depreciated_user_configs = ("interface", "listener", "skills", "session",
                                "tts", "stt", "logs", "device")
    if any([d in user_config.content for d in depreciated_user_configs]):
        LOG.warning(
            "Depreciated keys found in user config! Adding them to local config"
        )
        if "wake_words_enabled" in user_config.content.get(
                "interface", dict()):
            user_config["interface"]["wake_word_enabled"] = user_config[
                "interface"].pop("wake_words_enabled")
        config_to_move = {
            "interface": user_config.content.pop("interface", {}),
            "listener": user_config.content.pop("listener", {}),
            "skills": user_config.content.pop("skills", {}),
            "session": user_config.content.pop("session", {}),
            "tts": user_config.content.pop("tts", {}),
            "stt": user_config.content.pop("stt", {}),
            "logs": user_config.content.pop("logs", {}),
            "device": user_config.content.pop("device", {})
        }
        local_config.update_keys(config_to_move)
Example #2
0
def get_config_dir():
    """
    Get a default directory in which to find configuration files
    Returns: Path to configuration or else default
    """
    site = sysconfig.get_paths()['platlib']
    if exists(join(site, 'NGI')):
        return join(site, "NGI")
    for p in [path for path in sys.path if path != ""]:
        if exists(join(p, "NGI")):
            return join(p, "NGI")
        if re.match(".*/lib/python.*/site-packages", p):
            clean_path = "/".join(p.split("/")[0:-4])
            if exists(join(clean_path, "NGI")):
                LOG.warning(
                    f"Depreciated core structure found at {clean_path}")
                return join(clean_path, "NGI")
            elif exists(join(clean_path, "neon_core")):
                # Dev Environment
                return clean_path
            elif exists(join(clean_path, "mycroft")):
                LOG.info(f"Mycroft core structure found at {clean_path}")
                return clean_path
            elif exists(join(clean_path, ".venv")):
                # Localized Production Environment (Servers)
                return clean_path
    default_path = expanduser("~/.local/share/neon")
    # LOG.info(f"System packaged core found! Using default configuration at {default_path}")
    return default_path
Example #3
0
def get_neon_lang_config() -> dict:
    """
    Get a language config for language utilities
    Returns:
        dict of config params used by Language Detector and Translator modules
    """
    core_config = get_neon_local_config()
    language_config = deepcopy(get_neon_user_config().content.get(
        "speech", {}))
    language_config["internal"] = language_config.get(
        "internal", "en-us")  # TODO: This is core, not user DM
    language_config["user"] = language_config.get("stt_language", "en-us")
    language_config["boost"] = False
    language_config["detection_module"] = core_config.get(
        "stt", {}).get("detection_module")
    language_config["translation_module"] = core_config.get(
        "stt", {}).get("translation_module")

    merged_language = {
        **_safe_mycroft_config().get("language", {}),
        **language_config
    }
    if merged_language.keys() != language_config.keys():
        LOG.warning(f"Keys missing from Neon config! {merged_language.keys()}")

    return merged_language
def get_neon_skills_config() -> dict:
    """
    Get a configuration dict for the skills module. Merge any values from Mycroft config if missing from Neon.
    Returns:
        dict of config params used for the Mycroft Skills module
    """
    core_config = get_neon_local_config()
    mycroft_config = _safe_mycroft_config()
    neon_skills = deepcopy(core_config.get("skills", {}))
    neon_skills["directory"] = os.path.expanduser(core_config["dirVars"].get("skillsDir"))
    neon_skills["disable_osm"] = neon_skills["skill_manager"] != "osm"
    if not isinstance(neon_skills["auto_update_interval"], float):
        try:
            neon_skills["auto_update_interval"] = float(neon_skills["auto_update_interval"])
        except Exception as e:
            LOG.error(e)
            neon_skills["auto_update_interval"] = 24.0
    if not isinstance(neon_skills["appstore_sync_interval"], float):
        try:
            neon_skills["appstore_sync_interval"] = float(neon_skills["appstore_sync_interval"])
        except Exception as e:
            LOG.error(e)
            neon_skills["appstore_sync_interval"] = 6.0
    neon_skills["update_interval"] = neon_skills["auto_update_interval"]  # Backwards Compat.
    if not neon_skills["neon_token"]:
        try:
            neon_skills["neon_token"] = find_neon_git_token()  # TODO: GetPrivateKeys
            populate_github_token_config(neon_skills["neon_token"])
        except FileNotFoundError:
            LOG.warning(f"No Github token found; skills may fail to install!")
    skills_config = {**mycroft_config.get("skills", {}), **neon_skills}
    return skills_config
def dict_make_equal_keys(dct_to_change: MutableMapping, keys_dct: MutableMapping,
                         max_depth: int = 1, cur_depth: int = 0) -> MutableMapping:
    """
    Adds and removes keys from dct_to_change such that it has the same keys as keys_dct. Values from dct_to_change are
    preserved with any added keys using default values from keys_dct.
    Args:
        dct_to_change: Dict of user preferences to modify and return
        keys_dct: Dict containing all keys and default values
        max_depth: Int depth to recurse (0-indexed)
        cur_depth: Current depth relative to top-level config (0-indexed)
    Returns: dct_to_change with any keys not in keys_dct removed and any new keys added with default values

    """
    if not isinstance(dct_to_change, MutableMapping) or not isinstance(keys_dct, MutableMapping):
        raise AttributeError("merge_recursive_dicts expects two dict objects as args")
    for key in list(dct_to_change.keys()):
        if isinstance(keys_dct.get(key), dict) and isinstance(dct_to_change[key], MutableMapping):
            if max_depth > cur_depth and key not in ("tts", "stt"):
                dct_to_change[key] = dict_make_equal_keys(dct_to_change[key], keys_dct[key], max_depth, cur_depth + 1)
        elif key not in keys_dct.keys():
            dct_to_change.pop(key)
            LOG.warning(f"Removing '{key}' from dict!")
            # del dct_to_change[key]
    for key, value in keys_dct.items():
        if key not in dct_to_change.keys():
            dct_to_change[key] = value
    return dct_to_change
def get_neon_client_config() -> dict:
    core_config = get_neon_local_config()
    server_addr = core_config.get("remoteVars", {}).get("remoteHost", "167.172.112.7")
    if server_addr == "64.34.186.92":
        LOG.warning(f"Depreciated call to host: {server_addr}")
        server_addr = "167.172.112.7"
    return {"server_addr": server_addr,
            "devVars": core_config["devVars"],
            "remoteVars": core_config["remoteVars"]}
 def populate(self, content, check_existing=False):
     if not check_existing:
         self.__add__(content)
         return
     old_content = deepcopy(self._content)
     self._content = dict_merge(content, self._content)  # to_change, one_with_all_keys
     if old_content == self._content:
         LOG.warning(f"Update called with no change: {self.file_path}")
         return
     self._write_yaml_file()
Example #8
0
def get_neon_bus_config() -> dict:
    """
    Get a configuration dict for the messagebus. Merge any values from Mycroft config if missing from Neon.
    Returns:
        dict of config params used for a messagebus client
    """
    mycroft = _safe_mycroft_config().get("websocket", {})
    neon = get_neon_local_config().get("websocket", {})
    merged = {**mycroft, **neon}
    if merged.keys() != neon.keys():
        LOG.warning(f"Keys missing from Neon config! {merged.keys()}")
    return merged
Example #9
0
def get_neon_api_config() -> dict:
    """
    Get a configuration dict for the api module. Merge any values from Mycroft config if missing from Neon.
    Returns:
        dict of config params used for the Mycroft API module
    """
    core_config = get_neon_local_config()
    api_config = deepcopy(core_config.get("api"))
    api_config["metrics"] = core_config["prefFlags"].get("metrics", False)
    mycroft = _safe_mycroft_config().get("server", {})
    merged = {**mycroft, **api_config}
    if merged.keys() != api_config.keys():
        LOG.warning(f"Keys missing from Neon config! {merged.keys()}")
    return merged
    def update_keys(self, other):
        """
        Adds keys to this config such that it has all keys in 'other'. Configuration values are
        preserved with any added keys using default values from 'other'.
        Args:
            other: dict of keys and default values this should be added to this configuration
        """
        old_content = deepcopy(self._content)
        self._content = dict_update_keys(self._content, other)  # to_change, one_with_all_keys
        if old_content == self._content:
            LOG.warning(f"Update called with no change: {self.file_path}")
            return

        self._write_yaml_file()
def get_neon_audio_config() -> dict:
    """
    Get a configuration dict for the audio module. Merge any values from Mycroft config if missing from Neon.
    Returns:
        dict of config params used for the Audio module
    """
    mycroft = _safe_mycroft_config()
    local_config = get_neon_local_config()
    neon_audio = local_config.get("audioService", {})
    merged_audio = {**mycroft.get("Audio", {}), **neon_audio}
    if merged_audio.keys() != neon_audio.keys():
        LOG.warning(f"Keys missing from Neon config! {merged_audio.keys()}")

    return {"Audio": merged_audio,
            "tts": get_neon_tts_config(),
            "language": get_neon_lang_config()}
Example #12
0
    def create(config=None, results_event: Event = None):
        if config and not config.get(
                "module"
        ):  # No module, try getting stt config from passed config
            config = config.get("stt")
        if not config:  # No config, go get it
            config = get_neon_speech_config().get("stt", {})

        LOG.info(f"Create STT with config: {config}")
        clazz = OVOSSTTFactory.get_class(config)
        if not clazz:
            LOG.warning("plugin not found, falling back to Chromium STT")
            config["module"] = "google"  # TODO configurable fallback plugin
            clazz = OVOSSTTFactory.get_class(config)
            if not clazz:
                raise ValueError("fallback plugin not found")

        return WrappedSTT(clazz, config=config, results_event=results_event)
def get_neon_speech_config() -> dict:
    """
    Get a configuration dict for listener. Merge any values from Mycroft config if missing from Neon.
    Returns:
        dict of config params used for listener in neon_speech
    """
    mycroft = _safe_mycroft_config()
    local_config = get_neon_local_config()

    neon_listener_config = deepcopy(local_config.get("listener", {}))
    neon_listener_config["wake_word_enabled"] = local_config["interface"].get("wake_word_enabled", True)
    neon_listener_config["save_utterances"] = local_config["prefFlags"].get("saveAudio", False)
    neon_listener_config["confirm_listening"] = local_config["interface"].get("confirm_listening", True)
    neon_listener_config["record_utterances"] = neon_listener_config["save_utterances"]
    neon_listener_config["record_wake_words"] = neon_listener_config["save_utterances"]
    merged_listener = {**mycroft.get("listener", {}), **neon_listener_config}
    if merged_listener.keys() != neon_listener_config.keys():
        LOG.warning(f"Keys missing from Neon config! {merged_listener.keys()}")

    lang = mycroft.get("language", {}).get("internal", "en-us")  # core_lang

    neon_stt_config = local_config.get("stt", {})
    merged_stt_config = {**mycroft.get("stt", {}), **neon_stt_config}
    if merged_stt_config.keys() != neon_stt_config.keys():
        LOG.warning(f"Keys missing from Neon config! {merged_stt_config.keys()}")

    hotword_config = local_config.get("hotwords") or mycroft.get("hotwords")
    if hotword_config != local_config.get("hotwords"):
        LOG.warning(f"Neon hotword config missing! {hotword_config}")

    neon_audio_parser_config = local_config.get("audio_parsers", {})
    merged_audio_parser_config = {**mycroft.get("audio_parsers", {}), **neon_audio_parser_config}
    if merged_audio_parser_config.keys() != neon_audio_parser_config.keys():
        LOG.warning(f"Keys missing from Neon config! {merged_audio_parser_config.keys()}")

    return {"listener": merged_listener,
            "hotwords": hotword_config,
            "audio_parsers": merged_audio_parser_config,
            "lang": lang,
            "stt": merged_stt_config,
            "metric_upload": local_config["prefFlags"].get("metrics", False),
            "remote_server": local_config.get("remoteVars", {}).get("remoteHost", "64.34.186.120"),
            "data_dir": os.path.expanduser(local_config.get("dirVars", {}).get("rootDir") or "~/.local/share/neon"),
            "keys": {}  # TODO: Read from somewhere DM
            }