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)
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)
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)
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)
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)
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'))
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)