feat: Initial project setup with Wiki.js and management scripts

- Add Docker Compose setup for Wiki.js and PostgreSQL.
- Include setup and backup scripts for easy management.
- Create command-line scripts to create and edit wiki pages via the GraphQL API.
- Add comprehensive README and .gitignore.
This commit is contained in:
Aodhan Collins
2025-09-08 02:22:20 +01:00
parent a2adb89d93
commit d7b0f6fee0
6 changed files with 329 additions and 140 deletions

101
scripts/create_page.py Normal file
View File

@@ -0,0 +1,101 @@
import os
import requests
import argparse
from dotenv import load_dotenv
# Load environment variables from .env file
# This will search for a .env file in the current directory or parent directories
load_dotenv()
# --- Configuration ---
WIKI_URL = os.getenv("WIKI_URL")
API_KEY = os.getenv("WIKI_API_KEY")
# --- GraphQL Mutation ---
GRAPHQL_CREATE_MUTATION = """
mutation CreatePage($content: String!, $description: String!, $editor: String!, $isPrivate: Boolean!, $isPublished: Boolean!, $locale: String!, $path: String!, $tags: [String]!, $title: String!) {
pages {
create(content: $content, description: $description, editor: $editor, isPrivate: $isPrivate, isPublished: $isPublished, locale: $locale, path: $path, tags: $tags, title: $title) {
responseResult { succeeded, errorCode, slug, message }
page { id, path, title }
}
}
}
"""
def create_wiki_page(path, title, content_file, tags, locale):
"""Sends a GraphQL request to create a new wiki page."""
if not all([API_KEY, WIKI_URL]):
print("❌ Error: WIKI_API_KEY and/or WIKI_URL not found in environment variables.")
return
try:
with open(content_file, 'r') as f:
content = f.read()
except FileNotFoundError:
print(f"❌ Error: Content file not found at '{content_file}'")
return
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
variables = {
"content": content,
"description": f"Page for {title}",
"editor": "markdown",
"isPrivate": False,
"isPublished": True,
"locale": locale,
"path": path,
"tags": tags or [],
"title": title
}
graphql_query = {
"query": GRAPHQL_CREATE_MUTATION,
"variables": variables
}
print(f"🚀 Sending request to {WIKI_URL}/graphql to create page at path '{path}'...")
try:
response = requests.post(f"{WIKI_URL}/graphql", headers=headers, json=graphql_query, timeout=15)
response.raise_for_status()
result = response.json()
if 'errors' in result:
print("❌ GraphQL API returned errors:")
for error in result['errors']:
print(f" - {error.get('message')}")
return
creation_result = result.get('data', {}).get('pages', {}).get('create', {})
response_result = creation_result.get('responseResult', {})
if response_result.get('succeeded'):
page_info = creation_result.get('page', {})
print(f"✅ Success! Page '{page_info.get('title')}' created.")
print(f" - ID: {page_info.get('id')}")
print(f" - Path: {page_info.get('path')}")
print(f"🌐 View it at: {WIKI_URL}/{page_info.get('path')}")
else:
print(f"❌ API call failed: {response_result.get('message')}")
print(f" - Error Code: {response_result.get('errorCode')}")
except requests.exceptions.RequestException as e:
print(f"❌ An error occurred while connecting to the wiki: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Create a new page in Wiki.js.")
parser.add_argument('--path', required=True, help='The path for the new page (e.g., \"my-folder/my-page\").')
parser.add_argument('--title', required=True, help='The title of the new page.')
parser.add_argument('--content-file', required=True, help='Path to the markdown file containing the page content.')
parser.add_argument('--tags', nargs='*', help='A list of tags to add to the page.')
parser.add_argument('--locale', default='en', help='The locale for the page (default: en).')
args = parser.parse_args()
create_wiki_page(args.path, args.title, args.content_file, args.tags, args.locale)

133
scripts/edit_page.py Normal file
View File

@@ -0,0 +1,133 @@
import os
import requests
import argparse
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# --- Configuration ---
WIKI_URL = os.getenv("WIKI_URL")
API_KEY = os.getenv("WIKI_API_KEY")
# --- GraphQL Queries & Mutations ---
GRAPHQL_LIST_ALL_PAGES_QUERY = """
query AllPages {
pages {
list {
id
path
}
}
}
"""
GRAPHQL_UPDATE_MUTATION = """
mutation UpdatePage($id: Int!, $content: String, $description: String, $tags: [String], $title: String) {
pages {
update(id: $id, content: $content, description: $description, tags: $tags, title: $title) {
responseResult { succeeded, errorCode, slug, message }
page { id, path, title }
}
}
}
"""
def run_graphql_query(query, variables):
"""Helper function to run a GraphQL query."""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
try:
response = requests.post(f"{WIKI_URL}/graphql", headers=headers, json={"query": query, "variables": variables}, timeout=15)
response.raise_for_status()
result = response.json()
if 'errors' in result:
print("❌ GraphQL API returned errors:")
for error in result['errors']:
print(f" - {error.get('message')}")
return None
return result
except requests.exceptions.RequestException as e:
print(f"❌ An error occurred: {e}")
return None
def get_page_id(path_to_find, locale):
"""Get the ID of a page by fetching all pages and searching for its path."""
print("🔎 Fetching all pages to find the correct ID...")
result = run_graphql_query(GRAPHQL_LIST_ALL_PAGES_QUERY, {})
if not result:
print("❌ Failed to fetch the page list.")
return None
all_pages = result.get('data', {}).get('pages', {}).get('list', [])
if not all_pages:
print("❌ No pages were found on the wiki.")
return None
for page in all_pages:
if page.get('path') == path_to_find:
page_id = page.get('id')
print(f"📄 Found page with ID: {page_id} for path: '{path_to_find}'")
return page_id
print(f"❌ A page with the path '{path_to_find}' was not found.")
return None
def edit_wiki_page(path, content_file, new_title, locale):
"""Updates an existing wiki page."""
if not all([API_KEY, WIKI_URL]):
print("❌ Error: WIKI_API_KEY and/or WIKI_URL not found in environment variables.")
return
page_id = get_page_id(path, locale)
if not page_id:
return
variables = {
"id": page_id,
"description": f"Page at path {path} updated via script.",
"tags": []
}
if content_file:
try:
with open(content_file, 'r') as f:
variables['content'] = f.read()
print(f"🔄 Preparing to update content from '{content_file}'...")
except FileNotFoundError:
print(f"❌ Error: Content file not found at '{content_file}'")
return
if new_title:
variables['title'] = new_title
print(f"🔄 Preparing to update title to '{new_title}'...")
if 'content' not in variables and 'title' not in variables:
print("✨ Nothing to update. Please provide a new title or content file.")
return
result = run_graphql_query(GRAPHQL_UPDATE_MUTATION, variables)
if not result:
return
op_result = result.get('data', {}).get('pages', {}).get('update', {})
response_result = op_result.get('responseResult', {})
if response_result.get('succeeded'):
page_info = op_result.get('page', {})
print(f"✅ Success! Page '{page_info.get('title')}' updated.")
print(f"🌐 View it at: {WIKI_URL}/{page_info.get('path')}")
else:
print(f"❌ API call failed: {response_result.get('message')}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Edit an existing page in Wiki.js.")
parser.add_argument('--path', required=True, help='The path of the page to edit (e.g., \"home\").')
parser.add_argument('--content-file', help='Path to a markdown file with the new content.')
parser.add_argument('--title', help='A new title for the page.')
parser.add_argument('--locale', default='en', help='The locale of the page (default: en).')
args = parser.parse_args()
edit_wiki_page(args.path, args.content_file, args.title, args.locale)