Files
Orchestrator/scripts/bootstrap_tools.py
T
ankn cfaf670100 Squashed 'bahn/wissensdatenbank/' content from commit 07a8196e
git-subtree-dir: bahn/wissensdatenbank
git-subtree-split: 07a8196e5f9e55d027f90485beb95f4006387669
2026-06-30 21:19:25 +02:00

102 lines
3.5 KiB
Python

"""EINMALIGES Bootstrap-Skript: erzeugt config/tools.yaml aus der Support-Seite.
Findet alle "Tool <Name>"-Unterseiten von Seite 428909879 und schreibt pro Tool
einen Katalogeintrag (Name OHNE "Tool "-Praefix). Tool-weiter Scope = intern
(restriktiv). Danach wird config/tools.yaml MANUELL gepflegt.
Aufruf:
CONFLUENCE_URL=... CONFLUENCE_TOKEN=... python scripts/bootstrap_tools.py
"""
from __future__ import annotations
import os
import re
from atlassian import Confluence
SUPPORT_PAGE = "428909879"
BASE = "https://arija-confluence.jaas.service.deutschebahn.com/spaces/BES/pages"
HEADER = """\
# =============================================================================
# TOOL-KATALOG der Wissensdatenbank
# Initial generiert aus 'Zentraler 1st Level Support' (428909879).
# AB JETZT MANUELL PFLEGEN. Allgemeines Wissen steht in config/general.yaml.
#
# AUFBAU PRO TOOL:
# - id / name / domain
# scope: intern # tool-weit: intern | extern | allgemein | mixed
# owners: ["a@db.de"] # intern Verantwortliche
# contact: "team@db.de" # herausgebbarer Kontakt (Default einfachbahn@deutschebahn.com)
# sources: # 1..n Quellen, beliebig mischbar
# - url: "..."
# strategy: confluence_tree # confluence_page|confluence_tree|confluence_faq|
# # crawler|sitemap|gitlab_md|file|pdf
# # scope/Optionen pro Quelle optional ueberschreibbar
#
# SCOPE:
# intern -> alles intern (Default, restriktiv; z.B. CRM Salesforce)
# extern -> alles extern
# allgemein -> gilt fuer intern UND extern
# mixed -> Tool hat Quellen mit unterschiedlichem Scope (KEINE Trennung pro Seite;
# im Zweifel zwei Quellen). Source-scope kann "intern,extern" sein.
#
# confluence_tree-Tiefe: options.max_depth (-1=alle Unterseiten, 0=nur Seite)
# =============================================================================
tools:
"""
def slug(s: str) -> str:
s = re.sub(r"^tool\s+", "", s.strip(), flags=re.I)
s = re.sub(r"[^a-z0-9]+", "-", s.lower())
return s.strip("-")[:40]
def clean_name(s: str) -> str:
return re.sub(r"^tool\s+", "", s.strip(), flags=re.I).strip()
def walk(client, pid, out=None):
out = out if out is not None else []
for ch in client.get_child_pages(pid) or []:
out.append((ch.get("id"), ch.get("title")))
walk(client, ch.get("id"), out)
return out
def main() -> None:
client = Confluence(
url=os.environ["CONFLUENCE_URL"], token=os.environ["CONFLUENCE_TOKEN"], cloud=False
)
tools = [(pid, t.strip()) for pid, t in walk(client, SUPPORT_PAGE)
if t.strip().lower().startswith("tool")]
lines = [HEADER.rstrip("\n")]
seen = set()
for pid, title in tools:
sid = slug(title)
if sid in seen:
sid = f"{sid}-{pid}"
seen.add(sid)
url = f"{BASE}/{pid}/" + re.sub(r"[^A-Za-z0-9]+", "+", title).strip("+")
lines += [
f" - id: {sid}",
f' name: "{clean_name(title)}"',
f" domain: {sid}",
" scope: intern",
" sources:",
f' - url: "{url}"',
" strategy: confluence_tree",
f' tags: ["{sid}"]',
]
with open("config/tools.yaml", "w", encoding="utf-8") as f:
f.write("\n".join(lines) + "\n")
print(f"config/tools.yaml geschrieben: {len(tools)} Tools (alle scope: intern)")
if __name__ == "__main__":
main()