Files
llm/scripts/one_c_its_platform.py
T

116 lines
4.0 KiB
Python

from __future__ import annotations
import re
import urllib.parse
from typing import Any
PLATFORM_DOC_RE = re.compile(r"/db/(v(?:8|83|85)\d*doc)(?:/|$)", flags=re.IGNORECASE)
BOOKMARK_PATH_RE = re.compile(r"/bookmark/([^/]+)/([^/?#]+)", flags=re.IGNORECASE)
CONTENT_PATH_RE = re.compile(r"/content/(-?\d+)/(?:hdoc|\d+)", flags=re.IGNORECASE)
HASH_BOOKMARK_RE = re.compile(r"^#?bookmark:([^:]+):([^:]+)$", flags=re.IGNORECASE)
HASH_CONTENT_RE = re.compile(r"^#?content:([^:]+):([^:]+)$", flags=re.IGNORECASE)
def platform_doc_id_from_url(url: str) -> str | None:
match = PLATFORM_DOC_RE.search(urllib.parse.urlparse(url).path)
return match.group(1).lower() if match else None
def platform_version_from_doc_id(doc_id: str | None) -> str | None:
if not doc_id:
return None
doc_id = doc_id.lower()
if doc_id == "v8doc":
return "8.x"
match = re.fullmatch(r"v83(\d+)doc", doc_id)
if match:
patch = int(match.group(1))
return f"8.3.{patch}"
match = re.fullmatch(r"v85(\d+)doc", doc_id)
if match:
patch = int(match.group(1))
return f"8.5.{patch}"
match = re.fullmatch(r"v8(\d+)doc", doc_id)
if match:
patch = int(match.group(1))
return f"8.{patch}"
return None
def platform_version_from_url(url: str) -> str | None:
return platform_version_from_doc_id(platform_doc_id_from_url(url))
def parse_doc_coordinate(url: str) -> dict[str, str | None]:
parsed = urllib.parse.urlparse(url)
path = parsed.path
fragment = urllib.parse.unquote(parsed.fragment or "")
coordinate: dict[str, str | None] = {
"platform_doc_id": platform_doc_id_from_url(url),
"platform_version": platform_version_from_url(url),
"doc_book": None,
"doc_bookmark": None,
"doc_content_id": None,
"doc_coordinate": None,
}
bookmark = BOOKMARK_PATH_RE.search(path)
if bookmark:
coordinate["doc_book"] = bookmark.group(1)
coordinate["doc_bookmark"] = bookmark.group(2)
else:
hash_bookmark = HASH_BOOKMARK_RE.match(fragment)
if hash_bookmark:
coordinate["doc_book"] = hash_bookmark.group(1)
coordinate["doc_bookmark"] = hash_bookmark.group(2)
content = CONTENT_PATH_RE.search(path)
if content:
coordinate["doc_content_id"] = content.group(1)
else:
hash_content = HASH_CONTENT_RE.match(fragment)
if hash_content:
coordinate["doc_book"] = coordinate["doc_book"] or hash_content.group(1)
coordinate["doc_content_id"] = hash_content.group(2)
parts = [
coordinate.get("platform_doc_id"),
coordinate.get("doc_book"),
coordinate.get("doc_bookmark") or coordinate.get("doc_content_id"),
]
if any(parts):
coordinate["doc_coordinate"] = ":".join(part or "_" for part in parts)
return coordinate
def materialize_doc_url(url: str) -> str:
parsed = urllib.parse.urlparse(url)
fragment = urllib.parse.unquote(parsed.fragment or "")
if not fragment:
return url
hash_bookmark = HASH_BOOKMARK_RE.match(fragment)
if hash_bookmark:
path = parsed.path.rstrip("/") + f"/bookmark/{hash_bookmark.group(1)}/{hash_bookmark.group(2)}"
return urllib.parse.urlunparse(parsed._replace(path=path, fragment=""))
hash_content = HASH_CONTENT_RE.match(fragment)
if hash_content:
content_id = hash_content.group(2)
path = parsed.path.rstrip("/") + f"/content/{content_id}/hdoc"
return urllib.parse.urlunparse(parsed._replace(path=path, fragment=""))
return urllib.parse.urlunparse(parsed._replace(fragment=""))
def merge_platform_metadata(record: dict[str, Any], url: str) -> dict[str, Any]:
coordinate = parse_doc_coordinate(url)
merged = dict(record)
for key, value in coordinate.items():
if value and not merged.get(key):
merged[key] = value
if not merged.get("platform_family") and merged.get("platform_doc_id"):
merged["platform_family"] = "1C:Enterprise 8"
return merged