Classify appearance templates by XML root
This commit is contained in:
@@ -172,7 +172,7 @@ ONEC_TEMPLATE_PLATFORM_TYPES = [
|
||||
"xml_type": "DataCompositionAppearanceTemplate",
|
||||
"decoder": "data_composition_appearance",
|
||||
"status": "not_implemented",
|
||||
"aliases": ["МакетОформленияКомпоновкиДанных", "DataCompositionAppearanceTemplate"],
|
||||
"aliases": ["МакетОформленияКомпоновкиДанных", "DataCompositionAppearanceTemplate", "AppearanceTemplate"],
|
||||
},
|
||||
{
|
||||
"id": "external_component",
|
||||
@@ -4087,6 +4087,7 @@ def declared_template_platform_type_from_part(part: dict[str, Any]) -> dict[str,
|
||||
classification.get("template_type"),
|
||||
classification.get("platform_type_id"),
|
||||
classification.get("platform_type"),
|
||||
classification.get("xml_root"),
|
||||
]
|
||||
)
|
||||
candidates.extend(classification.get("strings_sample") or [])
|
||||
@@ -4101,7 +4102,7 @@ def template_type_candidates_from_features(features: dict[str, Any], content_par
|
||||
candidates: list[dict[str, Any]] = []
|
||||
declared = normalize_onec_template_platform_type(features.get("declared_platform_type_id") or features.get("declared_platform_type"))
|
||||
if declared:
|
||||
declared.update({"confidence": "high", "evidence": ["TemplateType metadata"]})
|
||||
declared.update({"confidence": "high", "evidence": [str(features.get("declared_platform_type_evidence") or "TemplateType metadata")]})
|
||||
candidates.append(declared)
|
||||
|
||||
def append_candidate(candidate: dict[str, Any]) -> None:
|
||||
@@ -4140,6 +4141,14 @@ def public_template_summary(
|
||||
(template_type for template_type in (declared_template_platform_type_from_part(part) for part in parts) if template_type),
|
||||
None,
|
||||
)
|
||||
declared_type_evidence = "TemplateType metadata"
|
||||
if any(
|
||||
normalize_onec_template_platform_type(
|
||||
((part.get("classification") or {}).get("xml_root") if isinstance(part.get("classification"), dict) else None)
|
||||
)
|
||||
for part in parts
|
||||
):
|
||||
declared_type_evidence = "payload XML root"
|
||||
features = {
|
||||
"tabular_document": any(((part.get("features") or {}).get("tabular_document")) for part in content_parts),
|
||||
"html": any(((part.get("features") or {}).get("html")) for part in content_parts),
|
||||
@@ -4149,6 +4158,7 @@ def public_template_summary(
|
||||
"declared_platform_type": declared_platform_type.get("name"),
|
||||
"declared_platform_type_id": declared_platform_type.get("id"),
|
||||
"declared_platform_xml_type": declared_platform_type.get("xml_type"),
|
||||
"declared_platform_type_evidence": declared_type_evidence,
|
||||
}
|
||||
if declared_platform_type
|
||||
else {}
|
||||
|
||||
@@ -7,6 +7,9 @@ import hashlib
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
|
||||
XML_ROOT_RE = re.compile(r"^\s*(?:<\?xml[^>]*>\s*)?<([A-Za-z_][\w.-]*(?::[A-Za-z_][\w.-]*)?)\b")
|
||||
|
||||
from .payload import collect_strings, decode_payload_lossless, encode_text, parse_brace_text, root_signature, scalar
|
||||
|
||||
|
||||
@@ -483,6 +486,11 @@ def classify_payload(data: bytes, *, include_text: bool = False, include_tree: b
|
||||
stream["text"] = declared_prefix["text"]
|
||||
stream["text_preview"] = str(declared_prefix["text"] or "").replace("\x00", "")[:500]
|
||||
text = decoded.get("text")
|
||||
xml_root = None
|
||||
if isinstance(text, str):
|
||||
match = XML_ROOT_RE.match(text.lstrip("\ufeff"))
|
||||
if match:
|
||||
xml_root = match.group(1).rsplit(":", 1)[-1]
|
||||
tree = None
|
||||
root = None
|
||||
base64_decoded: list[dict[str, Any]] = []
|
||||
@@ -505,6 +513,7 @@ def classify_payload(data: bytes, *, include_text: bool = False, include_tree: b
|
||||
"sha1": sha1_hex(data),
|
||||
"payload_sha1": sha1_hex(bytes(payload)),
|
||||
"markers": markers,
|
||||
**({"xml_root": xml_root} if xml_root else {}),
|
||||
"root": root,
|
||||
"role": classify_role(root_marker, markers, text, stream_blocks, base64_decoded),
|
||||
"strings_sample": strings_sample,
|
||||
|
||||
@@ -6949,6 +6949,16 @@ def test_public_template_summary_uses_declared_template_type_alias() -> None:
|
||||
assert summary["template_type_candidates"][0]["confidence"] == "high"
|
||||
|
||||
|
||||
def test_public_template_summary_recognizes_live_appearance_xml_root() -> None:
|
||||
summary = adapter_server.public_template_summary(
|
||||
[{"role": "content", "classification": {"xml_root": "AppearanceTemplate"}, "features": {}}]
|
||||
)
|
||||
|
||||
assert summary["platform_type"] == "Макет оформления компоновки данных"
|
||||
assert summary["template_type_candidates"][0]["id"] == "data_composition_appearance_template"
|
||||
assert summary["template_type_candidates"][0]["evidence"] == ["payload XML root"]
|
||||
|
||||
|
||||
def test_moxel_template_artifact_kind_tracks_coordinate_hint_schema() -> None:
|
||||
assert adapter_server.MOXEL_TEMPLATE_ARTIFACT_KIND == "template_part_moxel_v11"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user