예제 #1
0
 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)
예제 #2
0
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,
    })
예제 #3
0
파일: readers.py 프로젝트: p2pu/osqa-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,
    })
예제 #4
0
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
예제 #5
0
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))
예제 #6
0
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())
예제 #7
0
파일: writers.py 프로젝트: p2pu/osqa-badges
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))
예제 #8
0
파일: writers.py 프로젝트: p2pu/osqa-badges
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())
예제 #9
0
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
예제 #10
0
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
예제 #11
0
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,
        })