API update - new comments format

This commit is contained in:
Srijan Choudhary 2014-04-20 18:46:43 +05:30
parent d3aa8129c4
commit 71024cea70
2 changed files with 80 additions and 11 deletions

View File

@ -97,15 +97,31 @@ class Comments:
return None
def fetch(self, uri, mode=5):
def fetch(self, uri, mode=5, after=0, parent='any', order_by='id', limit=None):
"""
Return comments for :param:`uri` with :param:`mode`.
"""
rv = self.db.execute([
'SELECT comments.* FROM comments INNER JOIN threads ON',
' threads.uri=? AND comments.tid=threads.id AND (? | comments.mode) = ?'
'ORDER BY id ASC;'], (uri, mode, mode)).fetchall()
sql = [ 'SELECT comments.* FROM comments INNER JOIN threads ON',
' threads.uri=? AND comments.tid=threads.id AND (? | comments.mode) = ?',
' AND comments.created>?']
sql_args = [uri, mode, mode, after]
if parent != 'any':
if parent is None or parent == 'NULL':
sql.append('AND comments.parent IS NULL')
else:
sql.append('AND comments.parent=?')
sql_args.append(parent)
sql.append('ORDER BY ? ASC')
sql_args.append(order_by)
if limit != None and limit != 0:
sql.append('LIMIT ?')
sql_args.append(limit)
rv = self.db.execute(sql, sql_args).fetchall()
for item in rv:
yield dict(zip(Comments.fields, item))
@ -181,6 +197,17 @@ class Comments:
return {'likes': likes + 1, 'dislikes': dislikes}
return {'likes': likes, 'dislikes': dislikes + 1}
def reply_count(self, url):
"""
Return comment count for main thread and all reply threads for one url.
"""
sql = [ 'SELECT comments.parent,count(*) FROM comments INNER JOIN threads ON',
' threads.uri=? AND comments.tid=threads.id',
' AND comments.mode = 1 group by comments.parent;']
return dict(self.db.execute(sql, [url]).fetchall())
def count(self, *urls):
"""
Return comment count for one ore more urls..

View File

@ -320,11 +320,53 @@ class API(object):
@requires(str, 'uri')
def fetch(self, environ, request, uri):
rv = list(self.comments.fetch(uri))
if not rv:
fetch_args={'uri': uri}
if request.args.get('after'):
fetch_args['after'] = request.args.get('after')
if request.args.get('limit'):
try:
fetch_args['limit'] = int(request.args.get('limit'))
except ValueError:
return BadRequest("Limit should be integer")
if request.args.get('parent'):
try:
fetch_args['parent'] = int(request.args.get('parent'))
root_id = int(request.args.get('parent'))
except ValueError:
return BadRequest("Parent should be integer")
else:
root_id = None
if request.args.get('plain', '0') == '0':
plain = True
else:
plain = False
reply_counts = self.comments.reply_count(uri)
full_list = list(self.comments.fetch(**fetch_args))
root_list = [i for i in full_list if i['parent'] == root_id]
if not root_list:
raise NotFound
for item in rv:
rv = {
'id' : root_id,
'passed_replies' : len(root_list),
'total_replies' : reply_counts[root_id],
'replies' : self.process_fetched_list(root_list, plain)
}
# We are only checking for one level deep comments
if root_id is None:
for comment in rv['replies']:
replies = [i for i in full_list if i['parent'] == comment['id']]
comment['passed_replies'] = len(replies)
comment['total_replies'] = reply_counts[comment['id']]
comment['replies'] = self.process_fetched_list(replies, plain)
return JSON(rv, 200)
def process_fetched_list(self, fetched_list, plain=False):
for item in fetched_list:
key = item['email'] or item['remote_addr']
val = self.cache.get('hash', key.encode('utf-8'))
@ -338,11 +380,11 @@ class API(object):
for key in set(item.keys()) - API.FIELDS:
item.pop(key)
if request.args.get('plain', '0') == '0':
for item in rv:
if plain:
for item in fetched_list:
item['text'] = self.isso.render(item['text'])
return JSON(rv, 200)
return fetched_list
@xhr
def like(self, environ, request, id):