from .constants import CONF_KEY_BASE, CONF_KEY_PLAYERSETTINGS, \
CONF_KEY_MUSICPROVIDERS, CONF_KEY_PLAYERPROVIDERS, EVENT_CONFIG_CHANGED
+class WatchedDict(dict):
-class MassConfig(dict):
+ def __init__(self, mass, parent, savefunc, existing_dict=None):
+ self.mass = mass
+ self.parent = parent
+ self.savefunc = savefunc
+ if existing_dict:
+ for key, value in existing_dict.items():
+ self[key] = value
+
+ def __setitem__(self, key, new_value):
+ # optional processing here
+ if key not in self:
+ if isinstance(new_value, dict):
+ new_value = WatchedDict(self.mass, key, self.savefunc, new_value)
+ super().__setitem__(key, new_value)
+ elif self[key] != new_value:
+ # value changed
+ super().__setitem__(key, new_value)
+ self[key] = new_value
+ self.mass.event_loop.create_task(
+ self.mass.signal_event(EVENT_CONFIG_CHANGED, f"{self.parent}.{key}"))
+ self.savefunc()
+
+class MassConfig(WatchedDict):
''' Class which holds our configuration '''
def __init__(self, mass):
self.mass = mass
self.loading = False
- self[CONF_KEY_BASE] = {}
- self[CONF_KEY_MUSICPROVIDERS] = {}
- self[CONF_KEY_PLAYERPROVIDERS] = {}
- self[CONF_KEY_PLAYERSETTINGS] = {}
+ self.savefunc = self.__save
+ self.parent = None
+ self[CONF_KEY_BASE] = WatchedDict(mass, None, self.__save)
+ self[CONF_KEY_MUSICPROVIDERS] = WatchedDict(mass, None, self.__save)
+ self[CONF_KEY_PLAYERPROVIDERS] = WatchedDict(mass, None, self.__save)
+ self[CONF_KEY_PLAYERSETTINGS] = WatchedDict(mass, None, self.__save)
self.__load()
-
@property
def base(self):
''' return base config '''
self[base_key][conf_key] = new_conf
return self[base_key][conf_key]
- def __setitem__(self, key, new_value):
- # optional processing here
- if key not in self:
- super().__setitem__(key, new_value)
- elif self[key] != new_value:
- # value changed
- super().__setitem__(key, new_value)
- self[key] = new_value
- self.mass.event_loop.create_task(
- self.mass.signal_event(EVENT_CONFIG_CHANGED, self))
- self.__save()
-
def __save(self):
''' save config to file '''
if self.loading:
app.add_routes([web.get('/stream/{player_id}/{queue_item_id}', self.mass.http_streamer.stream)])
app.add_routes([web.get('/api/search', self.search)])
app.add_routes([web.get('/api/config', self.get_config)])
- app.add_routes([web.post('/api/config', self.save_config)])
+ app.add_routes([web.post('/api/config/{key}/{subkey}', self.save_config)])
app.add_routes([web.get('/api/players', self.players)])
app.add_routes([web.get('/api/players/{player_id}', self.player)])
app.add_routes([web.get('/api/players/{player_id}/queue', self.player_queue)])
async def save_config(self, request):
''' save (partial) config '''
- LOGGER.debug('save config called from api')
- new_config = await request.json()
- config_changed = False
- for key, value in self.mass.config.items():
- if isinstance(value, dict):
- for subkey, subvalue in value.items():
- if subkey in new_config[key]:
- if self.mass.config[key][subkey] != new_config[key][subkey]:
- config_changed = True
- self.mass.config[key][subkey] = new_config[key][subkey]
- elif key in new_config:
- if self.mass.config[key] != new_config[key]:
- config_changed = True
- self.mass.config[key] = new_config[key]
- if config_changed:
- self.mass.save_config()
- await self.mass.signal_event('config_changed')
- return web.Response(text='success')
+ conf_key = request.match_info.get('key')
+ conf_subkey = request.match_info.get('subkey')
+ new_values = await request.json()
+ LOGGER.debug(f'save config called for {conf_key}/{conf_subkey} - new value: {new_values}')
+ cur_values = self.mass.config[conf_key][conf_subkey]
+ result = {"success": True, "restart_required": False, "settings_changed": False}
+ if cur_values != new_values:
+ # config changed
+ result["settings_changed"] = True
+ self.mass.config[conf_key][conf_subkey] = new_values
+ if conf_key != "player_settings":
+ result["restart_required"] = True
+ return web.json_response(result)
async def json_rpc(self, request):
'''