96 lines
2.2 KiB
Python
96 lines
2.2 KiB
Python
from copy import copy, deepcopy
|
|
import json
|
|
from datetime import datetime
|
|
|
|
|
|
def parse_iso_date(date: str) -> datetime:
|
|
return datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.000%z')
|
|
|
|
|
|
def fmt_iso_date(date: datetime) -> str:
|
|
return date.strftime('%Y-%m-%dT%H:%M:%S.000%z')
|
|
|
|
|
|
PROPERTY_DEFAULT = {
|
|
int: 'LONG',
|
|
str: 'STRING',
|
|
float: 'DOUBLE',
|
|
}
|
|
|
|
"""
|
|
type: [external, simple, complex]
|
|
content-type[complex]:
|
|
"""
|
|
|
|
PROPERTY_TYPES = {
|
|
'BINARY': {
|
|
'type': 'complex',
|
|
'content-type': 'jcr-value/binary'
|
|
},
|
|
'BOOLEAN': {
|
|
'type': 'simple',
|
|
'serialize': json.dumps
|
|
},
|
|
'DATE': {
|
|
'type': 'complex',
|
|
'content-type': 'jcr-value/date',
|
|
'serialize': fmt_iso_date,
|
|
'deserialize': parse_iso_date
|
|
},
|
|
'DECIMAL': {
|
|
'type': 'complex',
|
|
'content-type': 'jcr-value/decimal',
|
|
'serialize': str,
|
|
},
|
|
'DOUBLE': {
|
|
'type': 'simple',
|
|
'serialize': str,
|
|
},
|
|
'LONG': {
|
|
'type': 'simple',
|
|
'serialize': str,
|
|
},
|
|
'NAME': {},
|
|
'PATH': {},
|
|
'REFERENCE': {},
|
|
'STRING': {
|
|
'type': 'simple',
|
|
'serialize': json.dumps,
|
|
'deserialize': json.loads
|
|
},
|
|
'UNDEFINED': {},
|
|
'URI': {},
|
|
'WEAKREFERENCE': {},
|
|
}
|
|
|
|
|
|
class Property:
|
|
pass
|
|
|
|
|
|
class Node:
|
|
def __init__(self, path: str, primary_type: str, is_new: bool = True, data: dict = None):
|
|
# TODO validate path and type
|
|
self.path = path
|
|
self.data = data or {}
|
|
self.data['jcr:primaryType'] = primary_type
|
|
self.original_path = copy(path)
|
|
self.original_data = deepcopy(data)
|
|
self.is_new = is_new
|
|
|
|
def _build_diff(self) -> str:
|
|
if self.is_new:
|
|
return self._build_diff_new()
|
|
else:
|
|
return self._build_diff_change()
|
|
|
|
def _build_diff_new(self) -> str:
|
|
data = []
|
|
ptype_dict = {'jcr:primaryType': self.data['jcr:primaryType']}
|
|
data.append(f'+{self.path} : {json.dumps(ptype_dict)}')
|
|
for key, value in self.data:
|
|
if key == 'jcr:primaryType':
|
|
continue # primaryType is handled differently
|
|
data.append(f'^{self.path}/{key} : {json.dumps(value)}')
|
|
return '\n'.join(data) + '\n'
|