Bugfix/polling fixes (#1296)

* fixed identifier to be unique across all accounts

* now skills will load on http error and skills will upload once to web once identity2 exist

* extracted stuff out of __init__ so that skills work on load and skills get upload when identiy2 exists

* iniatiated class attribute to None
pull/1300/head
Michael Nguyen 2017-12-08 21:27:06 -06:00 committed by Matthew D. Scholefield
parent 6873d0a0b7
commit 136f1af8c3
1 changed files with 64 additions and 55 deletions

View File

@ -81,21 +81,33 @@ class SkillSettings(dict):
def __init__(self, directory, name): def __init__(self, directory, name):
super(SkillSettings, self).__init__() super(SkillSettings, self).__init__()
self.api = DeviceApi() self.api = DeviceApi()
self._device_identity = self.api.identity.uuid
self.config = ConfigurationManager.get() self.config = ConfigurationManager.get()
self.name = name self.name = name
self.directory = directory self.directory = directory
# set file paths # set file paths
self._settings_path = join(directory, 'settings.json') self._settings_path = join(directory, 'settings.json')
self._meta_path = join(directory, 'settingsmeta.json') self._meta_path = join(directory, 'settingsmeta.json')
self._api_path = "/" + self._device_identity + "/skill"
self.is_alive = True self.is_alive = True
self.loaded_hash = hash(str(self)) self.loaded_hash = hash(str(self))
self._complete_intialization = False
self._device_identity = None
self._api_path = None
self._user_identity = None
# if settingsmeta.json exists # if settingsmeta.json exists
# this block of code is a control flow for # this block of code is a control flow for
# different scenarios that may arises with settingsmeta # different scenarios that may arises with settingsmeta
if isfile(self._meta_path): if isfile(self._meta_path):
self._poll_skill_settings()
self.load_skill_settings()
# TODO: break this up into two classes
def initiatlize_remote_settings(self):
""" initializes the remote settings to the server """
# if settingsmeta.json exists
# this block of code is a control flow for
# different scenarios that may arises with settingsmeta
self._device_identity = self.api.identity.uuid
self._api_path = "/" + self._device_identity + "/skill"
self._user_identity = self.api.get()['user']['uuid'] self._user_identity = self.api.get()['user']['uuid']
LOG.info("settingsmeta.json exist for {}".format(self.name)) LOG.info("settingsmeta.json exist for {}".format(self.name))
settings_meta = self._load_settings_meta() settings_meta = self._load_settings_meta()
@ -104,14 +116,14 @@ class SkillSettings(dict):
# if hash is new then there is a diff version of settingsmeta # if hash is new then there is a diff version of settingsmeta
if self._is_new_hash(hashed_meta): if self._is_new_hash(hashed_meta):
# first look at all other devices on user account to see # first look at all other devices on user account to see
# if the settings exist. if it does then sync with this device # if the settings exist. if it does then sync with device
if skill_settings: if skill_settings:
# not_owner flags that this settings is loaded from # not_owner flags that this settings is loaded from
# another device. If a skill settings doesn't have # another device. If a skill settings doesn't have
# not_owner, then the skill is created from that device # not_owner, then the skill is created from that device
self['not_owner'] = True self['not_owner'] = True
self.save_skill_settings(skill_settings) self.save_skill_settings(skill_settings)
else: # upload skill settings if other devices do not have it else: # upload skill settings if
uuid = self._load_uuid() uuid = self._load_uuid()
if uuid is not None: if uuid is not None:
self._delete_metadata(uuid) self._delete_metadata(uuid)
@ -129,12 +141,7 @@ class SkillSettings(dict):
self._upload_meta(settings_meta, hashed_meta) self._upload_meta(settings_meta, hashed_meta)
else: else:
self.save_skill_settings(settings) self.save_skill_settings(settings)
self._complete_intialization = True
t = Timer(60, self._poll_skill_settings, [hashed_meta])
t.daemon = True
t.start()
self.load_skill_settings()
@property @property
def _is_stored(self): def _is_stored(self):
@ -259,6 +266,8 @@ class SkillSettings(dict):
response = self._send_settings_meta(meta) response = self._send_settings_meta(meta)
if response: if response:
self._save_uuid(response['uuid']) self._save_uuid(response['uuid'])
if 'not_owner' in self:
del self['not_owner']
self._save_hash(hashed_meta) self._save_hash(hashed_meta)
def _delete_old_meta(self): def _delete_old_meta(self):
@ -338,8 +347,11 @@ class SkillSettings(dict):
if skills_settings is not None: if skills_settings is not None:
self.save_skill_settings(skills_settings) self.save_skill_settings(skills_settings)
self.store() self.store()
else:
settings_meta = self._load_settings_meta()
self._upload_meta(settings_meta, hashed_meta)
def _poll_skill_settings(self, hashed_meta): def _poll_skill_settings(self):
""" If identifier exists for this skill poll to backend to """ If identifier exists for this skill poll to backend to
request settings and store it if it changes request settings and store it if it changes
TODO: implement as websocket TODO: implement as websocket
@ -347,22 +359,19 @@ class SkillSettings(dict):
Args: Args:
hashed_meta (int): the hashed identifier hashed_meta (int): the hashed identifier
""" """
skills_settings = None try:
if self.get('not_owner'): if not self._complete_intialization:
skills_settings = self._request_other_settings(hashed_meta) self.initiatlize_remote_settings()
if not skills_settings:
skills_settings = self._request_my_settings(hashed_meta)
if skills_settings is not None:
self.save_skill_settings(skills_settings)
self.store()
else: else:
settings_meta = self._load_settings_meta() self.update_remote()
self._upload_meta(settings_meta, hashed_meta) except Exception as e:
LOG.error(e)
LOG.exception("")
# this is used in core so do not delete!
if self.is_alive: if self.is_alive:
# continues to poll settings every 60 seconds # continues to poll settings every 60 seconds
t = Timer(60, self._poll_skill_settings, [hashed_meta]) t = Timer(60, self._poll_skill_settings)
t.daemon = True t.daemon = True
t.start() t.start()