Admin interface for snippets
This commit is contained in:
parent
45df60cfc6
commit
53ce827b17
15 changed files with 214 additions and 83 deletions
|
|
@ -46,6 +46,32 @@ database = [
|
|||
''',
|
||||
bitbucket='leafstorm/flask-xml-rpc',
|
||||
docs='http://packages.python.org/Flask-XML-RPC/'
|
||||
),
|
||||
Extension('flask-csrf', 'Steve Losh',
|
||||
description='''
|
||||
<p>A small Flask extension for adding
|
||||
<a href=http://en.wikipedia.org/wiki/CSRF>CSRF</a> protection.
|
||||
''',
|
||||
docs='http://sjl.bitbucket.org/flask-csrf/',
|
||||
bitbucket='sjl/flask-csrf'
|
||||
),
|
||||
Extension('flask-lesscss', 'Steve Losh',
|
||||
description='''
|
||||
<p>
|
||||
A small Flask extension that makes it easy to use
|
||||
<a href=http://lesscss.org/>LessCSS</a> with your
|
||||
Flask application.
|
||||
''',
|
||||
docs='http://sjl.bitbucket.org/flask-lesscss/',
|
||||
bitbucket='sjl/flask-lesscss'
|
||||
),
|
||||
Extension('flask-urls', 'Steve Losh',
|
||||
description='''
|
||||
<p>
|
||||
A collection of URL-related functions for Flask applications.
|
||||
''',
|
||||
docs='http://sjl.bitbucket.org/flask-urls/',
|
||||
bitbucket='sjl/flask-urls'
|
||||
)
|
||||
]
|
||||
database.sort(key=lambda x: x.name.lower())
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from flask import Module, render_template, session, redirect, url_for, \
|
||||
request, flash, g, Response
|
||||
from flask_website import openid_auth
|
||||
from flask_website import oid
|
||||
from flask_website.database import db_session, User
|
||||
|
||||
general = Module(__name__)
|
||||
|
|
@ -20,17 +20,30 @@ def logout():
|
|||
|
||||
|
||||
@general.route('/login/', methods=['GET', 'POST'])
|
||||
@oid.loginhandler
|
||||
def login():
|
||||
if g.user is not None:
|
||||
return redirect(url_for('general.index'))
|
||||
rv = openid_auth.check_return_from_provider()
|
||||
if rv is not None:
|
||||
return rv
|
||||
if request.method == 'POST':
|
||||
openid = request.values.get('openid')
|
||||
if openid:
|
||||
return openid_auth.login(openid)
|
||||
return render_template('general/login.html')
|
||||
return oid.try_login(openid, ask_for=['fullname', 'nickname'])
|
||||
error = oid.fetch_error()
|
||||
if error:
|
||||
flash(u'Error: ' + error)
|
||||
return render_template('general/login.html', next=oid.get_next_url())
|
||||
|
||||
|
||||
@oid.after_login
|
||||
def create_or_login(resp):
|
||||
session['openid'] = resp.identity_url
|
||||
user = User.query.filter_by(openid=resp.identity_url).first()
|
||||
if user is not None:
|
||||
flash(u'Successfully signed in')
|
||||
g.user = user
|
||||
return redirect(oid.get_next_url())
|
||||
return redirect(url_for('first_login', next=oid.get_next_url(),
|
||||
name=resp.fullname or resp.nickname))
|
||||
|
||||
|
||||
@general.route('/first-login/', methods=['GET', 'POST'])
|
||||
|
|
@ -45,6 +58,7 @@ def first_login():
|
|||
db_session.add(User(request.form['name'], session['openid']))
|
||||
db_session.commit()
|
||||
flash(u'Successfully created profile and logged in')
|
||||
return openid_auth.redirect_back()
|
||||
return redirect(oid.get_next_url())
|
||||
return render_template('general/first_login.html',
|
||||
next=oid.get_next_url(),
|
||||
openid=session['openid'])
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from urlparse import urljoin
|
|||
from flask import Module, render_template, request, flash, abort, redirect, \
|
||||
g, url_for
|
||||
from werkzeug.contrib.atom import AtomFeed
|
||||
from flask_website.utils import requires_login, format_creole
|
||||
from flask_website.utils import requires_login, requires_admin, format_creole
|
||||
from flask_website.database import Category, Snippet, Comment, db_session
|
||||
|
||||
snippets = Module(__name__, url_prefix='/snippets')
|
||||
|
|
@ -71,7 +71,7 @@ def edit(id):
|
|||
snippet = Snippet.query.get(id)
|
||||
if snippet is None:
|
||||
abort(404)
|
||||
if snippet.author != g.user:
|
||||
if g.user is None or (not g.user.is_admin and snippet.author != g.user):
|
||||
abort(401)
|
||||
preview = None
|
||||
form = dict(title=snippet.title, body=snippet.body,
|
||||
|
|
@ -117,6 +117,64 @@ def category(slug):
|
|||
snippets=snippets)
|
||||
|
||||
|
||||
@snippets.route('/manage-categories/', methods=['GET', 'POST'])
|
||||
@requires_admin
|
||||
def manage_categories():
|
||||
categories = Category.query.order_by(Category.name).all()
|
||||
if request.method == 'POST':
|
||||
for category in categories:
|
||||
category.name = request.form['name.%d' % category.id]
|
||||
category.slug = request.form['slug.%d' % category.id]
|
||||
db_session.commit()
|
||||
flash(u'Categories updated')
|
||||
return redirect(url_for('manage_categories'))
|
||||
return render_template('snippets/manage_categories.html',
|
||||
categories=categories)
|
||||
|
||||
|
||||
@snippets.route('/new-category/', methods=['POST'])
|
||||
@requires_admin
|
||||
def new_category():
|
||||
category = Category(name=request.form['name'])
|
||||
db_session.add(category)
|
||||
db_session.commit()
|
||||
flash(u'Category %s created.' % category.name)
|
||||
return redirect(url_for('manage_categories'))
|
||||
|
||||
|
||||
@snippets.route('/delete-category/<int:id>/', methods=['GET', 'POST'])
|
||||
@requires_admin
|
||||
def delete_category(id):
|
||||
category = Category.query.get(id)
|
||||
if category is None:
|
||||
abort(404)
|
||||
if request.method == 'POST':
|
||||
if 'cancel' in request.form:
|
||||
flash(u'Deletion was aborted')
|
||||
return redirect(url_for('manage_categories'))
|
||||
move_to_id = request.form.get('move_to', type=int)
|
||||
if move_to_id:
|
||||
move_to = Category.query.get(move_to_id)
|
||||
if move_to is None:
|
||||
flash(u'Category was removed in the meantime')
|
||||
else:
|
||||
for snippet in category.snippets.all():
|
||||
snippet.category = move_to
|
||||
db_session.delete(category)
|
||||
flash(u'Category %s deleted and entries moved to %s.' %
|
||||
(category.name, move_to.name))
|
||||
else:
|
||||
category.snippets.delete()
|
||||
db_session.delete(category)
|
||||
flash(u'Category %s deleted' % category.name)
|
||||
db_session.commit()
|
||||
return redirect(url_for('manage_categories'))
|
||||
return render_template('snippets/delete_category.html',
|
||||
category=category,
|
||||
other_categories=Category.query
|
||||
.filter(Category.id != category.id).all())
|
||||
|
||||
|
||||
@snippets.route('/recent.atom')
|
||||
def recent_feed():
|
||||
feed = AtomFeed(u'Recent Flask Snippets',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue