117 lines
4.1 KiB
Python
117 lines
4.1 KiB
Python
# Copyright (c) 2025 Patrick Motsch
|
|
# All rights reserved.
|
|
"""
|
|
Document reference models for typed document references in workflows.
|
|
"""
|
|
|
|
from typing import List, Optional
|
|
from pydantic import BaseModel, Field
|
|
from modules.shared.i18nRegistry import i18nModel
|
|
|
|
|
|
class DocumentReference(BaseModel):
|
|
"""Base class for document references"""
|
|
pass
|
|
|
|
|
|
@i18nModel("Dokumentlisten-Referenz")
|
|
class DocumentListReference(DocumentReference):
|
|
"""Reference to a document list via message label"""
|
|
messageId: Optional[str] = Field(
|
|
None,
|
|
description="Optional message ID for cross-round references",
|
|
json_schema_extra={"label": "Nachrichten-ID"},
|
|
)
|
|
label: str = Field(
|
|
description="Document list label",
|
|
json_schema_extra={"label": "Bezeichnung"},
|
|
)
|
|
|
|
def to_string(self) -> str:
|
|
"""Convert to string format: docList:messageId:label or docList:label"""
|
|
if self.messageId:
|
|
return f"docList:{self.messageId}:{self.label}"
|
|
return f"docList:{self.label}"
|
|
|
|
|
|
@i18nModel("Dokumentelement-Referenz")
|
|
class DocumentItemReference(DocumentReference):
|
|
"""Reference to a specific document item"""
|
|
documentId: str = Field(
|
|
description="Document ID",
|
|
json_schema_extra={"label": "Dokument-ID"},
|
|
)
|
|
fileName: Optional[str] = Field(
|
|
None,
|
|
description="Optional file name",
|
|
json_schema_extra={"label": "Dateiname"},
|
|
)
|
|
|
|
def to_string(self) -> str:
|
|
"""Convert to string format: docItem:documentId:fileName or docItem:documentId"""
|
|
if self.fileName:
|
|
return f"docItem:{self.documentId}:{self.fileName}"
|
|
return f"docItem:{self.documentId}"
|
|
|
|
|
|
@i18nModel("Dokumentreferenz-Liste")
|
|
class DocumentReferenceList(BaseModel):
|
|
"""List of document references with conversion methods"""
|
|
references: List[DocumentReference] = Field(
|
|
default_factory=list,
|
|
description="List of document references",
|
|
json_schema_extra={"label": "Referenzen"},
|
|
)
|
|
|
|
def to_string_list(self) -> List[str]:
|
|
"""Convert all references to string list"""
|
|
return [ref.to_string() for ref in self.references]
|
|
|
|
@classmethod
|
|
def from_string_list(cls, stringList: List[str]) -> "DocumentReferenceList":
|
|
"""Parse string list to typed references
|
|
|
|
Supports formats:
|
|
- docList:label
|
|
- docList:messageId:label
|
|
- docItem:documentId
|
|
- docItem:documentId:fileName
|
|
"""
|
|
references = []
|
|
|
|
for refStr in stringList:
|
|
if not refStr or not isinstance(refStr, str):
|
|
continue
|
|
|
|
refStr = refStr.strip()
|
|
|
|
# Parse docList: references
|
|
if refStr.startswith("docList:"):
|
|
parts = refStr[8:].split(":", 1) # Remove "docList:" prefix
|
|
if len(parts) == 2:
|
|
# docList:messageId:label
|
|
messageId, label = parts
|
|
references.append(DocumentListReference(messageId=messageId, label=label))
|
|
elif len(parts) == 1 and parts[0]:
|
|
# docList:label
|
|
references.append(DocumentListReference(label=parts[0]))
|
|
|
|
# Parse docItem: references
|
|
elif refStr.startswith("docItem:"):
|
|
parts = refStr[8:].split(":", 1) # Remove "docItem:" prefix
|
|
if len(parts) == 2:
|
|
# docItem:documentId:fileName
|
|
documentId, fileName = parts
|
|
references.append(DocumentItemReference(documentId=documentId, fileName=fileName))
|
|
elif len(parts) == 1 and parts[0]:
|
|
# docItem:documentId
|
|
references.append(DocumentItemReference(documentId=parts[0]))
|
|
|
|
# Unknown format - skip or log warning
|
|
else:
|
|
# Try to parse as simple string (backward compatibility)
|
|
# Assume it's a label if it doesn't match known patterns
|
|
if refStr:
|
|
references.append(DocumentListReference(label=refStr))
|
|
|
|
return cls(references=references)
|