Skip to content

Commit

Permalink
Merge pull request #192 from OpenVoiceOS/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
JarbasAl authored Oct 26, 2023
2 parents ae1df77 + 5f079a1 commit 4fe82c7
Show file tree
Hide file tree
Showing 25 changed files with 934 additions and 574 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ on:
- dev
paths-ignore:
- 'ovos_plugin_manager/version.py'
- 'requirements/**'
- 'examples/**'
- '.github/**'
- '.gitignore'
Expand All @@ -19,7 +18,6 @@ on:
- master
paths-ignore:
- 'ovos_plugin_manager/version.py'
- 'requirements/**'
- 'examples/**'
- '.github/**'
- '.gitignore'
Expand Down Expand Up @@ -53,7 +51,7 @@ jobs:
pip install .
- name: Install test dependencies
run: |
pip install pytest pytest-timeout pytest-cov neon-lang-plugin-libretranslate
pip install -r requirements/test.txt
- name: Run unittests
run: |
pytest --cov=ovos_plugin_manager --cov-report xml test/unittests
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ dist

# Created by unit tests
.pytest_cache/
/.gtm/
200 changes: 66 additions & 134 deletions CHANGELOG.md

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions ovos_plugin_manager/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ def setup_audio_service(service_module, config=None, bus=None):
Arguments:
service_module: Python module to run
config (dict): Mycroft configuration dict
config (dict): OpenVoiceOS configuration dict
bus (MessageBusClient): Messagebus interface
Returns:
(list) List of created services.
"""
config = config or Configuration()
config = config or Configuration().get("Audio", {})
bus = bus or get_mycroft_bus()

if (hasattr(service_module, 'autodetect') and
callable(service_module.autodetect)):
try:
Expand All @@ -71,8 +72,8 @@ def load_audio_service_plugins(config=None, bus=None):
"""Load installed audioservice plugins.
Arguments:
config: Mycroft core configuration
bus: Mycroft messagebus
config: OpenVoiceOS core configuration
bus: OpenVoiceOS messagebus
Returns:
List of started services
Expand Down
2 changes: 1 addition & 1 deletion ovos_plugin_manager/audio_transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def load_audio_transformer_plugin(module_name: str) -> type(AudioTransformer):
"""Wrapper function for loading audio_transformer plugin.
Arguments:
(str) Mycroft audio_transformer module name from config
(str) OpenVoiceOS audio_transformer module name from config
Returns:
class: found audio_transformer plugin class
"""
Expand Down
41 changes: 41 additions & 0 deletions ovos_plugin_manager/dialog_transformers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from ovos_plugin_manager.templates.transformers import DialogTransformer, TTSTransformer
from ovos_plugin_manager.utils import PluginTypes
from ovos_plugin_manager.utils import load_plugin, find_plugins


def find_dialog_transformer_plugins() -> dict:
"""
Find all installed plugins
@return: dict plugin names to entrypoints
"""
return find_plugins(PluginTypes.DIALOG_TRANSFORMER)


def load_dialog_transformer_plugin(module_name: str) -> type(DialogTransformer):
"""Wrapper function for loading dialog_transformer plugin.
Arguments:
(str) OpenVoiceOS dialog_transformer module name from config
Returns:
class: found dialog_transformer plugin class
"""
return load_plugin(module_name, PluginTypes.DIALOG_TRANSFORMER)


def find_tts_transformer_plugins() -> dict:
"""
Find all installed plugins
@return: dict plugin names to entrypoints
"""
return find_plugins(PluginTypes.TTS_TRANSFORMER)


def load_tts_transformer_plugin(module_name: str) -> type(TTSTransformer):
"""Wrapper function for loading dialog_transformer plugin.
Arguments:
(str) OpenVoiceOS dialog_transformer module name from config
Returns:
class: found dialog_transformer plugin class
"""
return load_plugin(module_name, PluginTypes.TTS_TRANSFORMER)
19 changes: 10 additions & 9 deletions ovos_plugin_manager/hardware/led/animations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from threading import Event

from ovos_utils.log import LOG
from time import time, sleep
from time import time
from typing import Optional

from ovos_plugin_manager.hardware.led import AbstractLed, Color
Expand All @@ -11,6 +11,7 @@
class LedAnimation:
def __init__(self, leds: AbstractLed, **kwargs):
self.leds = leds
self._delay = Event()

@abstractmethod
def start(self, timeout: Optional[int] = None, one_shot: bool = False):
Expand Down Expand Up @@ -56,7 +57,7 @@ def start(self, timeout=None, one_shot=False):
brightness += step
self.leds.fill(tuple(brightness * part for part in
self.color.as_rgb_tuple()))
sleep(self.step_delay)
self._delay.wait(self.step_delay)
if one_shot and brightness >= 1:
ending = True
elif ending and brightness <= 0:
Expand Down Expand Up @@ -94,7 +95,7 @@ def start(self, timeout=None, one_shot=False):
while not self.stopping.is_set():
for led in range(0, self.leds.num_leds):
self.leds.set_led(led, self.foreground_color.as_rgb_tuple())
sleep(self.step_delay)
self._delay.wait(self.step_delay)
self.leds.set_led(led, self.background_color.as_rgb_tuple())
if one_shot:
self.stopping.set()
Expand Down Expand Up @@ -129,7 +130,7 @@ def start(self, timeout=None, one_shot=True):
leds.reverse()
for led in leds:
self.leds.set_led(led, self.fill_color.as_rgb_tuple())
sleep(self.step_delay)
self._delay.wait(self.step_delay)

def stop(self):
pass
Expand Down Expand Up @@ -227,17 +228,17 @@ def start(self, timeout=None, one_shot=False):
end_time = time() + timeout if timeout else None

self.leds.fill(Color.BLACK.as_rgb_tuple())
sleep(0.5)
self._delay.wait(0.5)
while not self.stopping.is_set():
for i in range(self.num_blinks):
self.leds.fill(self.color.as_rgb_tuple())
sleep(0.25)
self._delay.wait(0.25)
self.leds.fill(Color.BLACK.as_rgb_tuple())
sleep(0.5)
self._delay.wait(0.5)
if one_shot:
self.stopping.set()
elif self.repeat:
sleep(2)
self._delay.wait(2)
else:
self.stopping.set()
if end_time and time() > end_time:
Expand Down Expand Up @@ -273,7 +274,7 @@ def start(self, timeout: Optional[int] = None, one_shot: bool = False):
else:
self.leds.set_led(led, Color.BLACK.as_rgb_tuple(), False)
self.leds.show()
sleep(self.delay)
self._delay.wait(self.delay)
evens = not evens
if one_shot and evens: # We did one animation
self.stopping.set()
Expand Down
143 changes: 97 additions & 46 deletions ovos_plugin_manager/language.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,14 @@ def get_lang_detect_module_configs(module_name: str):
return load_plugin_configs(module_name, PluginConfigTypes.LANG_DETECT)


_fallback_lang_detect_plugin = "ovos-lang-detect-ngram-lm"
_fallback_translate_plugin = "ovos-translate-plugin-server"


class OVOSLangDetectionFactory:
""" replicates the base neon class, but uses only OPM enabled plugins"""
"""
replicates the base neon class, but uses only OPM enabled plugins
"""
MAPPINGS = {
"libretranslate": "libretranslate_detection_plug",
"google": "googletranslate_detection_plug",
Expand All @@ -112,41 +118,63 @@ class OVOSLangDetectionFactory:
"lingua_podre": "lingua_podre_plug"
}

# TODO - get_class method
@staticmethod
def get_class(config=None):
"""
Factory method to get a Language Detector class based on configuration.
Configuration contains a `language` section with
the name of a LangDetection module to be read by this method.
"language": {
"detection_module": <engine_name>
}
"""
config = config or Configuration()
if "language" in config:
config = config["language"]
lang_module = config.get("detection_module", config.get("module"))
if not lang_module:
raise ValueError("`language.detection_module` not configured")
if lang_module in OVOSLangDetectionFactory.MAPPINGS:
lang_module = OVOSLangDetectionFactory.MAPPINGS[lang_module]
return load_lang_detect_plugin(lang_module)

@staticmethod
def create(config=None):
"""Factory method to create a LangDetection engine based on configuration.
def create(config=None) -> LanguageDetector:
"""
Factory method to create a LangDetection engine based on configuration
The configuration file ``mycroft.conf`` contains a ``language`` section with
Configuration contains a `language` section with
the name of a LangDetection module to be read by this method.
"language": {
"language": {
"detection_module": <engine_name>
}
}
"""
config = config or Configuration()
if "language" in config:
config = config["language"]
lang_module = config.get("detection_module", config.get("module"))
try:
config = config or Configuration()
if "language" in config:
config = config["language"]
lang_module = config.get("detection_module", "libretranslate_detection_plug")
if lang_module in OVOSLangDetectionFactory.MAPPINGS:
lang_module = OVOSLangDetectionFactory.MAPPINGS[lang_module]

clazz = load_lang_detect_plugin(lang_module)
clazz = OVOSLangDetectionFactory.get_class(config)
if clazz is None:
raise ValueError
raise ValueError(f"Failed to load module: {lang_module}")
LOG.info(f'Loaded the Language Detection plugin {lang_module}')
return clazz(config=get_plugin_config(config, "language", lang_module))
if lang_module in OVOSLangDetectionFactory.MAPPINGS:
lang_module = OVOSLangDetectionFactory.MAPPINGS[lang_module]
return clazz(config=get_plugin_config(config, "language",
lang_module))
except Exception:
# The Language Detection backend failed to start, fall back if appropriate.
if lang_module != "libretranslate_detection_plug":
lang_module = "libretranslate_detection_plug"
LOG.error(f'Language Translation plugin {lang_module} not found\n'
f'Falling back to libretranslate plugin')
clazz = load_tx_plugin("libretranslate_detection_plug")
if lang_module != _fallback_lang_detect_plugin:
lang_module = _fallback_lang_detect_plugin
LOG.error(f'Language Detection plugin {lang_module} not found. '
f'Falling back to {_fallback_lang_detect_plugin}')
clazz = load_lang_detect_plugin(_fallback_lang_detect_plugin)
if clazz:
return clazz(config=get_plugin_config(config, "language", lang_module))
return clazz(config=get_plugin_config(config, "language",
lang_module))

raise

Expand All @@ -160,39 +188,62 @@ class OVOSLangTranslationFactory:
"apertium": "apertium_plug"
}

# TODO - get_class method
@staticmethod
def create(config=None):
"""Factory method to create a LangTranslation engine based on configuration.
def get_class(config=None):
"""
Factory method to get a Language Translator class based on configuration.
The configuration file ``mycroft.conf`` contains a ``language`` section with
the name of a LangDetection module to be read by this method.
Configuration contains a `language` section with
the name of a Translation module to be read by this method.
"language": {
"translation_module": <engine_name>
}
"""
config = config or Configuration()
if "language" in config:
config = config["language"]
lang_module = config.get("translation_module", config.get("module"))
if not lang_module:
raise ValueError("`language.translation_module` not configured")
if lang_module in OVOSLangTranslationFactory.MAPPINGS:
lang_module = OVOSLangTranslationFactory.MAPPINGS[lang_module]
return load_tx_plugin(lang_module)

"language": {
@staticmethod
def create(config=None) -> LanguageTranslator:
"""
Factory method to create a LangTranslation engine based on configuration
Configuration contains a `language` section with
the name of a Translation module to be read by this method.
"language": {
"translation_module": <engine_name>
}
}
"""
config = config or Configuration()
if "language" in config:
config = config["language"]
lang_module = config.get("translation_module", config.get("module"))
try:
config = config or Configuration()
if "language" in config:
config = config["language"]
lang_module = config.get("translation_module", "libretranslate_plug")
if lang_module in OVOSLangTranslationFactory.MAPPINGS:
lang_module = OVOSLangTranslationFactory.MAPPINGS[lang_module]
clazz = load_tx_plugin(lang_module)
clazz = OVOSLangTranslationFactory.get_class(config)
if clazz is None:
raise ValueError
raise ValueError(f"Failed to load module: {lang_module}")
LOG.info(f'Loaded the Language Translation plugin {lang_module}')
return clazz(config=get_plugin_config(config, "language", lang_module))
if lang_module in OVOSLangTranslationFactory.MAPPINGS:
lang_module = OVOSLangTranslationFactory.MAPPINGS[lang_module]
return clazz(config=get_plugin_config(config, "language",
lang_module))
except Exception:
# The Language Detection backend failed to start, fall back if appropriate.
if lang_module != "libretranslate_plug":
lang_module = "libretranslate_plug"
LOG.error(f'Language Translation plugin {lang_module} not found\n'
f'Falling back to libretranslate plugin')
clazz = load_tx_plugin("libretranslate_plug")
# The Language Translation backend failed to start, fall back if appropriate.
if lang_module != _fallback_translate_plugin:
lang_module = _fallback_translate_plugin
LOG.error(f'Language Translation plugin {lang_module} '
f'not found. Falling back to {_fallback_translate_plugin}')
clazz = load_tx_plugin(_fallback_translate_plugin)
if clazz:
return clazz(config=get_plugin_config(config, "language", lang_module))
return clazz(config=get_plugin_config(config, "language",
lang_module))

raise
Loading

0 comments on commit 4fe82c7

Please sign in to comment.