Merge branch 'refactor/backend-architecture' into development
This commit is contained in:
84
api/app/features/memoir/memoir_images/parser.py
Normal file
84
api/app/features/memoir/memoir_images/parser.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
from .schema import IMAGE_STATUS_PENDING
|
||||
|
||||
PLACEHOLDER_RE = re.compile(
|
||||
r"\{\{\{\{IMAGE:(.*?)\}\}\}\}|\{\{IMAGE:(.*?)\}\}",
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def parse_image_placeholders(content: str, max_images: int) -> list[dict[str, Any]]:
|
||||
items: list[dict[str, Any]] = []
|
||||
for match in PLACEHOLDER_RE.finditer(content or ""):
|
||||
description = (match.group(1) or match.group(2) or "").strip()
|
||||
if not description:
|
||||
continue
|
||||
items.append(
|
||||
{
|
||||
"index": len(items),
|
||||
"description": description,
|
||||
"placeholder": match.group(0),
|
||||
"start_offset": match.start(),
|
||||
}
|
||||
)
|
||||
if max_images is not None and len(items) >= max_images:
|
||||
break
|
||||
return items
|
||||
|
||||
|
||||
def build_initial_image_assets(
|
||||
placeholders: list[dict[str, Any]],
|
||||
provider: str,
|
||||
style: str,
|
||||
size: str,
|
||||
now_iso: str,
|
||||
) -> list[dict[str, Any]]:
|
||||
return [
|
||||
{
|
||||
"index": item["index"],
|
||||
"placeholder": item["placeholder"],
|
||||
"description": item["description"],
|
||||
"prompt": None,
|
||||
"url": None,
|
||||
"status": IMAGE_STATUS_PENDING,
|
||||
"provider": provider,
|
||||
"style": style,
|
||||
"size": size,
|
||||
"error": None,
|
||||
"created_at": now_iso,
|
||||
"updated_at": now_iso,
|
||||
}
|
||||
for item in placeholders
|
||||
]
|
||||
|
||||
|
||||
def split_narrative_to_sections(narrative: str) -> list[dict[str, Any]]:
|
||||
"""
|
||||
将带 {{IMAGE:...}} 占位符的正文按占位符拆成多段。
|
||||
返回 list[dict],每项含:
|
||||
- content: 本段纯文本(不含占位符)
|
||||
- placeholder_info: 本段后的配图占位信息,或 None(最后一段无图)
|
||||
"""
|
||||
if not (narrative or narrative.strip()):
|
||||
return []
|
||||
placeholders = parse_image_placeholders(narrative, max_images=None)
|
||||
sections: list[dict[str, Any]] = []
|
||||
for i in range(len(placeholders) + 1):
|
||||
if i == 0:
|
||||
start = 0
|
||||
else:
|
||||
prev = placeholders[i - 1]
|
||||
start = prev["start_offset"] + len(prev["placeholder"])
|
||||
if i < len(placeholders):
|
||||
end = placeholders[i]["start_offset"]
|
||||
placeholder_info = placeholders[i]
|
||||
else:
|
||||
end = len(narrative)
|
||||
placeholder_info = None
|
||||
content = narrative[start:end]
|
||||
if isinstance(content, str):
|
||||
content = content.strip()
|
||||
sections.append({"content": content or "", "placeholder_info": placeholder_info})
|
||||
return sections
|
||||
Reference in New Issue
Block a user