示例#1
0
def delete_rankable(request, rankable_id):
    """
    View for deleting a news item or comment.

    Responds to GET and POST.  GET for getting the template and POST
    for actually doing the deleting.
    """
    rankable = get_object_or_404(Rankable, pk=rankable_id)

    next = reverse('news.views.rankables.delete_rankable', 
                   args=(rankable.id,))

    # This calculates the page we came from.
    # If it is not given, it just defaults to the 
    # news item (if that's what is being deleted),
    # or the parent news item of the comment that
    # is being deleted.
    top_news_item = rankable.get_parent_news_item()
    from_page = request.GET.get('from', 
            reverse('news.views.news_items.news_item', 
                args=(top_news_item.id,)))
    assert_or_404(valid_next_redirect(from_page))

    # you should not be able to see this page or edit any comment
    # if you are not logged in or if you are trying to edit someone
    # else's comment
    assert_or_404(request.user.is_authenticated() and \
            rankable.can_be_deleted(request.user.get_profile()))

    # this must be a comment or a news item
    assert_or_404(rankable.is_comment() or rankable.is_news_item())

    # make sure the item hasn't already been deleted.
    assert_or_404(not rankable.dead)

    # on GET we can just return the template
    if request.method != "POST":
        news_item = None
        comment = None
        if rankable.is_comment():
            comment = rankable.comment
        elif rankable.is_news_item():
            news_item = rankable.newsitem
        return render_to_response('news/delete_rankable.html',
                {'news_item': news_item,
                 'comment': comment,
                 'rankable': rankable,
                 'from_page': from_page,
                 'next': next},
                context_instance=RequestContext(request))


    # this should either be "yes" or "no"
    submitvalue = get_from_POST_or_404(request, 'submitvalue')

    if submitvalue == "yes":
        rankable.dead = True
        rankable.save()

    return HttpResponseRedirect(from_page)
示例#2
0
def edit_comment(request, comment_id):
    """
    View for editing a comment.

    Responds to GET and POST.  Get for getting the view and POST
    for updating the comment.
    """
    com = get_object_or_404(Comment, pk=comment_id)

    next = reverse('news.views.comments.edit_comment', 
                   args=(com.id,))

    # This calculates the page we came from.
    # If it is not given, it just defaults to the 
    # news item (if that's what is being deleted),
    # or the parent news item of the comment that
    # is being deleted.
    top_news_item = com.get_parent_news_item()
    from_page = request.GET.get('from', 
            reverse('news.views.news_items.news_item', 
                args=(top_news_item.id,)))
    assert_or_404(valid_next_redirect(from_page))

    # you should not be able to see this page or edit any comment
    # if you are not logged in or if you are trying to edit someone
    # else's comment
    assert_or_404(request.user.is_authenticated() and \
           com.can_be_edited(request.user.get_profile()))

    # make sure the item hasn't already been deleted.
    assert_or_404(not com.dead)

    # on GET we can just return the template
    if request.method != "POST":
        comment_posting_error = get_from_session(request, 'comment_posting_error')
        comment_text = get_from_session(request, 'comment_text')
        return render_to_response('news/edit_comment.html',
                {'comment_posting_error': comment_posting_error,
                 'comment': com,
                 # this will default to comment_text but if it is blank it
                 # looks at com.text
                 'comment_text': comment_text or com.text,
                 'from_page': from_page,
                 'next': next},
                context_instance=RequestContext(request))

    comment_text = get_from_POST_or_404(request, 'comment_text')

    # if it is not valid, set the error message 
    # and reload this page
    if not valid_comment_text(comment_text):
        request.session['comment_posting_error'] = "Comment not valid"
        request.session['comment_text'] = comment_text
        return HttpResponseRedirect(next)

    com.text = comment_text
    com.save()

    return HttpResponseRedirect(from_page)
示例#3
0
def logout_view(request):
    """
    Log out a user.  (It doesn't matter if they are logged in or not...)

    Takes GET requests.
    """
    next = request.GET.get('next', reverse('news.views.news_items.index'))
    assert_or_404(valid_next_redirect(next))

    logout(request)
    return HttpResponseRedirect(next)
示例#4
0
def vote(request):
    """
    This view takes a vote for a comment or news item.
    It then redirects back to said comment or news item.

    It only takes GET requests.
    """
    rankable_id = get_from_GET_or_404(request, "id")
    direction = get_from_GET_or_404(request, "direction")
    next = get_from_GET_or_404(request, "next")

    assert_or_404(direction == "up" or direction == "down")
    assert_or_404(valid_next_redirect(next))

    rankable = get_object_or_404(Rankable, id=rankable_id)

    if not request.user.is_authenticated():
        # TODO: this next should actually be redirecting back to this vote view,
        # which then redirects to whatever the previous view was, so, two levels
        # of redirection.
        return HttpResponseRedirect(reverse("news.views.login.login_view") + "?next=" + next)

    userprofile = request.user.get_profile()

    if rankable.already_voted(userprofile):
        return HttpResponseRedirect(next)

    if not rankable.can_vote(userprofile):
        request.session["voting_error"] = "Not enough comment points"
        return HttpResponseRedirect(reverse("news.views.payment.buy_points"))

    if direction == "up":
        rankable.rating += 1
    elif direction == "down":
        assert_or_404(rankable.can_be_downvoted())
        rankable.rating -= 1
    else:
        raise Http404

    rankable.update_ranking()
    rankable.save()
    Rated.objects.create(rankable=rankable, userprofile=userprofile, direction=direction)

    userprofile.comment_points -= rankable.vote_cost(userprofile)
    userprofile.save()

    return HttpResponseRedirect(next)
示例#5
0
def create_account(request):
    """
    Respond to posts for creating an account.

    Only takes POSTs.
    """
    # if next is passed, get it
    next = request.GET.get('next', reverse('news.views.news_items.index'))
    next = request.POST.get('next', next)
    assert_or_404(valid_next_redirect(next))

    assert_or_404(request.method == 'POST')

    username = get_from_POST_or_404(request, 'username')
    password = get_from_POST_or_404(request, 'password')

    # make sure it's a valid username
    if not valid_username(username):
        request.session['create_account_error'] = 'Username can only ' + \
            'consist of letters, numbers, and underscores, and must be ' + \
            'less than 30 characters'
        request.session['create_account_username'] = username
        return HttpResponseRedirect(reverse('news.views.login.login_view') +
                "?next=" + next)

    # make sure no other users have this username
    if User.objects.filter(username=username):
        request.session['create_account_error'] = \
                'Username ' + username + ' taken'
        request.session['create_account_username'] = username
        return HttpResponseRedirect(reverse('news.views.login.login_view') +
                "?next=" + next)

    # make sure it's a valid password
    if not valid_password(password):
        request.session['create_account_error'] = \
                 'Password cannot be blank and must be less than 30 characters'
        request.session['create_account_username'] = username
        return HttpResponseRedirect(reverse('news.views.login.login_view') +
                "?next=" + next)

    # create the user and userprofile
    user = User.objects.create_user(username, '', password)
    UserProfile.objects.create(user=user)

    return login_view(request)
示例#6
0
    def testValidNextRedirect(self):
        """ Test valid_next_redirect(). """

        # if the redirect can't be resolved to a view, then there is probably nothing
        # wrong
        self.assertFalse(valid_next_redirect("http://google.com"))
        self.assertFalse(valid_next_redirect("http://google.com/"))
        self.assertFalse(valid_next_redirect("http://google.com/new"))
        self.assertFalse(
                valid_next_redirect(reverse('news.views.login.login_view')+'a'))

        # everything that can be resolved to a view is probably okay
        self.assert_(valid_next_redirect(reverse('news.views.login.login_view')))
        self.assert_(valid_next_redirect(
            reverse('news.views.users.user', args=('ice',))))
        self.assert_(valid_next_redirect(
            reverse('news.views.login.login_view') + '?what=who'))
        self.assert_(valid_next_redirect(
            reverse('news.views.login.login_view') + '#other?what=who'))
示例#7
0
def login_view(request):
    """
    Perform login or show login page.

    On GETs it shows the login page, 
    on POSTS it tries to log the user in.
    """
    # If next is passed, get it.
    # I am only attempting to get it from POST so I can use it in testing.
    next = request.GET.get('next', reverse('news.views.news_items.index'))
    next = request.POST.get('next', next)
    assert_or_404(valid_next_redirect(next))

    if request.method != 'POST':
        # if there is a login error or create account error 
        # in session, get the value
        login_error = get_from_session(request, "login_error")
        username = get_from_session(request, "login_username")
        create_account_error = get_from_session(request, 
                "create_account_error")
        create_account_username = get_from_session(request, 
                "create_account_username")
        return render_to_response('news/login.html',
                {'login_error': login_error, 
                 'username': username,
                 'create_account_error': create_account_error,
                 'create_account_username': create_account_username,
                 'next': next},
                context_instance=RequestContext(request))

    username = get_from_POST_or_404(request, 'username')
    password = get_from_POST_or_404(request, 'password')
    user = authenticate(username=username, password=password)

    if user is None:
        request.session['login_error'] = "Invalid username or password"
        request.session['login_username'] = username
        return HttpResponseRedirect(reverse('news.views.login.login_view') +
                "?next=" + next)
    if not user.is_active:
        request.session['login_error'] = "Account disabled"
        request.session['login_username'] = username
        return HttpResponseRedirect(reverse('news.views.login.login_view') +
                "?next=" + next)

    # before we login the user, makes sure to get their session variables,
    # and put them back into the session after calling login().
    # login() will flush everything, so we need to make sure to save the stuff
    # we want.  This is used when the user trys to post 
    # a comment if they are not logged in.  We will reload 
    # the page and send them back to the page with their comment
    # already filled in.
    comment_text = get_from_session(request, 'comment_text')
    comment_text_for_id = get_from_session(request, 'comment_text_for_id')

    submit_title = get_from_session(request, 'submit_title')
    submit_url = get_from_session(request, 'submit_url')
    submit_text = get_from_session(request, 'submit_text')

    # user has be authenticated and they are active
    login(request, user)

    request.session['comment_text'] = comment_text
    request.session['comment_text_for_id'] = comment_text_for_id

    request.session['submit_title'] = submit_title
    request.session['submit_url'] = submit_url
    request.session['submit_text'] = submit_text

    return HttpResponseRedirect(next)