realms-wiki/realms/modules/wiki/views.py

242 lines
8.4 KiB
Python
Raw Normal View History

2015-12-13 10:59:56 +02:00
import itertools
import sys
from flask import abort, g, render_template, request, redirect, Blueprint, flash, url_for, current_app
2014-10-22 00:06:27 +03:00
from flask.ext.login import login_required, current_user
2015-12-16 07:30:33 +02:00
from realms.lib.util import to_canonical, remove_ext, gravatar_url
from .models import PageNotFound
2013-12-03 22:09:57 +02:00
2014-10-22 00:06:27 +03:00
blueprint = Blueprint('wiki', __name__)
2014-08-30 18:06:12 +03:00
2013-12-03 22:09:57 +02:00
@blueprint.route("/_commit/<sha>/<path:name>")
2013-12-04 00:28:16 +02:00
def commit(name, sha):
if current_app.config.get('PRIVATE_WIKI') and current_user.is_anonymous():
return current_app.login_manager.unauthorized()
2013-12-03 22:09:57 +02:00
cname = to_canonical(name)
data = g.current_wiki.get_page(cname, sha=sha)
if not data:
abort(404)
return render_template('wiki/page.html', name=name, page=data, commit=sha)
2013-12-03 22:09:57 +02:00
@blueprint.route(r"/_compare/<path:name>/<regex('\w+'):fsha><regex('\.{2,3}'):dots><regex('\w+'):lsha>")
2013-12-03 22:09:57 +02:00
def compare(name, fsha, dots, lsha):
if current_app.config.get('PRIVATE_WIKI') and current_user.is_anonymous():
return current_app.login_manager.unauthorized()
2016-07-10 01:26:55 +03:00
diff = g.current_wiki.get_page(name, sha=fsha).compare(lsha)
2014-10-22 00:06:27 +03:00
return render_template('wiki/compare.html',
name=name, diff=diff, old=fsha, new=lsha)
2013-12-03 22:09:57 +02:00
2014-08-20 18:28:25 +03:00
@blueprint.route("/_revert", methods=['POST'])
2014-08-30 18:06:12 +03:00
@login_required
2013-12-03 22:09:57 +02:00
def revert():
cname = to_canonical(request.form.get('name'))
2014-08-30 18:06:12 +03:00
commit = request.form.get('commit')
message = request.form.get('message', "Reverting %s" % cname)
2014-09-11 00:08:19 +03:00
if not current_app.config.get('ALLOW_ANON') and current_user.is_anonymous():
2014-10-31 00:59:19 +02:00
return dict(error=True, message="Anonymous posting not allowed"), 403
2014-10-22 00:06:27 +03:00
if cname in current_app.config.get('WIKI_LOCKED_PAGES'):
return dict(error=True, message="Page is locked"), 403
try:
sha = g.current_wiki.get_page(cname).revert(commit,
message=message,
username=current_user.username,
email=current_user.email)
except PageNotFound as e:
return dict(error=True, message=e.message), 404
2014-09-11 00:08:19 +03:00
if sha:
flash("Page reverted")
return dict(sha=sha)
2014-08-20 18:28:25 +03:00
@blueprint.route("/_history/<path:name>")
2013-12-03 22:09:57 +02:00
def history(name):
if current_app.config.get('PRIVATE_WIKI') and current_user.is_anonymous():
return current_app.login_manager.unauthorized()
return render_template('wiki/history.html', name=name)
@blueprint.route("/_history_data/<path:name>")
def history_data(name):
"""Ajax provider for paginated history data."""
if current_app.config.get('PRIVATE_WIKI') and current_user.is_anonymous():
return current_app.login_manager.unauthorized()
draw = int(request.args.get('draw', 0))
start = int(request.args.get('start', 0))
length = int(request.args.get('length', 10))
page = g.current_wiki.get_page(name)
items = list(itertools.islice(page.history, start, start + length))
for item in items:
2015-12-16 07:30:33 +02:00
item['gravatar'] = gravatar_url(item['author_email'])
2016-07-10 01:26:55 +03:00
item['DT_RowId'] = item['sha']
total_records, hist_complete = page.history_cache
if not hist_complete:
# Force datatables to fetch more data when it gets to the end
total_records += 1
return {
'draw': draw,
'recordsTotal': total_records,
'recordsFiltered': total_records,
'data': items,
'fully_loaded': hist_complete
}
2013-12-03 22:09:57 +02:00
@blueprint.route("/_edit/<path:name>")
2014-08-30 18:06:12 +03:00
@login_required
2013-12-03 22:09:57 +02:00
def edit(name):
cname = to_canonical(name)
page = g.current_wiki.get_page(cname)
if not page:
# Page doesn't exist
return redirect(url_for('wiki.create', name=cname))
g.assets['js'].append('editor.js')
return render_template('wiki/edit.html',
name=cname,
content=page.data,
2016-07-08 00:54:15 +03:00
# TODO: Remove this? See #148
info=next(page.history),
sha=page.sha,
partials=page.partials)
2014-01-17 01:37:55 +02:00
@blueprint.route("/_create/", defaults={'name': None})
@blueprint.route("/_create/<path:name>")
2014-08-30 18:06:12 +03:00
@login_required
def create(name):
cname = to_canonical(name) if name else ""
if cname and g.current_wiki.get_page(cname):
# Page exists, edit instead
return redirect(url_for('wiki.edit', name=cname))
2013-12-03 22:09:57 +02:00
g.assets['js'].append('editor.js')
return render_template('wiki/edit.html',
name=cname,
content="",
info={})
2013-12-03 22:09:57 +02:00
2015-12-13 10:59:56 +02:00
def _get_subdir(path, depth):
parts = path.split('/', depth)
if len(parts) > depth:
return parts[-2]
def _tree_index(items, path=""):
depth = len(path.split("/"))
items = sorted(items, key=lambda x: x['name'])
for subdir, items in itertools.groupby(items, key=lambda x: _get_subdir(x['name'], depth)):
if not subdir:
for item in items:
yield dict(item, dir=False)
else:
size = 0
ctime = sys.maxint
mtime = 0
for item in items:
size += item['size']
ctime = min(item['ctime'], ctime)
mtime = max(item['mtime'], mtime)
yield dict(name=path + subdir + "/",
mtime=mtime,
ctime=ctime,
size=size,
dir=True)
2015-12-12 21:56:10 +02:00
@blueprint.route("/_index", defaults={"path": ""})
@blueprint.route("/_index/<path:path>")
def index(path):
2015-12-13 10:59:56 +02:00
if current_app.config.get('PRIVATE_WIKI') and current_user.is_anonymous():
return current_app.login_manager.unauthorized()
2015-12-12 21:56:10 +02:00
items = g.current_wiki.get_index()
if path:
path = to_canonical(path) + "/"
items = filter(lambda x: x['name'].startswith(path), items)
if not request.args.get('flat', '').lower() in ['yes', '1', 'true']:
items = _tree_index(items, path=path)
return render_template('wiki/index.html', index=items, path=path)
@blueprint.route("/<path:name>", methods=['POST', 'PUT', 'DELETE'])
2014-08-30 18:06:12 +03:00
@login_required
def page_write(name):
cname = to_canonical(name)
if not cname:
2014-10-22 00:06:27 +03:00
return dict(error=True, message="Invalid name")
if not current_app.config.get('ALLOW_ANON') and current_user.is_anonymous():
2014-10-31 00:59:19 +02:00
return dict(error=True, message="Anonymous posting not allowed"), 403
2013-12-03 22:09:57 +02:00
if request.method == 'POST':
# Create
2014-10-22 00:06:27 +03:00
if cname in current_app.config.get('WIKI_LOCKED_PAGES'):
return dict(error=True, message="Page is locked"), 403
sha = g.current_wiki.get_page(cname).write(request.form['content'],
message=request.form['message'],
create=True,
username=current_user.username,
email=current_user.email)
elif request.method == 'PUT':
edit_cname = to_canonical(request.form['name'])
2014-10-22 00:06:27 +03:00
if edit_cname in current_app.config.get('WIKI_LOCKED_PAGES'):
return dict(error=True, message="Page is locked"), 403
2014-01-17 01:37:55 +02:00
if edit_cname != cname:
g.current_wiki.get_page(cname).rename(edit_cname)
2013-12-03 22:09:57 +02:00
sha = g.current_wiki.get_page(edit_cname).write(request.form['content'],
message=request.form['message'],
username=current_user.username,
email=current_user.email)
2013-12-03 22:09:57 +02:00
return dict(sha=sha)
2015-09-28 07:57:56 +03:00
elif request.method == 'DELETE':
# DELETE
if cname in current_app.config.get('WIKI_LOCKED_PAGES'):
return dict(error=True, message="Page is locked"), 403
sha = g.current_wiki.get_page(cname).delete(username=current_user.username,
email=current_user.email)
return dict(sha=sha)
2014-10-09 23:47:12 +03:00
2014-08-20 18:28:25 +03:00
@blueprint.route("/", defaults={'name': 'home'})
@blueprint.route("/<path:name>")
2013-12-03 22:09:57 +02:00
def page(name):
if current_app.config.get('PRIVATE_WIKI') and current_user.is_anonymous():
return current_app.login_manager.unauthorized()
2013-12-03 22:09:57 +02:00
cname = to_canonical(name)
if cname != name:
2014-01-17 01:12:21 +02:00
return redirect(url_for('wiki.page', name=cname))
2013-12-03 22:09:57 +02:00
data = g.current_wiki.get_page(cname)
2013-12-03 22:09:57 +02:00
if data:
return render_template('wiki/page.html', name=cname, page=data, partials=data.partials)
2013-12-03 22:09:57 +02:00
else:
return redirect(url_for('wiki.create', name=cname))