new /count?uri=path and count.js
A separate (minified) JS to load only the comment count for each `<a href="...#isso-thread">...</a>` link. If there are no comments, return a 404, otherwise return the number JSON formatted. To built `count.ks`, run `r.js -o build.count.js`.
This commit is contained in:
parent
1105e3e016
commit
45d4e18aef
@ -54,6 +54,7 @@ url_map = Map([
|
||||
Rule('/', methods=['PUT', 'DELETE'], endpoint=views.comment.modify),
|
||||
Rule('/new', methods=['POST'], endpoint=views.comment.create),
|
||||
Rule('/like', methods=['POST'], endpoint=views.comment.like),
|
||||
Rule('/count', methods=['GET'], endpoint=views.comment.count),
|
||||
|
||||
Rule('/admin/', endpoint=views.admin.index)
|
||||
])
|
||||
|
18
isso/db.py
18
isso/db.py
@ -73,6 +73,13 @@ class Abstract:
|
||||
same ip address are ignored as well)."""
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def count(self, path=None, mode=1):
|
||||
"""return count of comments for path (optional) and mode (defaults to
|
||||
visible, not deleted or moderated comments)."""
|
||||
return
|
||||
|
||||
|
||||
class SQLite(Abstract):
|
||||
"""A basic :class:`Abstract` implementation using SQLite3. All comments
|
||||
share a single database. The tuple (id, path) acts as unique identifier
|
||||
@ -213,6 +220,17 @@ class SQLite(Abstract):
|
||||
|
||||
return likes + 1
|
||||
|
||||
def count(self, path=None, mode=1):
|
||||
|
||||
if path is not None:
|
||||
with sqlite3.connect(self.dbpath) as con:
|
||||
return con.execute("SELECT COUNT(*) FROM comments WHERE path=?" \
|
||||
+ " AND (? | mode) = ?", (path, mode, mode)).fetchone()
|
||||
|
||||
with sqlite3.connect(self.dbpath) as con:
|
||||
return con.execute("SELECT COUNT(*) FROM comments WHERE" \
|
||||
+ "(? | mode) = ?", (path, mode, mode)).fetchone()
|
||||
|
||||
def retrieve(self, path, mode=5):
|
||||
with sqlite3.connect(self.dbpath) as con:
|
||||
rv = con.execute("SELECT * FROM comments WHERE path=? AND (? | mode) = ?" \
|
||||
|
@ -104,11 +104,22 @@ define(["lib/q"], function(Q) {
|
||||
})
|
||||
}
|
||||
|
||||
var count = function(uri) {
|
||||
return curl("GET", endpoint + "/count?" + qs({uri: uri}), null)
|
||||
.then(function (rv) {
|
||||
if (rv.status == 200)
|
||||
return JSON.parse(rv.body)
|
||||
|
||||
throw {status: rv.status, reason: rv.body};
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
endpoint: endpoint,
|
||||
create: create,
|
||||
remove: remove,
|
||||
fetchall: fetchall
|
||||
fetchall: fetchall,
|
||||
count: count
|
||||
}
|
||||
|
||||
});
|
16
isso/js/app/count.js
Normal file
16
isso/js/app/count.js
Normal file
@ -0,0 +1,16 @@
|
||||
define(["app/api", "lib/HTML"], function(api, HTML) {
|
||||
return function() {
|
||||
HTML.query("a").each(function(el, i, all) {
|
||||
if (! el.href.match("#isso-thread$")) {
|
||||
return;
|
||||
};
|
||||
|
||||
var uri = el.href.match("^(.+)#isso-thread$")[1]
|
||||
.replace(/^.*\/\/[^\/]+/, '');
|
||||
console.log(uri)
|
||||
api.count(uri).then(function(rv) {
|
||||
el.textContent = rv + (rv > 1 ? " Kommentare" : " Kommentar");
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
7
isso/js/build.count.js
Normal file
7
isso/js/build.count.js
Normal file
@ -0,0 +1,7 @@
|
||||
({
|
||||
bseUrl: ".",
|
||||
name: "lib/almond",
|
||||
include: ['count'],
|
||||
out: "count.min.js",
|
||||
wrap: true
|
||||
})
|
5
isso/js/count.js
Normal file
5
isso/js/count.js
Normal file
@ -0,0 +1,5 @@
|
||||
require(["lib/ready", "app/count"], function(domready, count) {
|
||||
domready(function() {
|
||||
count();
|
||||
})
|
||||
});
|
@ -1,5 +1,6 @@
|
||||
require(["lib/ready", "app/isso"], function(domready, isso) {
|
||||
require(["lib/ready", "app/isso", "app/count"], function(domready, isso, count) {
|
||||
domready(function() {
|
||||
count();
|
||||
isso.init();
|
||||
})
|
||||
});
|
||||
|
@ -168,3 +168,14 @@ def approve(app, environ, request, path, id):
|
||||
app.db.activate(path, id)
|
||||
return Response(app.dumps(app.db.get(path, id)), 200,
|
||||
content_type='application/json')
|
||||
|
||||
|
||||
@requires(str, 'uri')
|
||||
def count(app, environ, request, uri):
|
||||
|
||||
rv = app.db.count(uri, mode=1)[0]
|
||||
|
||||
if rv == 0:
|
||||
abort(404)
|
||||
|
||||
return Response(json.dumps(rv), 200, content_type='application/json')
|
||||
|
@ -201,3 +201,25 @@ class TestComments(unittest.TestCase):
|
||||
|
||||
assert rv.keys() == []
|
||||
|
||||
def testCounts(self):
|
||||
|
||||
assert self.get('/count?uri=%2Fpath%2F').status_code == 404
|
||||
self.post('/new?uri=%2Fpath%2F', data=json.dumps({"text": "..."}))
|
||||
|
||||
rv = self.get('/count?uri=%2Fpath%2F')
|
||||
assert rv.status_code == 200
|
||||
assert json.loads(rv.data) == 1
|
||||
|
||||
for x in range(3):
|
||||
self.post('/new?uri=%2Fpath%2F', data=json.dumps({"text": "..."}))
|
||||
|
||||
rv = self.get('/count?uri=%2Fpath%2F')
|
||||
assert rv.status_code == 200
|
||||
assert json.loads(rv.data) == 4
|
||||
|
||||
for x in range(4):
|
||||
self.delete('/?uri=%%2Fpath%%2F&id=%i' % (x + 1))
|
||||
|
||||
rv = self.get('/count?uri=%2Fpath%2F')
|
||||
assert rv.status_code == 404
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user