182 files
This commit is contained in:
@@ -15,8 +15,8 @@ from .const import (
|
||||
CONF_TASKS,
|
||||
DEFAULT_WARNING_DAYS,
|
||||
DOMAIN,
|
||||
GLOBAL_UNIQUE_ID,
|
||||
)
|
||||
from .helpers.aggregate import get_object_entries, merged_tasks
|
||||
from .helpers.schedule import Schedule, read_legacy_fields
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -73,8 +73,7 @@ def _build_export_object(
|
||||
# Merge static + Store dynamic data for each task
|
||||
rd = getattr(entry, "runtime_data", None)
|
||||
store = getattr(rd, "store", None) if rd else None
|
||||
static_tasks = entry.data.get(CONF_TASKS, {})
|
||||
tasks_data = store.merge_all_tasks(static_tasks) if store is not None else static_tasks
|
||||
tasks_data = merged_tasks(entry)
|
||||
ct_tasks = (coordinator_data or {}).get(CONF_TASKS, {})
|
||||
|
||||
tasks = []
|
||||
@@ -116,6 +115,9 @@ def _build_export_object(
|
||||
"entity_slug": tdata.get("entity_slug"),
|
||||
"adaptive_config": tdata.get("adaptive_config"),
|
||||
"checklist": tdata.get("checklist") or [],
|
||||
# In-cycle ticks (#73) — merged_tasks overlays them from the Store;
|
||||
# exporting them keeps half-done checklists across backup/restore.
|
||||
"checklist_progress": tdata.get("checklist_progress"),
|
||||
"schedule_time": tdata.get("schedule_time"),
|
||||
# v2.17+ / #83 task fields — persisted and user-facing, so a JSON
|
||||
# backup must restore them (same field-completeness contract as #67
|
||||
@@ -197,15 +199,11 @@ def _build_export_object(
|
||||
}
|
||||
|
||||
|
||||
def object_entries(hass: HomeAssistant, entry_ids: set[str] | None = None) -> list[ConfigEntry]:
|
||||
"""The maintenance OBJECT entries (never the global hub), optionally
|
||||
narrowed to a selection. Shared by every exporter so JSON/YAML/CSV apply
|
||||
the same selective-export filter. ``entry_ids=None`` means all objects."""
|
||||
return [
|
||||
entry
|
||||
for entry in hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.unique_id != GLOBAL_UNIQUE_ID and (entry_ids is None or entry.entry_id in entry_ids)
|
||||
]
|
||||
# The maintenance OBJECT entries (never the global hub). Shared by every
|
||||
# exporter so JSON/YAML/CSV apply the same selective-export filter — the
|
||||
# implementation lives in helpers.aggregate, this module keeps the name its
|
||||
# importers (csv_handler, doc_archive, WS adopt handlers) bind to.
|
||||
object_entries = get_object_entries
|
||||
|
||||
|
||||
def build_export_data(
|
||||
@@ -284,3 +282,49 @@ def export_maintenance_data(
|
||||
"""
|
||||
data = build_export_data(hass, include_history=include_history)
|
||||
return serialize_export(data, fmt)
|
||||
|
||||
|
||||
# Global settings the export deliberately leaves behind: HA user ids are
|
||||
# instance-bound (and the panel-access allowlist is security-relevant), and
|
||||
# the adopted-task stash is transient re-adopt state.
|
||||
_NON_PORTABLE_SETTINGS = ("admin_panel_user_ids", "adopted_task_notes")
|
||||
|
||||
|
||||
def build_settings_export(hass: HomeAssistant) -> dict[str, Any]:
|
||||
"""The SECOND export: the global entry's settings.
|
||||
|
||||
``build_export_data`` deliberately carries only objects — groups, saved
|
||||
views, vacation config, notification/budget settings and the feature
|
||||
toggles live on the global entry and export through here instead
|
||||
(2026-08 round-trip audit decision). Instance-bound keys are excluded
|
||||
(see ``_NON_PORTABLE_SETTINGS``).
|
||||
"""
|
||||
from .const import (
|
||||
CONF_GROUPS,
|
||||
CONF_SAVED_FILTER_VIEWS,
|
||||
CONF_VACATION_BUFFER_DAYS,
|
||||
CONF_VACATION_ENABLED,
|
||||
CONF_VACATION_END,
|
||||
CONF_VACATION_EXEMPT_TASK_IDS,
|
||||
CONF_VACATION_START,
|
||||
)
|
||||
from .helpers.global_options import get_global_options
|
||||
from .helpers.settings_registry import ALLOWED_SETTING_KEYS
|
||||
|
||||
opts = get_global_options(hass)
|
||||
settings: dict[str, Any] = {
|
||||
k: opts[k] for k in ALLOWED_SETTING_KEYS if k in opts and k not in _NON_PORTABLE_SETTINGS
|
||||
}
|
||||
# Structured sections with their own WS surfaces (not in the registry).
|
||||
for key in (
|
||||
CONF_GROUPS,
|
||||
CONF_SAVED_FILTER_VIEWS,
|
||||
CONF_VACATION_ENABLED,
|
||||
CONF_VACATION_START,
|
||||
CONF_VACATION_END,
|
||||
CONF_VACATION_BUFFER_DAYS,
|
||||
CONF_VACATION_EXEMPT_TASK_IDS,
|
||||
):
|
||||
if key in opts:
|
||||
settings[key] = opts[key]
|
||||
return {"version": 1, "global_settings": settings}
|
||||
|
||||
Reference in New Issue
Block a user