implemented a stop-gap change to keep the skill API from breaking
parent
5c742d2ed0
commit
b1a63638c1
|
@ -44,7 +44,7 @@ from mycroft.util.log import LOG
|
|||
from .event_container import EventContainer, create_wrapper, get_handler_name
|
||||
from ..event_scheduler import EventSchedulerInterface
|
||||
from ..intent_service_interface import IntentServiceInterface
|
||||
from ..settings import get_local_settings, save_settings
|
||||
from ..settings import save_settings, Settings
|
||||
from ..skill_data import (
|
||||
load_vocabulary,
|
||||
load_regex,
|
||||
|
@ -129,7 +129,7 @@ class MycroftSkill:
|
|||
# Get directory of skill
|
||||
self.root_dir = dirname(abspath(sys.modules[self.__module__].__file__))
|
||||
if use_settings:
|
||||
self.settings = get_local_settings(self.root_dir, self.name)
|
||||
self.settings = Settings(self)
|
||||
else:
|
||||
self.settings = None
|
||||
self.settings_change_callback = None
|
||||
|
|
|
@ -74,14 +74,17 @@ ONE_MINUTE = 60
|
|||
def get_local_settings(skill_dir, skill_name) -> dict:
|
||||
"""Build a dictionary using the JSON string stored in settings.json."""
|
||||
settings_path = Path(skill_dir).joinpath('settings.json')
|
||||
with open(str(settings_path)) as settings_file:
|
||||
try:
|
||||
skill_settings = json.load(settings_file)
|
||||
# TODO change to check for JSONDecodeError in 19.08
|
||||
except Exception:
|
||||
log_msg = 'Failed to load {} settings from settings.json'
|
||||
LOG.exception(log_msg.format(skill_name))
|
||||
skill_settings = {}
|
||||
if settings_path.is_file():
|
||||
with open(str(settings_path)) as settings_file:
|
||||
try:
|
||||
skill_settings = json.load(settings_file)
|
||||
# TODO change to check for JSONDecodeError in 19.08
|
||||
except Exception:
|
||||
log_msg = 'Failed to load {} settings from settings.json'
|
||||
LOG.exception(log_msg.format(skill_name))
|
||||
skill_settings = {}
|
||||
else:
|
||||
skill_settings = {}
|
||||
|
||||
return skill_settings
|
||||
|
||||
|
@ -362,3 +365,36 @@ class SkillSettingsDownloader:
|
|||
data={skill_gid: remote_settings}
|
||||
)
|
||||
self.bus.emit(message)
|
||||
|
||||
|
||||
# TODO: remove in 20.02
|
||||
class Settings:
|
||||
def __init__(self, skill):
|
||||
self._skill = skill
|
||||
self._settings = get_local_settings(skill.root_dir, skill.name)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr not in ['store', 'set_changed_callback']:
|
||||
return getattr(self._settings, attr)
|
||||
else:
|
||||
return super().getattr(attr)
|
||||
|
||||
def __setitem__(self, key, val):
|
||||
self._settings[key] = val
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._settings[key]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._settings)
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self._settings
|
||||
|
||||
def store(self, force=False):
|
||||
LOG.warning('DEPRECATED - use mycroft.skills.settings.save_settings()')
|
||||
save_settings(self._skill.root_dir, self._settings)
|
||||
|
||||
def set_changed_callback(self, callback):
|
||||
LOG.warning('DEPRECATED - set the settings_changed_callback attribute')
|
||||
self._skill.settings_change_callback = callback
|
||||
|
|
|
@ -13,13 +13,15 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
import json
|
||||
from unittest.mock import call, Mock, patch
|
||||
from os import remove
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import call, Mock, patch
|
||||
|
||||
from mycroft.skills.settings import (
|
||||
SkillSettingsDownloader,
|
||||
SettingsMetaUploader
|
||||
SettingsMetaUploader,
|
||||
Settings
|
||||
)
|
||||
from ..base import MycroftUnitTestBase
|
||||
|
||||
|
@ -287,3 +289,55 @@ class TestSettingsDownloader(MycroftUnitTestBase):
|
|||
[remote_skill_settings],
|
||||
self.message_bus_mock.message_data
|
||||
)
|
||||
|
||||
|
||||
class TestSettings(TestCase):
|
||||
def setUp(self) -> None:
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
self.temp_dir = Path(temp_dir)
|
||||
self.skill_mock = Mock()
|
||||
self.skill_mock.root_dir = str(self.temp_dir)
|
||||
self.skill_mock.name = 'test_skill'
|
||||
|
||||
def test_empty_settings(self):
|
||||
settings = Settings(self.skill_mock)
|
||||
self.assertDictEqual(settings._settings, {})
|
||||
|
||||
def test_settings_file_exists(self):
|
||||
settings_path = self.temp_dir.joinpath('settings.json')
|
||||
with open(settings_path, 'w') as settings_file:
|
||||
settings_file.write('{"foo": "bar"}\n')
|
||||
|
||||
settings = Settings(self.skill_mock)
|
||||
self.assertDictEqual(settings._settings, {'foo': 'bar'})
|
||||
self.assertEqual(settings['foo'], 'bar')
|
||||
self.assertNotIn('store', settings)
|
||||
self.assertIn('foo', settings)
|
||||
|
||||
def test_change_settings(self):
|
||||
settings = Settings(self.skill_mock)
|
||||
settings['foo'] = 'bar'
|
||||
self.assertDictEqual(settings._settings, {'foo': 'bar'})
|
||||
self.assertIn('foo', settings)
|
||||
|
||||
def test_store_settings(self):
|
||||
settings = Settings(self.skill_mock)
|
||||
settings['foo'] = 'bar'
|
||||
settings.store()
|
||||
settings_path = self.temp_dir.joinpath('settings.json')
|
||||
with open(settings_path) as settings_file:
|
||||
file_contents = settings_file.read()
|
||||
|
||||
self.assertEqual(file_contents, '{"foo": "bar"}')
|
||||
|
||||
def test_set_changed_callback(self):
|
||||
def test_callback():
|
||||
pass
|
||||
|
||||
settings = Settings(self.skill_mock)
|
||||
settings.set_changed_callback(test_callback)
|
||||
|
||||
self.assertEqual(
|
||||
self.skill_mock.settings_change_callback,
|
||||
test_callback
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue