Admin interface.
parent
41ffb610e8
commit
7a63237a10
14
manage.py
14
manage.py
|
@ -1,5 +1,8 @@
|
|||
import sys
|
||||
import sqlite3
|
||||
import hashlib
|
||||
import getpass
|
||||
import random
|
||||
try:
|
||||
from webapp import config
|
||||
except ImportError:
|
||||
|
@ -43,5 +46,16 @@ def main():
|
|||
conn.commit()
|
||||
conn.close()
|
||||
sys.stdout.write("Database create succesfully.\n")
|
||||
elif action == "createadmin":
|
||||
username = raw_input("Username: ")
|
||||
password = getpass.getpass()
|
||||
realname = raw_input("Real Name: ")
|
||||
conn = sqlite3.connect(config.DB_FILE)
|
||||
salt = ''.join([random.choice([chr(c) for c in range(ord('a'), ord('z'))]) for _ in range(20)])
|
||||
c = conn.cursor()
|
||||
hashed = hashlib.sha256(password + salt).hexdigest()
|
||||
c.execute("INSERT INTO users (_username, _password, _salt, _real_name) VALUES (?, ?, ?, ?)", [username, hashed, salt, realname])
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
sys.exit(main())
|
||||
|
|
|
@ -401,3 +401,13 @@ ul.form-errors li {
|
|||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
ul.flashes {
|
||||
margin: 0 0 0 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.flashes li {
|
||||
list-style: none;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
|
|
@ -20,5 +20,13 @@ $(function(){
|
|||
}
|
||||
$(".upvote").click(vote_click);
|
||||
$(".downvote").click(vote_click);
|
||||
$(".ajaxhide").click(function() {
|
||||
var url = $(this).attr("href");
|
||||
var quote = $(this).parent().parent();
|
||||
$.get(url, function() {
|
||||
$(quote).fadeOut("normal");
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
<a class="downvote" href="#" style="text-decoration: line-through;">Down↓</a>
|
||||
{% endif %}
|
||||
{{ quote.date }}
|
||||
{% if admin %}
|
||||
<a class="ajaxhide" href="/quotes/approve/{{ quote.id }}">approve</a>
|
||||
<a class="ajaxhide" href="/quotes/delete/{{ quote.id }}">delete</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="quotetext">{{ quote.text|safe }}</p>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import flask
|
||||
import time
|
||||
import hashlib
|
||||
from webapp import app, config, database, forms
|
||||
|
||||
def get_quotes():
|
||||
|
@ -20,12 +21,24 @@ def get_quotes():
|
|||
|
||||
def get_user_votes(_id):
|
||||
"""Get user votes (if any) for quote id."""
|
||||
if ("vote_%i" % _id) in flask.session:
|
||||
return int(flask.session["vote_%i" % _id])
|
||||
database.execute("SELECT _approved FROM quotes WHERE _id = ?;", _id)
|
||||
approved = database.fetchall()[0][0]
|
||||
if approved:
|
||||
key = "vote_%i" % _id
|
||||
else:
|
||||
key = "uvote_%i" % _id
|
||||
if key in flask.session:
|
||||
return int(flask.session[key])
|
||||
return 0
|
||||
|
||||
def set_user_votes(_id, votes):
|
||||
flask.session["vote_%i" % _id] = str(votes)
|
||||
database.execute("SELECT _approved FROM quotes WHERE _id = ?;", _id)
|
||||
approved = database.fetchall()[0][0]
|
||||
if approved:
|
||||
key = "vote_%i" % _id
|
||||
else:
|
||||
key = "uvote_%i" % _id
|
||||
flask.session[key] = str(votes)
|
||||
|
||||
def upvote(_id):
|
||||
if get_user_votes(_id) < 1:
|
||||
|
@ -59,7 +72,7 @@ def recent_quotes():
|
|||
def queue_quotes():
|
||||
database.execute("SELECT _id, _up, _down, _text, _meta, _date FROM quotes WHERE _approved = 0;")
|
||||
quotes = get_quotes()
|
||||
return flask.render_template("list.html", quotes=quotes, title="Moderation Queue")
|
||||
return flask.render_template("list.html", quotes=quotes, title="Moderation Queue", admin = "username" in flask.session)
|
||||
|
||||
@app.route("/quotes/view/<int:_id>")
|
||||
def quote_view(_id):
|
||||
|
@ -77,13 +90,53 @@ def downvote_quote(_id):
|
|||
downvote(_id)
|
||||
return quote_view(_id)
|
||||
|
||||
@app.route("/quotes/approve/<int:_id>")
|
||||
def approve_quote(_id):
|
||||
if "username" not in flask.session:
|
||||
return quote_view(_id)
|
||||
database.execute("UPDATE quotes SET _approved = 1 WHERE _id = ?", _id)
|
||||
database.execute("UPDATE quotes SET _up = 0 WHERE _id = ?", _id)
|
||||
database.execute("UPDATE quotes SET _down = 0 WHERE _id = ?", _id)
|
||||
return quote_view(_id)
|
||||
|
||||
@app.route("/quotes/delete/<int:_id>")
|
||||
def delete_quote(_id):
|
||||
if "username" not in flask.session:
|
||||
return quote_view(_id)
|
||||
database.execute("DELETE FROM quotes WHERE _id = ?", _id)
|
||||
return quote_view(_id)
|
||||
|
||||
|
||||
@app.route("/new", methods=["GET", "POST"])
|
||||
def new_quote():
|
||||
form = forms.NewQuote(flask.request.form)
|
||||
if flask.request.method == "POST" and form.validate():
|
||||
database.execute("INSERT INTO quotes (_text, _meta, _date) VALUES (?, ?, ?);", form.text.data, form.meta.data, time.time())
|
||||
flask.flash("Quote added to mdoeration queue.")
|
||||
flask.flash("Quote added to moderation queue.")
|
||||
return flask.redirect(flask.url_for('recent_quotes'))
|
||||
return flask.render_template('new_quote.html', form=form)
|
||||
|
||||
@app.route("/login", methods=["GET", "POST"])
|
||||
def login():
|
||||
if flask.request.method == "POST":
|
||||
username = flask.request.form["username"]
|
||||
password = flask.request.form["password"]
|
||||
database.execute("SELECT _password, _salt FROM users WHERE _username = ?;", username)
|
||||
users = database.fetchall()
|
||||
if len(users) != 1:
|
||||
flask.flash("Invalid login data.")
|
||||
return flask.redirect(flask.url_for('recent_quotes'))
|
||||
_hash, salt = users[0]
|
||||
hashed = hashlib.sha256(password + salt).hexdigest()
|
||||
if hashed != _hash:
|
||||
flask.flash("Invalid login data.")
|
||||
return flask.redirect(flask.url_for('recent_quotes'))
|
||||
flask.session["username"] = username
|
||||
flask.flash("Succesfully logged in.")
|
||||
return flask.redirect(flask.url_for('queue_quotes'))
|
||||
|
||||
return """<form action="/login" method="post">
|
||||
<input type="text" name="username" />
|
||||
<input type="password" name="password" />
|
||||
<input type="submit" />
|
||||
</form>"""
|
||||
|
|
Reference in New Issue