Complete name-first 1C adapter saved-state support
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""Pure reverse index for 1C common-command group membership."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from collections.abc import Iterable, Mapping
|
||||
from typing import Any
|
||||
|
||||
from .payload import decode_payload_lossless, parse_brace_text
|
||||
|
||||
|
||||
_GUID_RE = re.compile(
|
||||
r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
||||
)
|
||||
|
||||
|
||||
def _tree_item_at_path(tree: Any, path: tuple[int, ...]) -> Any | None:
|
||||
node = tree
|
||||
for index in path:
|
||||
if not isinstance(node, dict) or not isinstance(node.get("items"), list):
|
||||
return None
|
||||
items = node["items"]
|
||||
if index < 0 or index >= len(items):
|
||||
return None
|
||||
node = items[index]
|
||||
return node
|
||||
|
||||
|
||||
def _tree_scalar_at_path(tree: Any, path: tuple[int, ...]) -> str:
|
||||
node = _tree_item_at_path(tree, path)
|
||||
if isinstance(node, dict) and node.get("type") in {"atom", "string"}:
|
||||
return str(node.get("value") or "")
|
||||
return ""
|
||||
|
||||
|
||||
def common_command_group_guid(tree: Any) -> str | None:
|
||||
"""Return the group GUID stored in an observed CommonCommand Config tree."""
|
||||
body = _tree_item_at_path(tree, (1, 1, 2))
|
||||
group_guid = _tree_scalar_at_path(body, (7, 1)).strip().lower()
|
||||
return group_guid if _GUID_RE.fullmatch(group_guid) else None
|
||||
|
||||
|
||||
def parse_common_command_tree(data: bytes) -> Any | None:
|
||||
"""Decode a CommonCommand payload without raising on unsupported data."""
|
||||
try:
|
||||
decoded = decode_payload_lossless(data)
|
||||
text = decoded.get("text")
|
||||
if not text or "{" not in text:
|
||||
return None
|
||||
return parse_brace_text(text)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def index_common_command_groups(
|
||||
commands: Iterable[Mapping[str, Any]],
|
||||
payloads: Mapping[str, bytes],
|
||||
) -> dict[str, Any]:
|
||||
"""Build ``CommandGroup GUID -> CommonCommand rows`` from Config payloads."""
|
||||
command_rows = [dict(item) for item in commands]
|
||||
normalized_payloads = {str(key).strip().lower(): value for key, value in payloads.items()}
|
||||
groups: dict[str, list[dict[str, Any]]] = {}
|
||||
source_missing = 0
|
||||
undecodable = 0
|
||||
unassigned = 0
|
||||
|
||||
for item in command_rows:
|
||||
guid = str(item.get("guid") or "").strip().lower()
|
||||
data = normalized_payloads.get(guid)
|
||||
if not data:
|
||||
source_missing += 1
|
||||
continue
|
||||
tree = parse_common_command_tree(data)
|
||||
if tree is None:
|
||||
undecodable += 1
|
||||
continue
|
||||
group_guid = common_command_group_guid(tree)
|
||||
if group_guid is None:
|
||||
unassigned += 1
|
||||
continue
|
||||
groups.setdefault(group_guid, []).append(item)
|
||||
|
||||
return {
|
||||
"groups": groups,
|
||||
"scanned": len(command_rows),
|
||||
"source_missing": source_missing,
|
||||
"undecodable": undecodable,
|
||||
"unassigned": unassigned,
|
||||
}
|
||||
Reference in New Issue
Block a user