1 from django.core import validators
2 from django import oldforms
3 from django.core.mail import mail_admins, mail_managers
4 from django.http import Http404
5 from django.core.exceptions import ObjectDoesNotExist
6 from django.shortcuts import render_to_response
7 from django.template import RequestContext
8 from django.contrib.comments.models import Comment, FreeComment, RATINGS_REQUIRED, RATINGS_OPTIONAL, IS_PUBLIC
9 from django.contrib.contenttypes.models import ContentType
10 from django.contrib.auth.forms import AuthenticationForm
11 from django.http import HttpResponseRedirect
12 from django.utils.text import normalize_newlines
13 from django.conf import settings
14 from django.utils.translation import ungettext, ugettext as _
15 from django.utils.encoding import smart_unicode
16 import base64, datetime
17
18 COMMENTS_PER_PAGE = 20
19
73
78
89
120
157
159 """
160 Post a comment
161
162 Redirects to the `comments.comments.comment_was_posted` view upon success.
163
164 Templates: `comment_preview`
165 Context:
166 comment
167 the comment being posted
168 comment_form
169 the comment form
170 options
171 comment options
172 target
173 comment target
174 hash
175 security hash (must be included in a posted form to succesfully
176 post a comment).
177 rating_options
178 comment ratings options
179 ratings_optional
180 are ratings optional?
181 ratings_required
182 are ratings required?
183 rating_range
184 range of ratings
185 rating_choices
186 choice of ratings
187 """
188 if extra_context is None: extra_context = {}
189 if not request.POST:
190 raise Http404, _("Only POSTs are allowed")
191 try:
192 options, target, security_hash = request.POST['options'], request.POST['target'], request.POST['gonzo']
193 except KeyError:
194 raise Http404, _("One or more of the required fields wasn't submitted")
195 photo_options = request.POST.get('photo_options', '')
196 rating_options = normalize_newlines(request.POST.get('rating_options', ''))
197 if Comment.objects.get_security_hash(options, photo_options, rating_options, target) != security_hash:
198 raise Http404, _("Somebody tampered with the comment form (security violation)")
199
200 if rating_options:
201 rating_range, rating_choices = Comment.objects.get_rating_options(base64.decodestring(rating_options))
202 else:
203 rating_range, rating_choices = [], []
204 content_type_id, object_id = target.split(':')
205 try:
206 obj = ContentType.objects.get(pk=content_type_id).get_object_for_this_type(pk=object_id)
207 except ObjectDoesNotExist:
208 raise Http404, _("The comment form had an invalid 'target' parameter -- the object ID was invalid")
209 option_list = options.split(',')
210 new_data = request.POST.copy()
211 new_data['content_type_id'] = content_type_id
212 new_data['object_id'] = object_id
213 new_data['ip_address'] = request.META.get('REMOTE_ADDR')
214 new_data['is_public'] = IS_PUBLIC in option_list
215 manipulator = PublicCommentManipulator(request.user,
216 ratings_required=RATINGS_REQUIRED in option_list,
217 ratings_range=rating_range,
218 num_rating_choices=len(rating_choices))
219 errors = manipulator.get_validation_errors(new_data)
220
221
222 if manipulator.get_user() and not manipulator.get_user().is_authenticated() and 'password' in new_data and manipulator.get_user().check_password(new_data['password']):
223 from django.contrib.auth import login
224 login(request, manipulator.get_user())
225 if errors or 'preview' in request.POST:
226 class CommentFormWrapper(oldforms.FormWrapper):
227 def __init__(self, manipulator, new_data, errors, rating_choices):
228 oldforms.FormWrapper.__init__(self, manipulator, new_data, errors)
229 self.rating_choices = rating_choices
230 def ratings(self):
231 field_list = [self['rating%d' % (i+1)] for i in range(len(rating_choices))]
232 for i, f in enumerate(field_list):
233 f.choice = rating_choices[i]
234 return field_list
235 comment = errors and '' or manipulator.get_comment(new_data)
236 comment_form = CommentFormWrapper(manipulator, new_data, errors, rating_choices)
237 return render_to_response('comments/preview.html', {
238 'comment': comment,
239 'comment_form': comment_form,
240 'options': options,
241 'target': target,
242 'hash': security_hash,
243 'rating_options': rating_options,
244 'ratings_optional': RATINGS_OPTIONAL in option_list,
245 'ratings_required': RATINGS_REQUIRED in option_list,
246 'rating_range': rating_range,
247 'rating_choices': rating_choices,
248 }, context_instance=RequestContext(request, extra_context, context_processors))
249 elif 'post' in request.POST:
250
251
252 if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
253 mail_admins("Banned IP attempted to post comment", smart_unicode(request.POST) + "\n\n" + str(request.META))
254 else:
255 manipulator.do_html2python(new_data)
256 comment = manipulator.save(new_data)
257 return HttpResponseRedirect("../posted/?c=%s:%s" % (content_type_id, object_id))
258 else:
259 raise Http404, _("The comment form didn't provide either 'preview' or 'post'")
260
262 """
263 Post a free comment (not requiring a log in)
264
265 Redirects to `comments.comments.comment_was_posted` view on success.
266
267 Templates: `comment_free_preview`
268 Context:
269 comment
270 comment being posted
271 comment_form
272 comment form object
273 options
274 comment options
275 target
276 comment target
277 hash
278 security hash (must be included in a posted form to succesfully
279 post a comment).
280 """
281 if extra_context is None: extra_context = {}
282 if not request.POST:
283 raise Http404, _("Only POSTs are allowed")
284 try:
285 options, target, security_hash = request.POST['options'], request.POST['target'], request.POST['gonzo']
286 except KeyError:
287 raise Http404, _("One or more of the required fields wasn't submitted")
288 if Comment.objects.get_security_hash(options, '', '', target) != security_hash:
289 raise Http404, _("Somebody tampered with the comment form (security violation)")
290 content_type_id, object_id = target.split(':')
291 content_type = ContentType.objects.get(pk=content_type_id)
292 try:
293 obj = content_type.get_object_for_this_type(pk=object_id)
294 except ObjectDoesNotExist:
295 raise Http404, _("The comment form had an invalid 'target' parameter -- the object ID was invalid")
296 option_list = options.split(',')
297 new_data = request.POST.copy()
298 new_data['content_type_id'] = content_type_id
299 new_data['object_id'] = object_id
300 new_data['ip_address'] = request.META['REMOTE_ADDR']
301 new_data['is_public'] = IS_PUBLIC in option_list
302 manipulator = PublicFreeCommentManipulator()
303 errors = manipulator.get_validation_errors(new_data)
304 if errors or 'preview' in request.POST:
305 comment = errors and '' or manipulator.get_comment(new_data)
306 return render_to_response('comments/free_preview.html', {
307 'comment': comment,
308 'comment_form': oldforms.FormWrapper(manipulator, new_data, errors),
309 'options': options,
310 'target': target,
311 'hash': security_hash,
312 }, context_instance=RequestContext(request, extra_context, context_processors))
313 elif 'post' in request.POST:
314
315
316 if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
317 from django.core.mail import mail_admins
318 mail_admins("Practical joker", smart_unicode(request.POST) + "\n\n" + str(request.META))
319 else:
320 manipulator.do_html2python(new_data)
321 comment = manipulator.save(new_data)
322 return HttpResponseRedirect("../posted/?c=%s:%s" % (content_type_id, object_id))
323 else:
324 raise Http404, _("The comment form didn't provide either 'preview' or 'post'")
325
346