admin interface can delete comments :>

This commit is contained in:
posativ 2012-10-24 23:22:39 +02:00
parent 15ead12683
commit 6bb7b8c8d9
6 changed files with 132 additions and 8 deletions

View File

@ -31,4 +31,5 @@ def index(app, environ, request):
except (SignatureExpired, BadSignature):
return redirect('/')
return Response(render('admin.mako'), content_type='text/html')
ctx = {'app': app, 'request': request}
return Response(render('admin.mako', **ctx), content_type='text/html')

View File

@ -65,13 +65,13 @@ def modify(app, environ, request, path, id):
try:
rv = app.unsign(request.cookies.get('session-%s-%s' % (urllib.quote(path, ''), id), ''))
except (SignatureExpired, BadSignature):
return abort(403)
try:
rv = app.unsign(request.cookies.get('session-admin', ''))
except (SignatureExpired, BadSignature):
return abort(403)
# verify checksum, mallory might skip cookie deletion when he deletes a comment
if app.db.get(path, id).md5 != rv[2]:
abort(403)
if not (rv[0] == '*' or rv[0:2] == [path, id]):
if not (rv == '*' or rv[0:2] == [path, id] or app.db.get(path, id).md5 != rv[2]):
abort(403)
if request.method == 'PUT':

View File

@ -44,7 +44,7 @@ class Abstract:
by another valid comment's parent attribute or stand-a-lone. In this
case the comment can't be removed without losing depending comments.
Hence, delete removes all visible data such as text, author, email,
website sets the mode field to 2.
website sets the mode field to 4.
In the second case this comment can be safely removed without any side
effects."""
@ -145,7 +145,7 @@ class SQLite(Abstract):
def delete(self, path, id):
with sqlite3.connect(self.dbpath) as con:
refs = con.execute('SELECT * FROM comments WHERE parent=?', (id, )).fetchone()
refs = con.execute('SELECT * FROM comments WHERE path=? AND parent=?', (path, id)).fetchone()
if refs is None:
con.execute('DELETE FROM comments WHERE path=? AND id=?', (path, id))

52
isso/templates/admin.js Normal file
View File

@ -0,0 +1,52 @@
function remove(path, id, func) {
$.ajax({
url: '/1.0/' + encodeURIComponent(path) + '/' + id,
method: 'DELETE',
type: 'json',
error: function(resp) {
alert('Mööp.');
},
success: function(resp) {
func();
},
});
};
// function approve(path, id, func) {
// $.ajax({
// url: ''
// })
// }
function initialize() {
$('article > footer > a').forEach(function(item) {
var node = $(item).parent().parent()[0]
var path = node.getAttribute("data-path");
var id = node.getAttribute("data-id");
if (item.text == 'Approve') {
$(item).on('click', function(event) {
event.stop();
});
} else {
$(item).on('click', function(event) {
if (confirm("RLY?") == true) {
remove(path, id, function() {
$(node).remove()
});
};
event.stop();
});
};
});
};
$.domReady(function() {
initialize();
});

View File

@ -1,17 +1,84 @@
<%inherit file="base.mako"/>
<%block name="js">
<%include file="admin.js"/>
</%block>
<%
from time import strftime, gmtime
from urllib import quote, urlencode
from urlparse import parse_qsl
def query(**kw):
qs = dict(parse_qsl(request.query_string))
qs.update(kw)
return urlencode(qs)
def get(name, convert):
limit = request.args.get(name)
return convert(limit) if limit is not None else None
%>
<%block name="title">
Isso Dashboard
</%block>
<%def name="make(comment)">
<article data-path="${quote(comment.path)}" data-id="${comment.id}">
<header>
<h1><a href="${comment.path}">${comment.path}</a></h1>
<span class="created">${strftime('%a %d %B %Y', gmtime(comment.created))}</span>
<span class="author">
% if comment.website:
<a href="${comment.website}">${comment.author}</a>
% else:
${comment.author}
% endif
</span>
<span class="email">${comment.email}</span>
</header>
<div class="text">
${app.markup.convert(comment.text)}
</div>
<footer>
% if comment.pending:
<a href="#">Approve</a> |
% endif
<a href="#">Delete</a>
</footer>
</article>
</%def>
<h1>Dashboard</h1>
<div>
<h2>Pending</h2>
<span class="limit">
[ <a href="?${query(pendinglimit=10)}">10</a>
| <a href="?${query(pendinglimit=20)}">20</a>
| <a href="?${query(pendinglimit=0)}">All</a> ]
</span>
% for comment in app.db.recent(limit=get('pendinglimit', int), mode=2):
${make(comment)}
% endfor
</div>
<div>
<h2>Recent</h2>
<span class="limit">
[<a href="?${query(recentlimit=10)}">10</a>
| <a href="?${query(recentlimit=20)}">20</a>
| <a href="?${query(recentlimit=0)}">All</a>]
</span>
% for comment in app.db.recent(limit=get('recentlimit', int), mode=5):
${make(comment)}
% endfor
</div>

View File

@ -2,6 +2,10 @@
<head>
<title><%block name="title" /></title>
<meta charset="utf-8" />
<script type="text/javascript" src="/static/ender.js"></script>
<script type="text/javascript">
<%block name="js" />
</script>
<style>
body {