Files
Brancheneinstufung2/sync_docs_to_notion.py
Floke 1742b1c83b feat(notion): Add documentation sync script
- Created sync_docs_to_notion.py to parse and upload markdown docs to Notion.
2026-01-06 20:35:03 +00:00

176 lines
5.2 KiB
Python

import requests
import json
import os
import re
TOKEN_FILE = 'notion_api_key.txt'
PARENT_PAGE_ID = "2e088f42-8544-8024-8289-deb383da3818"
DOC_FILE = "notion_integration.md"
def parse_markdown_to_blocks(md_content):
blocks = []
lines = md_content.split('\n')
in_code_block = False
code_content = []
for line in lines:
# Don't strip indentation for code blocks, but do for logic checks
stripped = line.strip()
# Handle Code Blocks
if stripped.startswith("```"):
if in_code_block:
# End of code block
blocks.append({
"object": "block",
"type": "code",
"code": {
"rich_text": [{"type": "text", "text": {"content": "\n".join(code_content)}}],
"language": "plain text"
}
})
code_content = []
in_code_block = False
else:
# Start of code block
in_code_block = True
continue
if in_code_block:
code_content.append(line)
continue
if not stripped:
continue
# Headings
if line.startswith("# "):
blocks.append({
"object": "block",
"type": "heading_1",
"heading_1": {
"rich_text": [{"type": "text", "text": {"content": line[2:]}}]
}
})
elif line.startswith("## "):
blocks.append({
"object": "block",
"type": "heading_2",
"heading_2": {
"rich_text": [{"type": "text", "text": {"content": line[3:]}}]
}
})
elif line.startswith("### "):
blocks.append({
"object": "block",
"type": "heading_3",
"heading_3": {
"rich_text": [{"type": "text", "text": {"content": line[4:]}}]
}
})
# List Items
elif stripped.startswith("* ") or stripped.startswith("- "):
content = stripped[2:]
blocks.append({
"object": "block",
"type": "bulleted_list_item",
"bulleted_list_item": {
"rich_text": [{"type": "text", "text": {"content": content}}]
}
})
# Numbered List (Simple detection)
elif re.match(r"^\d+\.", stripped):
content = re.sub(r"^\d+\.\s*", "", stripped)
blocks.append({
"object": "block",
"type": "numbered_list_item",
"numbered_list_item": {
"rich_text": [{"type": "text", "text": {"content": content}}]
}
})
# Tables (Very basic handling: convert to code block for preservation)
elif stripped.startswith("|"):
blocks.append({
"object": "block",
"type": "code",
"code": {
"rich_text": [{"type": "text", "text": {"content": line}}],
"language": "plain text"
}
})
# Paragraphs
else:
blocks.append({
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [{"type": "text", "text": {"content": line}}]
}
})
return blocks
def upload_doc(token):
try:
with open(DOC_FILE, 'r') as f:
content = f.read()
except FileNotFoundError:
print(f"Error: Could not find '{DOC_FILE}'")
return
print(f"Parsing '{DOC_FILE}'...")
children_blocks = parse_markdown_to_blocks(content)
url = "https://api.notion.com/v1/pages"
headers = {
"Authorization": f"Bearer {token}",
"Notion-Version": "2022-06-28",
"Content-Type": "application/json"
}
payload = {
"parent": { "page_id": PARENT_PAGE_ID },
"properties": {
"title": [
{
"text": {
"content": "📘 Notion Integration Dokumentation"
}
}
]
},
"children": children_blocks[:100] # Safe limit
}
print(f"Uploading to Notion under parent {PARENT_PAGE_ID}...")
try:
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
data = response.json()
print("\n=== SUCCESS ===")
print(f"Documentation uploaded!")
print(f"URL: {data.get('url')}")
except requests.exceptions.HTTPError as e:
print(f"\n=== ERROR ===")
print(f"HTTP Error: {e}")
print(f"Response: {response.text}")
except Exception as e:
print(f"\n=== ERROR ===")
print(f"An error occurred: {e}")
def main():
try:
with open(TOKEN_FILE, 'r') as f:
token = f.read().strip()
except FileNotFoundError:
print(f"Error: Could not find '{TOKEN_FILE}'")
return
upload_doc(token)
if __name__ == "__main__":
main()