def news_item(request, news_item_id=None): """ View for a news item. Only responds to GET requests. """ top_news_item = get_object_or_404(NewsItem, pk=news_item_id) child_comments = get_child_comments(top_news_item.child_set, 0) header = 'News Item' # these are only set if there is an error or something comment_posting_error = get_from_session(request, 'comment_posting_error') comment_text = get_from_session(request, 'comment_text') comment_text_for_id = get_from_session(request, 'comment_text_for_id') # comment_text_for_id needs to be a string if str(comment_text_for_id) != news_item_id: comment_text = '' comment_posting_error = '' next = reverse('news.views.news_items.news_item', args=(top_news_item.id,)) top_news_item.update_ranking() return render_to_response('news/news_item.html', {'top_news_item': top_news_item, 'child_comments': child_comments, 'header': header, 'comment_posting_error':comment_posting_error, 'comment_text': comment_text, 'next': next}, context_instance=RequestContext(request))
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 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 comment(request, comment_id): """ View for a comment. Only responds to GETS. """ top_comment = get_object_or_404(Comment, pk=comment_id) child_comments = get_child_comments(top_comment.child_set, 0) header = 'Comment' # these are set if there is an error or something when trying to post # the comment comment_posting_error = get_from_session(request, 'comment_posting_error') comment_text = get_from_session(request, 'comment_text') comment_text_for_id = get_from_session(request, 'comment_text_for_id') # comment_text_for_id needs to be a string if str(comment_text_for_id) != comment_id: comment_posting_error = '' comment_text = '' next = reverse('news.views.comments.comment', args=(top_comment.id,)) top_comment.update_ranking() return render_to_response('news/comment.html', {'top_comment': top_comment, 'child_comments': child_comments, 'header': header, 'comment_posting_error': comment_posting_error, 'comment_text': comment_text, 'next': next}, context_instance=RequestContext(request))
def submit_comment(request): """ View for submitting a comment. If the user is not authenticated, we set the session variables 'comment_text', and 'comment_text_for_id'. We then send the user to the login page. When the user is directed back to their previous comment view or news item view, these session variables are read and inserted into the view. Only takes POSTs. """ assert_or_404(request.method == 'POST') parent_id = get_from_POST_or_404(request, 'parent_id') parent = get_object_or_404(Rankable, id=parent_id) comment_text = get_from_POST_or_404(request, 'comment_text') # if a comment matches the parent id, that means we # are responding to a comment. If a news item matches the # comment id, that means we are responding to a news item. # We figure this out now because we use it a bunch later. if Comment.objects.filter(id=parent.id): next = reverse('news.views.comments.comment', args=(parent_id,)) else: next = reverse('news.views.news_items.news_item', args=(parent_id,)) if not valid_comment_text(comment_text): request.session['comment_posting_error'] = "Comment not valid" request.session['comment_text_for_id'] = parent.id return HttpResponseRedirect(next) # if the user is not authenticated, send them to login, # (and set some session variables so they don't lose the comment they posted) if not request.user.is_authenticated(): request.session['comment_text'] = comment_text request.session['comment_text_for_id'] = parent.id return HttpResponseRedirect(reverse('news.views.login.login_view') + '?next=' + next) # if the user doesn't have enough comment points to post, # return them to this page and show them an error. if not parent.can_post_comment(request.user.get_profile()): request.session['comment_posting_error'] = "Insufficient comment points" request.session['comment_text_for_id'] = parent.id request.session['comment_text'] = comment_text return HttpResponseRedirect(next) userprofile = request.user.get_profile() # post comment com = Comment.objects.create(poster=userprofile, text=comment_text, parent=parent) Rated.objects.create(rankable=com, userprofile=userprofile, direction='up') userprofile.comment_points -= com.comment_cost(userprofile) userprofile.save() # I don't think this is needed, because these keys should already # be taken out of session when they are read (we only set them on error), # but just to make sure we clear them here. del_from_session(request, 'comment_text') del_from_session(request, 'comment_text_for') del_from_session(request, 'comment_text_for_id') # if there is a parent, return the comment view for that parent return HttpResponseRedirect(next)
def user(request, username): """ View for a user. On GET it shows the user profile (which is editable if the user is logged in and looking at their own profile.) On POST it tries to update the user's profile. """ userprofile = get_object_or_404(UserProfile, user__username=username) next = reverse('news.views.users.user', args=(userprofile.username,)) if request.method != 'POST': posting_error = get_from_session(request, 'userprofile_posting_error') email_address = get_from_session(request, 'userprofile_email') website = get_from_session(request, 'userprofile_website') about = get_from_session(request, 'userprofile_about') return render_to_response('news/user.html', {'viewing_userprofile': userprofile, 'next': next, 'posting_error': posting_error, 'error_email': email_address, 'error_website': website, 'error_about': about}, context_instance=RequestContext(request)) # don't allow users to POST without being logged in. # Also make sure the the user trying to post is the # one that is logged in. assert_or_404(request.user.is_authenticated()) assert_or_404(request.user == userprofile.user) email_address = get_from_POST_or_404(request, 'email_address') website = get_from_POST_or_404(request, 'website') about = get_from_POST_or_404(request, 'about') option_show_email = request.POST.get('option_show_email', False) option_use_javascript = request.POST.get('option_use_javascript', False) option_show_dead = request.POST.get('option_show_dead', False) # there shouldn't be a problem with option_show_email # or option_use_javascript, or option_show_dead, # so we can go ahead and set them if option_use_javascript == False: userprofile.option_use_javascript = False else: userprofile.option_use_javascript = True if option_show_email == False: userprofile.option_show_email = False else: userprofile.option_show_email = True if option_show_dead == False: userprofile.option_show_dead = False else: userprofile.option_show_dead = True userprofile.save() if email_address and not valid_email(email_address): request.session['userprofile_posting_error'] = "Email address too long" request.session['userprofile_email'] = email_address request.session['userprofile_website'] = website request.session['userprofile_about'] = about return HttpResponseRedirect(reverse('news.views.users.user', args=(userprofile.username,))) if website: website = improve_url(website) if not valid_url(website): request.session['userprofile_posting_error'] = "URL not valid" request.session['userprofile_email'] = email_address request.session['userprofile_website'] = website request.session['userprofile_about'] = about return HttpResponseRedirect(reverse('news.views.users.user', args=(userprofile.username,))) if about and not valid_text(about): request.session['userprofile_posting_error'] = "About not valid" request.session['userprofile_email'] = email_address request.session['userprofile_website'] = website request.session['userprofile_about'] = about return HttpResponseRedirect(reverse('news.views.users.user', args=(userprofile.username,))) userprofile.website = website userprofile.about = about userprofile.user.email = email_address userprofile.save() userprofile.user.save() return HttpResponseRedirect( reverse('news.views.users.user', args=(userprofile.username,)))