-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdiscuss.py
168 lines (150 loc) · 5.2 KB
/
discuss.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
__author__ = 'samportnow'
from flask import Flask, request, url_for, render_template, redirect, session
from flask.ext.pymongo import PyMongo
import datetime
from bson.objectid import ObjectId
import markdown2
from werkzeug.contrib.cache import SimpleCache
from flask import jsonify
app = Flask(__name__)
mongo = PyMongo(app)
cache = SimpleCache()
cached_comments = None
#
app.jinja_env.filters['markdownify'] = markdown2.markdown
@app.route('/clear/')
def clear():
mongo.db.comments.remove()
cache.clear()
return redirect(url_for('home'))
@app.route('/<content_id>/', methods=['GET', 'POST'])
def home(content_id):
#cached_comments is going to be global, so we can update it
#as needed when users vote, without querying the database
global cached_comments
#if there's a post, we add the comment
if request.method == 'POST':
add_comment()
#in order to render the comments, we first get a cursor that
#is the all of the comments without parent. these are
#our first level comments
cursor = mongo.db.comments.find({
'parent' : None,
'content_id' : content_id,
})
#once we have this cursor, we look up all the comments
if cache.get(content_id) is None:
comments = get_all_comments(cursor=cursor)
cache.set(content_id, comments, timeout=500000)
cached_comments = cache.get(content_id)
else:
cached_comments = cache.get(content_id)
return render_template('node.html', **{
'comments' : cached_comments,
'content_id' : content_id,
})
def add_comment():
""" Add a comment or reply. """
# Validate parent ID, if there is one
parent_id = request.form.get('parent', None)
if parent_id:
parent_id = ObjectId(parent_id)
if not mongo.db.comments.find({'_id': parent_id}).count():
raise Exception('Parent ID doesn\'t exist.')
content_id = request.form.get('content_id', None)
if content_id is None:
raise Exception('Must provide content ID.')
# Validate indent, the indent is where you get the
# 'threading'. if there's no indent val, this
# defaults to 0
#we want to know when the comments were posted
posted = datetime.datetime.utcnow()
#we want to know the text
text = request.form['comment']
if not text.strip():
return
if parent_id:
mongo.db.comments.update(
{'_id':parent_id},
{'$set':{'last':False}})
cursor = mongo.db.comments.find_one({
'parent' : parent_id,
'content_id' : content_id,
})
new_id = mongo.db.comments.insert({
'posted': posted,
'text': text,
'parent': parent_id,
'children': [],
'votes': 1,
'content_id': content_id,
})
#if this is a reply, we update that 'document'
#to include a ref to its a child (the reply)
if parent_id:
mongo.db.comments.update(
{'_id': parent_id},
{'$push': {'children': {
'ref_id': str(new_id),
}}})
# Refresh home page
cache.clear()
return redirect(url_for('home', content_id=content_id))
def get_all_comments(cursor):
"""
we recursively go through the db. we go
through all of the first level comments,
but if they have children, hit those directly
after so we get the children before we get the
rest of the first level comments.
each time we add to our list of comments
"""
comments = list(cursor)
for comment_idx in range(len(comments)):
comment = comments[comment_idx]
child_refs = comment['children']
children = []
for child_idx in range(len(child_refs)):
children += get_all_comments(
mongo.db.comments.find({
'_id' : ObjectId(child_refs[child_idx]['ref_id']),
})
)
comment['children'] = children
return comments
@app.route('/vote/', methods=['GET','POST'])
def vote():
val = request.form.get("val", None)
id = request.form.get("id", None)
comment = mongo.db.comments.find_one({
'_id' : ObjectId(id),
})
votes = comment['votes']
content_id = comment['content_id']
#votes = mongo.db.comments.find_one({'_id':ObjectId(id)})['votes']
votes += int(val)
mongo.db.comments.update(
{'_id':ObjectId(id)},
{'$set':{'votes':votes}})
#update the comment to store the vote
update_comment(cached_comments, ObjectId(id), 'votes', int(val))
#reset the cache
cache.set(content_id, cached_comments)
return jsonify(votes=votes)
def update_comment(comment_cache, _id, key, value):
#queue is a copy of our comment cache
queue = comment_cache[:]
while queue:
#comments is the current index of the queue
#(we removed as we iterate)
comments = queue.pop(0)
#if we get the correct id, we ad the value to it
if comments['_id'] == _id:
print 'WHAT UP I FOUND THE COMMENT'
comments[key] += value
return
#if we have children we add it to the end of the queue
if comments['children']:
queue.extend(comments['children'])
if __name__ == '__main__':
app.run(debug=True)