Fix remote settings overwrite at startup

Mycroft always mangeled any local settings changes at startup.

This caches the last settings from home on disk and only updates skills
_if_ there is a change.

This means that as if a member is changed locally (manually edited or
changed by the skill itself) it will be kept until another change is made
to the skill on Home.
pull/2707/head
Åke Forslund 2020-09-25 08:08:05 +02:00
parent 95fc0be02c
commit bd19d1673c
1 changed files with 42 additions and 3 deletions

View File

@ -57,9 +57,11 @@ SkillSettings Usage Example:
"""
import json
import os
from os.path import dirname
import re
from pathlib import Path
from threading import Timer
from xdg.BaseDirectory import xdg_cache_home
import yaml
@ -68,6 +70,7 @@ from mycroft.configuration import Configuration
from mycroft.messagebus.message import Message
from mycroft.util import camel_case_split
from mycroft.util.log import LOG
from mycroft.util.file_utils import ensure_directory_exists
from .msm_wrapper import build_msm_config, create_msm
ONE_MINUTE = 60
@ -309,6 +312,42 @@ class SettingsMetaUploader:
return success
# Path to remote cache
REMOTE_CACHE = Path(xdg_cache_home, 'mycroft', 'remote_skill_settings.json')
def load_remote_settings_cache():
"""Load cached remote skill settings.
Returns:
(dict) Loaded remote settings cache or None of none exists.
"""
remote_settings = {}
if REMOTE_CACHE.exists():
try:
with open(str(REMOTE_CACHE)) as cache:
remote_settings = json.load(cache)
except Exception as error:
LOG.warning('Failed to read remote_cache ({})'.format(error))
return remote_settings
def save_remote_settings_cache(remote_settings):
"""Save updated remote settings to cache file.
Arguments:
remote_settings (dict): downloaded remote settings.
"""
try:
ensure_directory_exists(dirname(str(REMOTE_CACHE)))
with open(str(REMOTE_CACHE), 'w') as cache:
json.dump(remote_settings, cache)
except Exception as error:
LOG.warning('Failed to write remote_cache. ({})'.format(error))
else:
LOG.debug('Updated local cache of remote skill settings.')
class SkillSettingsDownloader:
"""Manages download of skill settings.
@ -319,8 +358,8 @@ class SkillSettingsDownloader:
def __init__(self, bus):
self.bus = bus
self.continue_downloading = True
self.last_download_result = {}
self.remote_settings = None
self.last_download_result = load_remote_settings_cache()
self.api = DeviceApi()
self.download_timer = None
self.sync_enabled = Configuration.get()["server"]\
@ -351,11 +390,11 @@ class SkillSettingsDownloader:
LOG.debug('Skill settings changed since last download')
self._emit_settings_change_events(remote_settings)
self.last_download_result = remote_settings
save_remote_settings_cache(remote_settings)
else:
LOG.debug('No skill settings changes since last download')
else:
LOG.debug('Settings not downloaded - device is not paired')
# If this method is called outside of the timer loop, ensure the
# existing timer is canceled before starting a new one.
if self.download_timer: