-
Notifications
You must be signed in to change notification settings - Fork 0
/
comment.py
211 lines (182 loc) · 9.27 KB
/
comment.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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import jinja2
import os
import urllib
import webapp2
import rankdata
import category
import item
from google.appengine.ext import db
from google.appengine.api import users
jinja_environment = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
select_category_page_path = 'comment/selectcategory'
select_category_action_path = 'comment/selectcategoryaction'
select_item_page_path = 'comment/selectitem'
select_item_action_path = 'comment/selectitemaction'
make_comment_page_path = 'comment/makecomment'
make_comment_action_path = 'comment/makecommentaction'
def get_ancestor_key(category_key, item_name):
"""Returns ancestor key of the specified comment
Each comment must have an item ancestor. The format of ancestor key is
'author/category name/item name'. Also each item must have a category
ancestor. The category_key is actually the ancestor key of item which
format is 'author/category name'.
:param category_key the specified category key
:param item_name the specified item name
:returns: ancestor key of specified comment
"""
cate_key = db.Key.from_path('Category', category_key)
return db.Key.from_path('Item',
'{category_key}/{item}'.format(category_key=category_key, item=item_name),
parent=cate_key)
def get_comment(category_key, item_name, commenter):
"""Returns comment of specified categry key, item name, and commenter
Each item must have a category ancestor. The category_key is actually
the ancestor key of item which format is 'author/category name'
:param category_key the specified category key
:param item_name the specified item name
:param commenter the specified commenter
:returns: comment of specified category key, item name and commenter
"""
comment_key = db.Key.from_path('Comment',
'{category_key}/{item}/{commenter}'.format(category_key=category_key, item=item_name, commenter=commenter),
parent=get_ancestor_key(category_key, item_name))
return db.get(comment_key)
def get_comments(category_key, item_name, order='-submit_time'):
"""Returns all comments of specified category key, item name and order
Each item must have a category ancestor. The category_key is actually
the ancestor key of item which format is 'author/category name'
:param category_key the specified category key
:param item_name the specified item name
:param order the specified order. The default value is ordering by
submit time field in descending
:returns: all comments of specified category key, item name and order
"""
ancestor_key = get_ancestor_key(category_key, item_name)
comment_query = rankdata.Comment.all().ancestor(ancestor_key).order(order)
return comment_query.run()
def delete_all_comments(category_key, item_name):
"""Delete all comments of specified category key, and item name
Each item must have a category ancestor. The category_key is actually
the ancestor key of item which format is 'author/category name'
:param category_key the specified category key
:param item_name the specified item name
"""
ancestor_key = get_ancestor_key(category_key, item_name)
comment_query = rankdata.Comment.all().ancestor(ancestor_key)
for comment in comment_query.run():
db.delete(comment)
class SelectCategoryPage(webapp2.RequestHandler):
"""Construct select category HTML page
"""
def get(self):
"""Handle user request
The select category HTML page would list all categories of all
users. The user should select one of them
"""
invalid_select = self.request.get('select_category')
user = users.get_current_user()
categories = category.get_categories(item_number=1)
url = users.create_logout_url(self.request.uri) if user else users.create_login_url(self.request.uri)
template_values = {
'categories': categories,
'url': url,
'user': user,
'invalid_select': invalid_select,
}
template = jinja_environment.get_template('{path}.html'.format(path=select_category_page_path))
self.response.out.write(template.render(template_values))
class SelectCategoryAction(webapp2.RequestHandler):
"""Construct select item HTML page
"""
def get(self):
"""Handle user request
The select item HTML page would list all items in category. The
user should select one of them to comment
"""
category_key = self.request.get('category_key')
if not category_key:
self.redirect('/{path}?'.format(path=select_category_page_path) +
urllib.urlencode({'select_category': 'Nothing'}))
return
invalid_select = self.request.get('select_item')
user = users.get_current_user()
url = users.create_logout_url(self.request.uri) if user else users.create_login_url(self.request.uri)
category_data = category.get_category_by_key(key=category_key)
items = item.get_items(author=category_data.author, category_name=category_data.name)
template_values = {
'category': category_data,
'items': items,
'url': url,
'user': user,
'invalid_select': invalid_select,
}
template = jinja_environment.get_template('{path}.html'.format(path=select_item_page_path))
self.response.out.write(template.render(template_values))
class SelectItemAction(webapp2.RequestHandler):
"""Construct comment HTML page
"""
def get(self):
"""Handle user request
The comment HTML page would list all comments for the specified
item. User could submit a comment.
"""
category_key = self.request.get('category_key')
item_name = self.request.get('item_name')
if not item_name:
self.redirect('/{path}?'.format(path=select_category_action_path) +
urllib.urlencode({'category_key': category_key, 'select_item': 'Nothing'}))
return
invalid_comment = self.request.get('re_comment')
invalid_content = self.request.get('invalid_content')
user = users.get_current_user()
url = users.create_logout_url(self.request.uri)
category_data = category.get_category_by_key(key=category_key)
comment_item = item.get_item_by_key(category_key=category_key,
item_name=item_name)
comments = get_comments(category_key=category_key, item_name=item_name)
template_values = {
'category': category_data,
'item': comment_item,
'comments': comments,
'url': url,
'user': user,
'invalid_comment': invalid_comment,
'invalid_content': invalid_content,
}
template = jinja_environment.get_template('{path}.html'.format(path=make_comment_page_path))
self.response.out.write(template.render(template_values))
class MakeCommentAction(webapp2.RequestHandler):
"""Handle make comment form submition
"""
def post(self):
"""Handle user request
The comment must have at least 10 characters. User could not submit
comment for an item twice.
"""
category_key = self.request.get('category_key')
item_name = self.request.get('item_name')
content = self.request.get('content').strip()
if content == '':
self.redirect('/{path}?'.format(path=select_item_action_path) +
urllib.urlencode({'category_key': category_key, 'item_name': item_name, 'invalid_content': 'empty content'}))
return
elif len(content) < 10:
self.redirect('/{path}?'.format(path=select_item_action_path) +
urllib.urlencode({'category_key': category_key, 'item_name': item_name, 'invalid_content': content}))
return
user = users.get_current_user()
if get_comment(category_key=category_key, item_name=item_name, commenter=user):
self.redirect('/{path}?'.format(path=select_item_action_path) +
urllib.urlencode({'category_key': category_key, 'item_name': item_name, 're_comment': 'Replicate'}))
else:
comment = rankdata.Comment(key_name='{category_key}/{item}/{commenter}'.format(category_key=category_key, item=item_name, commenter=user),
parent=get_ancestor_key(category_key=category_key, item_name=item_name),
commenter=user, content=content)
comment.put()
self.redirect('/{path}?'.format(path=select_item_action_path) +
urllib.urlencode({'category_key': category_key, 'item_name': item_name}))
app = webapp2.WSGIApplication([('/{path}'.format(path=select_category_page_path), SelectCategoryPage),
('/{path}'.format(path=select_category_action_path), SelectCategoryAction),
('/{path}'.format(path=select_item_action_path), SelectItemAction),
('/{path}'.format(path=make_comment_action_path), MakeCommentAction)],
debug=True)