From d3621b7fca2cf576daddd007fc3db82206906855 Mon Sep 17 00:00:00 2001 From: Michael Nguyen Date: Wed, 28 Jun 2017 17:31:35 -0500 Subject: [PATCH] [WIP] refactored --- mycroft/skills/core.py | 2 +- mycroft/skills/settings.py | 137 ++++++++++++++++++++++++------------- 2 files changed, 90 insertions(+), 49 deletions(-) diff --git a/mycroft/skills/core.py b/mycroft/skills/core.py index 38afbc3a6a..cba9794cce 100644 --- a/mycroft/skills/core.py +++ b/mycroft/skills/core.py @@ -212,7 +212,7 @@ class MycroftSkill(object): try: return self._settings except: - self._settings = SkillSettings(self._dir) + self._settings = SkillSettings(self._dir, self.name) return self._settings def bind(self, emitter): diff --git a/mycroft/skills/settings.py b/mycroft/skills/settings.py index f358b7b6ce..6a5955bdd9 100644 --- a/mycroft/skills/settings.py +++ b/mycroft/skills/settings.py @@ -30,7 +30,7 @@ import json import sys -from os.path import isfile, join +from os.path import isfile, join, exists, expanduser from mycroft.util.log import getLogger from mycroft.api import DeviceApi @@ -41,7 +41,8 @@ SKILLS_DIR = "/opt/mycroft/skills" class SkillSettings(dict): """ SkillSettings creates a dictionary that can easily be stored - to file, serialized as json. + to file, serialized as json. It also syncs to the backend for + skill configuration Args: settings_file (str): Path to storage file @@ -53,38 +54,15 @@ class SkillSettings(dict): self._device_identity = self.api.identity.uuid self._settings_path = join(directory, 'settings.json') self._meta_path = join(directory, 'settingsmeta.json') - self._uuid_path = join('~/.mycroft/skills/' + self.name, + self._uuid_path = join(expanduser('~/.mycroft/skills/') + self.name, 'identity.json') self._api_path = "/" + self._device_identity + "/skill" - - # if file exist, open and read stored values into self - if isfile(self._settings_path): - with open(self._settings _path) as f: - try: - json_data = json.load(f) - for key in json_data: - self.__setitem__(key, json_data[key]) - except Exception as e: - # Show error on webUI. Dev will have to fix - # metadata to be able to edit later. - logger.error(e) - - # if settingsmeta.json exist and loaded for the first time - if isfile(self._meta_path) and not isfile(self._uuid_path): - with open(self._meta_path) as f: - self.settings_meta = json.load(f) - - # use this for testing purposes - self.__setitem__('test', 'testing') - self.store() - - # # post metadata to tartarus and store uuid for skill - # response = self._post_metadata(self.settings_meta) - # self.__setitem__('uuid', response['uuid']) - # self.store() - self.loaded_hash = hash(str(self)) + self._send_settings_meta() + self._request_settings() + self._load_settings() + @property def _is_stored(self): return hash(str(self)) == self.loaded_hash @@ -98,6 +76,83 @@ class SkillSettings(dict): """ return super(SkillSettings, self).__setitem__(key, value) + def _send_settings_meta(self): + """ + If settings meta data exists and the skill is loaded for the + first time, send settingsmeta.json to the backend and store uuid + for skill + """ + if isfile(self._meta_path): + with open(self._meta_path) as f: + self.settings_meta = json.load(f) + + # If skill is loaded for the first time post metadata + # to backend and store uuid for skill + if not isfile(self._uuid_path): + response = self._post_metadata(self.settings_meta) + self._store_uuid(response) + + def _request_settings(self): + """ + Poll to backend to request settings and store it if it changes + TODO: implement as websocket + + """ + # TODO: A get request for specific skill uuid instead of getting all + if isfile(self._uuid_path): + with open(self._uuid_path, 'r') as f: + data = json.load(f) + + response = self._get_settings() + + for skill_setting in response: + if skill_setting['uuid'] == data['uuid']: + settings_list = skill_setting['skillMetadata']['sections'] + for section in settings_list: + for field in section["fields"]: + pass + + def _load_settings(self): + """ + If settings.json exist, open and read stored values into self + """ + if isfile(self._settings_path): + with open(self._settings_path) as f: + try: + json_data = json.load(f) + for key in json_data: + self.__setitem__(key, json_data[key]) + except Exception as e: + # TODO: Show error on webUI. Dev will have to fix + # metadata to be able to edit later. + logger.error(e) + + def _store_uuid(self, uuid): + """ + Store uuid as identity.json in ~/.mycroft/skills/{skillname} + """ + with open(self._uuid_path, 'w') as f: + json.dump(uuid, f) + + def _get_settings(self): + """ + Goes to backend to get skill configurations for this device + """ + return self.api.request({ + "method": "GET", + "path": self._api_path + }) + + def _post_metadata(self, settings_meta): + """ + POST settingsmeta to backend to be configured in home.mycroft.ai + """ + return self.api.request({ + "method": "POST", + "path": self._api_path, + "json": settings_meta + }) + def store(self): """ Store dictionary to file if it has changed @@ -107,24 +162,10 @@ class SkillSettings(dict): json.dump(self, f) self.loaded_hash = hash(str(self)) - def _store_uuid(self, uuid): - with open(self._uuid_path, 'w') as f: - json.dump(uuid, f) - - # def _get_request_body(self, meta): - - def _get_settings(self): - return self.api.request({ - "method": "GET", - "path": self._api_path - }) - - def _post_metadata(self, settings_meta): - return self.api.request({ - "method": "POST", - "path": self._api_path, - "json": settings_meta - }) + def test(self): + with open(self._uuid_path, 'r') as f: + data = json.load(f) + return data # account for settings changes through skill ie. change default playlist