"""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 = "" 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\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)