EMailed label return generation (alpha)
This commit is contained in:
+45
@@ -0,0 +1,45 @@
|
||||
"""
|
||||
JIRA's Description field comes back as Atlassian Document Format (ADF) -
|
||||
a nested JSON tree, not plain text. This walks it and extracts readable
|
||||
text, since all we need here is "what did the staff member write about
|
||||
what boxes are needed", not full document fidelity.
|
||||
|
||||
Degrades gracefully on node types it doesn't know (tables, mentions,
|
||||
emoji, etc.) rather than raising - a partially-extracted description is
|
||||
far more useful than a crash on an edge case we didn't anticipate.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
# Block-level node types that should end with a line break once their
|
||||
# content has been extracted, so paragraphs/list items don't run together.
|
||||
_BLOCK_TYPES = {"paragraph", "listItem", "heading", "codeBlock", "blockquote"}
|
||||
|
||||
|
||||
def adf_to_text(adf: Optional[dict]) -> str:
|
||||
if not isinstance(adf, dict):
|
||||
return ""
|
||||
|
||||
lines: list[str] = []
|
||||
_walk(adf, lines)
|
||||
# Collapse the accumulated fragments, trim stray blank lines from
|
||||
# nested block boundaries.
|
||||
text = "".join(lines)
|
||||
return "\n".join(line.rstrip() for line in text.split("\n")).strip()
|
||||
|
||||
|
||||
def _walk(node: dict, lines: list[str]) -> None:
|
||||
node_type = node.get("type")
|
||||
|
||||
if node_type == "text":
|
||||
lines.append(node.get("text", ""))
|
||||
elif node_type == "hardBreak":
|
||||
lines.append("\n")
|
||||
|
||||
for child in node.get("content", []) or []:
|
||||
if isinstance(child, dict):
|
||||
_walk(child, lines)
|
||||
|
||||
if node_type in _BLOCK_TYPES:
|
||||
lines.append("\n")
|
||||
Reference in New Issue
Block a user