def trigger_hooks(self, threaded, new=True): from forum.models import CustomBadge CustomBadge.load_custom_badges() if threaded: thread = Thread(target=trigger_hooks, args=[self, Action.hooks, new]) thread.setDaemon(True) thread.start() else: trigger_hooks(self, Action.hooks, new)
def badges(request): CustomBadge.load_custom_badges() badges = Badge.objects.all() if request.user.is_authenticated(): my_badges = Award.objects.filter(user=request.user).values('badge_id').distinct() else: my_badges = [] return pagination.paginated(request, ('badges', BadgesPaginatorContext()), { 'badges' : badges, 'mybadges' : my_badges, })
def question(request, id, slug='', answer=None): try: question = Question.objects.get(id=id) except: if slug: question = match_question_slug(id, slug) if question is not None: return HttpResponseRedirect(question.get_absolute_url()) raise Http404() if question.nis.deleted and not request.user.can_view_deleted_post(question): raise Http404 if request.GET.get('type', None) == 'rss': return RssAnswerFeed(request, question, include_comments=request.GET.get('comments', None) == 'yes')(request) if answer: answer = get_object_or_404(Answer, id=answer) if (question.nis.deleted and not request.user.can_view_deleted_post(question)) or answer.question != question: raise Http404 if answer.marked: return HttpResponsePermanentRedirect(question.get_absolute_url()) return answer_redirect(request, answer) if settings.FORCE_SINGLE_URL and (slug != slugify(question.title)): return HttpResponsePermanentRedirect(question.get_absolute_url()) if request.POST: answer_form = AnswerForm(request.POST, user=request.user) else: answer_form = AnswerForm(user=request.user) answers = request.user.get_visible_answers(question) update_question_view_times(request, question) if request.user.is_authenticated(): try: subscription = QuestionSubscription.objects.get(question=question, user=request.user) except: subscription = False else: subscription = False from forum.models import CustomBadge response_restricted = CustomBadge.is_response_restricted(request.user, question) return pagination.paginated(request, ('answers', AnswerPaginatorContext()), { "question" : question, "answer" : answer_form, "answers" : answers, "similar_questions" : question.get_related_questions(), "subscription": subscription, 'response_restricted': response_restricted, })
def answer_vote_buttons(post, user): from forum.models import CustomBadge context = dict(post=post, user_vote='none', can_comment=user.can_comment(post), is_voting_restricted=CustomBadge.is_voting_restricted(user, post)) if user.is_authenticated(): context['user_vote'] = {1: 'up', -1: 'down', None: 'none'}[VoteAction.get_for(user, post)] return context
def edit_answer(request, id): answer = get_object_or_404(Answer, id=id) if answer.deleted and not request.user.can_view_deleted_post(answer): raise Http404 elif not request.user.can_edit_post(answer): raise Http404 from forum.models import CustomBadge if CustomBadge.is_response_restricted(request.user, answer.parent): raise Http404 if request.method == "POST": revision_form = RevisionForm(answer, data=request.POST) revision_form.is_valid() revision = answer.revisions.get( revision=revision_form.cleaned_data['revision']) if 'select_revision' in request.POST: form = EditAnswerForm(answer, request.user, revision) else: form = EditAnswerForm(answer, request.user, revision, data=request.POST) if not 'select_revision' in request.POST and form.is_valid(): if form.has_changed(): action = ReviseAction(user=request.user, node=answer, ip=request.META['REMOTE_ADDR']).save( data=form.cleaned_data) if settings.WIKI_ON: if request.POST.get('wiki', False) and not answer.nis.wiki: answer.nstate.wiki = action elif answer.nis.wiki and (not request.POST.get( 'wiki', False)) and request.user.can_cancel_wiki(answer): answer.nstate.wiki = None else: if not revision == answer.active_revision: RollbackAction(user=request.user, node=answer, ip=request.META['REMOTE_ADDR']).save( data=dict(activate=revision)) return HttpResponseRedirect(answer.get_absolute_url()) else: revision_form = RevisionForm(answer) form = EditAnswerForm(answer, request.user) return render_to_response('answer_edit.html', { 'answer': answer, 'revision_form': revision_form, 'form': form, }, context_instance=RequestContext(request))
def answer(request, id): question = get_object_or_404(Question, id=id) from forum.models import CustomBadge if not CustomBadge.is_response_restricted(request.user, question) and request.POST: form = AnswerForm(request.POST, request.user) if request.session.pop('reviewing_pending_data', False) or not form.is_valid(): request.session['redirect_POST_data'] = request.POST return HttpResponseRedirect(question.get_absolute_url() + '#fmanswer') if request.user.is_authenticated( ) and request.user.email_valid_and_can_answer(): answer_action = AnswerAction(user=request.user, ip=request.META['REMOTE_ADDR']).save( dict(question=question, **form.cleaned_data)) answer = answer_action.node if settings.WIKI_ON and request.POST.get('wiki', False): answer.nstate.wiki = answer_action return HttpResponseRedirect(answer.get_absolute_url()) else: request.session['pending_submission_data'] = { 'POST': request.POST, 'data_name': _("answer"), 'type': 'answer', 'submission_url': reverse('answer', kwargs={'id': id}), 'time': datetime.datetime.now() } if request.user.is_authenticated(): request.user.message_set.create( message=_("Your answer is pending until you %s.") % html.hyperlink(reverse('send_validation_email'), _("validate your email"))) return HttpResponseRedirect(question.get_absolute_url()) else: return HttpResponseRedirect(reverse('auth_signin')) return HttpResponseRedirect(question.get_absolute_url())
def edit_answer(request, id): answer = get_object_or_404(Answer, id=id) if answer.deleted and not request.user.can_view_deleted_post(answer): raise Http404 elif not request.user.can_edit_post(answer): raise Http404 from forum.models import CustomBadge if CustomBadge.is_response_restricted(request.user, answer.parent): raise Http404 if request.method == "POST": revision_form = RevisionForm(answer, data=request.POST) revision_form.is_valid() revision = answer.revisions.get(revision=revision_form.cleaned_data['revision']) if 'select_revision' in request.POST: form = EditAnswerForm(answer, request.user, revision) else: form = EditAnswerForm(answer, request.user, revision, data=request.POST) if not 'select_revision' in request.POST and form.is_valid(): if form.has_changed(): action = ReviseAction(user=request.user, node=answer, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data) if settings.WIKI_ON: if request.POST.get('wiki', False) and not answer.nis.wiki: answer.nstate.wiki = action elif answer.nis.wiki and (not request.POST.get('wiki', False)) and request.user.can_cancel_wiki(answer): answer.nstate.wiki = None else: if not revision == answer.active_revision: RollbackAction(user=request.user, node=answer, ip=request.META['REMOTE_ADDR']).save(data=dict(activate=revision)) return HttpResponseRedirect(answer.get_absolute_url()) else: revision_form = RevisionForm(answer) form = EditAnswerForm(answer, request.user) return render_to_response('answer_edit.html', { 'answer': answer, 'revision_form': revision_form, 'form': form, }, context_instance=RequestContext(request))
def answer(request, id): question = get_object_or_404(Question, id=id) from forum.models import CustomBadge if not CustomBadge.is_response_restricted(request.user, question) and request.POST: form = AnswerForm(request.POST, request.user) if request.session.pop('reviewing_pending_data', False) or not form.is_valid(): request.session['redirect_POST_data'] = request.POST return HttpResponseRedirect(question.get_absolute_url() + '#fmanswer') if request.user.is_authenticated() and request.user.email_valid_and_can_answer(): answer_action = AnswerAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(dict(question=question, **form.cleaned_data)) answer = answer_action.node if settings.WIKI_ON and request.POST.get('wiki', False): answer.nstate.wiki = answer_action return HttpResponseRedirect(answer.get_absolute_url()) else: request.session['pending_submission_data'] = { 'POST': request.POST, 'data_name': _("answer"), 'type': 'answer', 'submission_url': reverse('answer', kwargs={'id': id}), 'time': datetime.datetime.now() } if request.user.is_authenticated(): request.user.message_set.create(message=_("Your answer is pending until you %s.") % html.hyperlink( reverse('send_validation_email'), _("validate your email") )) return HttpResponseRedirect(question.get_absolute_url()) else: return HttpResponseRedirect(reverse('auth_signin')) return HttpResponseRedirect(question.get_absolute_url())
def comment(request, id): post = get_object_or_404(Node, id=id) user = request.user if not request.method == 'POST': raise CommandException(_("Invalid request")) vote_type = request.POST.get('vote_type', 'comment') is_voting = (vote_type in ('up', 'down')) if not user.is_authenticated(): msg = is_voting and _('vote') or _('comment') raise AnonymousNotAllowedException(msg) from forum.models import CustomBadge if is_voting and CustomBadge.is_voting_restricted(user, post): msg = _( 'Only users with the badge (or the badge owners) are allowed to vote.' ) raise CommandException(msg) if is_voting and user == post.author: raise CannotDoOnOwnException(_('vote')) if vote_type == 'up' and not user.can_vote_up(): raise NotEnoughRepPointsException(_('upvote')) if vote_type == 'down' and not user.can_vote_down(): raise NotEnoughRepPointsException(_('downvote')) user_vote_count_today = user.get_vote_count_today() if is_voting and user_vote_count_today >= user.can_vote_count_today(): raise NotEnoughLeftException(_('votes'), str(settings.MAX_VOTES_PER_DAY)) comment_text = request.POST.get('comment', '').strip() if not len(comment_text): raise CommandException(_("Comment is empty")) if len(comment_text) < settings.FORM_MIN_COMMENT_BODY: raise CommandException( _("At least %d characters required on comment body.") % settings.FORM_MIN_COMMENT_BODY) if len(comment_text) > settings.FORM_MAX_COMMENT_BODY: raise CommandException( _("No more than %d characters on comment body.") % settings.FORM_MAX_COMMENT_BODY) old_vote = VoteAction.get_action_for(node=post, user=user) if is_voting and old_vote: is_too_old = (old_vote.action_date < datetime.datetime.now() - datetime.timedelta(days=int(settings.DENY_UNVOTE_DAYS))) if is_too_old: raise CommandException( _("Sorry but you cannot cancel a vote after %(ndays)d %(tdays)s from the original vote" ) % { 'ndays': int(settings.DENY_UNVOTE_DAYS), 'tdays': ungettext('day', 'days', int(settings.DENY_UNVOTE_DAYS)) }) if 'id' in request.POST: comment = get_object_or_404(Comment, id=request.POST['id']) if not user.can_edit_comment(comment): raise NotEnoughRepPointsException(_('edit comments')) else: if not user.can_comment(post): raise NotEnoughRepPointsException(_('comment')) if is_voting: new_vote_cls = (vote_type == 'up') and VoteUpAction or VoteDownAction score_inc = 0 if old_vote: old_vote.cancel(ip=request.META['REMOTE_ADDR']) score_inc += (old_vote.__class__ == VoteDownAction) and 1 or -1 if old_vote.__class__ != new_vote_cls: new_vote_cls(user=user, node=post, ip=request.META['REMOTE_ADDR']).save() score_inc += (new_vote_cls == VoteUpAction) and 1 or -1 else: vote_type = "none" if 'id' in request.POST: comment = ReviseAction(user=user, node=comment, ip=request.META['REMOTE_ADDR']).save(data=dict( text=comment_text)).node else: comment = CommentAction( user=user, ip=request.META['REMOTE_ADDR']).save( data=dict(text=comment_text, parent=post)).node if not is_voting: comment_type = VoteComment.COMMENT elif old_vote.__class__ != new_vote_cls and new_vote_cls == VoteUpAction: comment_type = VoteComment.VOTE_UP elif old_vote.__class__ != new_vote_cls and new_vote_cls != VoteUpAction: comment_type = VoteComment.VOTE_DOWN elif old_vote.__class__ == VoteUpAction: comment_type = VoteComment.CANCEL_VOTE_UP else: comment_type = VoteComment.CANCEL_VOTE_DOWN vote_comment = VoteComment(comment_type=comment_type, comment=comment) vote_comment.save() if comment.active_revision.revision == 1: response = { 'commands': { 'insert_comment': [ id, comment.id, comment.comment, user.decorated_name, user.get_profile_url(), reverse('delete_comment', kwargs={'id': comment.id}), reverse('node_markdown', kwargs={'id': comment.id}), reverse('convert_comment', kwargs={'id': comment.id}), user.can_delete_comment(comment) ] } } else: response = { 'commands': { 'update_comment': [comment.id, comment.comment] } } if is_voting: response['commands']['update_post_score'] = [id, score_inc] response['commands']['update_user_post_vote'] = [id, vote_type] votes_left = (int(settings.MAX_VOTES_PER_DAY) - user_vote_count_today) + (vote_type == 'none' and -1 or 1) if int(settings.START_WARN_VOTES_LEFT) >= votes_left: response['message'] = _("You have %(nvotes)s %(tvotes)s left today.") % \ {'nvotes': votes_left, 'tvotes': ungettext('vote', 'votes', votes_left)} return response
def comment(request, id): post = get_object_or_404(Node, id=id) user = request.user if not request.method == 'POST': raise CommandException(_("Invalid request")) vote_type = request.POST.get('vote_type', 'comment') is_voting = (vote_type in ('up', 'down')) if not user.is_authenticated(): msg = is_voting and _('vote') or _('comment') raise AnonymousNotAllowedException(msg) from forum.models import CustomBadge if is_voting and CustomBadge.is_voting_restricted(user, post): msg = _('Only users with the badge (or the badge owners) are allowed to vote.') raise CommandException(msg) if is_voting and user == post.author: raise CannotDoOnOwnException(_('vote')) if vote_type == 'up' and not user.can_vote_up(): raise NotEnoughRepPointsException(_('upvote')) if vote_type == 'down' and not user.can_vote_down(): raise NotEnoughRepPointsException(_('downvote')) user_vote_count_today = user.get_vote_count_today() if is_voting and user_vote_count_today >= user.can_vote_count_today(): raise NotEnoughLeftException(_('votes'), str(settings.MAX_VOTES_PER_DAY)) comment_text = request.POST.get('comment', '').strip() if not len(comment_text): raise CommandException(_("Comment is empty")) if len(comment_text) < settings.FORM_MIN_COMMENT_BODY: raise CommandException(_("At least %d characters required on comment body.") % settings.FORM_MIN_COMMENT_BODY) if len(comment_text) > settings.FORM_MAX_COMMENT_BODY: raise CommandException(_("No more than %d characters on comment body.") % settings.FORM_MAX_COMMENT_BODY) old_vote = VoteAction.get_action_for(node=post, user=user) if is_voting and old_vote: is_too_old = (old_vote.action_date < datetime.datetime.now() - datetime.timedelta(days=int(settings.DENY_UNVOTE_DAYS))) if is_too_old: raise CommandException( _("Sorry but you cannot cancel a vote after %(ndays)d %(tdays)s from the original vote") % {'ndays': int(settings.DENY_UNVOTE_DAYS), 'tdays': ungettext('day', 'days', int(settings.DENY_UNVOTE_DAYS))} ) if 'id' in request.POST: comment = get_object_or_404(Comment, id=request.POST['id']) if not user.can_edit_comment(comment): raise NotEnoughRepPointsException( _('edit comments')) else: if not user.can_comment(post): raise NotEnoughRepPointsException( _('comment')) if is_voting: new_vote_cls = (vote_type == 'up') and VoteUpAction or VoteDownAction score_inc = 0 if old_vote: old_vote.cancel(ip=request.META['REMOTE_ADDR']) score_inc += (old_vote.__class__ == VoteDownAction) and 1 or -1 if old_vote.__class__ != new_vote_cls: new_vote_cls(user=user, node=post, ip=request.META['REMOTE_ADDR']).save() score_inc += (new_vote_cls == VoteUpAction) and 1 or -1 else: vote_type = "none" if 'id' in request.POST: comment = ReviseAction(user=user, node=comment, ip=request.META['REMOTE_ADDR']).save( data=dict(text=comment_text)).node else: comment = CommentAction(user=user, ip=request.META['REMOTE_ADDR']).save( data=dict(text=comment_text, parent=post)).node if not is_voting: comment_type = VoteComment.COMMENT elif old_vote.__class__ != new_vote_cls and new_vote_cls == VoteUpAction: comment_type = VoteComment.VOTE_UP elif old_vote.__class__ != new_vote_cls and new_vote_cls != VoteUpAction: comment_type = VoteComment.VOTE_DOWN elif old_vote.__class__ == VoteUpAction: comment_type = VoteComment.CANCEL_VOTE_UP else: comment_type = VoteComment.CANCEL_VOTE_DOWN vote_comment = VoteComment(comment_type=comment_type, comment=comment) vote_comment.save() if comment.active_revision.revision == 1: response = { 'commands': { 'insert_comment': [id, comment.id, comment.comment, user.decorated_name, user.get_profile_url(), reverse('delete_comment', kwargs={'id': comment.id}), reverse('node_markdown', kwargs={'id': comment.id}), reverse('convert_comment', kwargs={'id': comment.id}), user.can_delete_comment(comment)] } } else: response = {'commands': {'update_comment': [comment.id, comment.comment]}} if is_voting: response['commands']['update_post_score'] = [id, score_inc] response['commands']['update_user_post_vote'] = [id, vote_type] votes_left = (int(settings.MAX_VOTES_PER_DAY) - user_vote_count_today) + (vote_type == 'none' and -1 or 1) if int(settings.START_WARN_VOTES_LEFT) >= votes_left: response['message'] = _("You have %(nvotes)s %(tvotes)s left today.") % \ {'nvotes': votes_left, 'tvotes': ungettext('vote', 'votes', votes_left)} return response
def question(request, id, slug='', answer=None): try: question = Question.objects.get(id=id) except: if slug: question = match_question_slug(id, slug) if question is not None: return HttpResponseRedirect(question.get_absolute_url()) raise Http404() if question.nis.deleted and not request.user.can_view_deleted_post( question): raise Http404 if request.GET.get('type', None) == 'rss': return RssAnswerFeed(request, question, include_comments=request.GET.get( 'comments', None) == 'yes')(request) if answer: answer = get_object_or_404(Answer, id=answer) if (question.nis.deleted and not request.user.can_view_deleted_post(question) ) or answer.question != question: raise Http404 if answer.marked: return HttpResponsePermanentRedirect(question.get_absolute_url()) return answer_redirect(request, answer) if settings.FORCE_SINGLE_URL and (slug != slugify(question.title)): return HttpResponsePermanentRedirect(question.get_absolute_url()) if request.POST: answer_form = AnswerForm(request.POST, user=request.user) else: answer_form = AnswerForm(user=request.user) answers = request.user.get_visible_answers(question) update_question_view_times(request, question) if request.user.is_authenticated(): try: subscription = QuestionSubscription.objects.get(question=question, user=request.user) except: subscription = False else: subscription = False from forum.models import CustomBadge response_restricted = CustomBadge.is_response_restricted( request.user, question) return pagination.paginated( request, ('answers', AnswerPaginatorContext()), { "question": question, "answer": answer_form, "answers": answers, "similar_questions": question.get_related_questions(), "subscription": subscription, 'response_restricted': response_restricted, })