80 lines
2.0 KiB
Python
80 lines
2.0 KiB
Python
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
|