Include configuration name and vendor in generated wiki footers.

This commit is contained in:
mihailkudravcev
2026-07-24 09:46:44 +03:00
parent 046a9a51e3
commit f9e8380348
6 changed files with 145 additions and 57 deletions
+88 -27
View File
@@ -1,16 +1,34 @@
"""Read 1C configuration version from dump tree."""
"""Read 1C configuration identity from dump tree."""
from __future__ import annotations
import re
from dataclasses import dataclass
from pathlib import Path
_VERSION_TAG = re.compile(r"<Version>([^<]+)</Version>")
_NAME_TAG = re.compile(
r"<Name>([^<]+)</Name>",
_NAME_TAG = re.compile(r"<Name>([^<]+)</Name>")
_VENDOR_TAG = re.compile(r"<Vendor>([^<]*)</Vendor>")
_SYN_RE = re.compile(
r"<Synonym>\s*<v8:item>\s*<v8:lang>ru</v8:lang>\s*<v8:content>(.*?)</v8:content>",
re.DOTALL,
)
@dataclass(frozen=True)
class ConfigIdentity:
"""Configuration name / version / vendor for wiki footers."""
version: str
name: str | None = None # technical Name
synonym: str | None = None # Synonym ru
vendor: str | None = None
@property
def display_name(self) -> str | None:
return self.synonym or self.name
def config_root_from_src(src_root: Path) -> Path:
"""src/ → configuration root (parent that usually has VERSION + Configuration.xml)."""
src_root = Path(src_root).resolve()
@@ -19,46 +37,89 @@ def config_root_from_src(src_root: Path) -> Path:
return src_root
def _configuration_xml(src_root: Path) -> Path | None:
src_root = Path(src_root)
root = config_root_from_src(src_root)
for xml_path in (
root / "src" / "Configuration.xml",
src_root / "Configuration.xml",
root / "Configuration.xml",
):
if xml_path.is_file():
return xml_path
return None
def _xml_unescape(s: str) -> str:
return (
s.replace("&lt;", "<")
.replace("&gt;", ">")
.replace("&amp;", "&")
.replace("&quot;", '"')
.replace("&apos;", "'")
)
def read_config_version(src_root: Path) -> str:
"""
Resolve configuration version.
Priority:
1. <config_root>/VERSION
2. <config_root>/src/Configuration.xml → <Version>
3. <src_root>/Configuration.xml → <Version>
2. Configuration.xml → <Version>
"""
return read_config_identity(src_root).version
def read_config_name(src_root: Path) -> str | None:
"""Technical configuration Name from Configuration.xml."""
return read_config_identity(src_root).name
def read_config_identity(src_root: Path) -> ConfigIdentity:
"""Version, Name, Synonym (ru), Vendor from dump."""
src_root = Path(src_root)
root = config_root_from_src(src_root)
version = "unknown"
version_file = root / "VERSION"
if version_file.is_file():
text = version_file.read_text(encoding="utf-8-sig", errors="ignore").strip()
if text:
return text.splitlines()[0].strip()
version = text.splitlines()[0].strip()
for xml_path in (
root / "src" / "Configuration.xml",
src_root / "Configuration.xml",
root / "Configuration.xml",
):
if not xml_path.is_file():
continue
name: str | None = None
synonym: str | None = None
vendor: str | None = None
xml_path = _configuration_xml(src_root)
if xml_path is not None:
raw = xml_path.read_text(encoding="utf-8-sig", errors="ignore")
m = _VERSION_TAG.search(raw)
# Prefer Properties block to avoid accidental matches deeper in the file
props = raw
if "<Properties>" in raw and "</Properties>" in raw:
props = raw.split("<Properties>", 1)[1].split("</Properties>", 1)[0]
if version == "unknown":
m = _VERSION_TAG.search(props)
if m:
version = m.group(1).strip()
m = _NAME_TAG.search(props)
if m:
return m.group(1).strip()
name = m.group(1).strip() or None
return "unknown"
m = _SYN_RE.search(props)
if m:
synonym = _xml_unescape(m.group(1).strip()) or None
m = _VENDOR_TAG.search(props)
if m:
vendor = _xml_unescape(m.group(1).strip()) or None
def read_config_name(src_root: Path) -> str | None:
src_root = Path(src_root)
root = config_root_from_src(src_root)
xml_path = root / "src" / "Configuration.xml"
if not xml_path.is_file():
xml_path = src_root / "Configuration.xml"
if not xml_path.is_file():
return None
raw = xml_path.read_text(encoding="utf-8-sig", errors="ignore")
m = _NAME_TAG.search(raw)
return m.group(1).strip() if m else None
return ConfigIdentity(
version=version or "unknown",
name=name,
synonym=synonym,
vendor=vendor,
)