Add save command to lovelace (#18655)

* Add save command to lovelace

* Default for save should by json

* typing
This commit is contained in:
Bram Kragten 2018-11-23 22:56:58 +01:00 committed by Paulus Schoutsen
parent 4c04abfccc
commit 37327f6cbd
2 changed files with 37 additions and 5 deletions

View File

@ -31,6 +31,7 @@ FORMAT_JSON = 'json'
OLD_WS_TYPE_GET_LOVELACE_UI = 'frontend/lovelace_config'
WS_TYPE_GET_LOVELACE_UI = 'lovelace/config'
WS_TYPE_MIGRATE_CONFIG = 'lovelace/config/migrate'
WS_TYPE_SAVE_CONFIG = 'lovelace/config/save'
WS_TYPE_GET_CARD = 'lovelace/config/card/get'
WS_TYPE_UPDATE_CARD = 'lovelace/config/card/update'
@ -53,6 +54,13 @@ SCHEMA_MIGRATE_CONFIG = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_MIGRATE_CONFIG,
})
SCHEMA_SAVE_CONFIG = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_SAVE_CONFIG,
vol.Required('config'): vol.Any(str, Dict),
vol.Optional('format', default=FORMAT_JSON):
vol.Any(FORMAT_JSON, FORMAT_YAML),
})
SCHEMA_GET_CARD = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_GET_CARD,
vol.Required('card_id'): str,
@ -204,6 +212,13 @@ def migrate_config(fname: str) -> None:
yaml.save_yaml(fname, config)
def save_config(fname: str, config, data_format: str = FORMAT_JSON) -> None:
"""Save config to file."""
if data_format == FORMAT_YAML:
config = yaml.yaml_to_object(config)
yaml.save_yaml(fname, config)
def get_card(fname: str, card_id: str, data_format: str = FORMAT_YAML)\
-> JSON_TYPE:
"""Load a specific card config for id."""
@ -422,13 +437,17 @@ async def async_setup(hass, config):
OLD_WS_TYPE_GET_LOVELACE_UI, websocket_lovelace_config,
SCHEMA_GET_LOVELACE_UI)
hass.components.websocket_api.async_register_command(
WS_TYPE_GET_LOVELACE_UI, websocket_lovelace_config,
SCHEMA_GET_LOVELACE_UI)
hass.components.websocket_api.async_register_command(
WS_TYPE_MIGRATE_CONFIG, websocket_lovelace_migrate_config,
SCHEMA_MIGRATE_CONFIG)
hass.components.websocket_api.async_register_command(
WS_TYPE_GET_LOVELACE_UI, websocket_lovelace_config,
SCHEMA_GET_LOVELACE_UI)
WS_TYPE_SAVE_CONFIG, websocket_lovelace_save_config,
SCHEMA_SAVE_CONFIG)
hass.components.websocket_api.async_register_command(
WS_TYPE_GET_CARD, websocket_lovelace_get_card, SCHEMA_GET_CARD)
@ -516,6 +535,15 @@ async def websocket_lovelace_migrate_config(hass, connection, msg):
migrate_config, hass.config.path(LOVELACE_CONFIG_FILE))
@websocket_api.async_response
@handle_yaml_errors
async def websocket_lovelace_save_config(hass, connection, msg):
"""Save Lovelace UI configuration."""
return await hass.async_add_executor_job(
save_config, hass.config.path(LOVELACE_CONFIG_FILE), msg['config'],
msg.get('format', FORMAT_JSON))
@websocket_api.async_response
@handle_yaml_errors
async def websocket_lovelace_get_card(hass, connection, msg):

View File

@ -1,7 +1,7 @@
"""ruamel.yaml utility functions."""
import logging
import os
from os import O_CREAT, O_TRUNC, O_WRONLY
from os import O_CREAT, O_TRUNC, O_WRONLY, stat_result
from collections import OrderedDict
from typing import Union, List, Dict
@ -104,13 +104,17 @@ def save_yaml(fname: str, data: JSON_TYPE) -> None:
yaml.indent(sequence=4, offset=2)
tmp_fname = fname + "__TEMP__"
try:
file_stat = os.stat(fname)
try:
file_stat = os.stat(fname)
except OSError:
file_stat = stat_result(
(0o644, -1, -1, -1, -1, -1, -1, -1, -1, -1))
with open(os.open(tmp_fname, O_WRONLY | O_CREAT | O_TRUNC,
file_stat.st_mode), 'w', encoding='utf-8') \
as temp_file:
yaml.dump(data, temp_file)
os.replace(tmp_fname, fname)
if hasattr(os, 'chown'):
if hasattr(os, 'chown') and file_stat.st_ctime > -1:
try:
os.chown(fname, file_stat.st_uid, file_stat.st_gid)
except OSError: