Ejemplo n.º 1
0
 def __call__(self, parser, token):
     tokens = token.contents.split()
     # Now tokens is a list like this:
     # ['get_comment_list', 'for', 'lcom.eventtimes', 'event.id', 'as', 'comment_list']
     if not len(tokens) in (6, 7):
         raise template.TemplateSyntaxError, "%r tag requires 5 or 6 arguments" % tokens[0]
     if tokens[1] != 'for':
         raise template.TemplateSyntaxError, "Second argument in %r tag must be 'for'" % tokens[0]
     try:
         package, module = tokens[2].split('.')
     except ValueError: # unpack list of wrong size
         raise template.TemplateSyntaxError, "Third argument in %r tag must be in the format 'package.module'" % tokens[0]
     try:
         content_type = contenttypes.get_object(package__label__exact=package, python_module_name__exact=module)
     except contenttypes.ContentTypeDoesNotExist:
         raise template.TemplateSyntaxError, "%r tag has invalid content-type '%s.%s'" % (tokens[0], package, module)
     var_name, obj_id = None, None
     if tokens[3].isdigit():
         obj_id = tokens[3]
         try: # ensure the object ID is valid
             content_type.get_object_for_this_type(pk=obj_id)
         except ObjectDoesNotExist:
             raise template.TemplateSyntaxError, "%r tag refers to %s object with ID %s, which doesn't exist" % (tokens[0], content_type.name, obj_id)
     else:
         var_name = tokens[3]
     if tokens[4] != 'as':
         raise template.TemplateSyntaxError, "Fourth argument in %r must be 'as'" % tokens[0]
     if len(tokens) == 7:
         if tokens[6] != 'reversed':
             raise template.TemplateSyntaxError, "Final argument in %r must be 'reversed' if given" % tokens[0]
         ordering = "-"
     else:
         ordering = ""
     return CommentListNode(package, module, var_name, obj_id, tokens[5], self.free, ordering)
Ejemplo n.º 2
0
 def __call__(self, parser, token):
     tokens = token.contents.split()
     if len(tokens) < 4:
         raise template.TemplateSyntaxError, "%r tag requires at least 3 arguments" % tokens[0]
     if tokens[1] != 'for':
         raise template.TemplateSyntaxError, "Second argument in %r tag must be 'for'" % tokens[0]
     try:
         package, module = tokens[2].split('.')
     except ValueError: # unpack list of wrong size
         raise template.TemplateSyntaxError, "Third argument in %r tag must be in the format 'package.module'" % tokens[0]
     try:
         content_type = contenttypes.get_object(package__label__exact=package, python_module_name__exact=module)
     except contenttypes.ContentTypeDoesNotExist:
         raise template.TemplateSyntaxError, "%r tag has invalid content-type '%s.%s'" % (tokens[0], package, module)
     obj_id_lookup_var, obj_id = None, None
     if tokens[3].isdigit():
         obj_id = tokens[3]
         try: # ensure the object ID is valid
             content_type.get_object_for_this_type(pk=obj_id)
         except ObjectDoesNotExist:
             raise template.TemplateSyntaxError, "%r tag refers to %s object with ID %s, which doesn't exist" % (tokens[0], content_type.name, obj_id)
     else:
         obj_id_lookup_var = tokens[3]
     kwargs = {}
     if len(tokens) > 4:
         if tokens[4] != 'with':
             raise template.TemplateSyntaxError, "Fourth argument in %r tag must be 'with'" % tokens[0]
         for option, args in zip(tokens[5::2], tokens[6::2]):
             if option in ('photos_optional', 'photos_required') and not self.free:
                 # VALIDATION ##############################################
                 option_list = args.split(',')
                 if len(option_list) % 3 != 0:
                     raise template.TemplateSyntaxError, "Incorrect number of comma-separated arguments to %r tag" % tokens[0]
                 for opt in option_list[::3]:
                     if not opt.isalnum():
                         raise template.TemplateSyntaxError, "Invalid photo directory name in %r tag: '%s'" % (tokens[0], opt)
                 for opt in option_list[1::3] + option_list[2::3]:
                     if not opt.isdigit() or not (comments.MIN_PHOTO_DIMENSION <= int(opt) <= comments.MAX_PHOTO_DIMENSION):
                         raise template.TemplateSyntaxError, "Invalid photo dimension in %r tag: '%s'. Only values between %s and %s are allowed." % (tokens[0], opt, comments.MIN_PHOTO_DIMENSION, comments.MAX_PHOTO_DIMENSION)
                 # VALIDATION ENDS #########################################
                 kwargs[option] = True
                 kwargs['photo_options'] = args
             elif option in ('ratings_optional', 'ratings_required') and not self.free:
                 # VALIDATION ##############################################
                 if 2 < len(args.split('|')) > 9:
                     raise template.TemplateSyntaxError, "Incorrect number of '%s' options in %r tag. Use between 2 and 8." % (option, tokens[0])
                 if re.match('^scale:\d+\-\d+\:$', args.split('|')[0]):
                     raise template.TemplateSyntaxError, "Invalid 'scale' in %r tag's '%s' options" % (tokens[0], option)
                 # VALIDATION ENDS #########################################
                 kwargs[option] = True
                 kwargs['rating_options'] = args
             elif option in ('is_public'):
                 kwargs[option] = (args == 'true')
             else:
                 raise template.TemplateSyntaxError, "%r tag got invalid parameter '%s'" % (tokens[0], option)
     return CommentFormNode(content_type, obj_id_lookup_var, obj_id, self.free, **kwargs)
Ejemplo n.º 3
0
def comment_was_posted(request):
    """
    Display "comment was posted" success page

    Templates: `comment_posted`
    Context:
        object
            The object the comment was posted on
    """
    obj = None
    if request.GET.has_key('c'):
        content_type_id, object_id = request.GET['c'].split(':')
        try:
            content_type = contenttypes.get_object(pk=content_type_id)
            obj = content_type.get_object_for_this_type(pk=object_id)
        except ObjectDoesNotExist:
            pass
    return render_to_response('comments/posted', {'object': obj}, context_instance=DjangoContext(request))
Ejemplo n.º 4
0
def shortcut(request, content_type_id, object_id):
    "Redirect to an object's page based on a content-type ID and an object ID."
    # Look up the object, making sure it's got a get_absolute_url() function.
    try:
        content_type = contenttypes.get_object(pk=content_type_id)
        obj = content_type.get_object_for_this_type(pk=object_id)
    except ObjectDoesNotExist:
        raise Http404, "Content type %s object %s doesn't exist" % (content_type_id, object_id)
    try:
        absurl = obj.get_absolute_url()
    except AttributeError:
        raise Http404, "%s objects don't have get_absolute_url() methods" % content_type.name

    # Try to figure out the object's domain, so we can do a cross-site redirect
    # if necessary.

    # If the object actually defines a domain, we're done.
    if absurl.startswith('http://'):
        return httpwrappers.HttpResponseRedirect(absurl)

    object_domain = None

    # Next, look for an many-to-many relationship to sites
    if hasattr(obj, 'get_site_list'):
        site_list = obj.get_site_list()
        if site_list:
            object_domain = site_list[0].domain

    # Next, look for a many-to-one relationship to sites
    elif hasattr(obj, 'get_site'):
        try:
            object_domain = obj.get_site().domain
        except sites.SiteDoesNotExist:
            pass

    # Then, fall back to the current site (if possible)
    else:
        try:
            object_domain = sites.get_current().domain
        except sites.SiteDoesNotExist:
            # Finally, give up and use a URL without the domain name
            return httpwrappers.HttpResponseRedirect(obj.get_absolute_url())
    return httpwrappers.HttpResponseRedirect('http://%s%s' % (object_domain, obj.get_absolute_url()))
Ejemplo n.º 5
0
def post_free_comment(request):
    """
    Post a free comment (not requiring a log in)

    Redirects to `comments.comments.comment_was_posted` view on success.

    Templates: `comment_free_preview`
    Context:
        comment
            comment being posted
        comment_form
            comment form object
        options
            comment options
        target
            comment target
        hash
            security hash (must be included in a posted form to succesfully
            post a comment).
    """
    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"
    if comments.get_security_hash(options, '', '', target) != security_hash:
        raise Http404, "Somebody tampered with the comment form (security violation)"
    content_type_id, object_id = target.split(':') # target is something like '52:5157'
    content_type = contenttypes.get_object(pk=content_type_id)
    try:
        obj = content_type.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(',')
    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['REMOTE_ADDR']
    new_data['is_public'] = comments.IS_PUBLIC in option_list
    manipulator = PublicFreeCommentManipulator()
    errors = manipulator.get_validation_errors(new_data)
    if errors or request.POST.has_key('preview'):
        comment = errors and '' or manipulator.get_comment(new_data)
        return render_to_response('comments/free_preview', {
            'comment': comment,
            'comment_form': formfields.FormWrapper(manipulator, new_data, errors),
            'options': options,
            'target': target,
            'hash': security_hash,
        }, 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:
            from django.core.mail import mail_admins
            mail_admins("Practical joker", 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'"
Ejemplo n.º 6
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'"