Files
KSP_project/scripts/wiki_publish_mission_gallery_runtime.py

115 lines
4.3 KiB
Python

"""Publish the mission-gallery runtime through Wiki.js global theme injection."""
from __future__ import annotations
import json
import sys
from pathlib import Path
import psycopg
from psycopg.rows import dict_row
from wiki_update_page import (
WikiUpdateError,
connect_info,
find_auth_group,
get_json_cast,
graphql,
grant_temporary_system_permission,
load_env,
login,
normalize_json,
remove_temporary_system_permission,
)
START = "<!-- ksp-mission-gallery-runtime:start -->"
END = "<!-- ksp-mission-gallery-runtime:end -->"
def replace_managed_block(existing: str, block: str) -> str:
start = existing.find(START)
end = existing.find(END)
if start >= 0 and end >= start:
end += len(END)
return (existing[:start] + block + existing[end:]).strip()
return (existing.strip() + "\n" + block).strip()
def main() -> int:
root = Path(__file__).resolve().parents[1]
env = load_env(root / ".env")
conninfo = connect_info(env)
identities = [value for value in (env.get("wiki_useremail"), env.get("wiki_username")) if value]
if not identities or not env.get("wiki_password"):
raise WikiUpdateError("Missing Wiki credentials")
runtime = (root / "scripts" / "wiki_mission_gallery_runtime.js").read_text(encoding="utf-8").strip()
managed_block = f"{START}\n<script data-ksp-mission-gallery-runtime>\n{runtime}\n</script>\n{END}"
group_id = None
try:
with psycopg.connect(**conninfo, row_factory=dict_row) as conn:
with conn.cursor() as cur:
group = find_auth_group(cur, "automation", [identity.lower() for identity in identities])
group_id = group["id"]
grant_temporary_system_permission(cur, group)
conn.commit()
token = login(env.get("WIKI_URL", "http://192.168.195.241:38353").rstrip("/"), identities, env["wiki_password"])
wiki_url = env.get("WIKI_URL", "http://192.168.195.241:38353").rstrip("/")
query = """
query ThemeConfig {
theming { config { theme iconset darkMode tocPosition injectCSS injectHead injectBody } }
}
"""
current_payload = graphql(wiki_url, query, token=token)
config = current_payload.get("data", {}).get("theming", {}).get("config")
if not config:
raise WikiUpdateError(f"Unable to read theme config: {json.dumps(current_payload)}")
inject_body = replace_managed_block(config.get("injectBody") or "", managed_block)
mutation = """
mutation SetTheme($theme: String!, $iconset: String!, $darkMode: Boolean!, $tocPosition: String, $injectCSS: String, $injectHead: String, $injectBody: String) {
theming {
setConfig(theme: $theme, iconset: $iconset, darkMode: $darkMode, tocPosition: $tocPosition, injectCSS: $injectCSS, injectHead: $injectHead, injectBody: $injectBody) {
responseResult { succeeded errorCode slug message }
}
}
}
"""
updated = graphql(
wiki_url,
mutation,
{
"theme": config["theme"],
"iconset": config["iconset"],
"darkMode": config["darkMode"],
"tocPosition": config.get("tocPosition"),
"injectCSS": config.get("injectCSS") or "",
"injectHead": config.get("injectHead") or "",
"injectBody": inject_body,
},
token,
)
result = updated.get("data", {}).get("theming", {}).get("setConfig", {}).get("responseResult", {})
print(
"theming.setConfig succeeded={succeeded} errorCode={errorCode} slug={slug} message={message}".format(
**{key: result.get(key) for key in ("succeeded", "errorCode", "slug", "message")}
)
)
if not result.get("succeeded"):
raise WikiUpdateError(f"Theme runtime publish failed: {json.dumps(updated)}")
print(f"mission_gallery_runtime_published bytes={len(runtime.encode('utf-8'))}")
return 0
finally:
if group_id is not None:
remove_temporary_system_permission(conninfo, group_id)
if __name__ == "__main__":
try:
sys.exit(main())
except WikiUpdateError as exc:
print(f"wiki_runtime_error={exc}")
sys.exit(2)