simplified deserialisation
All checks were successful
Python CI / test (push) Successful in 1m40s
Lint / lint (push) Successful in 1m29s
Tests / test (3.11) (push) Successful in 1m48s
Tests / test (3.12) (push) Successful in 1m51s
Tests / test (3.13) (push) Successful in 1m46s
Tests / test (3.14) (push) Successful in 1m29s
All checks were successful
Python CI / test (push) Successful in 1m40s
Lint / lint (push) Successful in 1m29s
Tests / test (3.11) (push) Successful in 1m48s
Tests / test (3.12) (push) Successful in 1m51s
Tests / test (3.13) (push) Successful in 1m46s
Tests / test (3.14) (push) Successful in 1m29s
This commit is contained in:
parent
3a2d8b05db
commit
293b568772
@ -27,6 +27,34 @@ def _normalize_asset_path(image_path: str, asset_manager) -> str:
|
|||||||
return image_path
|
return image_path
|
||||||
|
|
||||||
|
|
||||||
|
def _deserialize_element(elem_data: Dict[str, Any]) -> BaseLayoutElement:
|
||||||
|
"""
|
||||||
|
Deserialize element data into the appropriate element type.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
elem_data: Dictionary containing serialized element data with 'type' key
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Deserialized element instance (ImageData, PlaceholderData, or TextBoxData)
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If element type is unknown
|
||||||
|
"""
|
||||||
|
elem_type = elem_data.get("type")
|
||||||
|
|
||||||
|
if elem_type == "image":
|
||||||
|
element = ImageData()
|
||||||
|
elif elem_type == "placeholder":
|
||||||
|
element = PlaceholderData()
|
||||||
|
elif elem_type == "textbox":
|
||||||
|
element = TextBoxData()
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unknown element type: {elem_type}")
|
||||||
|
|
||||||
|
element.deserialize(elem_data)
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
class Command(ABC):
|
class Command(ABC):
|
||||||
"""Abstract base class for all commands"""
|
"""Abstract base class for all commands"""
|
||||||
|
|
||||||
@ -94,24 +122,8 @@ class AddElementCommand(Command):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(data: Dict[str, Any], project) -> "AddElementCommand":
|
def deserialize(data: Dict[str, Any], project) -> "AddElementCommand":
|
||||||
"""Deserialize from dictionary"""
|
"""Deserialize from dictionary"""
|
||||||
# Reconstruct element from serialized data
|
element = _deserialize_element(data["element"])
|
||||||
elem_data = data["element"]
|
# Note: page_layout will be handled by the CommandHistory deserializer
|
||||||
elem_type = elem_data.get("type")
|
|
||||||
|
|
||||||
element: BaseLayoutElement
|
|
||||||
if elem_type == "image":
|
|
||||||
element = ImageData()
|
|
||||||
elif elem_type == "placeholder":
|
|
||||||
element = PlaceholderData()
|
|
||||||
elif elem_type == "textbox":
|
|
||||||
element = TextBoxData()
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Unknown element type: {elem_type}")
|
|
||||||
|
|
||||||
element.deserialize(elem_data)
|
|
||||||
|
|
||||||
# Note: We need to find the correct page_layout
|
|
||||||
# This will be handled by the CommandHistory deserializer
|
|
||||||
cmd = AddElementCommand(None, element)
|
cmd = AddElementCommand(None, element)
|
||||||
cmd.executed = data.get("executed", False)
|
cmd.executed = data.get("executed", False)
|
||||||
return cmd
|
return cmd
|
||||||
@ -154,21 +166,7 @@ class DeleteElementCommand(Command):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(data: Dict[str, Any], project) -> "DeleteElementCommand":
|
def deserialize(data: Dict[str, Any], project) -> "DeleteElementCommand":
|
||||||
"""Deserialize from dictionary"""
|
"""Deserialize from dictionary"""
|
||||||
elem_data = data["element"]
|
element = _deserialize_element(data["element"])
|
||||||
elem_type = elem_data.get("type")
|
|
||||||
|
|
||||||
element: BaseLayoutElement
|
|
||||||
if elem_type == "image":
|
|
||||||
element = ImageData()
|
|
||||||
elif elem_type == "placeholder":
|
|
||||||
element = PlaceholderData()
|
|
||||||
elif elem_type == "textbox":
|
|
||||||
element = TextBoxData()
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Unknown element type: {elem_type}")
|
|
||||||
|
|
||||||
element.deserialize(elem_data)
|
|
||||||
|
|
||||||
cmd = DeleteElementCommand(None, element)
|
cmd = DeleteElementCommand(None, element)
|
||||||
cmd.executed = data.get("executed", False)
|
cmd.executed = data.get("executed", False)
|
||||||
return cmd
|
return cmd
|
||||||
@ -206,21 +204,7 @@ class MoveElementCommand(Command):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(data: Dict[str, Any], project) -> "MoveElementCommand":
|
def deserialize(data: Dict[str, Any], project) -> "MoveElementCommand":
|
||||||
"""Deserialize from dictionary"""
|
"""Deserialize from dictionary"""
|
||||||
elem_data = data["element"]
|
element = _deserialize_element(data["element"])
|
||||||
elem_type = elem_data.get("type")
|
|
||||||
|
|
||||||
element: BaseLayoutElement
|
|
||||||
if elem_type == "image":
|
|
||||||
element = ImageData()
|
|
||||||
elif elem_type == "placeholder":
|
|
||||||
element = PlaceholderData()
|
|
||||||
elif elem_type == "textbox":
|
|
||||||
element = TextBoxData()
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Unknown element type: {elem_type}")
|
|
||||||
|
|
||||||
element.deserialize(elem_data)
|
|
||||||
|
|
||||||
return MoveElementCommand(element, tuple(data["old_position"]), tuple(data["new_position"]))
|
return MoveElementCommand(element, tuple(data["old_position"]), tuple(data["new_position"]))
|
||||||
|
|
||||||
|
|
||||||
@ -264,21 +248,7 @@ class ResizeElementCommand(Command):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(data: Dict[str, Any], project) -> "ResizeElementCommand":
|
def deserialize(data: Dict[str, Any], project) -> "ResizeElementCommand":
|
||||||
"""Deserialize from dictionary"""
|
"""Deserialize from dictionary"""
|
||||||
elem_data = data["element"]
|
element = _deserialize_element(data["element"])
|
||||||
elem_type = elem_data.get("type")
|
|
||||||
|
|
||||||
element: BaseLayoutElement
|
|
||||||
if elem_type == "image":
|
|
||||||
element = ImageData()
|
|
||||||
elif elem_type == "placeholder":
|
|
||||||
element = PlaceholderData()
|
|
||||||
elif elem_type == "textbox":
|
|
||||||
element = TextBoxData()
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Unknown element type: {elem_type}")
|
|
||||||
|
|
||||||
element.deserialize(elem_data)
|
|
||||||
|
|
||||||
return ResizeElementCommand(
|
return ResizeElementCommand(
|
||||||
element,
|
element,
|
||||||
tuple(data["old_position"]),
|
tuple(data["old_position"]),
|
||||||
@ -389,21 +359,7 @@ class RotateElementCommand(Command):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(data: Dict[str, Any], project) -> "RotateElementCommand":
|
def deserialize(data: Dict[str, Any], project) -> "RotateElementCommand":
|
||||||
"""Deserialize from dictionary"""
|
"""Deserialize from dictionary"""
|
||||||
elem_data = data["element"]
|
element = _deserialize_element(data["element"])
|
||||||
elem_type = elem_data.get("type")
|
|
||||||
|
|
||||||
element: BaseLayoutElement
|
|
||||||
if elem_type == "image":
|
|
||||||
element = ImageData()
|
|
||||||
elif elem_type == "placeholder":
|
|
||||||
element = PlaceholderData()
|
|
||||||
elif elem_type == "textbox":
|
|
||||||
element = TextBoxData()
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Unknown element type: {elem_type}")
|
|
||||||
|
|
||||||
element.deserialize(elem_data)
|
|
||||||
|
|
||||||
return RotateElementCommand(element, data["old_rotation"], data["new_rotation"])
|
return RotateElementCommand(element, data["old_rotation"], data["new_rotation"])
|
||||||
|
|
||||||
|
|
||||||
@ -487,23 +443,12 @@ class AlignElementsCommand(Command):
|
|||||||
"""Deserialize from dictionary"""
|
"""Deserialize from dictionary"""
|
||||||
changes = []
|
changes = []
|
||||||
for change_data in data.get("changes", []):
|
for change_data in data.get("changes", []):
|
||||||
elem_data = change_data["element"]
|
try:
|
||||||
elem_type = elem_data.get("type")
|
element = _deserialize_element(change_data["element"])
|
||||||
|
|
||||||
element: BaseLayoutElement
|
|
||||||
if elem_type == "image":
|
|
||||||
element = ImageData()
|
|
||||||
elif elem_type == "placeholder":
|
|
||||||
element = PlaceholderData()
|
|
||||||
elif elem_type == "textbox":
|
|
||||||
element = TextBoxData()
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
element.deserialize(elem_data)
|
|
||||||
old_position = tuple(change_data["old_position"])
|
old_position = tuple(change_data["old_position"])
|
||||||
changes.append((element, old_position))
|
changes.append((element, old_position))
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
return AlignElementsCommand(changes)
|
return AlignElementsCommand(changes)
|
||||||
|
|
||||||
|
|
||||||
@ -549,24 +494,13 @@ class ResizeElementsCommand(Command):
|
|||||||
"""Deserialize from dictionary"""
|
"""Deserialize from dictionary"""
|
||||||
changes = []
|
changes = []
|
||||||
for change_data in data.get("changes", []):
|
for change_data in data.get("changes", []):
|
||||||
elem_data = change_data["element"]
|
try:
|
||||||
elem_type = elem_data.get("type")
|
element = _deserialize_element(change_data["element"])
|
||||||
|
|
||||||
element: BaseLayoutElement
|
|
||||||
if elem_type == "image":
|
|
||||||
element = ImageData()
|
|
||||||
elif elem_type == "placeholder":
|
|
||||||
element = PlaceholderData()
|
|
||||||
elif elem_type == "textbox":
|
|
||||||
element = TextBoxData()
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
element.deserialize(elem_data)
|
|
||||||
old_position = tuple(change_data["old_position"])
|
old_position = tuple(change_data["old_position"])
|
||||||
old_size = tuple(change_data["old_size"])
|
old_size = tuple(change_data["old_size"])
|
||||||
changes.append((element, old_position, old_size))
|
changes.append((element, old_position, old_size))
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
return ResizeElementsCommand(changes)
|
return ResizeElementsCommand(changes)
|
||||||
|
|
||||||
|
|
||||||
@ -609,21 +543,7 @@ class ChangeZOrderCommand(Command):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def deserialize(data: Dict[str, Any], project) -> "ChangeZOrderCommand":
|
def deserialize(data: Dict[str, Any], project) -> "ChangeZOrderCommand":
|
||||||
"""Deserialize from dictionary"""
|
"""Deserialize from dictionary"""
|
||||||
elem_data = data["element"]
|
element = _deserialize_element(data["element"])
|
||||||
elem_type = elem_data.get("type")
|
|
||||||
|
|
||||||
element: BaseLayoutElement
|
|
||||||
if elem_type == "image":
|
|
||||||
element = ImageData()
|
|
||||||
elif elem_type == "placeholder":
|
|
||||||
element = PlaceholderData()
|
|
||||||
elif elem_type == "textbox":
|
|
||||||
element = TextBoxData()
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Unknown element type: {elem_type}")
|
|
||||||
|
|
||||||
element.deserialize(elem_data)
|
|
||||||
|
|
||||||
return ChangeZOrderCommand(
|
return ChangeZOrderCommand(
|
||||||
None, element, data["old_index"], data["new_index"] # page_layout will be set by CommandHistory
|
None, element, data["old_index"], data["new_index"] # page_layout will be set by CommandHistory
|
||||||
)
|
)
|
||||||
|
|||||||
@ -734,6 +734,7 @@ class TestCommandHistory:
|
|||||||
"""Test deserializing unknown command type returns None and continues"""
|
"""Test deserializing unknown command type returns None and continues"""
|
||||||
history = CommandHistory()
|
history = CommandHistory()
|
||||||
mock_project = Mock()
|
mock_project = Mock()
|
||||||
|
mock_project.pages = []
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"undo_stack": [
|
"undo_stack": [
|
||||||
@ -797,6 +798,7 @@ class TestCommandHistory:
|
|||||||
|
|
||||||
# Deserialize
|
# Deserialize
|
||||||
mock_project = Mock()
|
mock_project = Mock()
|
||||||
|
mock_project.pages = []
|
||||||
new_history = CommandHistory()
|
new_history = CommandHistory()
|
||||||
new_history.deserialize(data, mock_project)
|
new_history.deserialize(data, mock_project)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user