Commits

Anonymous committed 558c124

it can show/edit wiki page. rst markup can be used for the text content.

Comments (0)

Files changed (7)

+syntax: glob
+*.db
+from __future__ import with_statement
+from sqlite3 import dbapi2 as sqlite3
+from contextlib import closing
+from flask import Flask, request, session, g, redirect, url_for, abort, \
+     render_template, flash
+from docutils.core import publish_parts
+
+
+def fromhere(path):
+    import os
+    return os.path.join(os.path.dirname(__file__), path)
+
+
+# configuration
+DATABASE = fromhere('flaskrest.db')
+DEBUG = True
+SECRET_KEY = 'development key'
+USERNAME = 'admin'
+PASSWORD = 'default'
+
+# disable docutils security hazards:
+# http://docutils.sourceforge.net/docs/howto/security.html
+SAFE_DOCUTILS = dict(file_insertion_enabled=False, raw_enabled=False)
+
+# create our little application :)
+app = Flask(__name__)
+app.config.from_object(__name__)
+app.config.from_envvar('FLASKR_SETTINGS', silent=True)
+
+
+def connect_db():
+    """Returns a new connection to the database."""
+    return sqlite3.connect(app.config['DATABASE'])
+
+
+def init_db():
+    """Creates the database tables."""
+    with closing(connect_db()) as db:
+        with app.open_resource('schema.sql') as f:
+            db.cursor().executescript(f.read())
+        db.commit()
+
+
+@app.before_request
+def before_request():
+    """Make sure we are connected to the database each request."""
+    g.db = connect_db()
+
+
+@app.after_request
+def after_request(response):
+    """Closes the database again at the end of the request."""
+    g.db.close()
+    return response
+
+
+@app.route('/')
+def index():
+    return redirect(url_for("page", title='StartPage'))
+
+
+@app.route('/save/<path:title>', methods=['POST'])
+def save(title):
+    print request.method, request.args
+    g.db.execute(
+        'insert or replace into pages (title, body) values (?, ?)',
+        [title, request.form['body']])
+    g.db.commit()
+    flash('Saved!')
+    return redirect(url_for("page", title=title))
+
+
+@app.route('/edit/<path:title>', methods=['GET', 'POST'])
+def edit(title):
+    body = g.db.execute('select body from pages where title = ?',
+                        [title]).fetchone()
+    return render_template("edit.html",
+                           title=title,
+                           text=body[0] if body else '')
+
+@app.route('/page/<path:title>')
+def page(title):
+    if title.endswith('/'):
+        return redirect(url_for('page', title=title[:-1]))
+
+    body = g.db.execute('select body from pages where title = ?',
+                        [title]).fetchone()
+    if body:
+        htmltext = publish_parts(
+            body[0], writer_name='html',
+            settings_overrides=SAFE_DOCUTILS)['html_body']
+        return render_template("page.html",
+                               title=title, htmltext=htmltext)
+    else:
+        return redirect(url_for('edit', title=title))
+
+
+if __name__ == '__main__':
+    app.run()
+drop table if exists pages;
+create table pages (
+  title string primary key,
+  body string not null
+);
+/* color scheme: #418041 #3D603D #155315 #79BF79 #8CBF8C
+ * http://colorschemedesigner.com/#2P11TfLk4w0w0
+ */
+
+body {
+    background: #E0E0E0;
+    font-family: sans-serif;
+}
+
+a {
+    color: #377BA8;
+}
+
+.page-title {
+    color: #155315;
+    border-bottom: #8CBF8C 1px solid;
+    font-size: 100%;
+    font-family: monospace;
+}
+
+h1, h2, h3, h4, h5, h6 {
+    color: #155315;
+}
+
+h1, h2 {
+    font-family: 'Georgia', serif;
+    margin: 0;
+}
+
+.page {
+    margin: 2em auto;
+}
+
+.entries {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+
+.entries li {
+    margin: 0.8em 1.2em;
+}
+
+.entries li h2 {
+    margin-left: -1em;
+}
+
+.add-entry {
+    border-bottom: 1px solid #ccc;
+    font-size: 0.9em;
+}
+
+.add-entry dl {
+    font-weight: bold;
+}
+
+.contents {
+    background: white;
+    font-size: 0.8em;
+    margin-bottom: 1em;
+    padding: 0.8em;
+}
+
+.contents textarea {
+    width: 100%;
+    height: 100%;
+}
+
+.flash {
+    background: #CEE5F5;
+    border: 1px solid #AACBE2;
+    padding: 0.5em;
+}
+
+.error {
+    background: #F0D6D6;
+    padding: 0.5em;
+}
+
+.system-messages {
+    background: #F0D6D6;
+    border: 1px solid #FF0000;
+    padding: 0.5em;
+}
+.system-messages h1 {
+    font-family: sans-serif;
+    font-size: 150%;
+    color: black;
+    border-bottom: 1px solid #FF0000;
+}
+.system-message-title {
+    padding: 0.3em;
+    background: #FFAAAA;
+}
+.system-message-title a {
+    color: #A60000;
+}

templates/edit.html

+{% extends "layout.html" %}
+{% block body %}
+  <form action="{{ url_for('save', title=title) }}"
+        method=post class=add-entry>
+    <textarea name=body rows=50 cols=200>{{ text }}</textarea>
+    <input type=submit value=Save>
+  </form>
+{% endblock %}

templates/layout.html

+<!doctype html>
+<title>{{ title }} | FlaskRest</title>
+<link rel=stylesheet type=text/css
+      href="{{ url_for('static', filename='style.css') }}">
+<div class=page>
+  <div class=page-title>{{ title }}</div>
+  <div class=contents>
+  {% for message in get_flashed_messages() %}
+    <div class=flash>{{ message }}</div>
+  {% endfor %}
+  {% block body %}{% endblock %}
+  </div>
+</div>

templates/page.html

+{% extends "layout.html" %}
+{% block body %}
+  <p>
+    {{ htmltext|safe }}
+  </p>
+  <p><a href="{{ url_for('edit', title=title) }}">Edit</a></p>
+{% endblock %}