From 0b207c7cfbf7a8e8ddf92375a240a68f6d9619f0 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Thu, 9 Mar 2023 23:02:35 +0000 Subject: [PATCH 01/43] Prepare Next Version --- ovos_utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 1e605472..eafc500e 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -2,6 +2,6 @@ # START_VERSION_BLOCK VERSION_MAJOR = 0 VERSION_MINOR = 0 -VERSION_BUILD = 30 +VERSION_BUILD = 31 VERSION_ALPHA = 0 # END_VERSION_BLOCK From c58221702e38209f42a9f406a685fd618b012611 Mon Sep 17 00:00:00 2001 From: Aditya Mehra Date: Fri, 24 Mar 2023 10:24:30 +1030 Subject: [PATCH 02/43] add show input box method for skills (#109) --- ovos_utils/gui.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ovos_utils/gui.py b/ovos_utils/gui.py index 7301f1bf..26e0d2f8 100644 --- a/ovos_utils/gui.py +++ b/ovos_utils/gui.py @@ -914,6 +914,32 @@ def show_url(self, url, override_idle=None, self.show_page("SYSTEM_UrlFrame.qml", override_idle, override_animations) + def show_input_box(self, title=None, placeholder=None, + confirm_text=None, exit_text=None, + override_idle=None, override_animations=None): + self["title"] = title + self["placeholder"] = placeholder + self["skill_id_handler"] = self.skill_id + if not confirm_text: + self["confirm_text"] = "Confirm" + else: + self["confirm_text"] = confirm_text + + if not exit_text: + self["exit_text"] = "Exit" + else: + self["exit_text"] = exit_text + + self.show_page("SYSTEM_InputBox.qml", override_idle, + override_animations) + + def remove_input_box(self): + LOG.info(f"GUI pages length {len(self.pages)}") + if len(self.pages) > 1: + self.remove_page("SYSTEM_InputBox.qml") + else: + self.release() + def release(self): """Signal that this skill is no longer using the GUI, allow different platforms to properly handle this event. From 779e60fb3f19b041979791e448b07f8b54b2555d Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Thu, 23 Mar 2023 23:55:35 +0000 Subject: [PATCH 03/43] Increment Version --- CHANGELOG.md | 12 ++++++++++++ ovos_utils/version.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 298c1ad0..ed34f84f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30...HEAD) + +**Merged pull requests:** + +- Add show input box method for skills [\#109](https://github.com/OpenVoiceOS/ovos-utils/pull/109) ([AIIX](https://github.com/AIIX)) + +## [V0.0.30](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.30) (2023-03-09) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30a4...V0.0.30) + ## [V0.0.30a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.30a4) (2023-03-09) [Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30a3...V0.0.30a4) diff --git a/ovos_utils/version.py b/ovos_utils/version.py index eafc500e..449d3d35 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 0 +VERSION_ALPHA = 1 # END_VERSION_BLOCK From 34f269f07034ecdfb1672a311ab45e8a7c018598 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Wed, 5 Apr 2023 04:02:51 +0100 Subject: [PATCH 04/43] refactor/ovos-bus-client (#110) * refactor/ovos-bus-client * circular import * scripts module --- .../intents/intent_service_interface.py | 4 +- ovos_utils/log.py | 11 +++-- ovos_utils/messagebus.py | 16 ++++++- ovos_utils/scripts.py | 45 ------------------- requirements/requirements.txt | 2 +- setup.py | 9 +--- 6 files changed, 25 insertions(+), 62 deletions(-) delete mode 100644 ovos_utils/scripts.py diff --git a/ovos_utils/intents/intent_service_interface.py b/ovos_utils/intents/intent_service_interface.py index e5407202..5580fa2c 100644 --- a/ovos_utils/intents/intent_service_interface.py +++ b/ovos_utils/intents/intent_service_interface.py @@ -1,8 +1,8 @@ from os.path import exists, isfile -from mycroft_bus_client import MessageBusClient -from mycroft_bus_client.message import Message, dig_for_message +from ovos_bus_client import MessageBusClient +from ovos_bus_client.message import Message, dig_for_message from ovos_utils import create_daemon from ovos_utils.log import LOG diff --git a/ovos_utils/log.py b/ovos_utils/log.py index a3c7ba5b..059d9f65 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -17,7 +17,6 @@ from logging.handlers import RotatingFileHandler from os.path import join -from mycroft_bus_client.message import dig_for_message class LOG: @@ -115,9 +114,13 @@ def _get_real_logger(cls): logger = cls.create_logger(name, tostdout=True) if cls.diagnostic_mode: - msg = dig_for_message() - if msg: - logger.debug(f"DIAGNOSTIC - source bus message {msg.serialize()}") + try: + from ovos_bus_client.message import dig_for_message + msg = dig_for_message() + if msg: + logger.debug(f"DIAGNOSTIC - source bus message {msg.serialize()}") + except ImportError: + pass return logger @classmethod diff --git a/ovos_utils/messagebus.py b/ovos_utils/messagebus.py index 03e284b4..03affc66 100644 --- a/ovos_utils/messagebus.py +++ b/ovos_utils/messagebus.py @@ -3,8 +3,7 @@ from inspect import signature from threading import Event -from mycroft_bus_client import MessageBusClient -from mycroft_bus_client.message import dig_for_message, Message + from ovos_config.config import Configuration from ovos_config.locale import get_default_lang from pyee import BaseEventEmitter @@ -127,6 +126,8 @@ def get_message_lang(message=None): Returns: The language code from the message or the default language. """ + from ovos_bus_client.message import dig_for_message + message = message or dig_for_message() default_lang = get_default_lang() if not message: @@ -139,6 +140,8 @@ def get_websocket(host, port, route='/', ssl=False, threaded=True): """ Returns a connection to a websocket """ + from ovos_bus_client import MessageBusClient + client = MessageBusClient(host, port, route, ssl) if threaded: client.run_in_thread() @@ -198,6 +201,8 @@ def wait_for_reply(message, reply_type=None, timeout=3.0, bus=None): Returns: The received message or None if the response timed out """ + from ovos_bus_client.message import Message + auto_close = bus is None bus = bus or get_mycroft_bus() if isinstance(message, str): @@ -220,6 +225,8 @@ def wait_for_reply(message, reply_type=None, timeout=3.0, bus=None): def send_message(message, data=None, context=None, bus=None): + from ovos_bus_client.message import Message + auto_close = bus is None bus = bus or get_mycroft_bus() if isinstance(message, str): @@ -572,6 +579,8 @@ def set_data_gatherer(self, callback, default_data=None, daemonic=False, interva """ prepare responder for sending, register answers """ + from ovos_bus_client.message import Message + self.bus.remove_all_listeners(self.trigger_message) if ".request" in self.trigger_message: response_type = self.trigger_message.replace(".request", ".reply") @@ -623,6 +632,7 @@ class BusQuery: """ def __init__(self, message, bus=None): + from ovos_bus_client.message import Message self.bus = bus or get_mycroft_bus() self._waiting = False self.response = Message(None, None, None) @@ -649,6 +659,8 @@ def _wait_response(self, timeout): self._waiting = False def send(self, response_type=None, timeout=10): + from ovos_bus_client.message import Message + self.response = Message(None, None, None) if response_type is None: response_type = self.query.type + ".reply" diff --git a/ovos_utils/scripts.py b/ovos_utils/scripts.py deleted file mode 100644 index fa693ae9..00000000 --- a/ovos_utils/scripts.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python3 -# each method here is a console_script defined in setup.py -# each corresponds to a cli util -from mycroft_bus_client import MessageBusClient, Message -from ovos_config import Configuration -import sys - - -def ovos_speak(): - if (args_count := len(sys.argv)) == 2: - utt = sys.argv[1] - lang = Configuration().get("lang", "en-us") - elif args_count == 3: - utt = sys.argv[1] - lang = sys.argv[2] - else: - print("USAGE: ovos-speak {utterance} [lang]") - raise SystemExit(2) - client = MessageBusClient() - client.run_in_thread() - client.emit(Message("speak", {"utterance": utt, "lang": lang})) - client.close() - - -def ovos_say_to(): - if (args_count := len(sys.argv)) == 2: - utt = sys.argv[1] - lang = Configuration().get("lang", "en-us") - elif args_count == 3: - utt = sys.argv[1] - lang = sys.argv[2] - else: - print("USAGE: ovos-say-to {utterance} [lang]") - raise SystemExit(2) - client = MessageBusClient() - client.run_in_thread() - client.emit(Message("recognizer_loop:utterance", {"utterances": [utt], "lang": lang})) - client.close() - - -def ovos_listen(): - client = MessageBusClient() - client.run_in_thread() - client.emit(Message("mycroft.mic.listen")) - client.close() diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 678653f9..bee77d36 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,4 +1,4 @@ -mycroft-messagebus-client~=0.9,!=0.9.2,!=0.9.3 +ovos-bus-client~=0.0, >=0.0.3a4 pexpect~=4.8 requests~=2.26 json_database~=0.7 diff --git a/setup.py b/setup.py index a5a5fa06..c8e7aa5e 100644 --- a/setup.py +++ b/setup.py @@ -70,12 +70,5 @@ def required(requirements_file): license='Apache', author='jarbasAI', author_email='jarbasai@mailfence.com', - description='collection of simple utilities for use across the mycroft ecosystem', - entry_points={ - 'console_scripts': [ - 'ovos-listen=ovos_utils.scripts:ovos_listen', - 'ovos-speak=ovos_utils.scripts:ovos_speak', - 'ovos-say-to=ovos_utils.scripts:ovos_say_to', - ] - } + description='collection of simple utilities for use across the mycroft ecosystem' ) From 71430c2dd3f44f4f7f9ee118cbaeca5e0916b4d4 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Wed, 5 Apr 2023 03:03:59 +0000 Subject: [PATCH 05/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed34f84f..538031da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a1...HEAD) + +**Merged pull requests:** + +- refactor/ovos-bus-client [\#110](https://github.com/OpenVoiceOS/ovos-utils/pull/110) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.31a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a1) (2023-03-23) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30...V0.0.31a1) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 449d3d35..0cdb3f4e 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 1 +VERSION_ALPHA = 2 # END_VERSION_BLOCK From df84def83705c71b5970677cb50f8cae5c7d8a1d Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Wed, 5 Apr 2023 04:26:34 +0100 Subject: [PATCH 06/43] feat/FakeMessage (#111) circular import refactor/ovos-bus-client --- .../intents/intent_service_interface.py | 7 +- ovos_utils/messagebus.py | 175 ++++++++++++++++-- requirements/extras.txt | 3 +- requirements/requirements.txt | 1 - 4 files changed, 168 insertions(+), 18 deletions(-) diff --git a/ovos_utils/intents/intent_service_interface.py b/ovos_utils/intents/intent_service_interface.py index 5580fa2c..03a5aef8 100644 --- a/ovos_utils/intents/intent_service_interface.py +++ b/ovos_utils/intents/intent_service_interface.py @@ -1,9 +1,7 @@ from os.path import exists, isfile -from ovos_bus_client import MessageBusClient -from ovos_bus_client.message import Message, dig_for_message -from ovos_utils import create_daemon +from ovos_utils.messagebus import get_mycroft_bus, Message, dig_for_message from ovos_utils.log import LOG @@ -327,8 +325,7 @@ class IntentQueryApi: def __init__(self, bus=None, timeout=5): if bus is None: - bus = MessageBusClient() - create_daemon(bus.run_forever) + bus = get_mycroft_bus() self.bus = bus self.timeout = timeout diff --git a/ovos_utils/messagebus.py b/ovos_utils/messagebus.py index 03affc66..34a9bc1f 100644 --- a/ovos_utils/messagebus.py +++ b/ovos_utils/messagebus.py @@ -1,9 +1,9 @@ import json import time +from copy import deepcopy from inspect import signature from threading import Event - from ovos_config.config import Configuration from ovos_config.locale import get_default_lang from pyee import BaseEventEmitter @@ -19,6 +19,15 @@ "ssl": False} +def dig_for_message(): + try: + from ovos_bus_client.message import dig_for_message as _dig + return _dig() + except ImportError: + pass + return None + + class FakeBus: def __init__(self, *args, **kwargs): self.started_running = False @@ -119,6 +128,160 @@ def close(self): self.on_close() +# fake Message object to allow usage with FakeBus +class FakeMessage: + """ fake Message object to allow usage with FakeBus without ovos-bus-client installed""" + + def __init__(self, msg_type, data=None, context=None): + """Used to construct a message object + + Message objects will be used to send information back and forth + between processes of mycroft service, voice, skill and cli + """ + self.msg_type = msg_type + self.data = data or {} + self.context = context or {} + + def __eq__(self, other): + try: + return other.msg_type == self.msg_type and \ + other.data == self.data and \ + other.context == self.context + except: + return False + + def serialize(self): + """This returns a string of the message info. + + This makes it easy to send over a websocket. This uses + json dumps to generate the string with type, data and context + + Returns: + str: a json string representation of the message. + """ + return json.dumps({'type': self.msg_type, + 'data': self.data, + 'context': self.context}) + + @staticmethod + def deserialize(value): + """This takes a string and constructs a message object. + + This makes it easy to take strings from the websocket and create + a message object. This uses json loads to get the info and generate + the message object. + + Args: + value(str): This is the json string received from the websocket + + Returns: + Message: message object constructed from the json string passed + int the function. + value(str): This is the string received from the websocket + """ + obj = json.loads(value) + return FakeMessage(obj.get('type') or '', + obj.get('data') or {}, + obj.get('context') or {}) + + def forward(self, msg_type, data=None): + """ Keep context and forward message + + This will take the same parameters as a message object but use + the current message object as a reference. It will copy the context + from the existing message object. + + Args: + msg_type (str): type of message + data (dict): data for message + + Returns: + Message: Message object to be used on the reply to the message + """ + data = data or {} + return FakeMessage(msg_type, data, context=self.context) + + def reply(self, msg_type, data=None, context=None): + """Construct a reply message for a given message + + This will take the same parameters as a message object but use + the current message object as a reference. It will copy the context + from the existing message object and add any context passed in to + the function. Check for a destination passed in to the function from + the data object and add that to the context as a destination. If the + context has a source then that will be swapped with the destination + in the context. The new message will then have data passed in plus the + new context generated. + + Args: + msg_type (str): type of message + data (dict): data for message + context: intended context for new message + + Returns: + Message: Message object to be used on the reply to the message + """ + data = deepcopy(data) or {} + context = context or {} + + new_context = deepcopy(self.context) + for key in context: + new_context[key] = context[key] + if 'destination' in data: + new_context['destination'] = data['destination'] + if 'source' in new_context and 'destination' in new_context: + s = new_context['destination'] + new_context['destination'] = new_context['source'] + new_context['source'] = s + return FakeMessage(msg_type, data, context=new_context) + + def response(self, data=None, context=None): + """Construct a response message for the message + + Constructs a reply with the data and appends the expected + ".response" to the message + + Args: + data (dict): message data + context (dict): message context + Returns + (Message) message with the type modified to match default response + """ + return self.reply(self.msg_type + '.response', data, context) + + def publish(self, msg_type, data, context=None): + """ + Copy the original context and add passed in context. Delete + any target in the new context. Return a new message object with + passed in data and new context. Type remains unchanged. + + Args: + msg_type (str): type of message + data (dict): date to send with message + context: context added to existing context + + Returns: + Message: Message object to publish + """ + context = context or {} + new_context = self.context.copy() + for key in context: + new_context[key] = context[key] + + if 'target' in new_context: + del new_context['target'] + + return FakeMessage(msg_type, data, context=new_context) + + +# patch for utils below +try: + from ovos_bus_client.message import Message +except ImportError: + LOG.warning("ovos-bus-client not installed") + Message = FakeMessage + + def get_message_lang(message=None): """Get the language from the message or the default language. Args: @@ -126,8 +289,6 @@ def get_message_lang(message=None): Returns: The language code from the message or the default language. """ - from ovos_bus_client.message import dig_for_message - message = message or dig_for_message() default_lang = get_default_lang() if not message: @@ -201,8 +362,6 @@ def wait_for_reply(message, reply_type=None, timeout=3.0, bus=None): Returns: The received message or None if the response timed out """ - from ovos_bus_client.message import Message - auto_close = bus is None bus = bus or get_mycroft_bus() if isinstance(message, str): @@ -225,8 +384,6 @@ def wait_for_reply(message, reply_type=None, timeout=3.0, bus=None): def send_message(message, data=None, context=None, bus=None): - from ovos_bus_client.message import Message - auto_close = bus is None bus = bus or get_mycroft_bus() if isinstance(message, str): @@ -579,7 +736,6 @@ def set_data_gatherer(self, callback, default_data=None, daemonic=False, interva """ prepare responder for sending, register answers """ - from ovos_bus_client.message import Message self.bus.remove_all_listeners(self.trigger_message) if ".request" in self.trigger_message: @@ -632,7 +788,6 @@ class BusQuery: """ def __init__(self, message, bus=None): - from ovos_bus_client.message import Message self.bus = bus or get_mycroft_bus() self._waiting = False self.response = Message(None, None, None) @@ -659,8 +814,6 @@ def _wait_response(self, timeout): self._waiting = False def send(self, response_type=None, timeout=10): - from ovos_bus_client.message import Message - self.response = Message(None, None, None) if response_type is None: response_type = self.query.type + ".reply" diff --git a/requirements/extras.txt b/requirements/extras.txt index da2939a2..8dd61339 100644 --- a/requirements/extras.txt +++ b/requirements/extras.txt @@ -1 +1,2 @@ -rapidfuzz~=1.0 \ No newline at end of file +rapidfuzz~=1.0 +ovos-bus-client~=0.0, >=0.0.3a4 \ No newline at end of file diff --git a/requirements/requirements.txt b/requirements/requirements.txt index bee77d36..e2449f54 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,4 +1,3 @@ -ovos-bus-client~=0.0, >=0.0.3a4 pexpect~=4.8 requests~=2.26 json_database~=0.7 From 3d256755886d6b43114b341bd8d4e9ba8242b0ae Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Wed, 5 Apr 2023 03:27:32 +0000 Subject: [PATCH 07/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 538031da..0813efe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a1...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a2...HEAD) + +**Merged pull requests:** + +- feat/FakeMessage [\#111](https://github.com/OpenVoiceOS/ovos-utils/pull/111) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.31a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a2) (2023-04-05) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a1...V0.0.31a2) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 0cdb3f4e..2c381c7b 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 2 +VERSION_ALPHA = 3 # END_VERSION_BLOCK From 921880e69ffa18e089f3504c030b8fd9b7df1a16 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Wed, 5 Apr 2023 17:08:03 -0700 Subject: [PATCH 08/43] Update rapidfuzz dependency (#112) --- requirements/extras.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/extras.txt b/requirements/extras.txt index 8dd61339..92c6844a 100644 --- a/requirements/extras.txt +++ b/requirements/extras.txt @@ -1,2 +1,2 @@ -rapidfuzz~=1.0 -ovos-bus-client~=0.0, >=0.0.3a4 \ No newline at end of file +rapidfuzz~=2.0 +ovos-bus-client~=0.0, >=0.0.3a4 From a55787f38314ded0e88dfe616cf355002dd649a3 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Thu, 6 Apr 2023 00:09:03 +0000 Subject: [PATCH 09/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0813efe6..5c0d3e7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a2...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a3...HEAD) + +**Merged pull requests:** + +- Update rapidfuzz dependency [\#112](https://github.com/OpenVoiceOS/ovos-utils/pull/112) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.31a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a3) (2023-04-05) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a2...V0.0.31a3) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 2c381c7b..8f34941c 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 3 +VERSION_ALPHA = 4 # END_VERSION_BLOCK From e1fab858d69b46e04c817805612352781050d719 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Fri, 7 Apr 2023 21:32:45 +0100 Subject: [PATCH 10/43] fix/missing_dependency (#114) --- requirements/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index e2449f54..d9bcd400 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -4,3 +4,4 @@ json_database~=0.7 kthread~=0.2 ovos_config~=0.0,>=0.0.7 watchdog +pyee \ No newline at end of file From 57d72f4f2242f389a45aa0f2dcfdb1be850856d4 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Fri, 7 Apr 2023 20:34:05 +0000 Subject: [PATCH 11/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c0d3e7c..d96db841 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a3...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a4...HEAD) + +**Fixed bugs:** + +- fix/missing\_dependency [\#114](https://github.com/OpenVoiceOS/ovos-utils/pull/114) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.31a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a4) (2023-04-06) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a3...V0.0.31a4) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 8f34941c..bcc9bf37 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 4 +VERSION_ALPHA = 5 # END_VERSION_BLOCK From 934f534ce238c4d619083e73be5d341a5211767e Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Fri, 7 Apr 2023 22:08:56 +0100 Subject: [PATCH 12/43] fix/missing_dependency (#115) --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d9bcd400..c98e873f 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,6 +2,6 @@ pexpect~=4.8 requests~=2.26 json_database~=0.7 kthread~=0.2 -ovos_config~=0.0,>=0.0.7 +ovos-config~=0.0,>=0.0.8a3 watchdog pyee \ No newline at end of file From dbe73fa2f3f68bdec633013e77c0fe7d2fb2e2c7 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Fri, 7 Apr 2023 21:10:04 +0000 Subject: [PATCH 13/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d96db841..c68cfd5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a4...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a5...HEAD) + +**Fixed bugs:** + +- fix/missing\_dependency [\#115](https://github.com/OpenVoiceOS/ovos-utils/pull/115) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.31a5](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a5) (2023-04-07) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a4...V0.0.31a5) **Fixed bugs:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index bcc9bf37..f03c43ba 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 5 +VERSION_ALPHA = 6 # END_VERSION_BLOCK From f2576eea5f328f38a71ff397ab051a35e9cfa501 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Tue, 11 Apr 2023 00:01:14 +0100 Subject: [PATCH 14/43] feat/PKGBUILD (#116) --- .github/workflows/publish_AUR.yml | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/publish_AUR.yml diff --git a/.github/workflows/publish_AUR.yml b/.github/workflows/publish_AUR.yml new file mode 100644 index 00000000..a3aa7f12 --- /dev/null +++ b/.github/workflows/publish_AUR.yml @@ -0,0 +1,40 @@ +# This workflow will generate a distribution and upload it to PyPI + +name: aur-publish + +on: + workflow_dispatch: + +jobs: + aur-publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: dev + fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. + - name: Setup Python + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: Install Build Tools + run: | + python -m pip install build wheel pip2pkgbuild + - name: Create PKGBUILD + run: | + pip2pkgbuild ovos-utils -p python -b python-ovos-utils + - name: Commit to dev + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: generate PKGBUILD + branch: dev + - name: Publish AUR package + uses: KSXGitHub/github-actions-deploy-aur@ + with: + pkgname: ovos-utils + pkgbuild: ./PKGBUILD + commit_username: ${{ secrets.AUR_USERNAME }} + commit_email: ${{ secrets.AUR_EMAIL }} + ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} + commit_message: Update AUR package + ssh_keyscan_types: rsa,dsa,ecdsa,ed25519 \ No newline at end of file From 2d056f167a2c3e043ba093ff579e95ddb5a40ece Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Tue, 11 Apr 2023 00:03:12 +0100 Subject: [PATCH 15/43] Update publish_AUR.yml --- .github/workflows/publish_AUR.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish_AUR.yml b/.github/workflows/publish_AUR.yml index a3aa7f12..d883f464 100644 --- a/.github/workflows/publish_AUR.yml +++ b/.github/workflows/publish_AUR.yml @@ -29,7 +29,7 @@ jobs: commit_message: generate PKGBUILD branch: dev - name: Publish AUR package - uses: KSXGitHub/github-actions-deploy-aur@ + uses: KSXGitHub/github-actions-deploy-aur@master with: pkgname: ovos-utils pkgbuild: ./PKGBUILD @@ -37,4 +37,4 @@ jobs: commit_email: ${{ secrets.AUR_EMAIL }} ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} commit_message: Update AUR package - ssh_keyscan_types: rsa,dsa,ecdsa,ed25519 \ No newline at end of file + ssh_keyscan_types: rsa,dsa,ecdsa,ed25519 From 8b501579b690ddcd194da07c9f480b7fd2e3d3e0 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Tue, 11 Apr 2023 00:46:08 +0100 Subject: [PATCH 16/43] Feat/optional ovos config (#106) --- .github/workflows/unit_tests.yml | 2 +- ovos_utils/configuration.py | 141 +++++++++++++++++++---------- ovos_utils/dialog.py | 4 +- ovos_utils/file_utils.py | 19 ++-- ovos_utils/fingerprinting.py | 4 +- ovos_utils/gui.py | 4 +- ovos_utils/log.py | 7 +- ovos_utils/messagebus.py | 9 +- ovos_utils/network_utils.py | 7 +- ovos_utils/process_utils.py | 4 +- ovos_utils/signal.py | 4 +- ovos_utils/skills/__init__.py | 8 +- ovos_utils/skills/locations.py | 7 +- ovos_utils/smtp_utils.py | 4 +- ovos_utils/sound/__init__.py | 19 ++-- requirements/extras.txt | 1 + requirements/requirements.txt | 1 - test/unittests/test_audio_utils.py | 2 +- test/unittests/test_skills.py | 17 +++- 19 files changed, 159 insertions(+), 105 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index fb2a95c6..496670dd 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -52,7 +52,7 @@ jobs: python -m pip install build wheel - name: Install core repo run: | - pip install . + pip install .[extras] - name: Install test dependencies run: | pip install pytest pytest-timeout pytest-cov diff --git a/ovos_utils/configuration.py b/ovos_utils/configuration.py index 4fe38f9b..fb63df28 100644 --- a/ovos_utils/configuration.py +++ b/ovos_utils/configuration.py @@ -6,56 +6,105 @@ xdg_data_dirs, xdg_cache_home ) -from ovos_utils.log import LOG - -from ovos_config.locations import ( - get_xdg_config_dirs, - get_xdg_data_dirs, - get_xdg_data_save_path, - get_xdg_config_save_path, - get_xdg_cache_save_path, - find_default_config, - find_user_config, - get_config_locations, - get_webcache_location, - get_xdg_config_locations -) +from os.path import expanduser, isfile +from os import makedirs +import json -from ovos_config.locale import get_default_lang -from ovos_config.meta import ( - get_ovos_config, - get_ovos_default_config_paths, - is_using_xdg, - get_xdg_base, - set_xdg_base, - set_config_filename, - set_default_config, - get_config_filename -) -from ovos_config.config import ( - read_mycroft_config, - update_mycroft_config -) +# if ovos-config not installed, these methods are still needed internally + +def get_xdg_base(): + try: + from ovos_config.meta import get_xdg_base as _get + return _get() + except ImportError: + return "mycroft" + + +def get_xdg_data_save_path(): + try: + from ovos_config.locations import get_xdg_data_save_path as _get + return _get() + except ImportError: + return expanduser("~/.local/share/mycroft") + + +def get_xdg_data_dirs(): + try: + from ovos_config.locations import get_xdg_data_dirs as _get + return _get() + except ImportError: + return [expanduser("~/.local/share/mycroft")] + + +def get_default_lang(): + try: + from ovos_config.locale import get_default_lang as _get + return _get() + except ImportError: + return read_mycroft_config().get("lang", "en-us") + + +def read_mycroft_config(): + try: + from ovos_config import Configuration + return Configuration() + except ImportError: + pass + path = expanduser(f"~/.config/mycroft/mycroft.conf") + if isfile(path): + with open(path) as f: + return json.load(f) + return { + # TODO - default cfg + "lang": "en-us" + } -from ovos_config.models import ( - LocalConf, - ReadOnlyConfig, - MycroftUserConfig, - MycroftDefaultConfig, - MycroftSystemConfig, - MycroftXDGConfig -) -from ovos_config.meta import save_ovos_config as save_ovos_core_config +def update_mycroft_config(config, path=None, bus=None): + try: + from ovos_config.config import update_mycroft_config as _update + _update(config, path, bus) + except ImportError: + pass + # save in default user location + path = expanduser(f"~/.config/mycroft") + makedirs(path, exist_ok=True) + with open(f"{path}/mycroft.conf", "w") as f: + json.dump(config, f, indent=2) -LOG.warning("configuration moved to the `ovos_config` package. This submodule " - "will be removed in ovos_utils 0.1.0") +# ovos-config not installed, optional compat imports below don't matter +try: + from ovos_config.locations import ( + get_xdg_config_dirs, + get_xdg_config_save_path, + get_xdg_cache_save_path, + find_default_config, + find_user_config, + get_config_locations, + get_webcache_location, + get_xdg_config_locations) + from ovos_config.meta import ( + get_ovos_config, + get_ovos_default_config_paths, + is_using_xdg, + set_xdg_base, + set_config_filename, + set_default_config, + get_config_filename + ) + from ovos_config.models import ( + LocalConf, + ReadOnlyConfig, + MycroftUserConfig, + MycroftDefaultConfig, + MycroftSystemConfig, + MycroftXDGConfig + ) + from ovos_config.meta import save_ovos_config as save_ovos_core_config +except ImportError: + from ovos_utils.log import LOG -def set_config_name(name, core_folder=None): - # TODO deprecate, was only out in a couple versions - LOG.warning("This reference is deprecated, use " - "`ovos_config.meta.set_config_filename`") - # renamed to match HolmesV - set_config_filename(name, core_folder) + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") diff --git a/ovos_utils/dialog.py b/ovos_utils/dialog.py index cfc0fd1a..7b519007 100644 --- a/ovos_utils/dialog.py +++ b/ovos_utils/dialog.py @@ -5,7 +5,7 @@ from pathlib import Path from ovos_utils.bracket_expansion import expand_options -from ovos_config.config import Configuration +from ovos_utils.configuration import read_mycroft_config from ovos_utils.file_utils import resolve_resource_file from ovos_utils.lang import translate_word from ovos_utils.log import LOG @@ -146,7 +146,7 @@ def get_dialog(phrase, lang=None, context=None): if not lang: try: - conf = Configuration() + conf = read_mycroft_config() lang = conf.get('lang') except FileNotFoundError: lang = "en-us" diff --git a/ovos_utils/file_utils.py b/ovos_utils/file_utils.py index 26e5aab0..7079ebb1 100644 --- a/ovos_utils/file_utils.py +++ b/ovos_utils/file_utils.py @@ -1,18 +1,20 @@ import collections import csv -import re import os -from os import walk -from os.path import splitext, join, dirname +import re import tempfile -from ovos_utils.bracket_expansion import expand_options -from ovos_utils.log import LOG -from ovos_utils.system import search_mycroft_core_location import time +from os import walk from os.path import dirname +from os.path import splitext, join -from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler +from watchdog.observers import Observer + +from ovos_utils.bracket_expansion import expand_options +from ovos_utils.configuration import read_mycroft_config +from ovos_utils.log import LOG +from ovos_utils.system import search_mycroft_core_location def get_temp_path(*args): @@ -103,8 +105,7 @@ def resolve_resource_file(res_name, root_path=None, config=None): str: path to resource or None if no resource found """ if config is None: - from ovos_config.config import Configuration - config = Configuration() + config = read_mycroft_config() # First look for fully qualified file (e.g. a user setting) if os.path.isfile(res_name): diff --git a/ovos_utils/fingerprinting.py b/ovos_utils/fingerprinting.py index 63a64fd1..a0c4f702 100644 --- a/ovos_utils/fingerprinting.py +++ b/ovos_utils/fingerprinting.py @@ -4,6 +4,7 @@ from os.path import join, isfile from ovos_utils.system import is_installed, is_running_from_module, has_screen, \ get_desktop_environment, search_mycroft_core_location, is_process_running +from ovos_utils.configuration import read_mycroft_config class MycroftPlatform(str, Enum): @@ -27,8 +28,7 @@ def detect_platform(): def get_config_fingerprint(config=None): if not config: - from ovos_config.config import Configuration - config = Configuration() + config = read_mycroft_config() conf = config listener_conf = conf.get("listener", {}) skills_conf = conf.get("skills", {}) diff --git a/ovos_utils/gui.py b/ovos_utils/gui.py index 26e0d2f8..e15706f8 100644 --- a/ovos_utils/gui.py +++ b/ovos_utils/gui.py @@ -7,7 +7,7 @@ from ovos_utils.log import LOG from ovos_utils.messagebus import wait_for_reply, get_mycroft_bus, Message from ovos_utils.system import is_installed, has_screen, is_process_running -from ovos_config import Configuration +from ovos_utils.configuration import read_mycroft_config def can_display(): @@ -461,7 +461,7 @@ class GUIInterface: """ def __init__(self, skill_id, bus=None, remote_server=None, config=None): - self.config = config or Configuration().get("gui", {}) + self.config = config or read_mycroft_config().get("gui", {}) if remote_server: self.config["remote-server"] = remote_server self._bus = bus diff --git a/ovos_utils/log.py b/ovos_utils/log.py index 059d9f65..c6104d6a 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -18,7 +18,6 @@ from os.path import join - class LOG: """ Custom logger class that acts like logging.Logger @@ -49,7 +48,7 @@ def __init__(cls, name='OVOS'): @classmethod def init(cls, config=None): - from ovos_config.meta import get_xdg_base + from ovos_utils.configuration import get_xdg_base from ovos_utils.xdg_utils import xdg_state_home config = config or {} @@ -148,9 +147,9 @@ def init_service_logger(service_name): # this is makes all logs from this service be configured to write to service_name.log file # if this is not called in every __main__.py entrypoint logs will be written # to a generic OVOS.log file shared across all services - from ovos_config import Configuration + from ovos_utils.configuration import read_mycroft_config - _cfg = Configuration() + _cfg = read_mycroft_config() _log_level = _cfg.get("log_level", "INFO") _logs_conf = _cfg.get("logs") or {} _logs_conf["level"] = _log_level diff --git a/ovos_utils/messagebus.py b/ovos_utils/messagebus.py index 34a9bc1f..3b565fcf 100644 --- a/ovos_utils/messagebus.py +++ b/ovos_utils/messagebus.py @@ -4,8 +4,7 @@ from inspect import signature from threading import Event -from ovos_config.config import Configuration -from ovos_config.locale import get_default_lang +from ovos_utils.configuration import read_mycroft_config, get_default_lang from pyee import BaseEventEmitter from ovos_utils import create_loop @@ -314,7 +313,7 @@ def get_mycroft_bus(host: str = None, port: int = None, route: str = None, """ Returns a connection to the mycroft messagebus """ - config = Configuration().get('websocket') or dict() + config = read_mycroft_config().get('websocket') or dict() host = host or config.get('host') or _DEFAULT_WS_CONFIG['host'] port = port or config.get('port') or _DEFAULT_WS_CONFIG['port'] route = route or config.get('route') or _DEFAULT_WS_CONFIG['route'] @@ -716,7 +715,7 @@ def __init__(self, trigger_message, name=None, bus=None, config=None): name(str): name identifier for .conf settings bus (WebsocketClient): mycroft messagebus websocket """ - config = config or Configuration() + config = config or read_mycroft_config() self.trigger_message = trigger_message self.name = name or self.__class__.__name__ self.bus = bus or get_mycroft_bus() @@ -859,7 +858,7 @@ def __init__(self, query_message, name=None, timeout=5, bus=None, self.query_message.context["source"] = self.name self.name = name or self.__class__.__name__ self.bus = bus or get_mycroft_bus() - config = config or Configuration() + config = config or read_mycroft_config() self.config = config.get(self.name, {}) self.timeout = timeout self.query = None diff --git a/ovos_utils/network_utils.py b/ovos_utils/network_utils.py index ecac01f3..26cd75a4 100644 --- a/ovos_utils/network_utils.py +++ b/ovos_utils/network_utils.py @@ -2,11 +2,9 @@ import requests -# backwards compat - was only out there for a couple alpha version -# TODO - remove next stable -from ovos_utils.process_utils import RuntimeRequirements as NetworkRequirements from ovos_utils.log import LOG +from ovos_utils.configuration import read_mycroft_config _DEFAULT_TEST_CONFIG = { @@ -22,8 +20,7 @@ def get_network_tests_config(): """Get network_tests object from mycroft.configuration.""" - from ovos_config import Configuration - config = Configuration() + config = read_mycroft_config() return config.get("network_tests", _DEFAULT_TEST_CONFIG) diff --git a/ovos_utils/process_utils.py b/ovos_utils/process_utils.py index 876a972b..7f227c58 100644 --- a/ovos_utils/process_utils.py +++ b/ovos_utils/process_utils.py @@ -24,6 +24,8 @@ from ovos_utils.log import LOG +from ovos_utils.configuration import get_xdg_base +from ovos_utils.file_utils import get_temp_path @dataclass @@ -291,8 +293,6 @@ class PIDLock: # python 3+ 'class Lock' """ @classmethod def init(cls): - from ovos_config.meta import get_xdg_base - from ovos_utils.file_utils import get_temp_path cls.DIRECTORY = cls.DIRECTORY or get_temp_path(get_xdg_base()) # # Class constants diff --git a/ovos_utils/signal.py b/ovos_utils/signal.py index e08789c7..a7670ee3 100644 --- a/ovos_utils/signal.py +++ b/ovos_utils/signal.py @@ -6,6 +6,7 @@ from ovos_utils.log import LOG +from ovos_utils.configuration import read_mycroft_config def get_ipc_directory(domain=None, config=None): @@ -23,8 +24,7 @@ def get_ipc_directory(domain=None, config=None): str: a path to the IPC directory """ if config is None: - from ovos_config.config import Configuration - config = Configuration() + config = read_mycroft_config() path = config.get("ipc_path") if not path: # If not defined, use /tmp/mycroft/ipc diff --git a/ovos_utils/skills/__init__.py b/ovos_utils/skills/__init__.py index 3ad39830..217bd221 100644 --- a/ovos_utils/skills/__init__.py +++ b/ovos_utils/skills/__init__.py @@ -1,4 +1,4 @@ -from ovos_config.config import Configuration, update_mycroft_config +from ovos_utils.configuration import read_mycroft_config, update_mycroft_config from ovos_utils.messagebus import wait_for_reply from ovos_utils.skills.locations import get_default_skills_directory, get_installed_skill_ids from ovos_utils.log import LOG @@ -39,7 +39,7 @@ def skills_loaded(bus=None): def blacklist_skill(skill, config=None): - config = config or Configuration() + config = config or read_mycroft_config() skills_config = config.get("skills", {}) blacklisted_skills = skills_config.get("blacklisted_skills", []) if skill not in blacklisted_skills: @@ -55,7 +55,7 @@ def blacklist_skill(skill, config=None): def whitelist_skill(skill, config=None): - config = config or Configuration() + config = config or read_mycroft_config() skills_config = config.get("skills", {}) blacklisted_skills = skills_config.get("blacklisted_skills", []) if skill in blacklisted_skills: @@ -71,7 +71,7 @@ def whitelist_skill(skill, config=None): def make_priority_skill(skill, config=None): - config = config or Configuration() + config = config or read_mycroft_config() skills_config = config.get("skills", {}) priority_skills = skills_config.get("priority_skills", []) if skill not in priority_skills: diff --git a/ovos_utils/skills/locations.py b/ovos_utils/skills/locations.py index 55a402d0..70ed6d63 100644 --- a/ovos_utils/skills/locations.py +++ b/ovos_utils/skills/locations.py @@ -1,8 +1,7 @@ from os.path import join, isdir, dirname, expanduser, isfile from os import makedirs, listdir from typing import List, Optional -from ovos_config.locations import get_xdg_data_save_path, get_xdg_data_dirs -from ovos_config.config import Configuration +from ovos_utils.configuration import read_mycroft_config, get_xdg_data_save_path, get_xdg_data_dirs from ovos_utils.log import LOG @@ -54,7 +53,7 @@ def get_skill_directories(conf: Optional[dict] = None) -> List[str]: # the contents of each skills directory must be individual skill folders # we are still dependent on the mycroft-core structure of skill_id/__init__.py - conf = conf or Configuration() + conf = conf or read_mycroft_config() # load all valid XDG paths # NOTE: skills are actually code, but treated as user data! @@ -101,7 +100,7 @@ def get_default_skills_directory(conf: Optional[dict] = None) -> str: Returns: Absolute path to default skills directory """ - conf = conf or Configuration() + conf = conf or read_mycroft_config() path_override = conf["skills"].get("directory_override") # if .conf wants to use a specific path, use it! diff --git a/ovos_utils/smtp_utils.py b/ovos_utils/smtp_utils.py index 5d24c3c8..18a2a4e3 100644 --- a/ovos_utils/smtp_utils.py +++ b/ovos_utils/smtp_utils.py @@ -2,7 +2,7 @@ from email.mime.text import MIMEText from smtplib import SMTP_SSL -from ovos_config import Configuration +from ovos_utils.configuration import read_mycroft_config def send_smtp(user, pswd, sender, @@ -19,7 +19,7 @@ def send_smtp(user, pswd, sender, def send_email(subject, body, recipient=None): - mail_config = Configuration.get("email") or {} + mail_config = read_mycroft_config().get("email") or {} if not mail_config: raise KeyError("email configuration not set") diff --git a/ovos_utils/sound/__init__.py b/ovos_utils/sound/__init__.py index cd26e83d..e3e28aaf 100644 --- a/ovos_utils/sound/__init__.py +++ b/ovos_utils/sound/__init__.py @@ -4,7 +4,8 @@ from copy import deepcopy from distutils.spawn import find_executable -from ovos_config import Configuration + +from ovos_utils.configuration import read_mycroft_config from ovos_utils.file_utils import resolve_resource_file from ovos_utils.log import LOG @@ -35,7 +36,7 @@ def play_acknowledge_sound(): to the user that their request was handled successfully. """ audio_file = resolve_resource_file( - Configuration().get('sounds', {}).get('acknowledge')) + read_mycroft_config().get('sounds', {}).get('acknowledge')) if not audio_file: LOG.warning("Could not find 'acknowledge' audio file!") @@ -50,7 +51,7 @@ def play_acknowledge_sound(): def play_listening_sound(): """Audibly indicate speech recording started.""" audio_file = resolve_resource_file( - Configuration().get('sounds', {}).get('start_listening')) + read_mycroft_config().get('sounds', {}).get('start_listening')) if not audio_file: LOG.warning("Could not find 'start_listening' audio file!") @@ -65,7 +66,7 @@ def play_listening_sound(): def play_end_listening_sound(): """Audibly indicate speech recording is no longer happening.""" audio_file = resolve_resource_file( - Configuration().get('sounds', {}).get('end_listening')) + read_mycroft_config().get('sounds', {}).get('end_listening')) if not audio_file: LOG.debug("Could not find 'end_listening' audio file!") @@ -85,7 +86,7 @@ def play_error_sound(): to the user that their request was NOT handled successfully. """ audio_file = resolve_resource_file( - Configuration().get('sounds', {}).get('error')) + read_mycroft_config().get('sounds', {}).get('error')) if not audio_file: LOG.warning("Could not find 'error' audio file!") @@ -141,7 +142,7 @@ def play_audio(uri, play_cmd=None, environment=None): Returns: subprocess.Popen object. None if the format is not supported or an error occurs playing the file. """ - config = Configuration() + config = read_mycroft_config() environment = environment or _get_pulse_environment(config) # NOTE: some urls like youtube streams will cause extension detection to fail @@ -186,7 +187,7 @@ def play_wav(uri, play_cmd=None, environment=None): Returns: subprocess.Popen object """ - config = Configuration() + config = read_mycroft_config() environment = environment or _get_pulse_environment(config) play_cmd = play_cmd or config.get("play_wav_cmdline") or "paplay %1" play_wav_cmd = str(play_cmd).split(" ") @@ -206,7 +207,7 @@ def play_mp3(uri, play_cmd=None, environment=None): Returns: subprocess.Popen object """ - config = Configuration() + config = read_mycroft_config() environment = environment or _get_pulse_environment(config) play_cmd = play_cmd or config.get("play_mp3_cmdline") or "mpg123 %1" play_mp3_cmd = str(play_cmd).split(" ") @@ -226,7 +227,7 @@ def play_ogg(uri, play_cmd=None, environment=None): Returns: subprocess.Popen object """ - config = Configuration() + config = read_mycroft_config() environment = environment or _get_pulse_environment(config) play_cmd = play_cmd or config.get("play_ogg_cmdline") or "ogg123 -q %1" play_ogg_cmd = str(play_cmd).split(" ") diff --git a/requirements/extras.txt b/requirements/extras.txt index 92c6844a..4331d9fa 100644 --- a/requirements/extras.txt +++ b/requirements/extras.txt @@ -1,2 +1,3 @@ rapidfuzz~=2.0 ovos-bus-client~=0.0, >=0.0.3a4 +ovos-config~=0.0,>=0.0.8a3 \ No newline at end of file diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c98e873f..44c870bc 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,6 +2,5 @@ pexpect~=4.8 requests~=2.26 json_database~=0.7 kthread~=0.2 -ovos-config~=0.0,>=0.0.8a3 watchdog pyee \ No newline at end of file diff --git a/test/unittests/test_audio_utils.py b/test/unittests/test_audio_utils.py index 84513a8f..f247979f 100644 --- a/test/unittests/test_audio_utils.py +++ b/test/unittests/test_audio_utils.py @@ -22,7 +22,7 @@ def __eq__(self, other): return True -@mock.patch('ovos_utils.sound.Configuration') +@mock.patch('ovos_utils.sound.read_mycroft_config') @mock.patch('ovos_utils.sound.subprocess') class TestPlaySounds(TestCase): def test_play_ogg(self, mock_subprocess, mock_conf): diff --git a/test/unittests/test_skills.py b/test/unittests/test_skills.py index ce245df2..1d01b8b4 100644 --- a/test/unittests/test_skills.py +++ b/test/unittests/test_skills.py @@ -2,6 +2,14 @@ from os import environ from os.path import isdir, join, dirname from unittest.mock import patch +from ovos_utils.skills.locations import get_skill_directories +from ovos_utils.skills.locations import get_default_skills_directory +from ovos_utils.skills.locations import get_installed_skill_ids +from ovos_utils.skills.locations import get_plugin_skills +try: + import ovos_config +except ImportError: + ovos_config = None class TestLocations(unittest.TestCase): @@ -9,7 +17,6 @@ class TestLocations(unittest.TestCase): def test_get_installed_skill_ids(self, plugins): plugins.return_value = (['plugin_dir', 'plugin_dir_2'], ['plugin_id', 'plugin_id_2']) - from ovos_utils.skills.locations import get_installed_skill_ids environ["XDG_DATA_DIRS"] = join(dirname(__file__), "test_skills_xdg") config = {"skills": { "extra_directories": [join(dirname(__file__), "test_skills_dir")] @@ -20,7 +27,8 @@ def test_get_installed_skill_ids(self, plugins): "skill-test-2.openvoiceos"}) def test_get_skill_directories(self): - from ovos_utils.skills.locations import get_skill_directories + if not ovos_config: + return # skip test since ovos.conf isn't taken into account # Default behavior, only one valid XDG path environ["XDG_DATA_DIRS"] = environ["XDG_DATA_HOME"] = \ @@ -41,13 +49,15 @@ def test_get_skill_directories(self): self.assertEqual(get_skill_directories(config), [default_dir, extra_dir]) + # Define invalid directories in extra_directories config['skills']['extra_directories'] += ["/not/a/directory"] self.assertEqual(get_skill_directories(config), [default_dir, extra_dir]) def test_get_default_skills_directory(self): - from ovos_utils.skills.locations import get_default_skills_directory + if not ovos_config: + return # skip test since ovos.conf isn't taken into account test_skills_dir = join(dirname(__file__), "test_skills_dir") # Configured override (legacy) @@ -70,7 +80,6 @@ def test_get_default_skills_directory(self): self.assertEqual(get_default_skills_directory(config), xdg_skills_dir) def test_get_plugin_skills(self): - from ovos_utils.skills.locations import get_plugin_skills dirs, ids = get_plugin_skills() for d in dirs: self.assertTrue(isdir(d)) From 13cc44b2fd7a196818567c3849a329596d2329e2 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Mon, 10 Apr 2023 23:47:08 +0000 Subject: [PATCH 17/43] Increment Version --- CHANGELOG.md | 11 ++++++++++- ovos_utils/version.py | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c68cfd5b..9699e23b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,16 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a5...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a6...HEAD) + +**Merged pull requests:** + +- feat/PKGBUILD [\#116](https://github.com/OpenVoiceOS/ovos-utils/pull/116) ([JarbasAl](https://github.com/JarbasAl)) +- Feat/optional ovos config [\#106](https://github.com/OpenVoiceOS/ovos-utils/pull/106) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.31a6](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a6) (2023-04-07) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a5...V0.0.31a6) **Fixed bugs:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index f03c43ba..f45f2d1e 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 6 +VERSION_ALPHA = 7 # END_VERSION_BLOCK From 5e385754b5ad5bd75b0ad08370cddf88aff3d2ee Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Tue, 11 Apr 2023 12:11:44 -0700 Subject: [PATCH 18/43] Update input device checks (#81) Co-authored-by: Daniel McKnight --- ovos_utils/device_input.py | 7 +--- test/unittests/test_device_input.py | 63 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 test/unittests/test_device_input.py diff --git a/ovos_utils/device_input.py b/ovos_utils/device_input.py index 5b6d54af..17e9b21b 100644 --- a/ovos_utils/device_input.py +++ b/ovos_utils/device_input.py @@ -11,7 +11,7 @@ def __init__(self) -> None: if not find_executable("libinput") and not find_executable("xinput"): LOG.warning("Could not find libinput, input device detection will be inaccurate") - # ToDo: add support for discovring the input device based of a connected + # ToDo: add support for discovering the input device based of a connected # monitors, currently linux only supports input listing directly from the # system def _build_linput_devices_list(self): @@ -138,8 +138,3 @@ def can_use_touch_mouse(): def can_use_keyboard(): return InputDeviceHelper().can_use_keyboard() - - -if __name__ == "__main__": - - can_use_touch_mouse() diff --git a/test/unittests/test_device_input.py b/test/unittests/test_device_input.py new file mode 100644 index 00000000..96d06a57 --- /dev/null +++ b/test/unittests/test_device_input.py @@ -0,0 +1,63 @@ +import unittest +from unittest import mock +from unittest.mock import Mock + + +class TestDeviceInput(unittest.TestCase): + def test_input_device_helper(self): + # TODO + pass + + @mock.patch('distutils.spawn.find_executable') + def test_can_use_touch_mouse(self, find_exec): + from ovos_utils.device_input import InputDeviceHelper + find_exec.return_value = True + dev_input = InputDeviceHelper() + + dev_input._build_linput_devices_list = Mock() + dev_input._build_xinput_devices_list = Mock() + + dev_input.libinput_devices_list = [{'Device': 'Mock', + 'Capabilities': ['mouse']}, + {'Device': "Mock 1", + 'Capabilities': ['touch']} + ] + self.assertTrue(dev_input.can_use_touch_mouse()) + + dev_input.libinput_devices_list.pop() + self.assertTrue(dev_input.can_use_touch_mouse()) + dev_input.libinput_devices_list.pop() + self.assertFalse(dev_input.can_use_touch_mouse()) + dev_input.xinput_devices_list = [{'Device': 'xinput', + 'Capabilities': ['tablet'] + }] + self.assertTrue(dev_input.can_use_touch_mouse()) + dev_input.xinput_devices_list.pop() + self.assertFalse(dev_input.can_use_touch_mouse()) + + @mock.patch('distutils.spawn.find_executable') + def test_can_use_keyboard(self, find_exec): + from ovos_utils.device_input import InputDeviceHelper + find_exec.return_value = True + dev_input = InputDeviceHelper() + + dev_input._build_linput_devices_list = Mock() + dev_input._build_xinput_devices_list = Mock() + + dev_input.libinput_devices_list = [{'Device': 'Mock', + 'Capabilities': ['keyboard']}, + {'Device': "Mock 1", + 'Capabilities': ['touch']} + ] + self.assertTrue(dev_input.can_use_keyboard()) + + dev_input.libinput_devices_list.pop() + self.assertTrue(dev_input.can_use_keyboard()) + dev_input.libinput_devices_list.pop() + self.assertFalse(dev_input.can_use_keyboard()) + dev_input.xinput_devices_list = [{'Device': 'xinput', + 'Capabilities': ['keyboard'] + }] + self.assertTrue(dev_input.can_use_keyboard()) + dev_input.xinput_devices_list.pop() + self.assertFalse(dev_input.can_use_keyboard()) From 728282a04f305fb6940be2bd722efb6c828443c9 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Tue, 11 Apr 2023 19:12:41 +0000 Subject: [PATCH 19/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9699e23b..e9be5d5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a6...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a7...HEAD) + +**Merged pull requests:** + +- Update input device checks [\#81](https://github.com/OpenVoiceOS/ovos-utils/pull/81) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.31a7](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a7) (2023-04-10) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a6...V0.0.31a7) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index f45f2d1e..2c00c967 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 7 +VERSION_ALPHA = 8 # END_VERSION_BLOCK From 708ce8c500897283d945c49e50badd3474a6b958 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Tue, 11 Apr 2023 20:13:17 +0100 Subject: [PATCH 20/43] add back wrapper around removed methods (#118) --- ovos_utils/configuration.py | 368 ++++++++++++++++++++++++++++++++---- 1 file changed, 328 insertions(+), 40 deletions(-) diff --git a/ovos_utils/configuration.py b/ovos_utils/configuration.py index fb63df28..9a234928 100644 --- a/ovos_utils/configuration.py +++ b/ovos_utils/configuration.py @@ -1,19 +1,80 @@ -from ovos_utils.system import search_mycroft_core_location, is_running_from_module -from ovos_utils.xdg_utils import ( - xdg_config_home, - xdg_config_dirs, - xdg_data_home, - xdg_data_dirs, - xdg_cache_home -) -from os.path import expanduser, isfile -from os import makedirs import json +from os import makedirs +from os.path import join, expanduser, exists, isfile + +import ovos_utils.xdg_utils as xdg +from ovos_utils.log import LOG -# if ovos-config not installed, these methods are still needed internally +# TODO - deprecate this submodule in 0.1.0 +# note that a couple of these are also used inside ovos-utils +# perhaps those usages should also move into workshop ? + +def get_default_lang(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.locale import get_default_lang as _get + return _get() + except ImportError: + return read_mycroft_config().get("lang", "en-us") + + +def find_user_config(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.locations import find_user_config as _get + return _get() + except ImportError: + + return join(get_xdg_config_save_path(), get_config_filename()) + + +def get_webcache_location(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + return join(get_xdg_config_save_path(), 'web_cache.json') + + +def get_config_locations(default=True, web_cache=True, system=True, + old_user=True, user=True): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.locations import get_config_locations as _get + return _get(default, web_cache, system, old_user, user) + except ImportError: + locs = [] + ovos_cfg = get_ovos_config() + if default: + locs.append(ovos_cfg["default_config_path"]) + if system: + locs.append(f"/etc/{ovos_cfg['base_folder']}/{ovos_cfg['config_filename']}") + if web_cache: + locs.append(get_webcache_location()) + if old_user: + locs.append(f"~/.{ovos_cfg['base_folder']}/{ovos_cfg['config_filename']}") + if user: + locs.append(f"{get_xdg_config_save_path()}/{ovos_cfg['config_filename']}") + return locs + + +def get_ovos_config(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.meta import get_ovos_config as _get + return _get() + except ImportError: + return {"xdg": True, + "base_folder": "mycroft", + "config_filename": "mycroft.conf"} + def get_xdg_base(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") try: from ovos_config.meta import get_xdg_base as _get return _get() @@ -21,7 +82,54 @@ def get_xdg_base(): return "mycroft" +def get_xdg_config_locations(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + # This includes both the user config and + # /etc/xdg/mycroft/mycroft.conf + xdg_paths = list(reversed( + [join(p, get_config_filename()) + for p in get_xdg_config_dirs()] + )) + return xdg_paths + + +def get_xdg_data_dirs(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.locations import get_xdg_data_dirs as _get + return _get() + except ImportError: + return [expanduser("~/.local/share/mycroft")] + + +def get_xdg_config_dirs(folder=None): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.locations import get_xdg_config_dirs as _get + return _get() + except ImportError: + folder = folder or get_xdg_base() + xdg_dirs = xdg.xdg_config_dirs() + [xdg.xdg_config_home()] + return [join(path, folder) for path in xdg_dirs] + + +def get_xdg_cache_save_path(folder=None): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.locations import get_xdg_cache_save_path as _get + return _get() + except ImportError: + folder = folder or get_xdg_base() + return join(xdg.xdg_cache_home(), folder) + + def get_xdg_data_save_path(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") try: from ovos_config.locations import get_xdg_data_save_path as _get return _get() @@ -29,23 +137,66 @@ def get_xdg_data_save_path(): return expanduser("~/.local/share/mycroft") -def get_xdg_data_dirs(): +def get_xdg_config_save_path(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") try: - from ovos_config.locations import get_xdg_data_dirs as _get + from ovos_config.locations import get_xdg_config_save_path as _get return _get() except ImportError: - return [expanduser("~/.local/share/mycroft")] + return expanduser("~/.config/mycroft") -def get_default_lang(): +def is_using_xdg(): + """ DEPRECATED """ + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + return True + + +def set_xdg_base(*args, **kwargs): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") try: - from ovos_config.locale import get_default_lang as _get + from ovos_config.meta import set_xdg_base as _set + _set(*args, **kwargs) + except: + pass + + +def set_config_filename(*args, **kwargs): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.meta import config_filename as _set + _set(*args, **kwargs) + except: + pass + + +def get_config_filename(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.locale import get_config_filename as _get return _get() except ImportError: - return read_mycroft_config().get("lang", "en-us") + return "mycroft.conf" + + +def get_ovos_default_config_paths(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.meta import get_ovos_default_config_paths as _get + return _get() + except: + return ["/etc/OpenVoiceOS/ovos.conf"] def read_mycroft_config(): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") try: from ovos_config import Configuration return Configuration() @@ -62,6 +213,8 @@ def read_mycroft_config(): def update_mycroft_config(config, path=None, bus=None): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") try: from ovos_config.config import update_mycroft_config as _update _update(config, path, bus) @@ -74,26 +227,27 @@ def update_mycroft_config(config, path=None, bus=None): json.dump(config, f, indent=2) -# ovos-config not installed, optional compat imports below don't matter +def set_default_config(*args, **kwargs): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.meta import set_default_config as _set + _set(*args, **kwargs) + except: + pass + + +def save_ovos_core_config(*args, **kwargs): + LOG.warning("configuration moved to the `ovos_config` package. This submodule " + "will be removed in ovos_utils 0.1.0") + try: + from ovos_config.meta import save_ovos_config as _set + _set(*args, **kwargs) + except: + pass + + try: - from ovos_config.locations import ( - get_xdg_config_dirs, - get_xdg_config_save_path, - get_xdg_cache_save_path, - find_default_config, - find_user_config, - get_config_locations, - get_webcache_location, - get_xdg_config_locations) - from ovos_config.meta import ( - get_ovos_config, - get_ovos_default_config_paths, - is_using_xdg, - set_xdg_base, - set_config_filename, - set_default_config, - get_config_filename - ) from ovos_config.models import ( LocalConf, ReadOnlyConfig, @@ -102,9 +256,143 @@ def update_mycroft_config(config, path=None, bus=None): MycroftSystemConfig, MycroftXDGConfig ) - from ovos_config.meta import save_ovos_config as save_ovos_core_config except ImportError: - from ovos_utils.log import LOG + LOG.warning("configuration classes moved to the `ovos_config.models` package. " + "This submodule will be removed in ovos_utils 0.1.0") + from combo_lock import NamedLock + import yaml + from ovos_utils.json_helper import load_commented_json, merge_dict - LOG.warning("configuration moved to the `ovos_config` package. This submodule " - "will be removed in ovos_utils 0.1.0") + + class LocalConf(dict): + """Config dictionary from file.""" + allow_overwrite = True + # lock is shared among all subclasses, + # regardless of what file is being edited only one file should change at a time + # this ensure orderly behaviour in anything monitoring changes, + # eg FileWatcher util, configuration.patch bus handlers + __lock = NamedLock("ovos_config") + + def __init__(self, path): + super().__init__(self) + self.path = path + if path: + self.load_local(path) + + def _get_file_format(self, path=None): + """The config file format + supported file extensions: + - json (.json) + - commented json (.conf) + - yaml (.yaml/.yml) + + returns "yaml" or "json" + """ + path = path or self.path + if not path: + return "dict" + if path.endswith(".yml") or path.endswith(".yaml"): + return "yaml" + else: + return "json" + + def load_local(self, path=None): + """Load local json file into self. + + Args: + path (str): file to load + """ + path = path or self.path + if not path: + LOG.error(f"in memory configuration, nothing to load") + return + if exists(path) and isfile(path): + with self.__lock: + try: + if self._get_file_format(path) == "yaml": + with open(path) as f: + config = yaml.safe_load(f) + else: + config = load_commented_json(path) + if config: + for key in config: + self.__setitem__(key, config[key]) + LOG.debug(f"Configuration {path} loaded") + else: + LOG.debug(f"Empty config found at: {path}") + except Exception as e: + LOG.exception(f"Error loading configuration '{path}'") + else: + LOG.debug(f"Configuration '{path}' not defined, skipping") + + def reload(self): + self.load_local(self.path) + + def store(self, path=None): + path = path or self.path + if not path: + LOG.error(f"in memory configuration, no save location") + return + with self.__lock: + if self._get_file_format(path) == "yaml": + with open(path, 'w+') as f: + yaml.dump(dict(self), f, allow_unicode=True, + default_flow_style=False, sort_keys=False) + else: + with open(path, 'w+') as f: + json.dump(self, f, indent=2) + + def merge(self, conf): + merge_dict(self, conf) + + + class ReadOnlyConfig(LocalConf): + """ read only """ + + def __init__(self, path, allow_overwrite=False): + super().__init__(path) + self.allow_overwrite = allow_overwrite + + def reload(self): + old = self.allow_overwrite + self.allow_overwrite = True + super().reload() + self.allow_overwrite = old + + def __setitem__(self, key, value): + if not self.allow_overwrite: + raise PermissionError(f"{self.path} is read only! it can not be modified at runtime") + super().__setitem__(key, value) + + def merge(self, *args, **kwargs): + if not self.allow_overwrite: + raise PermissionError(f"{self.path} is read only! it can not be modified at runtime") + super().merge(*args, **kwargs) + + def store(self, path=None): + if not self.allow_overwrite: + raise PermissionError(f"{self.path} is read only! it can not be modified at runtime") + super().store(path) + + + class MycroftDefaultConfig(ReadOnlyConfig): + def __init__(self): + super().__init__(join(get_xdg_config_save_path(), get_config_filename())) + + def set_root_config_path(self, root_config): + # in case we got it wrong / non standard + self.path = root_config + self.reload() + + + class MycroftSystemConfig(ReadOnlyConfig): + def __init__(self, allow_overwrite=False): + super().__init__("/etc/mycroft/mycroft.conf", allow_overwrite) + + + class RemoteConf(LocalConf): + def __init__(self, cache=get_webcache_location()): + super(RemoteConf, self).__init__(cache) + + + MycroftXDGConfig = MycroftUserConfig = MycroftDefaultConfig From 2fbd3105ac1e07a975892d6f1721b4db40157a99 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Tue, 11 Apr 2023 19:14:19 +0000 Subject: [PATCH 21/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9be5d5f..985a5bac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a7...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a8...HEAD) + +**Fixed bugs:** + +- add back wrapper around removed methods [\#118](https://github.com/OpenVoiceOS/ovos-utils/pull/118) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.31a8](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a8) (2023-04-11) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a7...V0.0.31a8) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 2c00c967..8295e3ce 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 8 +VERSION_ALPHA = 9 # END_VERSION_BLOCK From bf0df6190c323674eeec731402d1e55e151ee6e5 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:52:43 +0100 Subject: [PATCH 22/43] fix/bus compat (#121) --- ovos_utils/messagebus.py | 51 ++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/ovos_utils/messagebus.py b/ovos_utils/messagebus.py index 3b565fcf..be02de31 100644 --- a/ovos_utils/messagebus.py +++ b/ovos_utils/messagebus.py @@ -127,10 +127,41 @@ def close(self): self.on_close() -# fake Message object to allow usage with FakeBus -class FakeMessage: +class _MutableMessage(type): + """ To override isinstance checks we need to use a metaclass """ + + def __instancecheck__(self, instance): + try: + from ovos_bus_client.message import Message as _MycroftMessage + if isinstance(instance, _MycroftMessage): + return True + except: + pass + try: + from mycroft_bus_client.message import Message as _MycroftMessage + if isinstance(instance, _MycroftMessage): + return True + except: + pass + return super().__instancecheck__(instance) + + +# fake Message object to allow usage without ovos-bus-client installed +class Message(metaclass=_MutableMessage): """ fake Message object to allow usage with FakeBus without ovos-bus-client installed""" + def __new__(cls, *args, **kwargs): + try: # most common case + from ovos_bus_client import Message as _M + return _M(*args, **kwargs) + except: + pass + try: # some old install that upgraded during migration period + from mycroft_bus_client import Message as _M + return _M(*args, **kwargs) + except: # FakeMessage + return super().__new__(cls, *args, **kwargs) + def __init__(self, msg_type, data=None, context=None): """Used to construct a message object @@ -179,7 +210,7 @@ def deserialize(value): value(str): This is the string received from the websocket """ obj = json.loads(value) - return FakeMessage(obj.get('type') or '', + return Message(obj.get('type') or '', obj.get('data') or {}, obj.get('context') or {}) @@ -198,7 +229,7 @@ def forward(self, msg_type, data=None): Message: Message object to be used on the reply to the message """ data = data or {} - return FakeMessage(msg_type, data, context=self.context) + return Message(msg_type, data, context=self.context) def reply(self, msg_type, data=None, context=None): """Construct a reply message for a given message @@ -232,7 +263,7 @@ def reply(self, msg_type, data=None, context=None): s = new_context['destination'] new_context['destination'] = new_context['source'] new_context['source'] = s - return FakeMessage(msg_type, data, context=new_context) + return Message(msg_type, data, context=new_context) def response(self, data=None, context=None): """Construct a response message for the message @@ -270,15 +301,11 @@ def publish(self, msg_type, data, context=None): if 'target' in new_context: del new_context['target'] - return FakeMessage(msg_type, data, context=new_context) + return Message(msg_type, data, context=new_context) -# patch for utils below -try: - from ovos_bus_client.message import Message -except ImportError: - LOG.warning("ovos-bus-client not installed") - Message = FakeMessage +# compat +FakeMessage = Message def get_message_lang(message=None): From 164a15d100c82f3a2ca357bdddd3035a8d246750 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Tue, 11 Apr 2023 22:53:41 +0000 Subject: [PATCH 23/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 985a5bac..37188217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a8...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a9...HEAD) + +**Fixed bugs:** + +- fix/bus compat [\#121](https://github.com/OpenVoiceOS/ovos-utils/pull/121) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.31a9](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a9) (2023-04-11) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a8...V0.0.31a9) **Fixed bugs:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 8295e3ce..b8aab3e9 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 9 +VERSION_ALPHA = 10 # END_VERSION_BLOCK From 6ce2c272080c0e584b4d666679ef0bdca45a3412 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Tue, 11 Apr 2023 16:41:45 -0700 Subject: [PATCH 24/43] Deprecate internal `ovos_config.config` references (#122) --- ovos_utils/dialog.py | 6 +++++- ovos_utils/file_utils.py | 8 ++++++-- ovos_utils/fingerprinting.py | 9 +++++++-- ovos_utils/gui.py | 10 ++++++++-- ovos_utils/log.py | 11 ++++++++--- ovos_utils/messagebus.py | 13 +++++++++++-- ovos_utils/network_utils.py | 8 ++++++-- ovos_utils/process_utils.py | 10 ++++++++-- ovos_utils/signal.py | 8 ++++++-- ovos_utils/skills/__init__.py | 2 +- ovos_utils/skills/locations.py | 3 ++- ovos_utils/smtp_utils.py | 10 ++++++++-- ovos_utils/sound/__init__.py | 13 +++++++++---- 13 files changed, 85 insertions(+), 26 deletions(-) diff --git a/ovos_utils/dialog.py b/ovos_utils/dialog.py index 7b519007..d4dac70f 100644 --- a/ovos_utils/dialog.py +++ b/ovos_utils/dialog.py @@ -5,7 +5,6 @@ from pathlib import Path from ovos_utils.bracket_expansion import expand_options -from ovos_utils.configuration import read_mycroft_config from ovos_utils.file_utils import resolve_resource_file from ovos_utils.lang import translate_word from ovos_utils.log import LOG @@ -146,9 +145,14 @@ def get_dialog(phrase, lang=None, context=None): if not lang: try: + from ovos_config.config import read_mycroft_config conf = read_mycroft_config() lang = conf.get('lang') + except ImportError: + LOG.warning("Config not provided and ovos_config not available") + lang = "en-us" except FileNotFoundError: + LOG.warning("Configuration file not found, default lang to 'en-us'") lang = "en-us" filename = join('text', lang.lower(), phrase + '.dialog') diff --git a/ovos_utils/file_utils.py b/ovos_utils/file_utils.py index 7079ebb1..8b0a45c6 100644 --- a/ovos_utils/file_utils.py +++ b/ovos_utils/file_utils.py @@ -12,7 +12,6 @@ from watchdog.observers import Observer from ovos_utils.bracket_expansion import expand_options -from ovos_utils.configuration import read_mycroft_config from ovos_utils.log import LOG from ovos_utils.system import search_mycroft_core_location @@ -105,7 +104,12 @@ def resolve_resource_file(res_name, root_path=None, config=None): str: path to resource or None if no resource found """ if config is None: - config = read_mycroft_config() + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config() + except ImportError: + LOG.warning("Config not provided and ovos_config not available") + config = dict() # First look for fully qualified file (e.g. a user setting) if os.path.isfile(res_name): diff --git a/ovos_utils/fingerprinting.py b/ovos_utils/fingerprinting.py index a0c4f702..9d011d07 100644 --- a/ovos_utils/fingerprinting.py +++ b/ovos_utils/fingerprinting.py @@ -2,9 +2,9 @@ import socket from enum import Enum from os.path import join, isfile +from ovos_utils.log import LOG from ovos_utils.system import is_installed, is_running_from_module, has_screen, \ get_desktop_environment, search_mycroft_core_location, is_process_running -from ovos_utils.configuration import read_mycroft_config class MycroftPlatform(str, Enum): @@ -28,7 +28,12 @@ def detect_platform(): def get_config_fingerprint(config=None): if not config: - config = read_mycroft_config() + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config() + except ImportError: + LOG.warning("Config not provided and ovos_config not available") + config = dict() conf = config listener_conf = conf.get("listener", {}) skills_conf = conf.get("skills", {}) diff --git a/ovos_utils/gui.py b/ovos_utils/gui.py index e15706f8..d02abe93 100644 --- a/ovos_utils/gui.py +++ b/ovos_utils/gui.py @@ -7,7 +7,6 @@ from ovos_utils.log import LOG from ovos_utils.messagebus import wait_for_reply, get_mycroft_bus, Message from ovos_utils.system import is_installed, has_screen, is_process_running -from ovos_utils.configuration import read_mycroft_config def can_display(): @@ -461,7 +460,14 @@ class GUIInterface: """ def __init__(self, skill_id, bus=None, remote_server=None, config=None): - self.config = config or read_mycroft_config().get("gui", {}) + if not config: + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config().get("gui", {}) + except ImportError: + LOG.warning("Config not provided and ovos_config not available") + config = dict() + self.config = config if remote_server: self.config["remote-server"] = remote_server self._bus = bus diff --git a/ovos_utils/log.py b/ovos_utils/log.py index c6104d6a..01c15406 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -48,11 +48,16 @@ def __init__(cls, name='OVOS'): @classmethod def init(cls, config=None): - from ovos_utils.configuration import get_xdg_base + try: + from ovos_config.meta import get_xdg_base + default_base = get_xdg_base() + except ImportError: + default_base = "mycroft" from ovos_utils.xdg_utils import xdg_state_home config = config or {} - cls.base_path = config.get("path") or f"{xdg_state_home()}/{get_xdg_base()}" + cls.base_path = config.get("path") or \ + f"{xdg_state_home()}/{default_base}" cls.max_bytes = config.get("max_bytes", 50000000) cls.backup_count = config.get("backup_count", 3) cls.level = config.get("level", "INFO") @@ -147,7 +152,7 @@ def init_service_logger(service_name): # this is makes all logs from this service be configured to write to service_name.log file # if this is not called in every __main__.py entrypoint logs will be written # to a generic OVOS.log file shared across all services - from ovos_utils.configuration import read_mycroft_config + from ovos_config.config import read_mycroft_config _cfg = read_mycroft_config() _log_level = _cfg.get("log_level", "INFO") diff --git a/ovos_utils/messagebus.py b/ovos_utils/messagebus.py index be02de31..42cbb473 100644 --- a/ovos_utils/messagebus.py +++ b/ovos_utils/messagebus.py @@ -4,7 +4,7 @@ from inspect import signature from threading import Event -from ovos_utils.configuration import read_mycroft_config, get_default_lang +# from ovos_utils.configuration import read_mycroft_config, get_default_lang from pyee import BaseEventEmitter from ovos_utils import create_loop @@ -315,6 +315,7 @@ def get_message_lang(message=None): Returns: The language code from the message or the default language. """ + from ovos_config.locale import get_default_lang message = message or dig_for_message() default_lang = get_default_lang() if not message: @@ -340,6 +341,7 @@ def get_mycroft_bus(host: str = None, port: int = None, route: str = None, """ Returns a connection to the mycroft messagebus """ + from ovos_config.config import read_mycroft_config config = read_mycroft_config().get('websocket') or dict() host = host or config.get('host') or _DEFAULT_WS_CONFIG['host'] port = port or config.get('port') or _DEFAULT_WS_CONFIG['port'] @@ -742,6 +744,7 @@ def __init__(self, trigger_message, name=None, bus=None, config=None): name(str): name identifier for .conf settings bus (WebsocketClient): mycroft messagebus websocket """ + from ovos_config.config import read_mycroft_config config = config or read_mycroft_config() self.trigger_message = trigger_message self.name = name or self.__class__.__name__ @@ -885,7 +888,13 @@ def __init__(self, query_message, name=None, timeout=5, bus=None, self.query_message.context["source"] = self.name self.name = name or self.__class__.__name__ self.bus = bus or get_mycroft_bus() - config = config or read_mycroft_config() + if not config: + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config() + except ImportError: + LOG.warning("Config not provided and ovos_config not available") + config = dict() self.config = config.get(self.name, {}) self.timeout = timeout self.query = None diff --git a/ovos_utils/network_utils.py b/ovos_utils/network_utils.py index 26cd75a4..c4b9a9e4 100644 --- a/ovos_utils/network_utils.py +++ b/ovos_utils/network_utils.py @@ -4,7 +4,6 @@ from ovos_utils.log import LOG -from ovos_utils.configuration import read_mycroft_config _DEFAULT_TEST_CONFIG = { @@ -20,7 +19,12 @@ def get_network_tests_config(): """Get network_tests object from mycroft.configuration.""" - config = read_mycroft_config() + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config() + except ImportError: + LOG.warning("ovos_config not available. Falling back to default config") + config = dict() return config.get("network_tests", _DEFAULT_TEST_CONFIG) diff --git a/ovos_utils/process_utils.py b/ovos_utils/process_utils.py index 7f227c58..18a403db 100644 --- a/ovos_utils/process_utils.py +++ b/ovos_utils/process_utils.py @@ -24,7 +24,6 @@ from ovos_utils.log import LOG -from ovos_utils.configuration import get_xdg_base from ovos_utils.file_utils import get_temp_path @@ -293,7 +292,14 @@ class PIDLock: # python 3+ 'class Lock' """ @classmethod def init(cls): - cls.DIRECTORY = cls.DIRECTORY or get_temp_path(get_xdg_base()) + try: + from ovos_config.meta import get_xdg_base + base_dir = get_xdg_base() + except ImportError: + LOG.warning("ovos-config not available, using default " + "'mycroft' basedir") + base_dir = "mycroft" + cls.DIRECTORY = cls.DIRECTORY or get_temp_path(base_dir) # # Class constants DIRECTORY = None diff --git a/ovos_utils/signal.py b/ovos_utils/signal.py index a7670ee3..3bb97da6 100644 --- a/ovos_utils/signal.py +++ b/ovos_utils/signal.py @@ -6,7 +6,6 @@ from ovos_utils.log import LOG -from ovos_utils.configuration import read_mycroft_config def get_ipc_directory(domain=None, config=None): @@ -24,7 +23,12 @@ def get_ipc_directory(domain=None, config=None): str: a path to the IPC directory """ if config is None: - config = read_mycroft_config() + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config() + except ImportError: + LOG.warning("Config not provided and ovos_config not available") + config = dict() path = config.get("ipc_path") if not path: # If not defined, use /tmp/mycroft/ipc diff --git a/ovos_utils/skills/__init__.py b/ovos_utils/skills/__init__.py index 217bd221..8296f306 100644 --- a/ovos_utils/skills/__init__.py +++ b/ovos_utils/skills/__init__.py @@ -1,4 +1,4 @@ -from ovos_utils.configuration import read_mycroft_config, update_mycroft_config +from ovos_config.config import read_mycroft_config, update_mycroft_config from ovos_utils.messagebus import wait_for_reply from ovos_utils.skills.locations import get_default_skills_directory, get_installed_skill_ids from ovos_utils.log import LOG diff --git a/ovos_utils/skills/locations.py b/ovos_utils/skills/locations.py index 70ed6d63..1ec620e7 100644 --- a/ovos_utils/skills/locations.py +++ b/ovos_utils/skills/locations.py @@ -1,7 +1,8 @@ from os.path import join, isdir, dirname, expanduser, isfile from os import makedirs, listdir from typing import List, Optional -from ovos_utils.configuration import read_mycroft_config, get_xdg_data_save_path, get_xdg_data_dirs +from ovos_config.config import read_mycroft_config +from ovos_config.locations import get_xdg_data_save_path, get_xdg_data_dirs from ovos_utils.log import LOG diff --git a/ovos_utils/smtp_utils.py b/ovos_utils/smtp_utils.py index 18a2a4e3..6803b212 100644 --- a/ovos_utils/smtp_utils.py +++ b/ovos_utils/smtp_utils.py @@ -2,7 +2,7 @@ from email.mime.text import MIMEText from smtplib import SMTP_SSL -from ovos_utils.configuration import read_mycroft_config +from ovos_utils.log import LOG def send_smtp(user, pswd, sender, @@ -19,7 +19,13 @@ def send_smtp(user, pswd, sender, def send_email(subject, body, recipient=None): - mail_config = read_mycroft_config().get("email") or {} + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config() + except ImportError: + LOG.warning("Config not provided and ovos_config not available") + config = dict() + mail_config = config.get("email") or {} if not mail_config: raise KeyError("email configuration not set") diff --git a/ovos_utils/sound/__init__.py b/ovos_utils/sound/__init__.py index e3e28aaf..c03b9285 100644 --- a/ovos_utils/sound/__init__.py +++ b/ovos_utils/sound/__init__.py @@ -1,16 +1,21 @@ import os import subprocess import time + from copy import deepcopy from distutils.spawn import find_executable - - -from ovos_utils.configuration import read_mycroft_config - from ovos_utils.file_utils import resolve_resource_file from ovos_utils.log import LOG from ovos_utils.signal import check_for_signal +try: + from ovos_config.config import read_mycroft_config +except ImportError: + LOG.warning("Config not provided and ovos_config not available") + + def read_mycroft_config(): + return dict() + # Create a custom environment to use that can be ducked by a phone role. # This is kept separate from the normal os.environ to ensure that the TTS # role isn't affected and that any thirdparty software launched through From 79f9d106009b8d0e0c90fe6496771f9d72d589e1 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Tue, 11 Apr 2023 23:42:53 +0000 Subject: [PATCH 25/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37188217..e4b541dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a9...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a10...HEAD) + +**Merged pull requests:** + +- Deprecate internal `ovos_config.config` references [\#122](https://github.com/OpenVoiceOS/ovos-utils/pull/122) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.31a10](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a10) (2023-04-11) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a9...V0.0.31a10) **Fixed bugs:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index b8aab3e9..ec521766 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 10 +VERSION_ALPHA = 11 # END_VERSION_BLOCK From 643bdd3835edfd62b6a3092cf9ba8feccbad6ed6 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Wed, 12 Apr 2023 17:59:41 +0100 Subject: [PATCH 26/43] feat/native_OCP (#120) --- ovos_utils/skills/audioservice.py | 247 +++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 5 deletions(-) diff --git a/ovos_utils/skills/audioservice.py b/ovos_utils/skills/audioservice.py index fb0c4089..4cf7c908 100644 --- a/ovos_utils/skills/audioservice.py +++ b/ovos_utils/skills/audioservice.py @@ -13,19 +13,19 @@ # limitations under the License. # +from datetime import timedelta # This file is directly copied from HolmesV, it's a simple utility to # interface with the AudioService via messagebus outside core from os.path import abspath -from datetime import timedelta -from ovos_utils.messagebus import Message, get_mycroft_bus + +from ovos_utils.log import LOG +from ovos_utils.messagebus import Message, get_mycroft_bus, dig_for_message def ensure_uri(s): """Interprete paths as file:// uri's. - Args: s: string to be checked - Returns: if s is uri, s is returned otherwise file:// is prepended """ @@ -43,9 +43,12 @@ def ensure_uri(s): raise ValueError('Invalid track') -class AudioServiceInterface: +class ClassicAudioServiceInterface: """AudioService class for interacting with the audio subsystem + Audio is managed by OCP in the default implementation, + usually this class should not be directly used, see OCPInterface instead + Args: bus: Mycroft messagebus connection """ @@ -208,3 +211,237 @@ def available_backends(self): def is_playing(self): """True if the audioservice is playing, else False.""" return self.track_info() != {} + + +class AudioServiceInterface(ClassicAudioServiceInterface): + """ClassicAudioService compatible class for interacting with OCP subsystem + Args: + bus: Mycroft messagebus connection + """ + + def __init__(self, bus=None): + super().__init__(bus) + LOG.warning("AudioServiceInterface has been deprecated, compatibility layer in use\n" + "please move to OCPInterface") + + @staticmethod + def _uri2meta(uri): + if isinstance(uri, list): + uri = uri[0] + try: + from ovos_ocp_files_plugin.plugin import OCPFilesMetadataExtractor + return OCPFilesMetadataExtractor.extract_metadata(uri) + except: + meta = {"uri": uri, + "skill_id": "mycroft.audio_interface", + "playback": 2, # PlaybackType.AUDIO, # TODO mime type check + "status": 33 # TrackState.QUEUED_AUDIO + } + meta["skill_id"] = "mycroft.audio_interface" + return meta + + def _format_msg(self, msg_type, msg_data=None): + # this method ensures all skills are .forward from the utterance + # that triggered the skill, this ensures proper routing and metadata + msg_data = msg_data or {} + msg = dig_for_message() + if msg: + msg = msg.forward(msg_type, msg_data) + else: + msg = Message(msg_type, msg_data) + # at this stage source == skills, lets indicate audio service took over + sauce = msg.context.get("source") + if sauce == "skills": + msg.context["source"] = "audio_service" + return msg + + # OCP bus api + def queue(self, tracks=None): + """Queue up a track to playing playlist. + TODO allow rich metadata for OCP: + - support dicts in tracks + NOTE: skills using this won't be compatible with mycroft-core ... + Args: + tracks: track uri or list of track uri's + Each track can be added as a tuple with (uri, mime) + to give a hint of the mime type to the system + """ + tracks = tracks or [] + if isinstance(tracks, (str, tuple)): + tracks = [tracks] + elif not isinstance(tracks, list): + raise ValueError + tracks = [self._uri2meta(t) for t in tracks] + msg = self._format_msg('ovos.common_play.playlist.queue', + {'tracks': tracks}) + self.bus.emit(msg) + + def play(self, tracks=None, utterance=None, repeat=None): + """Start playback. + Args: + tracks: track uri or list of track uri's + Each track can be added as a tuple with (uri, mime) + to give a hint of the mime type to the system + utterance: forward utterance for further processing by the + audio service. + repeat: if the playback should be looped + """ + repeat = repeat or False + tracks = tracks or [] + utterance = utterance or '' + if isinstance(tracks, (str, tuple)): + tracks = [tracks] + elif not isinstance(tracks, list): + raise ValueError + tracks = [self._uri2meta(t) for t in tracks] + + msg = self._format_msg('ovos.common_play.play', + {"media": tracks[0], + "playlist": tracks, + "utterance": utterance, + 'repeat': repeat}) + self.bus.emit(msg) + + def stop(self): + """Stop the track.""" + msg = self._format_msg("ovos.common_play.stop") + self.bus.emit(msg) + + def next(self): + """Change to next track.""" + msg = self._format_msg("ovos.common_play.next") + self.bus.emit(msg) + + def prev(self): + """Change to previous track.""" + msg = self._format_msg("ovos.common_play.previous") + self.bus.emit(msg) + + def pause(self): + """Pause playback.""" + msg = self._format_msg("ovos.common_play.pause") + self.bus.emit(msg) + + def resume(self): + """Resume paused playback.""" + msg = self._format_msg("ovos.common_play.resume") + self.bus.emit(msg) + + def seek_forward(self, seconds=1): + """Skip ahead X seconds. + Args: + seconds (int): number of seconds to skip + """ + if isinstance(seconds, timedelta): + seconds = seconds.total_seconds() + msg = self._format_msg('ovos.common_play.seek', + {"seconds": seconds}) + self.bus.emit(msg) + + def seek_backward(self, seconds=1): + """Rewind X seconds + Args: + seconds (int): number of seconds to rewind + """ + if isinstance(seconds, timedelta): + seconds = seconds.total_seconds() + msg = self._format_msg('ovos.common_play.seek', + {"seconds": seconds * -1}) + self.bus.emit(msg) + + def get_track_length(self): + """ + getting the duration of the audio in miliseconds + """ + length = 0 + msg = self._format_msg('ovos.common_play.get_track_length') + info = self.bus.wait_for_response(msg, timeout=1) + if info: + length = info.data.get("length", 0) + return length + + def get_track_position(self): + """ + get current position in miliseconds + """ + pos = 0 + msg = self._format_msg('ovos.common_play.get_track_position') + info = self.bus.wait_for_response(msg, timeout=1) + if info: + pos = info.data.get("position", 0) + return pos + + def set_track_position(self, miliseconds): + """Go to X position. + Arguments: + miliseconds (int): position to go to in miliseconds + """ + msg = self._format_msg('ovos.common_play.set_track_position', + {"position": miliseconds}) + self.bus.emit(msg) + + def track_info(self): + """Request information of current playing track. + Returns: + Dict with track info. + """ + msg = self._format_msg('ovos.common_play.track_info') + response = self.bus.wait_for_response(msg) + return response.data if response else {} + + def available_backends(self): + """Return available audio backends. + Returns: + dict with backend names as keys + """ + msg = self._format_msg('ovos.common_play.list_backends') + response = self.bus.wait_for_response(msg) + return response.data if response else {} + + +class OCPInterface(AudioServiceInterface): + """bus api interface for OCP subsystem + Args: + bus: Mycroft messagebus connection + """ + + def __init__(self, bus=None): + self.bus = bus or get_mycroft_bus() + + # OCP bus api + def queue(self, tracks): + """Queue up a track to OCP playing playlist. + + Args: + tracks: track dict or list of track dicts (OCP result style) + """ + + assert isinstance(tracks, list) + assert all(isinstance(t, dict) for t in tracks) + + msg = self._format_msg('ovos.common_play.playlist.queue', + {'tracks': tracks}) + self.bus.emit(msg) + + def play(self, tracks, utterance=None): + """Start playback. + Args: + tracks: track dict or list of track dicts (OCP result style) + utterance: forward utterance for further processing by OCP + + TODO handle utterance: + - allow services to register .voc files + - match utterance against vocs in OCP + - select audio service based on parsing + eg. "play X in spotify" + """ + assert isinstance(tracks, list) + assert all(isinstance(t, dict) for t in tracks) + + utterance = utterance or '' + + msg = self._format_msg('ovos.common_play.play', + {"media": tracks[0], + "playlist": tracks, + "utterance": utterance}) + self.bus.emit(msg) From 2bf4fdc0deb1bfb296810f7d21196052089e64dd Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Wed, 12 Apr 2023 17:00:49 +0000 Subject: [PATCH 27/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4b541dc..3ca43243 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a10...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a11...HEAD) + +**Merged pull requests:** + +- feat/native\_OCP [\#120](https://github.com/OpenVoiceOS/ovos-utils/pull/120) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.31a11](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a11) (2023-04-11) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a10...V0.0.31a11) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index ec521766..2cb2409c 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 11 +VERSION_ALPHA = 12 # END_VERSION_BLOCK From 309abad6bd29f3d96943c7a17768213cef5772bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Trellu?= Date: Thu, 13 Apr 2023 15:30:23 -0400 Subject: [PATCH 28/43] [log] Only creates directory if not stdout (#125) --- ovos_utils/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_utils/log.py b/ovos_utils/log.py index 01c15406..a09964d8 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -62,7 +62,6 @@ def init(cls, config=None): cls.backup_count = config.get("backup_count", 3) cls.level = config.get("level", "INFO") cls.diagnostic_mode = config.get("diagnostic", False) - os.makedirs(cls.base_path, exist_ok=True) @classmethod def create_logger(cls, name, tostdout=True): @@ -77,6 +76,7 @@ def create_logger(cls, name, tostdout=True): logger.addHandler(stdout_handler) # log to file if cls.base_path != "stdout": + os.makedirs(cls.base_path, exist_ok=True) path = join(cls.base_path, cls.name.lower().strip() + ".log") handler = RotatingFileHandler(path, maxBytes=cls.max_bytes, From 1146062ab74ceb61e92f12bc94b37c358626b5ae Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Thu, 13 Apr 2023 19:31:35 +0000 Subject: [PATCH 29/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ca43243..ed84ff44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a11...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a12...HEAD) + +**Fixed bugs:** + +- \[log\] Only creates directory if not stdout [\#125](https://github.com/OpenVoiceOS/ovos-utils/pull/125) ([goldyfruit](https://github.com/goldyfruit)) + +## [V0.0.31a12](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a12) (2023-04-12) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a11...V0.0.31a12) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 2cb2409c..a12e11bc 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 12 +VERSION_ALPHA = 13 # END_VERSION_BLOCK From cf8467fd9f3605a02cd5216e404a616e950adc5a Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Thu, 13 Apr 2023 13:51:12 -0700 Subject: [PATCH 30/43] Update docstrings, annotate deprecation, and outline unit tests (#119) --- .github/workflows/unit_tests.yml | 2 +- ovos_utils/__init__.py | 7 ++ ovos_utils/bracket_expansion.py | 3 +- ovos_utils/dialog.py | 22 +++-- ovos_utils/enclosure/__init__.py | 22 ++++- ovos_utils/events.py | 17 ++-- ovos_utils/file_utils.py | 75 +++++++++------ ovos_utils/fingerprinting.py | 1 + ovos_utils/gui.py | 95 +++++++++++++------ .../intents/intent_service_interface.py | 20 ++-- ovos_utils/intents/layers.py | 4 +- ovos_utils/json_helper.py | 1 + ovos_utils/network_utils.py | 43 ++++++--- ovos_utils/ovos_service_api.py | 8 ++ ovos_utils/process_utils.py | 1 - ovos_utils/skills/__init__.py | 27 +++--- ovos_utils/skills/audioservice.py | 11 ++- ovos_utils/smtp_utils.py | 17 ---- ovos_utils/sound/alsa.py | 29 +----- ovos_utils/sound/pulse.py | 9 +- ovos_utils/system.py | 1 + test/unittests/test_bracket_expansion.py | 31 ++++++ test/unittests/test_dialog.py | 19 ++++ test/unittests/test_enclosure.py | 16 ++++ test/unittests/test_events.py | 27 ++++++ test/unittests/test_file_utils.py | 57 +++++++++++ test/unittests/test_fingerprinting.py | 6 ++ test/unittests/test_gui.py | 80 ++++++++++++++++ test/unittests/test_intents.py | 65 +++++++++++++ test/unittests/test_json_helpers.py | 18 ++-- test/unittests/test_lang.py | 24 +++++ test/unittests/test_log.py | 11 +++ test/unittests/test_messagebus.py | 6 ++ test/{ => unittests}/test_metrics.py | 0 test/unittests/test_network_utils.py | 44 +++++++++ test/unittests/test_parse.py | 23 +++++ test/unittests/test_process_utils.py | 6 ++ test/unittests/test_security.py | 6 ++ test/unittests/test_signal.py | 6 ++ test/unittests/test_skills.py | 45 +++++++++ test/unittests/test_smtp_utils.py | 6 ++ test/unittests/test_sound.py | 57 +++++++++++ test/unittests/test_ssml.py | 6 +- test/unittests/test_utils.py | 41 +++++++- test/unittests/test_xdg_utils.py | 6 ++ test/unittests/test_xml_helper.py | 6 ++ 46 files changed, 846 insertions(+), 181 deletions(-) create mode 100644 test/unittests/test_bracket_expansion.py create mode 100644 test/unittests/test_dialog.py create mode 100644 test/unittests/test_enclosure.py create mode 100644 test/unittests/test_events.py create mode 100644 test/unittests/test_file_utils.py create mode 100644 test/unittests/test_fingerprinting.py create mode 100644 test/unittests/test_gui.py create mode 100644 test/unittests/test_intents.py create mode 100644 test/unittests/test_lang.py create mode 100644 test/unittests/test_log.py create mode 100644 test/unittests/test_messagebus.py rename test/{ => unittests}/test_metrics.py (100%) create mode 100644 test/unittests/test_network_utils.py create mode 100644 test/unittests/test_parse.py create mode 100644 test/unittests/test_process_utils.py create mode 100644 test/unittests/test_security.py create mode 100644 test/unittests/test_signal.py create mode 100644 test/unittests/test_smtp_utils.py create mode 100644 test/unittests/test_sound.py create mode 100644 test/unittests/test_xdg_utils.py create mode 100644 test/unittests/test_xml_helper.py diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 496670dd..51537bda 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -55,7 +55,7 @@ jobs: pip install .[extras] - name: Install test dependencies run: | - pip install pytest pytest-timeout pytest-cov + pip install pytest pytest-timeout pytest-cov mock - name: Run unittests run: | pytest --cov=ovos_utils --cov-report xml test/unittests diff --git a/ovos_utils/__init__.py b/ovos_utils/__init__.py index 4b063031..a720b73e 100644 --- a/ovos_utils/__init__.py +++ b/ovos_utils/__init__.py @@ -23,6 +23,7 @@ # TODO: Deprecate below imports from ovos_utils.file_utils import resolve_ovos_resource_file, resolve_resource_file from ovos_utils.network_utils import get_ip, get_external_ip, is_connected_dns, is_connected_http, is_connected +from ovos_utils.log import LOG class classproperty(property): @@ -33,6 +34,9 @@ def __get__(self, owner_self, owner_cls): def ensure_mycroft_import(): + # TODO: Deprecate in 0.1.0 + LOG.warning("This method is deprecated. Anything depending on `mycroft`" + "should install `ovos-core` as a dependency") try: import mycroft except ImportError: @@ -46,6 +50,9 @@ def ensure_mycroft_import(): def get_mycroft_root(): + # TODO: Deprecate in 0.1.0 + LOG.warning("This method is deprecated. Code should import from the current" + "namespace; other system paths are irrelevant.") paths = [ "/opt/venvs/mycroft-core/lib/python3.7/site-packages/", # mark1/2 "/opt/venvs/mycroft-core/lib/python3.4/site-packages/ ", # old mark1 installs diff --git a/ovos_utils/bracket_expansion.py b/ovos_utils/bracket_expansion.py index 1c69a6f5..35f02c1d 100644 --- a/ovos_utils/bracket_expansion.py +++ b/ovos_utils/bracket_expansion.py @@ -1,7 +1,8 @@ import re +from typing import List -def expand_parentheses(sent): +def expand_parentheses(sent: List[str]) -> List[str]: """ ['1', '(', '2', '|', '3, ')'] -> [['1', '2'], ['1', '3']] For example: diff --git a/ovos_utils/dialog.py b/ovos_utils/dialog.py index d4dac70f..3c936b0a 100644 --- a/ovos_utils/dialog.py +++ b/ovos_utils/dialog.py @@ -3,6 +3,7 @@ import re from os.path import join from pathlib import Path +from typing import Optional from ovos_utils.bracket_expansion import expand_options from ovos_utils.file_utils import resolve_resource_file @@ -103,12 +104,15 @@ def render(self, template_name, context=None, index=None): return line -def load_dialogs(dialog_dir, renderer=None): - """Load all dialog files within the specified directory. +def load_dialogs(dialog_dir: str, + renderer: Optional[MustacheDialogRenderer] = None) -> \ + MustacheDialogRenderer: + """ + Load all dialog files within the specified directory. Args: dialog_dir (str): directory that contains dialog files - + renderer (MustacheDialogRenderer): instance to load files with Returns: a loaded instance of a dialog renderer """ @@ -128,8 +132,10 @@ def load_dialogs(dialog_dir, renderer=None): return renderer -def get_dialog(phrase, lang=None, context=None): - """Looks up a resource file for the given phrase. +def get_dialog(phrase: str, lang: str = None, + context: Optional[dict] = None) -> str: + """ + 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. @@ -168,8 +174,10 @@ def get_dialog(phrase, lang=None, context=None): return stache.render('template', context) -def join_list(items, connector, sep=None, lang=''): - """ Join a list into a phrase using the given connector word +def join_list(items: list, connector: str, sep: Optional[str] = None, + lang: Optional[str] = '') -> str: + """ + Join a list into a phrase using the given connector word Examples: join_list([1,2,3], "and") -> "1, 2 and 3" join_list([1,2,3], "and", ";") -> "1; 2 and 3" diff --git a/ovos_utils/enclosure/__init__.py b/ovos_utils/enclosure/__init__.py index 7d6ca782..f9947a44 100644 --- a/ovos_utils/enclosure/__init__.py +++ b/ovos_utils/enclosure/__init__.py @@ -2,9 +2,12 @@ from ovos_utils.fingerprinting import detect_platform, MycroftPlatform from enum import Enum from os.path import exists +from typing import Optional +from ovos_utils.log import LOG class MycroftEnclosures(str, Enum): + # TODO: Deprecate in 0.1.0 PICROFT = "picroft" BIGSCREEN = "kde" OVOS = "OpenVoiceOS" @@ -17,7 +20,15 @@ class MycroftEnclosures(str, Enum): OTHER = "unknown" -def enclosure2rootdir(enclosure=None): +def enclosure2rootdir(enclosure: MycroftEnclosures = None) -> Optional[str]: + """ + Find the default installed core location for a specific platform. + @param enclosure: MycroftEnclosures object to get root path for + @return: string default root path + """ + # TODO: Deprecate in 0.1.0 + LOG.warning("This method is deprecated. Code should import from the current" + "namespace; other system paths are irrelevant.") enclosure = enclosure or detect_enclosure() if enclosure == MycroftEnclosures.OLD_MARK1: return MycroftRootLocations.OLD_MARK1 @@ -34,7 +45,14 @@ def enclosure2rootdir(enclosure=None): return None -def detect_enclosure(): +def detect_enclosure() -> MycroftEnclosures: + """ + Determine which enclosure is present on this file system. + @return: MycroftEnclosures object detected + """ + # TODO: Deprecate in 0.1.0 + LOG.warning("This method is deprecated. Platform-specific code should" + "use ovos_utils.fingerprinting.detect_platform directly") platform = detect_platform() if platform == MycroftPlatform.MARK1: if exists(MycroftRootLocations.OLD_MARK1): diff --git a/ovos_utils/events.py b/ovos_utils/events.py index 0258f252..07e8a872 100644 --- a/ovos_utils/events.py +++ b/ovos_utils/events.py @@ -7,8 +7,9 @@ from ovos_utils.messagebus import Message, FakeBus -def unmunge_message(message, skill_id): - """Restore message keywords by removing the Letterified skill ID. +def unmunge_message(message: Message, skill_id: str) -> Message: + """ + Restore message keywords by removing the Letterified skill ID. Args: message (Message): Intent result message skill_id (str): skill identifier @@ -26,8 +27,9 @@ def unmunge_message(message, skill_id): return message -def get_handler_name(handler): - """Name (including class if available) of handler function. +def get_handler_name(handler) -> str: + """ + Name (including class if available) of handler function. Args: handler (function): Function to be named @@ -41,8 +43,9 @@ def get_handler_name(handler): return handler.__name__ -def create_wrapper(handler, skill_id, on_start, on_end, on_error): - """Create the default skill handler wrapper. +def create_wrapper(handler, skill_id, on_start, on_end, on_error) -> callable: + """ + Create the default skill handler wrapper. This wrapper handles things like metrics, reporting handler start/stop and errors. @@ -77,7 +80,7 @@ def wrapper(message): return wrapper -def create_basic_wrapper(handler, on_error=None): +def create_basic_wrapper(handler, on_error=None) -> callable: """Create the default skill handler wrapper. This wrapper handles things like metrics, reporting handler start/stop diff --git a/ovos_utils/file_utils.py b/ovos_utils/file_utils.py index 8b0a45c6..21623758 100644 --- a/ovos_utils/file_utils.py +++ b/ovos_utils/file_utils.py @@ -3,6 +3,8 @@ import os import re import tempfile +from typing import Optional, List + import time from os import walk from os.path import dirname @@ -16,8 +18,9 @@ from ovos_utils.system import search_mycroft_core_location -def get_temp_path(*args): - """Generate a valid path in the system temp directory. +def get_temp_path(*args) -> str: + """ + Generate a valid path in the system temp directory. This method accepts one or more strings as arguments. The arguments are joined and returned as a complete path inside the systems temp directory. @@ -40,9 +43,13 @@ def get_temp_path(*args): return path -def get_cache_directory(folder): - # optional import to use ram for cache - # does not work in windows! +def get_cache_directory(folder: str) -> str: + """ + Get a temporary cache directory, preferably in RAM. + Note that Windows will not use RAM. + @param folder: base path to use for cache + @return: valid cache path + """ path = get_temp_path(folder) if os.name != 'nt': try: @@ -56,8 +63,9 @@ def get_cache_directory(folder): return path -def resolve_ovos_resource_file(res_name): - """Convert a resource into an absolute filename. +def resolve_ovos_resource_file(res_name: str) -> Optional[str]: + """ + Convert a resource into an absolute filename. used internally for ovos resources """ # First look for fully qualified file (e.g. a user setting) @@ -78,8 +86,10 @@ def resolve_ovos_resource_file(res_name): return None # Resource cannot be resolved -def resolve_resource_file(res_name, root_path=None, config=None): - """Convert a resource into an absolute filename. +def resolve_resource_file(res_name: str, root_path: Optional[str] = None, + config: Optional[dict] = None) -> Optional[str]: + """ + Convert a resource into an absolute filename. Resource names are in the form: 'filename.ext' or 'path/filename.ext' @@ -99,6 +109,7 @@ def resolve_resource_file(res_name, root_path=None, config=None): Args: res_name (str): a resource path/name + root_path: Optional root path to check config (dict): mycroft.conf, to read data directory from Returns: str: path to resource or None if no resource found @@ -134,18 +145,19 @@ def resolve_resource_file(res_name, root_path=None, config=None): return None # Resource cannot be resolved -def read_vocab_file(path): - """ Read voc file. +def read_vocab_file(path: str) -> List[List[str]]: + """ + Read voc file. - This reads a .voc file, stripping out empty lines comments and expand - parentheses. It returns each line as a list of all expanded - alternatives. + This reads a .voc file, stripping out empty lines comments and expand + parentheses. It returns each line as a list of all expanded + alternatives. - Args: - path (str): path to vocab file. + Args: + path (str): path to vocab file. - Returns: - List of Lists of strings. + Returns: + List of Lists of strings. """ vocab = [] with open(path, 'r', encoding='utf8') as voc_file: @@ -156,8 +168,9 @@ def read_vocab_file(path): return vocab -def load_regex_from_file(path, skill_id): - """Load regex from file +def load_regex_from_file(path: str, skill_id: str) -> List[str]: + """ + Load regex from file The regex is sent to the intent handler using the message bus Args: @@ -185,8 +198,9 @@ def load_regex_from_file(path, skill_id): return regexes -def load_vocabulary(basedir, skill_id): - """Load vocabulary from all files in the specified directory. +def load_vocabulary(basedir: str, skill_id: str) -> dict: + """ + Load vocabulary from all files in the specified directory. Args: basedir (str): path of directory to load from (will recurse) @@ -207,13 +221,12 @@ def load_vocabulary(basedir, skill_id): return vocabs -def load_regex(basedir, skill_id): - """Load regex from all files in the specified directory. +def load_regex(basedir: str, skill_id: str) -> List[List[str]]: + """ + Load regex from all files in the specified directory. Args: basedir (str): path of directory to load from - bus (messagebus emitter): messagebus instance used to send the vocab to - the intent service skill_id (str): skill identifier """ regexes = [] @@ -224,8 +237,9 @@ def load_regex(basedir, skill_id): return regexes -def read_value_file(filename, delim): - """Read value file. +def read_value_file(filename: str, delim: str) -> collections.OrderedDict: + """ + Read value file. The value file is a simple csv structure with a key and value. @@ -252,8 +266,9 @@ def read_value_file(filename, delim): return result -def read_translated_file(filename, data): - """Read a file inserting data. +def read_translated_file(filename: str, data: dict) -> Optional[List[str]]: + """ + Read a file inserting data. Args: filename (str): file to read diff --git a/ovos_utils/fingerprinting.py b/ovos_utils/fingerprinting.py index 9d011d07..bf6c0e9e 100644 --- a/ovos_utils/fingerprinting.py +++ b/ovos_utils/fingerprinting.py @@ -150,6 +150,7 @@ def is_mycroft_core(): except ImportError: return False + def is_vanilla_mycroft_core(): return is_mycroft_core() and not is_ovos() diff --git a/ovos_utils/gui.py b/ovos_utils/gui.py index d02abe93..50e46123 100644 --- a/ovos_utils/gui.py +++ b/ovos_utils/gui.py @@ -1,7 +1,10 @@ +from typing import List, Union + import time from collections import namedtuple from enum import IntEnum from os.path import join +# from ovos_bus_client import MessageBusClient from ovos_utils import resolve_ovos_resource_file, resolve_resource_file from ovos_utils.log import LOG @@ -9,28 +12,44 @@ from ovos_utils.system import is_installed, has_screen, is_process_running -def can_display(): - return has_screen() +_default_gui_apps = ( + "mycroft-gui-app", + "ovos-shell", + "mycroft-embedded-shell", + "plasmashell" +) + + +def can_display() -> bool: + """ + Return true if a display is available + """ + return bool(has_screen()) -def is_gui_installed(): - return is_installed("mycroft-gui-app") or \ - is_installed("ovos-shell") or \ - is_installed("mycroft-embedded-shell") or \ - is_installed("plasmashell") +def is_gui_installed(applications: List[str] = _default_gui_apps) -> bool: + """ + Return true if a GUI application is installed + @param applications: list of applications to check for + """ + return any((is_installed(app) for app in applications)) -def is_gui_running(): - return is_process_running("mycroft-gui-app") or \ - is_process_running("ovos-shell") or \ - is_process_running("mycroft-embedded-shell") or \ - is_process_running("plasmashell") +def is_gui_running(applications: List[str] = _default_gui_apps) -> bool: + """ + Return true if a GUI application is running + @param applications: list of applications to check for + """ + return any((is_process_running(app) for app in applications)) -def is_gui_connected(bus=None): - # bus api for https://github.com/MycroftAI/mycroft-core/pull/2682 - # send "gui.status.request" - # receive "gui.status.request.response" +def is_gui_connected(bus=None) -> bool: + """ + Check if a GUI is connected to the MessageBus. + sends "gui.status.request" and waits for "gui.status.request.response" + @param bus: MessageBusClient to use for query + @return: True if GUI is connected + """ response = wait_for_reply("gui.status.request", "gui.status.request.response", bus=bus) if response: @@ -38,24 +57,44 @@ def is_gui_connected(bus=None): return False -def can_use_local_gui(): +def can_use_local_gui() -> bool: + """ + Returns True if a local GUI is installed and running (does not check if the + GUI is connected to an accessible GUI service). + """ if can_display() and is_gui_installed() and is_gui_running(): return True return False -def can_use_gui(bus=None, local=False): +def can_use_gui(bus=None, + local: bool = False) -> bool: + """ + Check if a GUI is available to connect to + @param bus: MessageBusClient to use for query + @param local: If True, only check for a GUI on the local host + @return: True if a GUI is available + """ if local: return can_use_local_gui() return can_use_local_gui() or is_gui_connected(bus) -def extend_about_data(about_data, bus=None): + +def extend_about_data(about_data: Union[list, dict], + bus=None): + """ + Add more information to the "About" section in the GUI. + @param about_data: list of dict key, val information to add to the GUI + @param bus: MessageBusClient object to emit update on + """ bus = bus or get_mycroft_bus() if isinstance(about_data, list): - bus.emit(Message("smartspeaker.extension.extend.about", {"display_list": about_data})) + bus.emit(Message("smartspeaker.extension.extend.about", + {"display_list": about_data})) elif isinstance(about_data, dict): display_list = [about_data] - bus.emit(Message("smartspeaker.extension.extend.about", {"display_list": display_list})) + bus.emit(Message("smartspeaker.extension.extend.about", + {"display_list": display_list})) else: LOG.error("about_data is not a list or dictionary") @@ -435,8 +474,10 @@ def _on_show_idle(self, message): class _GUIDict(dict): - """ this is an helper dictionay subclass, it ensures that value changed - in it are propagated to the GUI service real time""" + """ + This is a helper dictionary subclass. It ensures that values changed + in it are propagated to the GUI service in real time. + """ def __init__(self, gui, **kwargs): self.gui = gui super().__init__(**kwargs) @@ -966,11 +1007,3 @@ def shutdown(self): self.release() for event, handler in self._events: self.bus.remove(event, handler) - - -if __name__ == "__main__": - from ovos_utils import wait_for_exit_signal - - LOG.set_level("DEBUG") - g = GUITracker() - wait_for_exit_signal() diff --git a/ovos_utils/intents/intent_service_interface.py b/ovos_utils/intents/intent_service_interface.py index 03a5aef8..9baa9cd0 100644 --- a/ovos_utils/intents/intent_service_interface.py +++ b/ovos_utils/intents/intent_service_interface.py @@ -5,10 +5,10 @@ from ovos_utils.log import LOG -def to_alnum(skill_id): - """Convert a skill id to only alphanumeric characters - - Non alpha-numeric characters are converted to "_" +def to_alnum(skill_id: str) -> str: + """ + Convert a skill id to only alphanumeric characters + Non-alphanumeric characters are converted to "_" Args: skill_id (str): identifier to be converted @@ -18,8 +18,9 @@ def to_alnum(skill_id): return ''.join(c if c.isalnum() else '_' for c in str(skill_id)) -def munge_regex(regex, skill_id): - """Insert skill id as letters into match groups. +def munge_regex(regex: str, skill_id: str) -> str: + """ + Insert skill id as letters into match groups. Args: regex (str): regex string @@ -32,7 +33,8 @@ def munge_regex(regex, skill_id): def munge_intent_parser(intent_parser, name, skill_id): - """Rename intent keywords to make them skill exclusive + """ + Rename intent keywords to make them skill exclusive This gives the intent parser an exclusive name in the format :. The keywords are given unique names in the format . @@ -533,7 +535,9 @@ def get_keywords_manifest(self): def open_intent_envelope(message): - """Convert dictionary received over messagebus to Intent.""" + """ + Convert dictionary received over messagebus to Intent. + """ # TODO can this method be fully removed from ovos_utils ? from adapt.intent import Intent diff --git a/ovos_utils/intents/layers.py b/ovos_utils/intents/layers.py index feabdd59..e1a1272c 100644 --- a/ovos_utils/intents/layers.py +++ b/ovos_utils/intents/layers.py @@ -2,11 +2,11 @@ from ovos_utils.log import LOG from time import sleep -LOG.error(f"This module is deprecated, import from `ovos_workshop.skills.layers") - class IntentLayers: def __init__(self, bus=None, layers=None): + # TODO: Deprecate in 0.1.0 + LOG.error(f"This module is deprecated, import from `ovos_workshop.skills.layers") layers = layers or [] self.bus = bus or get_mycroft_bus() # make intent levels for N layers diff --git a/ovos_utils/json_helper.py b/ovos_utils/json_helper.py index b2f18a35..c54ba9b5 100644 --- a/ovos_utils/json_helper.py +++ b/ovos_utils/json_helper.py @@ -1,5 +1,6 @@ import json from copy import copy +# TODO: Deprecate unused imports from json_database.utils import is_jsonifiable, get_key_recursively, \ get_key_recursively_fuzzy, get_value_recursively_fuzzy, \ get_value_recursively, jsonify_recursively diff --git a/ovos_utils/network_utils.py b/ovos_utils/network_utils.py index c4b9a9e4..b1a3e1da 100644 --- a/ovos_utils/network_utils.py +++ b/ovos_utils/network_utils.py @@ -1,4 +1,5 @@ import socket +from typing import Optional import requests @@ -28,8 +29,11 @@ def get_network_tests_config(): return config.get("network_tests", _DEFAULT_TEST_CONFIG) -def get_ip(): - # taken from https://stackoverflow.com/a/28950776/13703283 +def get_ip() -> str: + """ + Get the local IPv4 address of this device + taken from https://stackoverflow.com/a/28950776/13703283 + """ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: # doesn't even have to be reachable @@ -43,12 +47,18 @@ def get_ip(): def get_external_ip(): + """ + Get the public IPv4 address of this device + """ cfg = get_network_tests_config() - return requests.get(cfg.get("ip_url") or _DEFAULT_TEST_CONFIG['ip_url']).text + return requests.get(cfg.get("ip_url") or + _DEFAULT_TEST_CONFIG['ip_url']).text -def is_connected_dns(host=None, port=53, timeout=3): - """Check internet connection by connecting to DNS servers +def is_connected_dns(host: Optional[str] = None, port: int = 53, + timeout: int = 3) -> bool: + """ + Check internet connection by connecting to DNS servers Returns: True if internet connection can be detected """ @@ -69,15 +79,18 @@ def is_connected_dns(host=None, port=53, timeout=3): return False -def is_connected_http(host=None): - """Check internet connection by connecting to some website +def is_connected_http(host: Optional[str] = None) -> bool: + """ + Check internet connection by connecting to some website Returns: True if connection attempt succeeded """ if host is None: cfg = get_network_tests_config() - return is_connected_http(cfg.get("web_url") or _DEFAULT_TEST_CONFIG['web_url']) or \ - is_connected_http(cfg.get("web_url_secondary") or _DEFAULT_TEST_CONFIG['web_url_secondary']) + return is_connected_http(cfg.get("web_url") or + _DEFAULT_TEST_CONFIG['web_url']) or \ + is_connected_http(cfg.get("web_url_secondary") or + _DEFAULT_TEST_CONFIG['web_url_secondary']) try: status = requests.head(host).status_code @@ -87,12 +100,18 @@ def is_connected_http(host=None): return False -def is_connected(): +def is_connected() -> bool: + """ + Return True if any connection check (DNS or HTTP) is True + """ return any((is_connected_dns(), is_connected_http())) -def check_captive_portal(host=None, expected_text=None) -> bool: - """Returns True if a captive portal page is detected""" +def check_captive_portal(host: Optional[str] = None, + expected_text: Optional[str] = None) -> bool: + """ + Returns True if a captive portal page is detected + """ captive_portal = False if not host or not expected_text: diff --git a/ovos_utils/ovos_service_api.py b/ovos_utils/ovos_service_api.py index daaa6575..1552645a 100644 --- a/ovos_utils/ovos_service_api.py +++ b/ovos_utils/ovos_service_api.py @@ -1,10 +1,14 @@ import requests from json_database import JsonStorageXDG +from ovos_utils.log import LOG +# TODO: This will be deprecated in v0.1 class OVOSApiService: def __init__(self) -> None: + LOG.warning(f"ovos_utils.ovos_service_api is deprecated. " + f"Import from ovos-backend-client") self.uuid_storage = JsonStorageXDG("ovos_api_uuid") self.token_storage = JsonStorageXDG("ovos_api_token") @@ -172,8 +176,11 @@ def search_movie(self, query): r = requests.post(url, data=reqdata, headers=self.headers) return r.json() + class OvosGeolocate: def __init__(self): + LOG.warning(f"This reference is deprecated. " + f"Import from ovos-backend-client") pass def geolocate_ip(self, ip): @@ -194,6 +201,7 @@ def geolocate_location_config(self, address): r = requests.post(url, data=reqdata) return r.json() + class OvosSendMail: def __init__(self): self.api = OVOSApiService() diff --git a/ovos_utils/process_utils.py b/ovos_utils/process_utils.py index 18a403db..7cda68a8 100644 --- a/ovos_utils/process_utils.py +++ b/ovos_utils/process_utils.py @@ -304,7 +304,6 @@ def init(cls): # Class constants DIRECTORY = None FILE = '/{}.pid' - LOG.info(f"Create PIDLock in: {DIRECTORY}") # # Constructor diff --git a/ovos_utils/skills/__init__.py b/ovos_utils/skills/__init__.py index 8296f306..5d71ad1d 100644 --- a/ovos_utils/skills/__init__.py +++ b/ovos_utils/skills/__init__.py @@ -71,18 +71,21 @@ def whitelist_skill(skill, config=None): def make_priority_skill(skill, config=None): - config = config or read_mycroft_config() - skills_config = config.get("skills", {}) - priority_skills = skills_config.get("priority_skills", []) - if skill not in priority_skills: - priority_skills.append(skill) - conf = { - "skills": { - "priority_skills": priority_skills - } - } - update_mycroft_config(conf) - return True + # TODO: Deprecate in 0.1.0 + LOG.warning("This method is deprecated. Skills are now loaded based on " + "`runtime_requirements`") + # config = config or read_mycroft_config() + # skills_config = config.get("skills", {}) + # priority_skills = skills_config.get("priority_skills", []) + # if skill not in priority_skills: + # priority_skills.append(skill) + # conf = { + # "skills": { + # "priority_skills": priority_skills + # } + # } + # update_mycroft_config(conf) + # return True return False diff --git a/ovos_utils/skills/audioservice.py b/ovos_utils/skills/audioservice.py index 4cf7c908..27185518 100644 --- a/ovos_utils/skills/audioservice.py +++ b/ovos_utils/skills/audioservice.py @@ -22,10 +22,13 @@ from ovos_utils.messagebus import Message, get_mycroft_bus, dig_for_message -def ensure_uri(s): - """Interprete paths as file:// uri's. +def ensure_uri(s: str): + """ + Interpret paths as file:// uri's. + Args: - s: string to be checked + s: string path to be checked + Returns: if s is uri, s is returned otherwise file:// is prepended """ @@ -34,7 +37,7 @@ def ensure_uri(s): return 'file://' + abspath(s) else: return s - elif isinstance(s, (tuple, list)): + elif isinstance(s, (tuple, list)): # Handle (mime, uri) arg if '://' not in s[0]: return 'file://' + abspath(s[0]), s[1] else: diff --git a/ovos_utils/smtp_utils.py b/ovos_utils/smtp_utils.py index 6803b212..cd61b43c 100644 --- a/ovos_utils/smtp_utils.py +++ b/ovos_utils/smtp_utils.py @@ -41,20 +41,3 @@ def send_email(subject, body, recipient=None): user, recipient, subject, body, host, port) - - -if __name__ == "__main__": - USER = "JarbasAI" - YOUR_EMAIL_ADDRESS = "jarbasai@mailfence.com" - DESTINATARY_ADDRESS = "casimiro@jarbasai.online" - YOUR_PASSWORD = "a very very strong Password1!" - HOST = "smtp.mailfence.com" - PORT = 465 - - subject = 'test again' - body = 'this is a test bruh' - - send_email(USER, YOUR_PASSWORD, - YOUR_EMAIL_ADDRESS, DESTINATARY_ADDRESS, - subject, body, - HOST, PORT) diff --git a/ovos_utils/sound/alsa.py b/ovos_utils/sound/alsa.py index b879c065..3acb0c03 100644 --- a/ovos_utils/sound/alsa.py +++ b/ovos_utils/sound/alsa.py @@ -9,6 +9,9 @@ class AlsaControl: _mixer = None def __init__(self, control=None): + # TODO: Deprecate class in 0.1 + LOG.warning(f"This class is deprecated! Controls moved to" + f"ovos_phal_plugin_alsa.AlsaVolumeControlPlugin") if alsaaudio is None: LOG.error("pyalsaaudio not installed") LOG.info("Run pip install pyalsaaudio==0.8.2") @@ -98,29 +101,3 @@ def get_volume(self): def get_volume_percent(self): return self.get_volume() - - -if __name__ == "__main__": - from time import sleep - a = AlsaControl() - a.set_volume(100) - sleep(2) - print(a.is_muted()) - a.mute() - print(a.is_muted()) - sleep(2) - a.unmute() - print(a.is_muted()) - print(a.get_volume()) - sleep(2) - a.set_volume(50) - print(a.get_volume()) - sleep(2) - a.set_volume(70) - print(a.get_volume()) - sleep(2) - a.set_volume(10) - print(a.get_volume()) - sleep(2) - a.set_volume(80) - print(a.get_volume()) diff --git a/ovos_utils/sound/pulse.py b/ovos_utils/sound/pulse.py index a377c34c..a5cc4665 100644 --- a/ovos_utils/sound/pulse.py +++ b/ovos_utils/sound/pulse.py @@ -1,6 +1,7 @@ import subprocess import re import collections +from ovos_utils.log import LOG class PulseAudio: @@ -8,6 +9,9 @@ class PulseAudio: mute_re = re.compile('^set-sink-mute ([^ ]+) ((?:yes)|(?:no))') def __init__(self): + # TODO: Deprecate class in 0.1 + LOG.warning(f"This class is deprecated! Controls moved to" + f"ovos_phal_plugin_pulseaudio.PulseAudioVolumeControlPlugin") self._mute = collections.OrderedDict() self._volume = collections.OrderedDict() self.update() @@ -155,8 +159,3 @@ def decrease_volume(self, percent): elif volume > 100: volume = 100 self.set_all_volumes_percent(volume) - - -if __name__ == "__main__": - p = PulseAudio() - print(p.list_sources()) \ No newline at end of file diff --git a/ovos_utils/system.py b/ovos_utils/system.py index 2696048f..a3f6009e 100644 --- a/ovos_utils/system.py +++ b/ovos_utils/system.py @@ -11,6 +11,7 @@ from ovos_utils.log import LOG +# TODO: Deprecate MycroftRootLocations in 0.1.0 class MycroftRootLocations(str, Enum): PICROFT = "/home/pi/mycroft-core" BIGSCREEN = "/home/mycroft/mycroft-core" diff --git a/test/unittests/test_bracket_expansion.py b/test/unittests/test_bracket_expansion.py new file mode 100644 index 00000000..8e1c31e1 --- /dev/null +++ b/test/unittests/test_bracket_expansion.py @@ -0,0 +1,31 @@ +import unittest + + +class TestBracketExpansion(unittest.TestCase): + def test_expand_parentheses(self): + from ovos_utils.bracket_expansion import expand_parentheses + # TODO + + def test_expand_options(self): + from ovos_utils.bracket_expansion import expand_options + # TODO + + def test_fragment(self): + from ovos_utils.bracket_expansion import Fragment + # TODO + + def test_word(self): + from ovos_utils.bracket_expansion import Word + # TODO + + def test_sentence(self): + from ovos_utils.bracket_expansion import Sentence + # TODO + + def test_options(self): + from ovos_utils.bracket_expansion import Options + # TODO + + def test_sentence_tree_parser(self): + from ovos_utils.bracket_expansion import SentenceTreeParser + # TODO diff --git a/test/unittests/test_dialog.py b/test/unittests/test_dialog.py new file mode 100644 index 00000000..a29acbcc --- /dev/null +++ b/test/unittests/test_dialog.py @@ -0,0 +1,19 @@ +import unittest + + +class TestDialog(unittest.TestCase): + def test_mustache_dialog_renderer(self): + from ovos_utils.dialog import MustacheDialogRenderer + # TODO + + def test_load_dialogs(self): + from ovos_utils.dialog import load_dialogs + # TODO + + def test_get_dialog(self): + from ovos_utils.dialog import get_dialog + # TODO + + def test_join_list(self): + from ovos_utils.dialog import join_list + # TODO diff --git a/test/unittests/test_enclosure.py b/test/unittests/test_enclosure.py new file mode 100644 index 00000000..50f91aab --- /dev/null +++ b/test/unittests/test_enclosure.py @@ -0,0 +1,16 @@ +import unittest + +from mock import patch +from ovos_utils.messagebus import FakeBus + + +class TestEnclosureAPI(unittest.TestCase): + from ovos_utils.enclosure.api import EnclosureAPI + bus = FakeBus() + api = EnclosureAPI(bus) + # TODO: Test api methods + + +class TestMark1(unittest.TestCase): + # TODO Implement tests or move to separate PHAL plugin + pass diff --git a/test/unittests/test_events.py b/test/unittests/test_events.py new file mode 100644 index 00000000..6b374457 --- /dev/null +++ b/test/unittests/test_events.py @@ -0,0 +1,27 @@ +import unittest + + +class TestEvents(unittest.TestCase): + def test_unmunge_message(self): + from ovos_utils.events import unmunge_message + # TODO + + def test_get_handler_name(self): + from ovos_utils.events import get_handler_name + # TODO + + def test_create_wrapper(self): + from ovos_utils.events import create_wrapper + # TODO + + def test_create_basic_wrapper(self): + from ovos_utils.events import create_basic_wrapper + # TODO + + def test_event_container(self): + from ovos_utils.events import EventContainer + # TODO + + def test_event_scheduler_interface(self): + from ovos_utils.events import EventSchedulerInterface + # TODO diff --git a/test/unittests/test_file_utils.py b/test/unittests/test_file_utils.py new file mode 100644 index 00000000..787ec25f --- /dev/null +++ b/test/unittests/test_file_utils.py @@ -0,0 +1,57 @@ +import unittest +from os.path import isdir, isfile + + +class TestFileUtils(unittest.TestCase): + def test_get_temp_path(self): + from ovos_utils.file_utils import get_temp_path + self.assertTrue(isdir(get_temp_path())) + self.assertIsInstance(get_temp_path("test"), str) + self.assertIsInstance(get_temp_path("test/1/2.test"), str) + + def test_get_cache_directory(self): + from ovos_utils.file_utils import get_cache_directory + self.assertTrue(isdir(get_cache_directory("test"))) + self.assertTrue(isdir(get_cache_directory("test/another/test"))) + + def test_resolve_ovos_resource_file(self): + from ovos_utils.file_utils import resolve_ovos_resource_file + invalid = resolve_ovos_resource_file("not_real.file") + self.assertIsNone(invalid) + # TODO: Test valid case + + def test_resolve_resource_file(self): + from ovos_utils.file_utils import resolve_resource_file + # TODO + + def test_read_vocab_file(self): + from ovos_utils.file_utils import read_vocab_file + # TODO + + def test_load_regex_from_file(self): + from ovos_utils.file_utils import load_regex_from_file + # TODO + + def test_load_vocabulary(self): + from ovos_utils.file_utils import load_vocabulary + # TODO + + def test_load_regex(self): + from ovos_utils.file_utils import load_regex + # TODO + + def test_read_value_file(self): + from ovos_utils.file_utils import read_value_file + # TODO + + def test_read_translated_file(self): + from ovos_utils.file_utils import read_translated_file + # TODO + + def test_filewatcher(self): + from ovos_utils.file_utils import FileWatcher + # TODO + + def test_file_event_handler(self): + from ovos_utils.file_utils import FileEventHandler + # TODO diff --git a/test/unittests/test_fingerprinting.py b/test/unittests/test_fingerprinting.py new file mode 100644 index 00000000..df79264a --- /dev/null +++ b/test/unittests/test_fingerprinting.py @@ -0,0 +1,6 @@ +import unittest + + +class TestFingerprinting(unittest.TestCase): + # TODO: determine if any of these methods should be deprecated + pass diff --git a/test/unittests/test_gui.py b/test/unittests/test_gui.py new file mode 100644 index 00000000..f57ae04b --- /dev/null +++ b/test/unittests/test_gui.py @@ -0,0 +1,80 @@ +import unittest +from mock import patch, call + + +class TestGui(unittest.TestCase): + @patch("ovos_utils.gui.has_screen") + def test_can_display(self, has_screen): + from ovos_utils.gui import can_display + has_screen.return_value = False + self.assertFalse(can_display()) + has_screen.return_value = True + self.assertTrue(can_display()) + has_screen.return_value = None + self.assertFalse(can_display()) + + @patch("ovos_utils.gui.is_installed") + def test_is_gui_installed(self, is_installed): + from ovos_utils.gui import is_gui_installed + is_installed.return_value = False + self.assertFalse(is_gui_installed()) + is_installed.assert_has_calls([call("mycroft-gui-app"), + call("ovos-shell"), + call("mycroft-embedded-shell"), + call("plasmashell")]) + is_installed.return_value = True + self.assertTrue(is_gui_installed()) + is_installed.assert_called_with("mycroft-gui-app") + + # Test passed applications + self.assertTrue(is_gui_installed(["test"])) + is_installed.assert_called_with("test") + + @patch("ovos_utils.gui.is_process_running") + def test_is_gui_running(self, is_running): + from ovos_utils.gui import is_gui_running + is_running.return_value = False + self.assertFalse(is_gui_running()) + is_running.assert_has_calls([call("mycroft-gui-app"), + call("ovos-shell"), + call("mycroft-embedded-shell"), + call("plasmashell")]) + is_running.return_value = True + self.assertTrue(is_gui_running()) + is_running.assert_called_with("mycroft-gui-app") + + # Test passed applications + self.assertTrue(is_gui_running(["test"])) + is_running.assert_called_with("test") + + def test_is_gui_connected(self): + from ovos_utils.gui import is_gui_connected + # TODO + + def test_can_use_local_gui(self): + from ovos_utils.gui import can_use_local_gui + # TODO + + def test_can_use_gui(self): + from ovos_utils.gui import can_use_gui + # TODO + + def test_extend_about_data(self): + from ovos_utils.gui import extend_about_data + # TODO + + def test_gui_widgets(self): + from ovos_utils.gui import GUIWidgets + # TODO + + def test_gui_tracker(self): + from ovos_utils.gui import GUITracker + # TODO + + def test_gui_dict(self): + from ovos_utils.gui import _GUIDict + # TODO + + def test_gui_interface(self): + from ovos_utils.gui import GUIInterface + # TODO diff --git a/test/unittests/test_intents.py b/test/unittests/test_intents.py new file mode 100644 index 00000000..59f5fbff --- /dev/null +++ b/test/unittests/test_intents.py @@ -0,0 +1,65 @@ +import unittest + +from mock import mock, patch +from ovos_utils.messagebus import FakeBus + + +class TestIntent(unittest.TestCase): + from ovos_utils.intents import Intent + # TODO + + +class TestIntentBuilder(unittest.TestCase): + from ovos_utils.intents import IntentBuilder + # TODO + + +class TestAdaptIntent(unittest.TestCase): + from ovos_utils.intents import AdaptIntent + # TODO + pass + + +class TestConverse(unittest.TestCase): + from ovos_utils.intents.converse import ConverseTracker + # TODO + pass + + +class TestIntentServiceInterface(unittest.TestCase): + def test_to_alnum(self): + from ovos_utils.intents.intent_service_interface import to_alnum + test_alnum = "test_skill123" + self.assertEqual(test_alnum, to_alnum(test_alnum)) + test_dash = "test-skill123" + self.assertEqual(test_alnum, to_alnum(test_dash)) + test_slash = "test/skill123" + self.assertEqual(test_alnum, to_alnum(test_slash)) + + def test_munge_regex(self): + from ovos_utils.intents.intent_service_interface import munge_regex + skill_id = "test_skill" + non_regex = "just a string with no entity" + with_regex = "a string with this (?P.*)" + munged_regex = f"a string with this (?P<{skill_id}entity>.*)" + + self.assertEqual(non_regex, munge_regex(non_regex, skill_id)) + self.assertEqual(munged_regex, munge_regex(with_regex, skill_id)) + + def test_munge_intent_parser(self): + from ovos_utils.intents.intent_service_interface import \ + munge_intent_parser + # TODO + + def test_intent_service_interface(self): + from ovos_utils.intents.intent_service_interface import \ + IntentServiceInterface + # TODO + + def test_intent_query_api(self): + from ovos_utils.intents.intent_service_interface import IntentQueryApi + # TODO + + def test_open_intent_envelope(self): + pass + # TODO: Deprecated? diff --git a/test/unittests/test_json_helpers.py b/test/unittests/test_json_helpers.py index 0ba6a081..1d4ea913 100644 --- a/test/unittests/test_json_helpers.py +++ b/test/unittests/test_json_helpers.py @@ -6,12 +6,18 @@ class TestJsonHelpers(unittest.TestCase): - @classmethod - def setUpClass(self): - self.base_dict = {"one": 1, "two": 2, "three": 3, - "four": ["foo", "bar", "baz"], "five": 50} - self.delta_dict = {"two": 2, "three": 30, - "four": [4, 5, 6, "foo"], "five": None} + base_dict = {"one": 1, "two": 2, "three": 3, + "four": ["foo", "bar", "baz"], "five": 50} + delta_dict = {"two": 2, "three": 30, + "four": [4, 5, 6, "foo"], "five": None} + + def test_load_commented_json(self): + from ovos_utils.json_helper import load_commented_json + # TODO + + def test_uncomment_json(self): + from ovos_utils.json_helper import uncomment_json + # TODO def test_invert_dict(self): dct = {'a': 1, 'b': "d"} diff --git a/test/unittests/test_lang.py b/test/unittests/test_lang.py new file mode 100644 index 00000000..356c1fb8 --- /dev/null +++ b/test/unittests/test_lang.py @@ -0,0 +1,24 @@ +import unittest + + +class TestLang(unittest.TestCase): + def test_get_language_dir(self): + from ovos_utils.lang import get_language_dir + # TODO + + def test_translate_word(self): + from ovos_utils.lang import translate_word + # TODO + + def test_phonemes(self): + from ovos_utils.lang.phonemes import arpabet2ipa, ipa2arpabet + for key, val in arpabet2ipa.items(): + self.assertIsInstance(key, str) + self.assertIsInstance(val, str) + self.assertEqual(ipa2arpabet[val], key) + + def test_visemes(self): + from ovos_utils.lang.visimes import VISIMES + for key, val in VISIMES.items(): + self.assertIsInstance(key, str) + self.assertIsInstance(val, str) \ No newline at end of file diff --git a/test/unittests/test_log.py b/test/unittests/test_log.py new file mode 100644 index 00000000..4f2f3b32 --- /dev/null +++ b/test/unittests/test_log.py @@ -0,0 +1,11 @@ +import unittest + + +class TestLog(unittest.TestCase): + def test_log(self): + from ovos_utils.log import LOG + # TODO + + def test_init_service_logger(self): + from ovos_utils.log import init_service_logger + # TODO diff --git a/test/unittests/test_messagebus.py b/test/unittests/test_messagebus.py new file mode 100644 index 00000000..8a01676c --- /dev/null +++ b/test/unittests/test_messagebus.py @@ -0,0 +1,6 @@ +import unittest + + +class TestMessagebus(unittest.TestCase): + # TODO: Implement tests or move utils to `ovos-bus-client` package + pass \ No newline at end of file diff --git a/test/test_metrics.py b/test/unittests/test_metrics.py similarity index 100% rename from test/test_metrics.py rename to test/unittests/test_metrics.py diff --git a/test/unittests/test_network_utils.py b/test/unittests/test_network_utils.py new file mode 100644 index 00000000..41c61fb5 --- /dev/null +++ b/test/unittests/test_network_utils.py @@ -0,0 +1,44 @@ + +import unittest +from time import sleep + + +class TestNetworkUtils(unittest.TestCase): + def test_get_network_tests_config(self): + from ovos_utils.network_utils import get_network_tests_config + # self.assertEqual(set(get_network_tests_config().keys()), + # {'ip_url', 'dns_primary', 'dns_secondary', 'web_url', + # 'web_url_secondary', 'captive_portal_url', + # 'captive_portal_text'}) + # TODO: Validate config in helper method + + def test_get_ip(self): + from ovos_utils.network_utils import get_ip + ip_addr = get_ip() + self.assertIsInstance(ip_addr, str) + self.assertEqual(len(ip_addr.split('.')), 4) + + def test_get_external_ip(self): + from ovos_utils.network_utils import get_external_ip + ip_addr = get_external_ip() + self.assertIsInstance(ip_addr, str) + self.assertEqual(len(ip_addr.split('.')), 4) + + def test_is_connected_dns(self): + from ovos_utils.network_utils import is_connected_dns + self.assertIsInstance(is_connected_dns(), bool) + # TODO + + def test_is_connected_http(self): + from ovos_utils.network_utils import is_connected_http + self.assertIsInstance(is_connected_http(), bool) + # TODO + + def test_is_connected(self): + from ovos_utils.network_utils import is_connected + self.assertIsInstance(is_connected(), bool) + # TODO + + def test_check_captive_portal(self): + from ovos_utils.network_utils import check_captive_portal + # TODO diff --git a/test/unittests/test_parse.py b/test/unittests/test_parse.py new file mode 100644 index 00000000..71cf16ac --- /dev/null +++ b/test/unittests/test_parse.py @@ -0,0 +1,23 @@ +import unittest + + +class TestParse(unittest.TestCase): + def test_validate_matching_strategy(self): + from ovos_utils.parse import _validate_matching_strategy + # TODO + + def test_fuzzy_match(self): + from ovos_utils.parse import fuzzy_match + # TODO + + def test_match_one(self): + from ovos_utils.parse import match_one + # TODO + + def test_match_all(self): + from ovos_utils.parse import match_all + # TODO + + def test_remove_parentheses(self): + from ovos_utils.parse import remove_parentheses + # TODO diff --git a/test/unittests/test_process_utils.py b/test/unittests/test_process_utils.py new file mode 100644 index 00000000..d293b5d0 --- /dev/null +++ b/test/unittests/test_process_utils.py @@ -0,0 +1,6 @@ +import unittest + + +class TestProcessUtils(unittest.TestCase): + # TODO: Implement unit tests for process_utils + pass diff --git a/test/unittests/test_security.py b/test/unittests/test_security.py new file mode 100644 index 00000000..e5ff0abd --- /dev/null +++ b/test/unittests/test_security.py @@ -0,0 +1,6 @@ +import unittest + + +class TestSecurity(unittest.TestCase): + # TODO: Implement unit tests for security + pass diff --git a/test/unittests/test_signal.py b/test/unittests/test_signal.py new file mode 100644 index 00000000..6d65b01a --- /dev/null +++ b/test/unittests/test_signal.py @@ -0,0 +1,6 @@ +import unittest + + +class TestSignal(unittest.TestCase): + # TODO: Implement unit tests for signal + pass diff --git a/test/unittests/test_skills.py b/test/unittests/test_skills.py index 1d01b8b4..e6baa40b 100644 --- a/test/unittests/test_skills.py +++ b/test/unittests/test_skills.py @@ -12,6 +12,51 @@ ovos_config = None +class TestSkills(unittest.TestCase): + def test_get_non_properties(self): + from ovos_utils.skills import get_non_properties + # TODO + + def test_skills_loaded(self): + from ovos_utils.skills import skills_loaded + # TODO + + @patch("ovos_utils.skills.update_mycroft_config") + def test_blacklist_skill(self, update_config): + from ovos_utils.skills import blacklist_skill + # TODO + + @patch("ovos_utils.skills.update_mycroft_config") + def test_whitelist_skill(self, update_config): + from ovos_utils.skills import whitelist_skill + # TODO + + +class TestAudioservice(unittest.TestCase): + def test_ensure_uri(self): + from ovos_utils.skills.audioservice import ensure_uri + valid_uri = "file:///test" + non_uri = "/test" + # rel_uri = "test" + self.assertEqual(ensure_uri(valid_uri), valid_uri) + self.assertEqual(ensure_uri(non_uri), valid_uri) + # TODO: Relative path is relative to method and not caller? + # self.assertEqual(ensure_uri(rel_uri), + # f"file://{join(dirname(__file__), 'test')}") + + def test_classic_audio_service_interface(self): + from ovos_utils.skills.audioservice import ClassicAudioServiceInterface + # TODO + + def test_audio_service_interface(self): + from ovos_utils.skills.audioservice import AudioServiceInterface + # TODO + + def test_ocp_interface(self): + from ovos_utils.skills.audioservice import OCPInterface + # TODO + + class TestLocations(unittest.TestCase): @patch("ovos_utils.skills.locations.get_plugin_skills") def test_get_installed_skill_ids(self, plugins): diff --git a/test/unittests/test_smtp_utils.py b/test/unittests/test_smtp_utils.py new file mode 100644 index 00000000..aa791907 --- /dev/null +++ b/test/unittests/test_smtp_utils.py @@ -0,0 +1,6 @@ +import unittest + + +class TestSMTPUtils(unittest.TestCase): + # TODO: Implement unit tests for smtp_utils + pass diff --git a/test/unittests/test_sound.py b/test/unittests/test_sound.py new file mode 100644 index 00000000..b95e25c4 --- /dev/null +++ b/test/unittests/test_sound.py @@ -0,0 +1,57 @@ +import unittest +from time import sleep + + +class TestSound(unittest.TestCase): + # TODO: Some tests already implemented in `test_sound` + def test_get_pulse_environment(self): + from ovos_utils.sound import _get_pulse_environment + # TODO + + def test_play_acknowledge_sound(self): + from ovos_utils.sound import play_acknowledge_sound + # TODO + + def test_play_listening_sound(self): + from ovos_utils.sound import play_listening_sound + # TODO + + def test_play_end_listening_sound(self): + from ovos_utils.sound import play_end_listening_sound + # TODO + + def test_play_error_sound(self): + from ovos_utils.sound import play_error_sound + # TODO + + def test_find_player(self): + from ovos_utils.sound import _find_player + # TODO + + def test_play_audio(self): + from ovos_utils.sound import play_audio + # TODO + + def test_play_wav(self): + from ovos_utils.sound import play_wav + # TODO + + def test_play_mp3(self): + from ovos_utils.sound import play_wav + # TODO + + def test_play_ogg(self): + from ovos_utils.sound import play_ogg + # TODO + + def test_record(self): + from ovos_utils.sound import record + # TODO + + def test_is_speaking(self): + from ovos_utils.sound import is_speaking + # TODO + + def test_wait_while_speaking(self): + from ovos_utils.sound import wait_while_speaking + # TODO diff --git a/test/unittests/test_ssml.py b/test/unittests/test_ssml.py index b972022e..e7d9e9d9 100644 --- a/test/unittests/test_ssml.py +++ b/test/unittests/test_ssml.py @@ -3,10 +3,8 @@ class TestSSMLhelpers(unittest.TestCase): - @classmethod - def setUpClass(self): - self.base_utterance = "this is a test of Open Voice OS SSML utils" - self.base_utterance2 = "creating ssml for usage with text to speech" + base_utterance = "this is a test of Open Voice OS SSML utils" + base_utterance2 = "creating ssml for usage with text to speech" def test_init_flags(self): self.assertEqual( diff --git a/test/unittests/test_utils.py b/test/unittests/test_utils.py index 188c84ef..07d1d9d2 100644 --- a/test/unittests/test_utils.py +++ b/test/unittests/test_utils.py @@ -1,21 +1,46 @@ import unittest -from ovos_utils import rotate_list, camel_case_split, get_handler_name, flatten_list - class TestHelpers(unittest.TestCase): - def test_utils(self): + def test_classproperty(self): + # TODO + pass + + def test_timed_lru_cache(self): + # TODO + pass + + def test_create_killable_daemon(self): + # TODO + pass + + def test_create_daemon(self): + # TODO + pass + + def test_create_loop(self): + # TODO + pass + + def test_wait_for_exit_signal(self): + # TODO + pass + + def test_get_handler_name(self): + from ovos_utils import get_handler_name def some_function(): return self.assertEqual(get_handler_name(some_function), "some_function") - self.assertEqual(get_handler_name(self.test_utils), "test_utils") + def test_camel_case_split(self): + from ovos_utils import camel_case_split self.assertEqual(camel_case_split("MyAwesomeSkill"), "My Awesome Skill") - def test_list_utils(self): + def test_rotate_list(self): + from ovos_utils import rotate_list self.assertEqual(rotate_list([1, 2, 3]), [2, 3, 1]) self.assertEqual(rotate_list([1, 2, 3], 2), [3, 1, 2]) self.assertEqual(rotate_list([1, 2, 3], 3), [1, 2, 3]) @@ -24,6 +49,8 @@ def test_list_utils(self): self.assertEqual(rotate_list([1, 2, 3], -2), [2, 3, 1]) self.assertEqual(rotate_list([1, 2, 3], -3), [1, 2, 3]) + def test_flatten_list(self): + from ovos_utils import flatten_list self.assertEqual( flatten_list([["A", "B"], ["C"]]), ["A", "B", "C"] ) @@ -34,3 +61,7 @@ def test_list_utils(self): flatten_list([("A", "B"), ["C"], [["D", ["E", ["F"]]]]]), ["A", "B", "C", "D", "E", "F"] ) + + def test_datestr2ts(self): + # TODO + pass diff --git a/test/unittests/test_xdg_utils.py b/test/unittests/test_xdg_utils.py new file mode 100644 index 00000000..fa12da47 --- /dev/null +++ b/test/unittests/test_xdg_utils.py @@ -0,0 +1,6 @@ +import unittest + + +class TestXDGUtils(unittest.TestCase): + # TODO: Implement unit tests for xdg_utils + pass diff --git a/test/unittests/test_xml_helper.py b/test/unittests/test_xml_helper.py new file mode 100644 index 00000000..2d1a9105 --- /dev/null +++ b/test/unittests/test_xml_helper.py @@ -0,0 +1,6 @@ +import unittest + + +class TestXMLHelper(unittest.TestCase): + # TODO: Implement unit tests for xml_helper + pass From b1b6145e1ab7391562382a0f2159f708d1e70392 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Thu, 13 Apr 2023 20:52:23 +0000 Subject: [PATCH 31/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed84ff44..21856125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a12...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a13...HEAD) + +**Merged pull requests:** + +- Update docstrings, annotate deprecation, and outline unit tests [\#119](https://github.com/OpenVoiceOS/ovos-utils/pull/119) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.31a13](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a13) (2023-04-13) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a12...V0.0.31a13) **Fixed bugs:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index a12e11bc..25e01a42 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 13 +VERSION_ALPHA = 14 # END_VERSION_BLOCK From fcf38a5f7173aef5642ac69cbc22fdf5bb94a26f Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Fri, 14 Apr 2023 11:40:19 -0700 Subject: [PATCH 32/43] Stable extra dependencies (#127) --- requirements/extras.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/extras.txt b/requirements/extras.txt index 4331d9fa..4f726695 100644 --- a/requirements/extras.txt +++ b/requirements/extras.txt @@ -1,3 +1,3 @@ rapidfuzz~=2.0 -ovos-bus-client~=0.0, >=0.0.3a4 -ovos-config~=0.0,>=0.0.8a3 \ No newline at end of file +ovos-bus-client < 0.1.0 +ovos-config < 0.1.0 \ No newline at end of file From 51186b374694e525d7e88b483df5869cda6b94f7 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Fri, 14 Apr 2023 18:41:17 +0000 Subject: [PATCH 33/43] Increment Version --- CHANGELOG.md | 14 +++++++++++++- ovos_utils/version.py | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21856125..91a848c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,19 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a13...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a14...HEAD) + +**Closed issues:** + +- Is there an option to disable the log file creation [\#124](https://github.com/OpenVoiceOS/ovos-utils/issues/124) + +**Merged pull requests:** + +- Stable extra dependencies [\#127](https://github.com/OpenVoiceOS/ovos-utils/pull/127) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.31a14](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a14) (2023-04-13) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a13...V0.0.31a14) **Merged pull requests:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 25e01a42..ee16f8f0 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 14 +VERSION_ALPHA = 15 # END_VERSION_BLOCK From 237c17cda001b316eedecc31e42b0b7bfea58c17 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Fri, 14 Apr 2023 11:41:24 -0700 Subject: [PATCH 34/43] Update `wait_for_exit_signal` to use Event.wait instead of looped sleep (#128) --- ovos_utils/__init__.py | 5 ++--- test/unittests/scripts/wait_for_exit.py | 2 ++ test/unittests/test_utils.py | 19 +++++++++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 test/unittests/scripts/wait_for_exit.py diff --git a/ovos_utils/__init__.py b/ovos_utils/__init__.py index a720b73e..c2342305 100644 --- a/ovos_utils/__init__.py +++ b/ovos_utils/__init__.py @@ -14,7 +14,7 @@ import re from functools import lru_cache, wraps from os.path import isdir, join -from threading import Thread +from threading import Thread, Event from time import monotonic_ns from time import sleep @@ -141,8 +141,7 @@ def loop(*args, **kwargs): def wait_for_exit_signal(): """Blocks until KeyboardInterrupt is received""" try: - while True: - sleep(100) + Event().wait() except KeyboardInterrupt: pass diff --git a/test/unittests/scripts/wait_for_exit.py b/test/unittests/scripts/wait_for_exit.py new file mode 100644 index 00000000..f9dce617 --- /dev/null +++ b/test/unittests/scripts/wait_for_exit.py @@ -0,0 +1,2 @@ +from ovos_utils import wait_for_exit_signal +wait_for_exit_signal() diff --git a/test/unittests/test_utils.py b/test/unittests/test_utils.py index 07d1d9d2..fe2646ca 100644 --- a/test/unittests/test_utils.py +++ b/test/unittests/test_utils.py @@ -1,4 +1,8 @@ +import signal import unittest +from os.path import join, dirname +from sys import executable +from subprocess import Popen, TimeoutExpired class TestHelpers(unittest.TestCase): @@ -24,11 +28,22 @@ def test_create_loop(self): pass def test_wait_for_exit_signal(self): - # TODO - pass + test_file = join(dirname(__file__), "scripts", "wait_for_exit.py") + wait_thread = Popen([executable, test_file]) + + # No return + with self.assertRaises(TimeoutExpired): + wait_thread.communicate(timeout=1) + with self.assertRaises(TimeoutExpired): + wait_thread.communicate(timeout=1) + + # Send interrupt and get returncode 0 + wait_thread.send_signal(signal.SIGINT) + self.assertEqual(wait_thread.wait(1), 0) def test_get_handler_name(self): from ovos_utils import get_handler_name + def some_function(): return From 6c619a230e81546ba80cb890526614feb177a56c Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Fri, 14 Apr 2023 18:42:24 +0000 Subject: [PATCH 35/43] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_utils/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91a848c5..a1dca377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a14...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a15...HEAD) + +**Implemented enhancements:** + +- Update `wait_for_exit_signal` to use Event.wait instead of looped sleep [\#128](https://github.com/OpenVoiceOS/ovos-utils/pull/128) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.31a15](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a15) (2023-04-14) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a14...V0.0.31a15) **Closed issues:** diff --git a/ovos_utils/version.py b/ovos_utils/version.py index ee16f8f0..e9acc0a2 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 15 +VERSION_ALPHA = 16 # END_VERSION_BLOCK From 10ed48b1c06d4bacd04ab3b65e3e566a03b2c5a2 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Mon, 17 Apr 2023 11:17:30 -0700 Subject: [PATCH 36/43] Update release automation (#126) --- .github/workflows/dev2master.yml | 19 ------- .github/workflows/propose_release.yml | 32 +++++++++++ .github/workflows/publish_alpha.yml | 57 +++++++++----------- .github/workflows/publish_build.yml | 77 --------------------------- .github/workflows/publish_major.yml | 77 --------------------------- .github/workflows/publish_minor.yml | 77 --------------------------- .github/workflows/publish_release.yml | 45 ++++++++++++++++ scripts/bump_alpha.py | 18 ------- scripts/bump_build.py | 21 -------- scripts/bump_major.py | 27 ---------- scripts/bump_minor.py | 24 --------- scripts/remove_alpha.py | 13 ----- 12 files changed, 101 insertions(+), 386 deletions(-) delete mode 100644 .github/workflows/dev2master.yml create mode 100644 .github/workflows/propose_release.yml delete mode 100644 .github/workflows/publish_build.yml delete mode 100644 .github/workflows/publish_major.yml delete mode 100644 .github/workflows/publish_minor.yml create mode 100644 .github/workflows/publish_release.yml delete mode 100644 scripts/bump_alpha.py delete mode 100644 scripts/bump_build.py delete mode 100644 scripts/bump_major.py delete mode 100644 scripts/bump_minor.py delete mode 100644 scripts/remove_alpha.py diff --git a/.github/workflows/dev2master.yml b/.github/workflows/dev2master.yml deleted file mode 100644 index e59e57eb..00000000 --- a/.github/workflows/dev2master.yml +++ /dev/null @@ -1,19 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI - -name: Push dev -> master -on: - workflow_dispatch: - -jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - ref: dev - - name: Push dev -> master - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: master \ No newline at end of file diff --git a/.github/workflows/propose_release.yml b/.github/workflows/propose_release.yml new file mode 100644 index 00000000..47a12301 --- /dev/null +++ b/.github/workflows/propose_release.yml @@ -0,0 +1,32 @@ +name: Propose Stable Release +on: + workflow_dispatch: + inputs: + release_type: + type: choice + description: Release Type + options: + - build + - minor + - major +jobs: + update_version: + uses: neongeckocom/.github/.github/workflows/propose_semver_release.yml@master + with: + release_type: ${{ inputs.release_type }} + version_file: ovos_utils/version.py + alpha_var: VERSION_ALPHA + build_var: VERSION_BUILD + minor_var: VERSION_MINOR + major_var: VERSION_MAJOR + update_changelog: True + branch: dev + + pull_changes: + needs: update_version + uses: neongeckocom/.github/.github/workflows/pull_master.yml@master + with: + pr_assignee: ${{ github.actor }} + pr_draft: false + pr_title: ${{ needs.update_version.outputs.version }} + pr_body: ${{ needs.update_version.outputs.changelog }} diff --git a/.github/workflows/publish_alpha.yml b/.github/workflows/publish_alpha.yml index accf69d6..26060b40 100644 --- a/.github/workflows/publish_alpha.yml +++ b/.github/workflows/publish_alpha.yml @@ -19,55 +19,46 @@ on: workflow_dispatch: jobs: + update_version: + uses: neongeckocom/.github/.github/workflows/propose_semver_release.yml@master + with: + release_type: "alpha" + version_file: ovos_utils/version.py + alpha_var: VERSION_ALPHA + build_var: VERSION_BUILD + minor_var: VERSION_MINOR + major_var: VERSION_MAJOR + update_changelog: True + branch: dev build_and_publish: runs-on: ubuntu-latest + needs: update_version steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Increment Version - run: | - VER=$(python setup.py --version) - python scripts/bump_alpha.py - - name: "Generate release changelog" - uses: heinrichreimer/github-changelog-generator-action@v2.3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - id: changelog - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Increment Version - branch: dev - - name: version - run: echo "::set-output name=version::$(python setup.py --version)" - id: version - name: Create Release id: create_release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token with: - tag_name: V${{ steps.version.outputs.version }} - release_name: Release ${{ steps.version.outputs.version }} + tag_name: V${{ needs.update_version.outputs.version }} + release_name: Release ${{ needs.update_version.outputs.version }} body: | Changes in this Release - ${{ steps.changelog.outputs.changelog }} + ${{ needs.update_version.outputs.changelog }} draft: false prerelease: true commitish: dev + - name: Checkout Repository + uses: actions/checkout@v2 + with: + ref: dev + fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - name: Build Distribution Packages run: | python setup.py sdist bdist_wheel - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@master + - name: Publish to PyPI + if: False + # TODO: Remove test patch above + uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{secrets.PYPI_TOKEN}} diff --git a/.github/workflows/publish_build.yml b/.github/workflows/publish_build.yml deleted file mode 100644 index 279eedbf..00000000 --- a/.github/workflows/publish_build.yml +++ /dev/null @@ -1,77 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI - -name: Publish Build Release ..X -on: - workflow_dispatch: - -jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Remove alpha (declare stable) - run: | - VER=$(python setup.py --version) - python scripts/remove_alpha.py - - name: "Generate release changelog" - uses: heinrichreimer/github-changelog-generator-action@v2.3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - id: changelog - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Declare alpha stable - branch: dev - - name: Push dev -> master - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: master - force: true - - name: version - run: echo "::set-output name=version::$(python setup.py --version)" - id: version - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - with: - tag_name: V${{ steps.version.outputs.version }} - release_name: Release ${{ steps.version.outputs.version }} - body: | - Changes in this Release - ${{ steps.changelog.outputs.changelog }} - draft: false - prerelease: false - commitish: dev - - name: Build Distribution Packages - run: | - python setup.py sdist bdist_wheel - - name: Prepare next Build version - run: echo "::set-output name=version::$(python setup.py --version)" - id: alpha - - name: Increment Version ${{ steps.alpha.outputs.version }}Alpha0 - run: | - VER=$(python setup.py --version) - python scripts/bump_build.py - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Prepare Next Version - branch: dev - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{secrets.PYPI_TOKEN}} \ No newline at end of file diff --git a/.github/workflows/publish_major.yml b/.github/workflows/publish_major.yml deleted file mode 100644 index 1148d331..00000000 --- a/.github/workflows/publish_major.yml +++ /dev/null @@ -1,77 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI - -name: Publish Major Release X.0.0 -on: - workflow_dispatch: - -jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Remove alpha (declare stable) - run: | - VER=$(python setup.py --version) - python scripts/remove_alpha.py - - name: "Generate release changelog" - uses: heinrichreimer/github-changelog-generator-action@v2.3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - id: changelog - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Declare alpha stable - branch: dev - - name: Push dev -> master - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: master - force: true - - name: version - run: echo "::set-output name=version::$(python setup.py --version)" - id: version - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - with: - tag_name: V${{ steps.version.outputs.version }} - release_name: Release ${{ steps.version.outputs.version }} - body: | - Changes in this Release - ${{ steps.changelog.outputs.changelog }} - draft: false - prerelease: false - commitish: master - - name: Build Distribution Packages - run: | - python setup.py sdist bdist_wheel - - name: Prepare next Major version - run: echo "::set-output name=version::$(python setup.py --version)" - id: alpha - - name: Increment Version ${{ steps.alpha.outputs.version }}Alpha0 - run: | - VER=$(python setup.py --version) - python scripts/bump_major.py - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Prepare Next Version - branch: dev - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{secrets.PYPI_TOKEN}} \ No newline at end of file diff --git a/.github/workflows/publish_minor.yml b/.github/workflows/publish_minor.yml deleted file mode 100644 index 4ab885b8..00000000 --- a/.github/workflows/publish_minor.yml +++ /dev/null @@ -1,77 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI - -name: Publish Minor Release .X.0 -on: - workflow_dispatch: - -jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Remove alpha (declare stable) - run: | - VER=$(python setup.py --version) - python scripts/remove_alpha.py - - name: "Generate release changelog" - uses: heinrichreimer/github-changelog-generator-action@v2.3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - id: changelog - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Declare alpha stable - branch: dev - - name: Push dev -> master - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: master - force: true - - name: version - run: echo "::set-output name=version::$(python setup.py --version)" - id: version - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - with: - tag_name: V${{ steps.version.outputs.version }} - release_name: Release ${{ steps.version.outputs.version }} - body: | - Changes in this Release - ${{ steps.changelog.outputs.changelog }} - draft: false - prerelease: false - commitish: master - - name: Build Distribution Packages - run: | - python setup.py sdist bdist_wheel - - name: Prepare next Minor version - run: echo "::set-output name=version::$(python setup.py --version)" - id: alpha - - name: Increment Version ${{ steps.alpha.outputs.version }}Alpha0 - run: | - VER=$(python setup.py --version) - python scripts/bump_minor.py - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Prepare Next Version - branch: dev - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{secrets.PYPI_TOKEN}} \ No newline at end of file diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml new file mode 100644 index 00000000..3272b82c --- /dev/null +++ b/.github/workflows/publish_release.yml @@ -0,0 +1,45 @@ +name: Publish Release +on: + push: + branches: + - master + +jobs: + github_release: + if: false + # TODO: Remove test patch above + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: master + fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. + - name: version + run: echo "::set-output name=version::$(python setup.py --version)" + id: version + - name: "Generate release changelog" + uses: heinrichreimer/github-changelog-generator-action@v2.3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + id: changelog + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: V${{ steps.version.outputs.version }} + release_name: Release ${{ steps.version.outputs.version }} + body: | + Changes in this Release + ${{ steps.changelog.outputs.changelog }} + draft: false + prerelease: false + commitish: master + - name: Build Distribution Packages + run: | + python setup.py sdist bdist_wheel + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{secrets.PYPI_TOKEN}} \ No newline at end of file diff --git a/scripts/bump_alpha.py b/scripts/bump_alpha.py deleted file mode 100644 index cf2a9716..00000000 --- a/scripts/bump_alpha.py +++ /dev/null @@ -1,18 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_utils", "version.py") -version_var_name = "VERSION_ALPHA" - -with open(version_file, "r", encoding="utf-8") as v: - for line in v.readlines(): - if line.startswith(version_var_name): - version = int(line.split("=")[-1]) - new_version = int(version) + 1 - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(version_var_name): - print(f"{version_var_name} = {new_version}") - else: - print(line.rstrip('\n')) diff --git a/scripts/bump_build.py b/scripts/bump_build.py deleted file mode 100644 index f4cfcfde..00000000 --- a/scripts/bump_build.py +++ /dev/null @@ -1,21 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_utils", "version.py") -version_var_name = "VERSION_BUILD" -alpha_var_name = "VERSION_ALPHA" - -with open(version_file, "r", encoding="utf-8") as v: - for line in v.readlines(): - if line.startswith(version_var_name): - version = int(line.split("=")[-1]) - new_version = int(version) + 1 - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(version_var_name): - print(f"{version_var_name} = {new_version}") - elif line.startswith(alpha_var_name): - print(f"{alpha_var_name} = 0") - else: - print(line.rstrip('\n')) diff --git a/scripts/bump_major.py b/scripts/bump_major.py deleted file mode 100644 index 2f365774..00000000 --- a/scripts/bump_major.py +++ /dev/null @@ -1,27 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_utils", "version.py") -version_var_name = "VERSION_MAJOR" -minor_var_name = "VERSION_MINOR" -build_var_name = "VERSION_BUILD" -alpha_var_name = "VERSION_ALPHA" - -with open(version_file, "r", encoding="utf-8") as v: - for line in v.readlines(): - if line.startswith(version_var_name): - version = int(line.split("=")[-1]) - new_version = int(version) + 1 - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(version_var_name): - print(f"{version_var_name} = {new_version}") - elif line.startswith(minor_var_name): - print(f"{minor_var_name} = 0") - elif line.startswith(build_var_name): - print(f"{build_var_name} = 0") - elif line.startswith(alpha_var_name): - print(f"{alpha_var_name} = 0") - else: - print(line.rstrip('\n')) diff --git a/scripts/bump_minor.py b/scripts/bump_minor.py deleted file mode 100644 index 2fe8194f..00000000 --- a/scripts/bump_minor.py +++ /dev/null @@ -1,24 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_utils", "version.py") -version_var_name = "VERSION_MINOR" -build_var_name = "VERSION_BUILD" -alpha_var_name = "VERSION_ALPHA" - -with open(version_file, "r", encoding="utf-8") as v: - for line in v.readlines(): - if line.startswith(version_var_name): - version = int(line.split("=")[-1]) - new_version = int(version) + 1 - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(version_var_name): - print(f"{version_var_name} = {new_version}") - elif line.startswith(build_var_name): - print(f"{build_var_name} = 0") - elif line.startswith(alpha_var_name): - print(f"{alpha_var_name} = 0") - else: - print(line.rstrip('\n')) diff --git a/scripts/remove_alpha.py b/scripts/remove_alpha.py deleted file mode 100644 index ee94ee9f..00000000 --- a/scripts/remove_alpha.py +++ /dev/null @@ -1,13 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_utils", "version.py") - -alpha_var_name = "VERSION_ALPHA" - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(alpha_var_name): - print(f"{alpha_var_name} = 0") - else: - print(line.rstrip('\n')) From d33995431a5ea07fdd19c49cebdf6173477cde1e Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Mon, 17 Apr 2023 18:27:38 +0000 Subject: [PATCH 37/43] Increment Version to 0.0.31a17 --- ovos_utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_utils/version.py b/ovos_utils/version.py index e9acc0a2..d885a37e 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 16 +VERSION_ALPHA = 17 # END_VERSION_BLOCK From a0ce7815dc4abe82971d31735c6f87efe6a0998e Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Mon, 17 Apr 2023 18:28:20 +0000 Subject: [PATCH 38/43] Update Changelog --- CHANGELOG.md | 43 ++++++++++--------------------------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1dca377..f1171e93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,16 @@ # Changelog -## [Unreleased](https://github.com/OpenVoiceOS/ovos-utils/tree/HEAD) +## [0.0.31a17](https://github.com/OpenVoiceOS/ovos-utils/tree/0.0.31a17) (2023-04-17) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a15...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a16...0.0.31a17) + +**Merged pull requests:** + +- Update release automation [\#126](https://github.com/OpenVoiceOS/ovos-utils/pull/126) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.31a16](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a16) (2023-04-14) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a15...V0.0.31a16) **Implemented enhancements:** @@ -706,10 +714,6 @@ [Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.17a6...V0.0.19a2) -**Breaking changes:** - -- Refactor/remove deprecated [\#11](https://github.com/OpenVoiceOS/ovos-utils/pull/11) ([JarbasAl](https://github.com/JarbasAl)) - **Merged pull requests:** - Fix/package workflow [\#32](https://github.com/OpenVoiceOS/ovos-utils/pull/32) ([JarbasAl](https://github.com/JarbasAl)) @@ -738,50 +742,23 @@ [Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/0.0.12...V0.0.17a4) -**Implemented enhancements:** - -- Feat/diagnostic mode [\#18](https://github.com/OpenVoiceOS/ovos-utils/pull/18) ([NeonJarbas](https://github.com/NeonJarbas)) -- fix/play\_audio [\#14](https://github.com/OpenVoiceOS/ovos-utils/pull/14) ([NeonJarbas](https://github.com/NeonJarbas)) -- Feat/better stop watch [\#10](https://github.com/OpenVoiceOS/ovos-utils/pull/10) ([JarbasAl](https://github.com/JarbasAl)) -- Feat/more file utils [\#9](https://github.com/OpenVoiceOS/ovos-utils/pull/9) ([JarbasAl](https://github.com/JarbasAl)) -- add notification api change and style parameter [\#6](https://github.com/OpenVoiceOS/ovos-utils/pull/6) ([AIIX](https://github.com/AIIX)) - **Fixed bugs:** - Fix/core module detection + refactor xdg config path utils [\#28](https://github.com/OpenVoiceOS/ovos-utils/pull/28) ([NeonJarbas](https://github.com/NeonJarbas)) - Fix typo in configuration paths [\#27](https://github.com/OpenVoiceOS/ovos-utils/pull/27) ([NeonDaniel](https://github.com/NeonDaniel)) - Add back colour dependency [\#24](https://github.com/OpenVoiceOS/ovos-utils/pull/24) ([NeonDaniel](https://github.com/NeonDaniel)) - Add user config home to `get_xdg_config_dirs` [\#23](https://github.com/OpenVoiceOS/ovos-utils/pull/23) ([NeonDaniel](https://github.com/NeonDaniel)) -- Loosen dependency versions for OVOS image compat [\#16](https://github.com/OpenVoiceOS/ovos-utils/pull/16) ([NeonDaniel](https://github.com/NeonDaniel)) -- Ovos conf [\#12](https://github.com/OpenVoiceOS/ovos-utils/pull/12) ([NeonJarbas](https://github.com/NeonJarbas)) -- fix/update\_enclosure\_api [\#8](https://github.com/OpenVoiceOS/ovos-utils/pull/8) ([JarbasAl](https://github.com/JarbasAl)) -- Fix/nested delete [\#7](https://github.com/OpenVoiceOS/ovos-utils/pull/7) ([JarbasAl](https://github.com/JarbasAl)) - -**Closed issues:** - -- Dependency Version specs [\#13](https://github.com/OpenVoiceOS/ovos-utils/issues/13) -- dependencies are duplicated + add version specs [\#5](https://github.com/OpenVoiceOS/ovos-utils/issues/5) **Merged pull requests:** - feat/packaging workflows [\#29](https://github.com/OpenVoiceOS/ovos-utils/pull/29) ([JarbasAl](https://github.com/JarbasAl)) - Update license\_tests.yml [\#26](https://github.com/OpenVoiceOS/ovos-utils/pull/26) ([NeonJarbas](https://github.com/NeonJarbas)) - Feat/pypi workflow [\#25](https://github.com/OpenVoiceOS/ovos-utils/pull/25) ([NeonJarbas](https://github.com/NeonJarbas)) -- feat/license tests workflow [\#22](https://github.com/OpenVoiceOS/ovos-utils/pull/22) ([JarbasAl](https://github.com/JarbasAl)) -- refactor/replace\_pyxdg [\#21](https://github.com/OpenVoiceOS/ovos-utils/pull/21) ([NeonJarbas](https://github.com/NeonJarbas)) -- refactor/bump\_requests [\#20](https://github.com/OpenVoiceOS/ovos-utils/pull/20) ([NeonJarbas](https://github.com/NeonJarbas)) -- refactor/deprecate\_inflection [\#19](https://github.com/OpenVoiceOS/ovos-utils/pull/19) ([NeonJarbas](https://github.com/NeonJarbas)) -- Refactor requirements to read from files [\#15](https://github.com/OpenVoiceOS/ovos-utils/pull/15) ([NeonDaniel](https://github.com/NeonDaniel)) ## [0.0.12](https://github.com/OpenVoiceOS/ovos-utils/tree/0.0.12) (2021-11-04) [Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/25fe462e3c19a58f32dc1fd940bf7c96fc18e6de...0.0.12) -**Implemented enhancements:** - -- release0.0.12/extract get\_local\_settings and save\_settings from core [\#4](https://github.com/OpenVoiceOS/ovos-utils/pull/4) ([JarbasAl](https://github.com/JarbasAl)) -- Adds checked path to log that root config path was not found [\#3](https://github.com/OpenVoiceOS/ovos-utils/pull/3) ([NeonDaniel](https://github.com/NeonDaniel)) - \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* From a481a2382f21f98eb34a7908f7fc3fc6687924d5 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Mon, 17 Apr 2023 20:57:04 -0700 Subject: [PATCH 39/43] Address Feedback for 0.0.32 Release (#130) --- .github/workflows/publish_AUR.yml | 40 -------------- ovos_utils/dialog.py | 4 +- ovos_utils/enclosure/api.py | 2 +- ovos_utils/events.py | 2 +- ovos_utils/file_utils.py | 4 +- ovos_utils/fingerprinting.py | 32 ++++++++++++ ovos_utils/gui.py | 3 ++ ovos_utils/intents/converse.py | 2 +- ovos_utils/intents/layers.py | 2 +- ovos_utils/log.py | 9 ++-- ovos_utils/messagebus.py | 86 +++++++++++++++++++------------ ovos_utils/skills/audioservice.py | 3 +- 12 files changed, 106 insertions(+), 83 deletions(-) delete mode 100644 .github/workflows/publish_AUR.yml diff --git a/.github/workflows/publish_AUR.yml b/.github/workflows/publish_AUR.yml deleted file mode 100644 index d883f464..00000000 --- a/.github/workflows/publish_AUR.yml +++ /dev/null @@ -1,40 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI - -name: aur-publish - -on: - workflow_dispatch: - -jobs: - aur-publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel pip2pkgbuild - - name: Create PKGBUILD - run: | - pip2pkgbuild ovos-utils -p python -b python-ovos-utils - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: generate PKGBUILD - branch: dev - - name: Publish AUR package - uses: KSXGitHub/github-actions-deploy-aur@master - with: - pkgname: ovos-utils - pkgbuild: ./PKGBUILD - commit_username: ${{ secrets.AUR_USERNAME }} - commit_email: ${{ secrets.AUR_EMAIL }} - ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} - commit_message: Update AUR package - ssh_keyscan_types: rsa,dsa,ecdsa,ed25519 diff --git a/ovos_utils/dialog.py b/ovos_utils/dialog.py index 3c936b0a..2b0500fd 100644 --- a/ovos_utils/dialog.py +++ b/ovos_utils/dialog.py @@ -135,7 +135,7 @@ def load_dialogs(dialog_dir: str, def get_dialog(phrase: str, lang: str = None, context: Optional[dict] = None) -> str: """ - Looks up a resource file for the given phrase. + Looks up a resource file for the given phrase in the specified language. If no file is found, the requested phrase is returned as the string. This will use the default language for translations. @@ -150,6 +150,8 @@ def get_dialog(phrase: str, lang: str = None, """ if not lang: + LOG.warning(f"Expected a string lang and got None. This config" + f"fallback behavior will be deprecated in a future release") try: from ovos_config.config import read_mycroft_config conf = read_mycroft_config() diff --git a/ovos_utils/enclosure/api.py b/ovos_utils/enclosure/api.py index 117186ba..91936b05 100644 --- a/ovos_utils/enclosure/api.py +++ b/ovos_utils/enclosure/api.py @@ -1,4 +1,4 @@ -from ovos_utils.messagebus import Message +from ovos_utils.messagebus import FakeMessage as Message class EnclosureAPI: diff --git a/ovos_utils/events.py b/ovos_utils/events.py index 07e8a872..3663fd37 100644 --- a/ovos_utils/events.py +++ b/ovos_utils/events.py @@ -4,7 +4,7 @@ from ovos_utils.intents.intent_service_interface import to_alnum from ovos_utils.log import LOG -from ovos_utils.messagebus import Message, FakeBus +from ovos_utils.messagebus import FakeBus, FakeMessage as Message def unmunge_message(message: Message, skill_id: str) -> Message: diff --git a/ovos_utils/file_utils.py b/ovos_utils/file_utils.py index 21623758..f64f5e17 100644 --- a/ovos_utils/file_utils.py +++ b/ovos_utils/file_utils.py @@ -87,7 +87,7 @@ def resolve_ovos_resource_file(res_name: str) -> Optional[str]: def resolve_resource_file(res_name: str, root_path: Optional[str] = None, - config: Optional[dict] = None) -> Optional[str]: + config: dict = None) -> Optional[str]: """ Convert a resource into an absolute filename. @@ -115,6 +115,8 @@ def resolve_resource_file(res_name: str, root_path: Optional[str] = None, str: path to resource or None if no resource found """ if config is None: + LOG.warning(f"Expected a dict config and got None. This config" + f"fallback behavior will be deprecated in a future release") try: from ovos_config.config import read_mycroft_config config = read_mycroft_config() diff --git a/ovos_utils/fingerprinting.py b/ovos_utils/fingerprinting.py index bf6c0e9e..83f4e468 100644 --- a/ovos_utils/fingerprinting.py +++ b/ovos_utils/fingerprinting.py @@ -22,11 +22,15 @@ class MycroftPlatform(str, Enum): def detect_platform(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") return max(((k, v) for k, v in classify_fingerprint().items()), key=lambda k: k[1])[0] def get_config_fingerprint(config=None): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") if not config: try: from ovos_config.config import read_mycroft_config @@ -51,6 +55,8 @@ def get_config_fingerprint(config=None): def get_platform_fingerprint(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") return { "hostname": socket.gethostname(), "platform": platform.platform(), @@ -78,16 +84,22 @@ def get_platform_fingerprint(): def get_fingerprint(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") finger = get_platform_fingerprint() finger["configuration"] = get_config_fingerprint() return finger def core_supports_xdg(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") return True # no longer optional def get_mycroft_version(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") try: # ovos from mycroft.version import OVOS_VERSION_STR return OVOS_VERSION_STR @@ -128,6 +140,8 @@ def get_mycroft_version(): def is_chatterbox_core(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") try: import chatterbox return True @@ -136,6 +150,8 @@ def is_chatterbox_core(): def is_neon_core(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") try: import neon_core return True @@ -144,6 +160,8 @@ def is_neon_core(): def is_mycroft_core(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") try: import mycroft return True @@ -152,22 +170,32 @@ def is_mycroft_core(): def is_vanilla_mycroft_core(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") return is_mycroft_core() and not is_ovos() def is_holmes(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") return "HolmesV" in (get_mycroft_version() or "") or is_mycroft_lib() def is_mycroft_lib(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") return "mycroft-lib" in (get_mycroft_version() or "") def is_ovos(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") return is_running_from_module("ovos-core") def classify_platform_print(fingerprint=None): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") fingerprint = fingerprint or get_platform_fingerprint() # key, val pairs that indicate a certain platform fingerprints = { @@ -327,6 +355,8 @@ def classify_platform_print(fingerprint=None): def classify_config_print(fingerprint=None): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") fingerprint = fingerprint or get_config_fingerprint() # key, val pairs that indicate a certain platform @@ -447,6 +477,8 @@ def classify_config_print(fingerprint=None): def classify_fingerprint(): + LOG.warning("fingerprinting utils are deprecated. This submodule " + "will be removed in ovos_utils 0.1.0") plat = classify_platform_print() conf = classify_config_print() for k, v in conf.items(): diff --git a/ovos_utils/gui.py b/ovos_utils/gui.py index 50e46123..954ad33b 100644 --- a/ovos_utils/gui.py +++ b/ovos_utils/gui.py @@ -502,6 +502,9 @@ class GUIInterface: def __init__(self, skill_id, bus=None, remote_server=None, config=None): if not config: + LOG.warning(f"Expected a dict config and got None. This config" + f"fallback behavior will be deprecated in a future " + f"release") try: from ovos_config.config import read_mycroft_config config = read_mycroft_config().get("gui", {}) diff --git a/ovos_utils/intents/converse.py b/ovos_utils/intents/converse.py index 79705859..0d232cb1 100644 --- a/ovos_utils/intents/converse.py +++ b/ovos_utils/intents/converse.py @@ -2,7 +2,7 @@ from ovos_utils.intents.intent_service_interface import IntentQueryApi from ovos_utils.log import LOG -from ovos_utils.messagebus import Message +from ovos_utils.messagebus import FakeMessage as Message class ConverseTracker: diff --git a/ovos_utils/intents/layers.py b/ovos_utils/intents/layers.py index e1a1272c..7e7bfb76 100644 --- a/ovos_utils/intents/layers.py +++ b/ovos_utils/intents/layers.py @@ -1,4 +1,4 @@ -from ovos_utils.messagebus import Message, get_mycroft_bus +from ovos_utils.messagebus import get_mycroft_bus, FakeMessage as Message from ovos_utils.log import LOG from time import sleep diff --git a/ovos_utils/log.py b/ovos_utils/log.py index a09964d8..83dcc171 100644 --- a/ovos_utils/log.py +++ b/ovos_utils/log.py @@ -152,9 +152,12 @@ def init_service_logger(service_name): # this is makes all logs from this service be configured to write to service_name.log file # if this is not called in every __main__.py entrypoint logs will be written # to a generic OVOS.log file shared across all services - from ovos_config.config import read_mycroft_config - - _cfg = read_mycroft_config() + try: + from ovos_config.config import read_mycroft_config + _cfg = read_mycroft_config() + except ImportError: + LOG.warning("ovos_config not available. Falling back to defaults") + _cfg = dict() _log_level = _cfg.get("log_level", "INFO") _logs_conf = _cfg.get("logs") or {} _logs_conf["level"] = _log_level diff --git a/ovos_utils/messagebus.py b/ovos_utils/messagebus.py index 42cbb473..c1339663 100644 --- a/ovos_utils/messagebus.py +++ b/ovos_utils/messagebus.py @@ -147,7 +147,7 @@ def __instancecheck__(self, instance): # fake Message object to allow usage without ovos-bus-client installed -class Message(metaclass=_MutableMessage): +class FakeMessage(metaclass=_MutableMessage): """ fake Message object to allow usage with FakeBus without ovos-bus-client installed""" def __new__(cls, *args, **kwargs): @@ -205,12 +205,12 @@ def deserialize(value): value(str): This is the json string received from the websocket Returns: - Message: message object constructed from the json string passed + FakeMessage: message object constructed from the json string passed int the function. value(str): This is the string received from the websocket """ obj = json.loads(value) - return Message(obj.get('type') or '', + return FakeMessage(obj.get('type') or '', obj.get('data') or {}, obj.get('context') or {}) @@ -226,10 +226,10 @@ def forward(self, msg_type, data=None): data (dict): data for message Returns: - Message: Message object to be used on the reply to the message + FakeMessage: Message object to be used on the reply to the message """ data = data or {} - return Message(msg_type, data, context=self.context) + return FakeMessage(msg_type, data, context=self.context) def reply(self, msg_type, data=None, context=None): """Construct a reply message for a given message @@ -249,7 +249,7 @@ def reply(self, msg_type, data=None, context=None): context: intended context for new message Returns: - Message: Message object to be used on the reply to the message + FakeMessage: Message object to be used on the reply to the message """ data = deepcopy(data) or {} context = context or {} @@ -263,7 +263,7 @@ def reply(self, msg_type, data=None, context=None): s = new_context['destination'] new_context['destination'] = new_context['source'] new_context['source'] = s - return Message(msg_type, data, context=new_context) + return FakeMessage(msg_type, data, context=new_context) def response(self, data=None, context=None): """Construct a response message for the message @@ -291,7 +291,7 @@ def publish(self, msg_type, data, context=None): context: context added to existing context Returns: - Message: Message object to publish + FakeMessage: Message object to publish """ context = context or {} new_context = self.context.copy() @@ -301,11 +301,14 @@ def publish(self, msg_type, data, context=None): if 'target' in new_context: del new_context['target'] - return Message(msg_type, data, context=new_context) + return FakeMessage(msg_type, data, context=new_context) -# compat -FakeMessage = Message +class Message(FakeMessage): + def __int__(self, *args, **kwargs): + LOG.warning(f"This reference is deprecated, import from " + f"`ovos_bus_client.message` directly") + FakeMessage.__init__(self, *args, **kwargs) def get_message_lang(message=None): @@ -315,9 +318,13 @@ def get_message_lang(message=None): Returns: The language code from the message or the default language. """ - from ovos_config.locale import get_default_lang + try: + from ovos_config.locale import get_default_lang + default_lang = get_default_lang() + except ImportError: + LOG.warning("ovos_config not available. Using default lang en-us") + default_lang = "en-us" message = message or dig_for_message() - default_lang = get_default_lang() if not message: return default_lang lang = message.data.get("lang") or message.context.get("lang") or default_lang @@ -341,8 +348,12 @@ def get_mycroft_bus(host: str = None, port: int = None, route: str = None, """ Returns a connection to the mycroft messagebus """ - from ovos_config.config import read_mycroft_config - config = read_mycroft_config().get('websocket') or dict() + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config().get('websocket') or dict() + except ImportError: + LOG.warning("ovos_config not available. Falling back to default WS") + config = dict() host = host or config.get('host') or _DEFAULT_WS_CONFIG['host'] port = port or config.get('port') or _DEFAULT_WS_CONFIG['port'] route = route or config.get('route') or _DEFAULT_WS_CONFIG['route'] @@ -383,7 +394,7 @@ def wait_for_reply(message, reply_type=None, timeout=3.0, bus=None): """Send a message and wait for a response. Args: - message (Message or str or dict): message object or type to send + message (FakeMessage or str or dict): message object or type to send reply_type (str): the message type of the expected reply. Defaults to ".response". timeout: seconds to wait before timeout, defaults to 3 @@ -398,12 +409,12 @@ def wait_for_reply(message, reply_type=None, timeout=3.0, bus=None): except: pass if isinstance(message, str): - message = Message(message) + message = FakeMessage(message) elif isinstance(message, dict): - message = Message(message["type"], - message.get("data"), - message.get("context")) - elif not isinstance(message, Message): + message = FakeMessage(message["type"], + message.get("data"), + message.get("context")) + elif not isinstance(message, FakeMessage): raise ValueError response = bus.wait_for_response(message, reply_type, timeout) if auto_close: @@ -416,17 +427,17 @@ def send_message(message, data=None, context=None, bus=None): bus = bus or get_mycroft_bus() if isinstance(message, str): if isinstance(data, dict) or isinstance(context, dict): - message = Message(message, data, context) + message = FakeMessage(message, data, context) else: try: message = json.loads(message) except: - message = Message(message) + message = FakeMessage(message) if isinstance(message, dict): - message = Message(message["type"], - message.get("data"), - message.get("context")) - if not isinstance(message, Message): + message = FakeMessage(message["type"], + message.get("data"), + message.get("context")) + if not isinstance(message, FakeMessage): raise ValueError bus.emit(message) if auto_close: @@ -486,7 +497,7 @@ def to_alnum(skill_id): def unmunge_message(message, skill_id): """Restore message keywords by removing the Letterified skill ID. Args: - message (Message): Intent result message + message (FakeMessage): Intent result message skill_id (str): skill identifier Returns: Message without clear keywords @@ -744,8 +755,17 @@ def __init__(self, trigger_message, name=None, bus=None, config=None): name(str): name identifier for .conf settings bus (WebsocketClient): mycroft messagebus websocket """ - from ovos_config.config import read_mycroft_config - config = config or read_mycroft_config() + if not config: + LOG.warning(f"Expected a dict config and got None. This config" + f"fallback behavior will be deprecated in a future " + f"release") + try: + from ovos_config.config import read_mycroft_config + config = read_mycroft_config() + except ImportError: + LOG.warning("ovos_config not available. Falling back to " + "default configuration") + config = dict() self.trigger_message = trigger_message self.name = name or self.__class__.__name__ self.bus = bus or get_mycroft_bus() @@ -772,7 +792,7 @@ def set_data_gatherer(self, callback, default_data=None, daemonic=False, interva else: response_type = self.trigger_message + ".reply" - response = Message(response_type, default_data) + response = FakeMessage(response_type, default_data) self.service = BusService(response, bus=self.bus) self.callback = callback self.bus.on(self.trigger_message, self._respond) @@ -819,7 +839,7 @@ class BusQuery: def __init__(self, message, bus=None): self.bus = bus or get_mycroft_bus() self._waiting = False - self.response = Message(None, None, None) + self.response = FakeMessage(None, None, None) self.query = message self.valid_response_types = [] @@ -843,7 +863,7 @@ def _wait_response(self, timeout): self._waiting = False def send(self, response_type=None, timeout=10): - self.response = Message(None, None, None) + self.response = FakeMessage(None, None, None) if response_type is None: response_type = self.query.type + ".reply" self.add_response_type(response_type) diff --git a/ovos_utils/skills/audioservice.py b/ovos_utils/skills/audioservice.py index 27185518..fb658373 100644 --- a/ovos_utils/skills/audioservice.py +++ b/ovos_utils/skills/audioservice.py @@ -19,7 +19,8 @@ from os.path import abspath from ovos_utils.log import LOG -from ovos_utils.messagebus import Message, get_mycroft_bus, dig_for_message +from ovos_utils.messagebus import get_mycroft_bus, dig_for_message, \ + FakeMessage as Message def ensure_uri(s: str): From 1c748c87c0dfef6d7db0250cb527ff6ad2a61346 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Tue, 18 Apr 2023 18:08:11 +0000 Subject: [PATCH 40/43] Increment Version to 0.0.31a18 --- ovos_utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_utils/version.py b/ovos_utils/version.py index d885a37e..0e0210f7 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 17 +VERSION_ALPHA = 18 # END_VERSION_BLOCK From e5a0f975dfd711f2bb2e3d798f857b021468bc39 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Tue, 18 Apr 2023 18:08:45 +0000 Subject: [PATCH 41/43] Update Changelog --- CHANGELOG.md | 622 +-------------------------------------------------- 1 file changed, 2 insertions(+), 620 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1171e93..8e37b08f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog -## [0.0.31a17](https://github.com/OpenVoiceOS/ovos-utils/tree/0.0.31a17) (2023-04-17) +## [V0.0.31a17](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a17) (2023-04-17) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a16...0.0.31a17) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a16...V0.0.31a17) **Merged pull requests:** @@ -141,624 +141,6 @@ - Add show input box method for skills [\#109](https://github.com/OpenVoiceOS/ovos-utils/pull/109) ([AIIX](https://github.com/AIIX)) -## [V0.0.30](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.30) (2023-03-09) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30a4...V0.0.30) - -## [V0.0.30a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.30a4) (2023-03-09) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30a3...V0.0.30a4) - -**Merged pull requests:** - -- Update dependencies to stable versions [\#107](https://github.com/OpenVoiceOS/ovos-utils/pull/107) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.30a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.30a3) (2023-03-08) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30a2...V0.0.30a3) - -**Merged pull requests:** - -- Bump ovos-config dependency cleanup module init [\#104](https://github.com/OpenVoiceOS/ovos-utils/pull/104) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.30a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.30a2) (2023-03-08) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.30a1...V0.0.30a2) - -**Implemented enhancements:** - -- feat/console\_scripts [\#105](https://github.com/OpenVoiceOS/ovos-utils/pull/105) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.30a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.30a1) (2023-03-08) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.29...V0.0.30a1) - -**Merged pull requests:** - -- Implement module\_property decorator with unit test [\#103](https://github.com/OpenVoiceOS/ovos-utils/pull/103) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.29](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.29) (2023-03-03) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.29a2...V0.0.29) - -## [V0.0.29a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.29a2) (2023-03-03) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.29a1...V0.0.29a2) - -**Fixed bugs:** - -- fix/circular\_import [\#101](https://github.com/OpenVoiceOS/ovos-utils/pull/101) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.29a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.29a1) (2023-03-03) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.28...V0.0.29a1) - -**Implemented enhancements:** - -- Migrate/lock monotonic event [\#100](https://github.com/OpenVoiceOS/ovos-utils/pull/100) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.28](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.28) (2023-02-24) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.28a7...V0.0.28) - -## [V0.0.28a7](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.28a7) (2023-02-16) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.28a6...V0.0.28a7) - -**Merged pull requests:** - -- Refactor SSH helpers and add generic systemd helpers [\#95](https://github.com/OpenVoiceOS/ovos-utils/pull/95) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.28a6](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.28a6) (2023-02-15) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.28a5...V0.0.28a6) - -**Merged pull requests:** - -- Handle default network config values if core configuration is incomplete [\#99](https://github.com/OpenVoiceOS/ovos-utils/pull/99) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.28a5](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.28a5) (2023-02-15) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.28a4...V0.0.28a5) - -**Implemented enhancements:** - -- port network utils from mk2 [\#85](https://github.com/OpenVoiceOS/ovos-utils/issues/85) -- improve network checks [\#88](https://github.com/OpenVoiceOS/ovos-utils/pull/88) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.28a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.28a4) (2023-02-08) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.28a3...V0.0.28a4) - -**Implemented enhancements:** - -- minor utils fix [\#98](https://github.com/OpenVoiceOS/ovos-utils/pull/98) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.28a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.28a3) (2023-02-07) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.28a2...V0.0.28a3) - -**Implemented enhancements:** - -- feat/runtime\_requirements gui [\#97](https://github.com/OpenVoiceOS/ovos-utils/pull/97) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.28a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.28a2) (2023-02-04) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.28a1...V0.0.28a2) - -**Implemented enhancements:** - -- feat/network\_reqs\_from\_workshop [\#96](https://github.com/OpenVoiceOS/ovos-utils/pull/96) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.28a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.28a1) (2023-01-25) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27...V0.0.28a1) - -**Fixed bugs:** - -- According to the usage, you should be able to pass the name to LOG\(\). [\#94](https://github.com/OpenVoiceOS/ovos-utils/pull/94) ([gmsoft-tuxicoman](https://github.com/gmsoft-tuxicoman)) - -## [V0.0.27](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27) (2023-01-20) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27a8...V0.0.27) - -## [V0.0.27a8](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27a8) (2023-01-20) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27a7...V0.0.27a8) - -**Merged pull requests:** - -- Log deprecation warning in `layers` module [\#93](https://github.com/OpenVoiceOS/ovos-utils/pull/93) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.27a7](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27a7) (2023-01-12) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27a6...V0.0.27a7) - -**Merged pull requests:** - -- add transient duration config [\#92](https://github.com/OpenVoiceOS/ovos-utils/pull/92) ([emphasize](https://github.com/emphasize)) - -## [V0.0.27a6](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27a6) (2023-01-05) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27a5...V0.0.27a6) - -**Fixed bugs:** - -- fix/mouse\_detect\_again [\#90](https://github.com/OpenVoiceOS/ovos-utils/pull/90) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.27a5](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27a5) (2022-12-16) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27a4...V0.0.27a5) - -**Implemented enhancements:** - -- sync utils with core [\#89](https://github.com/OpenVoiceOS/ovos-utils/pull/89) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.27a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27a4) (2022-11-30) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27a3...V0.0.27a4) - -**Merged pull requests:** - -- Add background\_color to show image and show animated image [\#86](https://github.com/OpenVoiceOS/ovos-utils/pull/86) ([AIIX](https://github.com/AIIX)) - -## [V0.0.27a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27a3) (2022-11-15) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27a2...V0.0.27a3) - -**Merged pull requests:** - -- gui notification callback data [\#84](https://github.com/OpenVoiceOS/ovos-utils/pull/84) ([AIIX](https://github.com/AIIX)) - -## [V0.0.27a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27a2) (2022-11-11) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.27a1...V0.0.27a2) - -**Fixed bugs:** - -- fix sudo flag again [\#83](https://github.com/OpenVoiceOS/ovos-utils/pull/83) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.27a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.27a1) (2022-11-11) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.26...V0.0.27a1) - -**Fixed bugs:** - -- fix sudo flag [\#82](https://github.com/OpenVoiceOS/ovos-utils/pull/82) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.26](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.26) (2022-10-29) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.26a2...V0.0.26) - -## [V0.0.26a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.26a2) (2022-10-22) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.26a1...V0.0.26a2) - -**Implemented enhancements:** - -- refactor some stuff to properties for better compatibility with ovos-… [\#80](https://github.com/OpenVoiceOS/ovos-utils/pull/80) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.26a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.26a1) (2022-10-19) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25...V0.0.26a1) - -**Implemented enhancements:** - -- feat/event\_wrappers\_in\_outils [\#79](https://github.com/OpenVoiceOS/ovos-utils/pull/79) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25) (2022-10-18) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a15...V0.0.25) - -**Merged pull requests:** - -- license + vulnerability tests [\#78](https://github.com/OpenVoiceOS/ovos-utils/pull/78) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a15](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a15) (2022-10-18) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a14...V0.0.25a15) - -**Fixed bugs:** - -- fix input detect again [\#77](https://github.com/OpenVoiceOS/ovos-utils/pull/77) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a14](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a14) (2022-10-17) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a13...V0.0.25a14) - -**Fixed bugs:** - -- fallback to True for mouse detection if libinput is missing [\#76](https://github.com/OpenVoiceOS/ovos-utils/pull/76) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a13](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a13) (2022-10-17) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a12...V0.0.25a13) - -**Implemented enhancements:** - -- scan /dev/input for device detection [\#75](https://github.com/OpenVoiceOS/ovos-utils/pull/75) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a12](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a12) (2022-10-17) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a11...V0.0.25a12) - -**Fixed bugs:** - -- feat/xinput support [\#74](https://github.com/OpenVoiceOS/ovos-utils/pull/74) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a11](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a11) (2022-10-11) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a10...V0.0.25a11) - -**Merged pull requests:** - -- add mail api point to ovos api service [\#73](https://github.com/OpenVoiceOS/ovos-utils/pull/73) ([AIIX](https://github.com/AIIX)) - -## [V0.0.25a10](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a10) (2022-10-10) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a9...V0.0.25a10) - -**Closed issues:** - -- `get_mycroft_bus` ignores Configuration [\#71](https://github.com/OpenVoiceOS/ovos-utils/issues/71) - -**Merged pull requests:** - -- Update `ovos_config` references, Read config in `get_mycroft_bus` [\#72](https://github.com/OpenVoiceOS/ovos-utils/pull/72) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.25a9](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a9) (2022-10-10) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a8...V0.0.25a9) - -**Fixed bugs:** - -- remove "logs" subfolder [\#70](https://github.com/OpenVoiceOS/ovos-utils/pull/70) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a8](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a8) (2022-10-07) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a7...V0.0.25a8) - -**Implemented enhancements:** - -- Update log.py [\#69](https://github.com/OpenVoiceOS/ovos-utils/pull/69) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a7](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a7) (2022-10-03) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a6...V0.0.25a7) - -**Implemented enhancements:** - -- feat/email\_utils [\#68](https://github.com/OpenVoiceOS/ovos-utils/pull/68) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a6](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a6) (2022-09-28) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a5...V0.0.25a6) - -**Merged pull requests:** - -- Add geolocate methods support in ovos\_api\_service [\#67](https://github.com/OpenVoiceOS/ovos-utils/pull/67) ([AIIX](https://github.com/AIIX)) - -## [V0.0.25a5](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a5) (2022-09-16) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a4...V0.0.25a5) - -**Implemented enhancements:** - -- Add methods for controlled notifications [\#66](https://github.com/OpenVoiceOS/ovos-utils/pull/66) ([AIIX](https://github.com/AIIX)) - -## [V0.0.25a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a4) (2022-09-10) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a3...V0.0.25a4) - -**Implemented enhancements:** - -- feat/timed\_lru\_cache [\#65](https://github.com/OpenVoiceOS/ovos-utils/pull/65) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a3) (2022-09-10) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a2...V0.0.25a3) - -**Fixed bugs:** - -- fix/syntax\_error [\#64](https://github.com/OpenVoiceOS/ovos-utils/pull/64) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.25a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a2) (2022-09-08) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.25a1...V0.0.25a2) - -**Merged pull requests:** - -- Add method to restart arbitrary systemd service [\#63](https://github.com/OpenVoiceOS/ovos-utils/pull/63) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.25a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.25a1) (2022-09-07) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.24...V0.0.25a1) - -**Implemented enhancements:** - -- add more api methods [\#62](https://github.com/OpenVoiceOS/ovos-utils/pull/62) ([AIIX](https://github.com/AIIX)) - -## [V0.0.24](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.24) (2022-09-07) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.24a4...V0.0.24) - -## [V0.0.24a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.24a4) (2022-09-06) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.24a3...V0.0.24a4) - -**Merged pull requests:** - -- add systemctl mycroft restart option [\#61](https://github.com/OpenVoiceOS/ovos-utils/pull/61) ([AIIX](https://github.com/AIIX)) - -## [V0.0.24a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.24a3) (2022-09-06) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.24a2...V0.0.24a3) - -**Implemented enhancements:** - -- feat/ovos\_api [\#60](https://github.com/OpenVoiceOS/ovos-utils/pull/60) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.24a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.24a2) (2022-08-17) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.24a1...V0.0.24a2) - -**Merged pull requests:** - -- Handle exceptions getting cache directory when MemoryTempfile fails \(i.e. in a chroot\) [\#58](https://github.com/OpenVoiceOS/ovos-utils/pull/58) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.24a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.24a1) (2022-08-15) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.23...V0.0.24a1) - -**Merged pull requests:** - -- Add extend about data method to gui utils [\#57](https://github.com/OpenVoiceOS/ovos-utils/pull/57) ([AIIX](https://github.com/AIIX)) - -## [V0.0.23](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.23) (2022-07-20) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.23a7...V0.0.23) - -## [V0.0.23a7](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.23a7) (2022-07-20) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.23a6...V0.0.23a7) - -**Implemented enhancements:** - -- Skill location utilities [\#55](https://github.com/OpenVoiceOS/ovos-utils/pull/55) ([NeonDaniel](https://github.com/NeonDaniel)) - -**Merged pull requests:** - -- Update release tag workflows to include version change commits [\#56](https://github.com/OpenVoiceOS/ovos-utils/pull/56) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.23a6](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.23a6) (2022-07-06) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.23a5...V0.0.23a6) - -**Merged pull requests:** - -- refactor/use ovos\_config package [\#52](https://github.com/OpenVoiceOS/ovos-utils/pull/52) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.23a5](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.23a5) (2022-07-06) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.23a4...V0.0.23a5) - -**Implemented enhancements:** - -- port/file\_watcher [\#54](https://github.com/OpenVoiceOS/ovos-utils/pull/54) ([NeonJarbas](https://github.com/NeonJarbas)) - -## [V0.0.23a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.23a4) (2022-07-06) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.23a3...V0.0.23a4) - -**Merged pull requests:** - -- Loosen mycroft-messagebus-client dependency to allow 0.10.0 [\#53](https://github.com/OpenVoiceOS/ovos-utils/pull/53) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.23a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.23a3) (2022-06-15) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.23a2...V0.0.23a3) - -**Fixed bugs:** - -- Prevent raising exception when msm config not present [\#51](https://github.com/OpenVoiceOS/ovos-utils/pull/51) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.23a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.23a2) (2022-06-10) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.23a1...V0.0.23a2) - -**Fixed bugs:** - -- fix/allow\_LF\_lang\_to\_be\_None [\#50](https://github.com/OpenVoiceOS/ovos-utils/pull/50) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.23a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.23a1) (2022-06-07) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.22...V0.0.23a1) - -**Fixed bugs:** - -- fix/screen\_check [\#49](https://github.com/OpenVoiceOS/ovos-utils/pull/49) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.22](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.22) (2022-06-02) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.22a3...V0.0.22) - -## [V0.0.22a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.22a3) (2022-06-02) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.22a2...V0.0.22a3) - -**Fixed bugs:** - -- Fix/full lang [\#48](https://github.com/OpenVoiceOS/ovos-utils/pull/48) ([NeonJarbas](https://github.com/NeonJarbas)) - -## [V0.0.22a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.22a2) (2022-05-31) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.22a1...V0.0.22a2) - -**Implemented enhancements:** - -- feat/lang\_utils [\#47](https://github.com/OpenVoiceOS/ovos-utils/pull/47) ([NeonJarbas](https://github.com/NeonJarbas)) - -## [V0.0.22a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.22a1) (2022-05-17) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.21...V0.0.22a1) - -**Implemented enhancements:** - -- support ovos-shell [\#45](https://github.com/OpenVoiceOS/ovos-utils/pull/45) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.21](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.21) (2022-05-17) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.21a6...V0.0.21) - -## [V0.0.21a6](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.21a6) (2022-05-17) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.21a5...V0.0.21a6) - -**Implemented enhancements:** - -- add InputDeviceHelper to detect available inputs on current system [\#44](https://github.com/OpenVoiceOS/ovos-utils/pull/44) ([AIIX](https://github.com/AIIX)) - -## [V0.0.21a5](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.21a5) (2022-05-12) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.21a4...V0.0.21a5) - -**Implemented enhancements:** - -- Add widgets helper [\#43](https://github.com/OpenVoiceOS/ovos-utils/pull/43) ([AIIX](https://github.com/AIIX)) - -## [V0.0.21a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.21a4) (2022-05-09) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.21a3...V0.0.21a4) - -**Merged pull requests:** - -- refactor/migrate\_adapt\_boilerplate [\#42](https://github.com/OpenVoiceOS/ovos-utils/pull/42) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.21a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.21a3) (2022-05-07) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.21a2...V0.0.21a3) - -**Merged pull requests:** - -- add sdist [\#41](https://github.com/OpenVoiceOS/ovos-utils/pull/41) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.21a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.21a2) (2022-05-07) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.21a1...V0.0.21a2) - -**Merged pull requests:** - -- Fix/remove unused dep [\#40](https://github.com/OpenVoiceOS/ovos-utils/pull/40) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.21a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.21a1) (2022-05-07) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.20...V0.0.21a1) - -**Fixed bugs:** - -- Fix/adapt [\#39](https://github.com/OpenVoiceOS/ovos-utils/pull/39) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.20](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.20) (2022-04-27) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.20a4...V0.0.20) - -## [V0.0.20a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.20a4) (2022-04-27) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.20a3...V0.0.20a4) - -**Implemented enhancements:** - -- Adds ovos service api [\#38](https://github.com/OpenVoiceOS/ovos-utils/pull/38) ([AIIX](https://github.com/AIIX)) - -**Merged pull requests:** - -- notify matrix chat on PR merged [\#37](https://github.com/OpenVoiceOS/ovos-utils/pull/37) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.20a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.20a3) (2022-03-23) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.20a2...V0.0.20a3) - -**Implemented enhancements:** - -- Feat/list utils [\#36](https://github.com/OpenVoiceOS/ovos-utils/pull/36) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.20a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.20a2) (2022-03-16) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.20a1...V0.0.20a2) - -**Implemented enhancements:** - -- Feat/process utils [\#35](https://github.com/OpenVoiceOS/ovos-utils/pull/35) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.20a1](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.20a1) (2022-03-03) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.19...V0.0.20a1) - -**Fixed bugs:** - -- Fix/resolve resource file [\#34](https://github.com/OpenVoiceOS/ovos-utils/pull/34) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.19](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.19) (2022-03-03) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.19a3...V0.0.19) - -## [V0.0.19a3](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.19a3) (2022-03-03) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.19a2...V0.0.19a3) - -**Fixed bugs:** - -- fix/platform\_detect [\#33](https://github.com/OpenVoiceOS/ovos-utils/pull/33) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.19a2](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.19a2) (2022-03-03) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.17a6...V0.0.19a2) - -**Merged pull requests:** - -- Fix/package workflow [\#32](https://github.com/OpenVoiceOS/ovos-utils/pull/32) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.17a6](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.17a6) (2022-02-25) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.17a5...V0.0.17a6) - -**Fixed bugs:** - -- Handle stopwatch.stop before started [\#31](https://github.com/OpenVoiceOS/ovos-utils/pull/31) ([NeonDaniel](https://github.com/NeonDaniel)) - -## [V0.0.17a5](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.17a5) (2022-02-25) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.18...V0.0.17a5) - -**Merged pull requests:** - -- Refactor/workflows from template [\#30](https://github.com/OpenVoiceOS/ovos-utils/pull/30) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.18](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.18) (2022-02-24) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.17a4...V0.0.18) - -## [V0.0.17a4](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.17a4) (2022-02-24) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/0.0.12...V0.0.17a4) - -**Fixed bugs:** - -- Fix/core module detection + refactor xdg config path utils [\#28](https://github.com/OpenVoiceOS/ovos-utils/pull/28) ([NeonJarbas](https://github.com/NeonJarbas)) -- Fix typo in configuration paths [\#27](https://github.com/OpenVoiceOS/ovos-utils/pull/27) ([NeonDaniel](https://github.com/NeonDaniel)) -- Add back colour dependency [\#24](https://github.com/OpenVoiceOS/ovos-utils/pull/24) ([NeonDaniel](https://github.com/NeonDaniel)) -- Add user config home to `get_xdg_config_dirs` [\#23](https://github.com/OpenVoiceOS/ovos-utils/pull/23) ([NeonDaniel](https://github.com/NeonDaniel)) - -**Merged pull requests:** - -- feat/packaging workflows [\#29](https://github.com/OpenVoiceOS/ovos-utils/pull/29) ([JarbasAl](https://github.com/JarbasAl)) -- Update license\_tests.yml [\#26](https://github.com/OpenVoiceOS/ovos-utils/pull/26) ([NeonJarbas](https://github.com/NeonJarbas)) -- Feat/pypi workflow [\#25](https://github.com/OpenVoiceOS/ovos-utils/pull/25) ([NeonJarbas](https://github.com/NeonJarbas)) - -## [0.0.12](https://github.com/OpenVoiceOS/ovos-utils/tree/0.0.12) (2021-11-04) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/25fe462e3c19a58f32dc1fd940bf7c96fc18e6de...0.0.12) - \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* From 9508ff00e6688dcd4a0a5e25bb0379c0c4d23626 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Tue, 18 Apr 2023 18:10:50 +0000 Subject: [PATCH 42/43] Increment Version to 0.0.31 --- ovos_utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_utils/version.py b/ovos_utils/version.py index 0e0210f7..eafc500e 100644 --- a/ovos_utils/version.py +++ b/ovos_utils/version.py @@ -3,5 +3,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 31 -VERSION_ALPHA = 18 +VERSION_ALPHA = 0 # END_VERSION_BLOCK From 0804b6f1cd00522c0d73192b6a87b407e759142e Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Tue, 18 Apr 2023 18:11:26 +0000 Subject: [PATCH 43/43] Update Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e37b08f..96a9845d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [V0.0.31a18](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a18) (2023-04-18) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a17...V0.0.31a18) + ## [V0.0.31a17](https://github.com/OpenVoiceOS/ovos-utils/tree/V0.0.31a17) (2023-04-17) [Full Changelog](https://github.com/OpenVoiceOS/ovos-utils/compare/V0.0.31a16...V0.0.31a17)