mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-07-23 19:25:25 +03:00
204 lines
8.4 KiB
Diff
204 lines
8.4 KiB
Diff
Upstream pull-request: https://github.com/MycroftAI/mycroft-core/pull/2559
|
|
|
|
diff --git a/mycroft/skills/mycroft_skill/mycroft_skill.py b/mycroft/skills/mycroft_skill/mycroft_skill.py
|
|
index 4f3b6d9da6..d60a3279d0 100644
|
|
--- a/mycroft/skills/mycroft_skill/mycroft_skill.py
|
|
+++ b/mycroft/skills/mycroft_skill/mycroft_skill.py
|
|
@@ -21,8 +21,11 @@ import traceback
|
|
from itertools import chain
|
|
from os import walk
|
|
from os.path import join, abspath, dirname, basename, exists
|
|
+from pathlib import Path
|
|
from threading import Event, Timer
|
|
|
|
+from xdg import BaseDirectory
|
|
+
|
|
from adapt.intent import Intent, IntentBuilder
|
|
|
|
from mycroft import dialog
|
|
@@ -113,6 +116,7 @@ class MycroftSkill:
|
|
bus (MycroftWebsocketClient): Optional bus connection
|
|
use_settings (bool): Set to false to not use skill settings at all
|
|
"""
|
|
+
|
|
def __init__(self, name=None, bus=None, use_settings=True):
|
|
self.name = name or self.__class__.__name__
|
|
self.resting_name = None
|
|
@@ -123,16 +127,6 @@ class MycroftSkill:
|
|
#: Member variable containing the absolute path of the skill's root
|
|
#: directory. E.g. /opt/mycroft/skills/my-skill.me/
|
|
self.root_dir = dirname(abspath(sys.modules[self.__module__].__file__))
|
|
- if use_settings:
|
|
- self.settings = get_local_settings(self.root_dir, self.name)
|
|
- self._initial_settings = deepcopy(self.settings)
|
|
- else:
|
|
- self.settings = None
|
|
-
|
|
- #: Set to register a callback method that will be called every time
|
|
- #: the skills settings are updated. The referenced method should
|
|
- #: include any logic needed to handle the updated settings.
|
|
- self.settings_change_callback = None
|
|
|
|
self.gui = SkillGUI(self)
|
|
|
|
@@ -141,6 +135,19 @@ class MycroftSkill:
|
|
self.bind(bus)
|
|
#: Mycroft global configuration. (dict)
|
|
self.config_core = Configuration.get()
|
|
+
|
|
+ self.settings = None
|
|
+ self.settings_write_path = None
|
|
+ self.settings_read_path = None
|
|
+
|
|
+ if use_settings:
|
|
+ self._init_settings()
|
|
+
|
|
+ #: Set to register a callback method that will be called every time
|
|
+ #: the skills settings are updated. The referenced method should
|
|
+ #: include any logic needed to handle the updated settings.
|
|
+ self.settings_change_callback = None
|
|
+
|
|
self.dialog_renderer = None
|
|
|
|
#: Filesystem access to skill specific folder.
|
|
@@ -157,6 +164,42 @@ class MycroftSkill:
|
|
self.event_scheduler = EventSchedulerInterface(self.name)
|
|
self.intent_service = IntentServiceInterface()
|
|
|
|
+ def _init_settings(self):
|
|
+ """Setup skill settings."""
|
|
+
|
|
+ # To not break existing setups,
|
|
+ # save to skill directory if the file exists already
|
|
+ self.settings_write_path = Path(self.root_dir)
|
|
+
|
|
+ # Otherwise save to XDG_CONFIG_DIR
|
|
+ if not self.settings_write_path.joinpath('settings.json').exists():
|
|
+ self.settings_write_path = Path(BaseDirectory.save_config_path(
|
|
+ 'mycroft', 'skills', basename(self.root_dir)))
|
|
+
|
|
+ # To not break existing setups,
|
|
+ # read from skill directory if the settings file exists there
|
|
+ self.settings_read_path = Path(self.root_dir)
|
|
+
|
|
+ # Then, check XDG_CONFIG_DIR
|
|
+ if not self.settings_read_path.joinpath('settings.json').exists():
|
|
+ for dir in BaseDirectory.load_config_paths('mycroft',
|
|
+ 'skills',
|
|
+ basename(
|
|
+ self.root_dir)):
|
|
+ path = Path(dir)
|
|
+ #: If there is a settings file here, use it
|
|
+ if path.joinpath('settings.json').exists():
|
|
+ self.settings_read_path = path
|
|
+ break
|
|
+
|
|
+ # Lastly, check /etc/mycroft
|
|
+ if not self.settings_read_path.joinpath('settings.json').exists():
|
|
+ self.settings_read_path = Path(
|
|
+ '/etc/mycroft/skills/').joinpath(basename(self.root_dir))
|
|
+
|
|
+ self.settings = get_local_settings(self.settings_read_path, self.name)
|
|
+ self._initial_settings = deepcopy(self.settings)
|
|
+
|
|
@property
|
|
def enclosure(self):
|
|
if self._enclosure:
|
|
@@ -271,7 +314,7 @@ class MycroftSkill:
|
|
if remote_settings is not None:
|
|
LOG.info('Updating settings for skill ' + self.name)
|
|
self.settings.update(**remote_settings)
|
|
- save_settings(self.root_dir, self.settings)
|
|
+ save_settings(self.settings_write_path, self.settings)
|
|
if self.settings_change_callback is not None:
|
|
self.settings_change_callback()
|
|
|
|
@@ -544,7 +587,7 @@ class MycroftSkill:
|
|
|
|
if not voc or not exists(voc):
|
|
raise FileNotFoundError(
|
|
- 'Could not find {}.voc file'.format(voc_filename))
|
|
+ 'Could not find {}.voc file'.format(voc_filename))
|
|
# load vocab and flatten into a simple list
|
|
vocab = read_vocab_file(voc)
|
|
self.voc_match_cache[cache_key] = list(chain(*vocab))
|
|
@@ -811,7 +854,7 @@ class MycroftSkill:
|
|
"""Store settings and indicate that the skill handler has completed
|
|
"""
|
|
if self.settings != self._initial_settings:
|
|
- save_settings(self.root_dir, self.settings)
|
|
+ save_settings(self.settings_write_path, self.settings)
|
|
self._initial_settings = self.settings
|
|
if handler_info:
|
|
msg_type = handler_info + '.complete'
|
|
@@ -1233,7 +1276,7 @@ class MycroftSkill:
|
|
|
|
# Store settings
|
|
if self.settings != self._initial_settings:
|
|
- save_settings(self.root_dir, self.settings)
|
|
+ save_settings(self.settings_write_path, self.settings)
|
|
|
|
if self.settings_meta:
|
|
self.settings_meta.stop()
|
|
diff --git a/mycroft/skills/settings.py b/mycroft/skills/settings.py
|
|
index c210625f5b..f576b34c9e 100644
|
|
--- a/mycroft/skills/settings.py
|
|
+++ b/mycroft/skills/settings.py
|
|
@@ -93,18 +93,22 @@ def get_local_settings(skill_dir, skill_name) -> dict:
|
|
def save_settings(skill_dir, skill_settings):
|
|
"""Save skill settings to file."""
|
|
settings_path = Path(skill_dir).joinpath('settings.json')
|
|
- if Path(skill_dir).exists():
|
|
- with open(str(settings_path), 'w') as settings_file:
|
|
- try:
|
|
- json.dump(skill_settings, settings_file)
|
|
- except Exception:
|
|
- LOG.exception('error saving skill settings to '
|
|
- '{}'.format(settings_path))
|
|
- else:
|
|
- LOG.info('Skill settings successfully saved to '
|
|
- '{}' .format(settings_path))
|
|
- else:
|
|
- LOG.info('Skill folder no longer exists, can\'t save settings.')
|
|
+
|
|
+ # Either the file already exists in /opt, or we are writing
|
|
+ # to XDG_CONFIG_DIR and always have the permission to make
|
|
+ # sure the file always exists
|
|
+ if not Path(settings_path).exists():
|
|
+ settings_path.touch(mode=0o644)
|
|
+
|
|
+ with open(str(settings_path), 'w') as settings_file:
|
|
+ try:
|
|
+ json.dump(skill_settings, settings_file)
|
|
+ except Exception:
|
|
+ LOG.exception('error saving skill settings to '
|
|
+ '{}'.format(settings_path))
|
|
+ else:
|
|
+ LOG.info('Skill settings successfully saved to '
|
|
+ '{}' .format(settings_path))
|
|
|
|
|
|
def get_display_name(skill_name: str):
|
|
diff --git a/mycroft/skills/skill_loader.py b/mycroft/skills/skill_loader.py
|
|
index 2402740188..b7e8186967 100644
|
|
--- a/mycroft/skills/skill_loader.py
|
|
+++ b/mycroft/skills/skill_loader.py
|
|
@@ -259,7 +259,8 @@ class SkillLoader:
|
|
if first_run:
|
|
LOG.info("First run of " + self.skill_id)
|
|
self.instance.settings["__mycroft_skill_firstrun"] = False
|
|
- save_settings(self.skill_directory, self.instance.settings)
|
|
+ save_settings(self.instance.settings_write_path,
|
|
+ self.instance.settings)
|
|
intro = self.instance.get_intro_message()
|
|
if intro:
|
|
self.instance.speak(intro)
|
|
diff --git a/requirements.txt b/requirements.txt
|
|
index 509436fb89..c9358db687 100644
|
|
--- a/requirements.txt
|
|
+++ b/requirements.txt
|
|
@@ -30,3 +30,4 @@ fann2==1.0.7
|
|
padaos==0.1.9
|
|
precise-runner==0.2.1
|
|
petact==0.1.2
|
|
+pyxdg==0.26
|