Example #1
0
 def render(self, context):
     from django.utils.text import normalize_newlines
     import base64
     context.push()
     if self.obj_id_lookup_var is not None:
         try:
             self.obj_id = template.resolve_variable(self.obj_id_lookup_var, context)
         except template.VariableDoesNotExist:
             return ''
         # Validate that this object ID is valid for this content-type.
         # We only have to do this validation if obj_id_lookup_var is provided,
         # because do_comment_form() validates hard-coded object IDs.
         try:
             self.content_type.get_object_for_this_type(pk=self.obj_id)
         except ObjectDoesNotExist:
             context['display_form'] = False
         else:
             context['display_form'] = True
     else:
         context['display_form'] = True
     context['target'] = '%s:%s' % (self.content_type.id, self.obj_id)
     options = []
     for var, abbr in (('photos_required', comments.PHOTOS_REQUIRED),
                       ('photos_optional', comments.PHOTOS_OPTIONAL),
                       ('ratings_required', comments.RATINGS_REQUIRED),
                       ('ratings_optional', comments.RATINGS_OPTIONAL),
                       ('is_public', comments.IS_PUBLIC)):
         context[var] = getattr(self, var)
         if getattr(self, var):
             options.append(abbr)
     context['options'] = ','.join(options)
     if self.free:
         context['hash'] = comments.get_security_hash(context['options'], '', '', context['target'])
         default_form = FREE_COMMENT_FORM
     else:
         context['photo_options'] = self.photo_options
         context['rating_options'] = normalize_newlines(base64.encodestring(self.rating_options).strip())
         if self.rating_options:
             context['rating_range'], context['rating_choices'] = comments.get_rating_options(self.rating_options)
         context['hash'] = comments.get_security_hash(context['options'], context['photo_options'], context['rating_options'], context['target'])
         default_form = COMMENT_FORM
     output = template.Template(default_form).render(context)
     context.pop()
     return output
Example #2
0
def post_comment(request):
    """
    Post a comment

    Redirects to the `comments.comments.comment_was_posted` view upon success.

    Templates: `comment_preview`
    Context:
        comment
            the comment being posted
        comment_form
            the comment form
        options
            comment options
        target
            comment target
        hash
            security hash (must be included in a posted form to succesfully
            post a comment).
        rating_options
            comment ratings options
        ratings_optional
            are ratings optional?
        ratings_required
            are ratings required?
        rating_range
            range of ratings
        rating_choices
            choice of ratings
    """
    if not request.POST:
        raise Http404, "Only POSTs are allowed"
    try:
        options, target, security_hash = request.POST['options'], request.POST['target'], request.POST['gonzo']
    except KeyError:
        raise Http404, "One or more of the required fields wasn't submitted"
    photo_options = request.POST.get('photo_options', '')
    rating_options = normalize_newlines(request.POST.get('rating_options', ''))
    if comments.get_security_hash(options, photo_options, rating_options, target) != security_hash:
        raise Http404, "Somebody tampered with the comment form (security violation)"
    # Now we can be assured the data is valid.
    if rating_options:
        rating_range, rating_choices = comments.get_rating_options(base64.decodestring(rating_options))
    else:
        rating_range, rating_choices = [], []
    content_type_id, object_id = target.split(':') # target is something like '52:5157'
    try:
        obj = contenttypes.get_object(pk=content_type_id).get_object_for_this_type(pk=object_id)
    except ObjectDoesNotExist:
        raise Http404, "The comment form had an invalid 'target' parameter -- the object ID was invalid"
    option_list = options.split(',') # options is something like 'pa,ra'
    new_data = request.POST.copy()
    new_data['content_type_id'] = content_type_id
    new_data['object_id'] = object_id
    new_data['ip_address'] = request.META.get('REMOTE_ADDR')
    new_data['is_public'] = comments.IS_PUBLIC in option_list
    manipulator = PublicCommentManipulator(request.user,
        ratings_required=comments.RATINGS_REQUIRED in option_list,
        ratings_range=rating_range,
        num_rating_choices=len(rating_choices))
    errors = manipulator.get_validation_errors(new_data)
    # If user gave correct username/password and wasn't already logged in, log them in
    # so they don't have to enter a username/password again.
    if manipulator.get_user() and new_data.has_key('password') and manipulator.get_user().check_password(new_data['password']):
        request.session[users.SESSION_KEY] = manipulator.get_user_id()
    if errors or request.POST.has_key('preview'):
        class CommentFormWrapper(formfields.FormWrapper):
            def __init__(self, manipulator, new_data, errors, rating_choices):
                formfields.FormWrapper.__init__(self, manipulator, new_data, errors)
                self.rating_choices = rating_choices
            def ratings(self):
                field_list = [self['rating%d' % (i+1)] for i in range(len(rating_choices))]
                for i, f in enumerate(field_list):
                    f.choice = rating_choices[i]
                return field_list
        comment = errors and '' or manipulator.get_comment(new_data)
        comment_form = CommentFormWrapper(manipulator, new_data, errors, rating_choices)
        return render_to_response('comments/preview', {
            'comment': comment,
            'comment_form': comment_form,
            'options': options,
            'target': target,
            'hash': security_hash,
            'rating_options': rating_options,
            'ratings_optional': comments.RATINGS_OPTIONAL in option_list,
            'ratings_required': comments.RATINGS_REQUIRED in option_list,
            'rating_range': rating_range,
            'rating_choices': rating_choices,
        }, context_instance=DjangoContext(request))
    elif request.POST.has_key('post'):
        # If the IP is banned, mail the admins, do NOT save the comment, and
        # serve up the "Thanks for posting" page as if the comment WAS posted.
        if request.META['REMOTE_ADDR'] in BANNED_IPS:
            mail_admins("Banned IP attempted to post comment", str(request.POST) + "\n\n" + str(request.META))
        else:
            manipulator.do_html2python(new_data)
            comment = manipulator.save(new_data)
        return HttpResponseRedirect("/comments/posted/?c=%s:%s" % (content_type_id, object_id))
    else:
        raise Http404, "The comment form didn't provide either 'preview' or 'post'"