from typing import Dict, List, Union, TYPE_CHECKING from logging import Logger import json if TYPE_CHECKING: from .connection import Connection from .simplenode import SimpleNode LOGGER = Logger(__name__) def _build_patch_set(change: dict) -> str: line = ['^', change['path'], ' : '] if change['type'] in ('Long', 'Float', 'Boolean', 'String'): line.append(json.dumps(change['value'])) else: raise ValueError(f'Type {change["type"]!r} is currently not supported!') return ''.join(line) def _build_patch_delete(change: dict) -> str: return f'-{change["path"]} : ' _patch_builders = { 'set': _build_patch_set, 'delete': _build_patch_delete, } class PatchBuilder: changes: List[Dict] dry_run: bool def __init__(self, connection: 'Connection'): self.connection = connection self.changes = [] self.saved = False self.dry_run = False def set_value(self, path: str, value: Union[str, int, float], value_type: str): self.changes.append({ 'action': 'set', 'path': path, 'value': value, 'type': value_type }) def delete_node(self, path: str): self.changes.append({ 'action': 'delete', 'path': path }) def save(self): patch = [] for entry in self.changes: patch.append(_patch_builders[entry['action']](entry)) patch = list(filter(None, patch)) if len(patch) == 0: LOGGER.warning("No patch to submit") return if self.dry_run: print('\n'.join(patch)) else: self.connection.apply_diff('\n'.join(patch)) self.saved = True def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): if not self.saved: LOGGER.warning("Patch not saved") if self.connection: self.connection._patch_builder = None