Server side implementation for interactive entry edits
This commit is contained in:
@@ -1,21 +1,22 @@
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
import xml.etree.ElementTree as ET
|
||||
from typing import Union
|
||||
|
||||
from .util import format_timestamp
|
||||
|
||||
from .command import Command
|
||||
from .delete_command import DeleteCommand
|
||||
from .stop_command import StopCommand
|
||||
|
||||
from .background_entry import BackgroundEntry
|
||||
from .entry.background_entry import BackgroundEntry
|
||||
from .entry import Entry
|
||||
from .io_buffer import IOBuffer
|
||||
from .parse_error_entry import ParseErrorEntry
|
||||
from .read_entry import ReadEntry
|
||||
from .reasoning_entry import ReasoningEntry
|
||||
from .repeat_entry import RepeatEntry
|
||||
from .single_entry import SingleEntry
|
||||
from .write_entry import WriteEntry
|
||||
from .entry.parse_error_entry import ParseErrorEntry
|
||||
from .entry.read_entry import ReadEntry
|
||||
from .entry.reasoning_entry import ReasoningEntry
|
||||
from .entry.repeat_entry import RepeatEntry
|
||||
from .entry.single_entry import SingleEntry
|
||||
from .entry.write_entry import WriteEntry
|
||||
|
||||
class ResponseParser:
|
||||
"""
|
||||
@@ -48,7 +49,7 @@ class ResponseParser:
|
||||
"""
|
||||
return self._io_buffer
|
||||
|
||||
def parse(self, xml: str) -> Union[Command, Entry]:
|
||||
def parse(self, timestamp: datetime, xml: str) -> Union[Command, Entry]:
|
||||
"""
|
||||
Parse XML response into a Command or Entry.
|
||||
|
||||
@@ -59,8 +60,7 @@ class ResponseParser:
|
||||
Command or Entry based on the XML content
|
||||
ParseErrorEntry for any parsing or validation errors
|
||||
"""
|
||||
entry_id = str(uuid.uuid4())
|
||||
timestamp = datetime.now()
|
||||
entry_id = format_timestamp(timestamp)
|
||||
|
||||
parser = ET.XMLPullParser(events=("start", "end"))
|
||||
parser.feed(xml)
|
||||
@@ -70,15 +70,15 @@ class ResponseParser:
|
||||
if event == "start":
|
||||
break
|
||||
except ET.ParseError as e:
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, f"Invalid XML: {str(e)}")
|
||||
return ParseErrorEntry(entry_id, xml, f"Invalid XML: {str(e)}")
|
||||
|
||||
try:
|
||||
if root.tag == 'delete':
|
||||
target_id = root.get('id')
|
||||
if not target_id:
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Delete command missing required 'id' attribute")
|
||||
return ParseErrorEntry(entry_id, xml, "Delete command missing required 'id' attribute")
|
||||
if len(root.attrib) > 1:
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Delete command should only have 'id' attribute")
|
||||
return ParseErrorEntry(entry_id, xml, "Delete command should only have 'id' attribute")
|
||||
return DeleteCommand(target_id)
|
||||
|
||||
elif root.tag == 'stop':
|
||||
@@ -86,46 +86,46 @@ class ResponseParser:
|
||||
|
||||
elif root.tag == 'background':
|
||||
if len(root) != 0 or root.attrib or root.text is None or root.text.strip() == '':
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Background entry requires (only) script content")
|
||||
return BackgroundEntry(entry_id, timestamp, root.text)
|
||||
return ParseErrorEntry(entry_id, xml, "Background entry requires (only) script content")
|
||||
return BackgroundEntry(entry_id, root.text)
|
||||
|
||||
elif root.tag == 'repeat':
|
||||
if len(root) != 0 or root.text is None or root.text.strip() == '':
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Repeat entry requires (only) script content")
|
||||
return ParseErrorEntry(entry_id, xml, "Repeat entry requires (only) script content")
|
||||
if len(root.attrib) > 2 or any(k not in ('timeout', 'limit') for k in root.attrib):
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Repeat entry only accepts 'timeout' and 'limit' attributes")
|
||||
return ParseErrorEntry(entry_id, xml, "Repeat entry only accepts 'timeout' and 'limit' attributes")
|
||||
timeout = root.get('timeout')
|
||||
limit = root.get('limit')
|
||||
timeout = float(timeout) if timeout is not None else None
|
||||
limit = int(limit) if limit is not None else None
|
||||
return RepeatEntry(entry_id, timestamp, root.text, timeout, limit)
|
||||
return RepeatEntry(entry_id, root.text, timeout, limit)
|
||||
|
||||
elif root.tag == 'single':
|
||||
if len(root) != 0 or root.text is None or root.text.strip() == '':
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Single entry requires (only) script content")
|
||||
return ParseErrorEntry(entry_id, xml, "Single entry requires (only) script content")
|
||||
if len(root.attrib) > 2 or any(k not in ('timeout', 'limit') for k in root.attrib):
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Single entry only accepts 'timeout' and 'limit' attributes")
|
||||
return ParseErrorEntry(entry_id, xml, "Single entry only accepts 'timeout' and 'limit' attributes")
|
||||
timeout = root.get('timeout')
|
||||
limit = root.get('limit')
|
||||
timeout = float(timeout) if timeout is not None else None
|
||||
limit = int(limit) if limit is not None else None
|
||||
return SingleEntry(entry_id, timestamp, root.text, timeout, limit)
|
||||
return SingleEntry(entry_id, root.text, timeout, limit)
|
||||
|
||||
elif root.tag == 'reasoning':
|
||||
if len(root) != 0 or root.attrib or root.text is None or root.text.strip() == '':
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Reasoning entry requires (only) text content")
|
||||
return ReasoningEntry(entry_id, timestamp, root.text)
|
||||
return ParseErrorEntry(entry_id, xml, "Reasoning entry requires (only) text content")
|
||||
return ReasoningEntry(entry_id, root.text)
|
||||
|
||||
elif root.tag == 'read_stdin':
|
||||
return ReadEntry(entry_id, timestamp, self._io_buffer)
|
||||
return ReadEntry(entry_id, self._io_buffer)
|
||||
|
||||
elif root.tag == 'write_stdout':
|
||||
if len(root) != 0 or root.attrib or root.text is None or root.text.strip() == '':
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, "Write stdout entry requires (only) text content")
|
||||
return WriteEntry(entry_id, timestamp, root.text, self._io_buffer)
|
||||
return ParseErrorEntry(entry_id, xml, "Write stdout entry requires (only) text content")
|
||||
return WriteEntry(entry_id, root.text, self._io_buffer)
|
||||
|
||||
else:
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, f"Unknown root element: {root.tag}")
|
||||
return ParseErrorEntry(entry_id, xml, f"Unknown root element: {root.tag}")
|
||||
|
||||
except Exception as e:
|
||||
return ParseErrorEntry(entry_id, timestamp, xml, f"Error parsing response: {str(e)}")
|
||||
return ParseErrorEntry(entry_id, xml, f"Error parsing response: {str(e)}")
|
||||
|
||||
Reference in New Issue
Block a user