Skip to content

Instantly share code, notes, and snippets.

@shmup
Last active January 18, 2025 22:53
Show Gist options
  • Save shmup/961cdbd795b7895704d3a511af3931c3 to your computer and use it in GitHub Desktop.
Save shmup/961cdbd795b7895704d3a511af3931c3 to your computer and use it in GitHub Desktop.
wiki.py
#!/usr/bin/env python3
from flask import Flask, request, redirect, url_for
from markupsafe import escape
import re
import json
import atexit
from urllib.parse import urlparse
app = Flask(__name__)
def load_pages():
try:
with open('pages.json', 'r') as f:
return json.load(f)
except FileNotFoundError:
return {}
def save_pages(pages):
with open('pages.json', 'w') as f:
json.dump(pages, f)
pages = load_pages()
atexit.register(save_pages, pages)
def get_child_pages(parent_page):
child_pages = []
for page_name in pages.keys():
if page_name.startswith(parent_page + '/'):
child_page = page_name.split('/')[-1]
child_pages.append(child_page)
return child_pages
def parse_wiki(content):
def replace_link(match):
link = match.group(1)
if '/' in link:
link_parts = link.split('/')
parent_page = '/'.join(link_parts[:-1])
child_page = link_parts[-1]
return f'<a href="{url_for("show_page", pagename=parent_page)}/{child_page}">{link}</a>'
else:
return f'<a href="{url_for("show_page", pagename=link)}">{link}</a>'
content = re.sub(r'\[\[([^\]]+)\]\]', replace_link, escape(content))
content = content.replace('\n', '<br>')
return content
@app.route('/', methods=['GET'])
def redirect_to_homepage():
return redirect(url_for('show_page', pagename='HomePage'))
@app.route('/<path:pagename>', methods=['POST'])
def save_page(pagename):
pages[pagename] = request.form['content']
return redirect(url_for('show_page', pagename=pagename))
@app.route('/<path:pagename>/edit', methods=['GET'])
def edit_page(pagename):
content = pages.get(pagename, '')
return f'''
<form method="POST" action="{url_for("save_page", pagename=pagename)}">
<textarea name="content" rows="10" cols="50">{content}</textarea><br>
<input type="submit" value="Save">
</form>
'''
@app.route('/<path:pagename>', methods=['GET'])
def show_page(pagename):
pagename = pagename.rstrip('/')
content = pages.get(pagename, '')
parsed_content = parse_wiki(content)
edit_link = f'<p><a href="{url_for("edit_page", pagename=pagename)}">Edit</a></p>'
if not content:
parsed_content = 'This page does not exist yet.'
edit_link = edit_link.replace('Edit', 'Create')
child_pages = get_child_pages(pagename)
if child_pages:
child_page_links = '<ul>' + ''.join([
f'<li><a href="{url_for("show_page", pagename=pagename + "/" + child_page)}">{child_page}</a></li>'
for child_page in child_pages
]) + '</ul>'
else:
child_page_links = ''
parent_page = urlparse(pagename).path.split('/')[:-1]
if parent_page:
parent_page = '/'.join(parent_page)
up_link = f'<p><a href="{url_for("show_page", pagename=parent_page)}">Up &#8593;</a></p>'
else:
up_link = ''
return f'{up_link}{parsed_content}{edit_link}{child_page_links}'
if __name__ == '__main__':
app.run(port=5001, debug=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment