Exemple #1
0
    def test_no_inactive_users(self):
        """Ensure that inactive users' questions don't appear in the feed."""
        u = user(is_active=False, save=True)

        q = Question(title='Test Question', content='Lorem Ipsum Dolor',
                     creator_id=u.id)
        q.save()
        assert q.id not in [x.id for x in QuestionsFeed().items({})]
Exemple #2
0
from django.conf import settings
from django.conf.urls import patterns, url
from django.contrib.contenttypes.models import ContentType

from kitsune.questions.feeds import (QuestionsFeed, AnswersFeed,
                                     TaggedQuestionsFeed)
from kitsune.questions.models import Question, Answer
from kitsune.flagit import views as flagit_views
from kitsune.sumo.views import handle404

if settings.DISABLE_FEEDS:
    questions_feed_view = handle404
    answers_feed_view = handle404
    tagged_feed_view = handle404
else:
    questions_feed_view = QuestionsFeed()
    answers_feed_view = AnswersFeed()
    tagged_feed_view = TaggedQuestionsFeed()

urlpatterns = patterns(
    'kitsune.questions.views',
    url(r'^$', 'product_list', name='questions.home'),
    url(r'^/answer-preview-async$',
        'answer_preview_async',
        name='questions.answer_preview_async'),
    url(r'^/dashboard/metrics$', 'metrics', name='questions.metrics'),
    url(r'^/dashboard/metrics/(?P<locale_code>[^/]+)$',
        'metrics',
        name='questions.locale_metrics'),

    # AAQ
Exemple #3
0
        name='questions.vote'),
    url(r'^/(?P<question_id>\d+)/vote/(?P<answer_id>\d+)$',
        'answer_vote', name='questions.answer_vote'),
    url(r'^/(?P<question_id>\d+)/add-tag$', 'add_tag',
        name='questions.add_tag'),
    url(r'^/(?P<question_id>\d+)/remove-tag$', 'remove_tag',
        name='questions.remove_tag'),
    url(r'^/(?P<question_id>\d+)/add-tag-async$', 'add_tag_async',
        name='questions.add_tag_async'),
    url(r'^/(?P<question_id>\d+)/remove-tag-async$', 'remove_tag_async',
        name='questions.remove_tag_async'),

    # Feeds
    # Note: this needs to be above questions.list because "feed"
    # matches the product slug regex.
    url(r'^/feed$', QuestionsFeed(), name='questions.feed'),
    url(r'^/(?P<question_id>\d+)/feed$', AnswersFeed(),
        name='questions.answers.feed'),
    url(r'^/tagged/(?P<tag_slug>[\w\-]+)/feed$', TaggedQuestionsFeed(),
        name='questions.tagged_feed'),

    # Mark as spam
    url(r'^/mark_spam$', 'mark_spam', name='questions.mark_spam'),
    url(r'^/unmark_spam$', 'unmark_spam', name='questions.unmark_spam'),

    # Question lists
    url(r'^/(?P<product_slug>[\w+\-\,]+)$', 'question_list',
        name='questions.list'),

    # Flag content ("Report this post")
    url(r'^/(?P<object_id>\d+)/flag$', flagit_views.flag,
Exemple #4
0
def question_list(request, product_slug):
    """View the list of questions."""
    if settings.DISABLE_QUESTIONS_LIST_GLOBAL:
        messages.add_message(request, messages.WARNING,
                             "You cannot list questions at this time.")
        return HttpResponseRedirect("/")

    filter_ = request.GET.get("filter")
    owner = request.GET.get("owner",
                            request.session.get("questions_owner", "all"))
    show = request.GET.get("show")
    # Show defaults to NEEDS ATTENTION
    if show not in FILTER_GROUPS:
        show = "needs-attention"

    tagged = request.GET.get("tagged")
    tags = None
    topic_slug = request.GET.get("topic")

    order = request.GET.get("order", "updated")
    if order not in ORDER_BY:
        order == "updated"
    sort = request.GET.get("sort", "desc")

    product_slugs = product_slug.split(",")
    products = []

    if len(product_slugs) > 1 or product_slugs[0] != "all":
        for slug in product_slugs:
            products.append(get_object_or_404(Product, slug=slug))
        multiple = len(products) > 1
    else:
        # We want all products (no product filtering at all).
        if settings.DISABLE_QUESTIONS_LIST_ALL:
            messages.add_message(
                request, messages.WARNING,
                "You cannot list all questions at this time.")
            return HttpResponseRedirect("/")

        products = None
        multiple = True

    if topic_slug and not multiple:
        # We don't support topics when there is more than one product.
        # There is no way to know what product the topic applies to.
        try:
            topic = Topic.objects.get(slug=topic_slug, product=products[0])
        except Topic.DoesNotExist:
            topic = None
    else:
        topic = None

    question_qs = Question.objects

    if filter_ not in FILTER_GROUPS[show]:
        filter_ = None

    if filter_ == "new":
        question_qs = question_qs.new()
    elif filter_ == "unhelpful-answers":
        question_qs = question_qs.unhelpful_answers()
    elif filter_ == "needsinfo":
        question_qs = question_qs.needs_info()
    elif filter_ == "solution-provided":
        question_qs = question_qs.solution_provided()
    elif filter_ == "solved":
        question_qs = question_qs.solved()
    elif filter_ == "locked":
        question_qs = question_qs.locked()
    elif filter_ == "recently-unanswered":
        question_qs = question_qs.recently_unanswered()
    else:
        if show == "needs-attention":
            question_qs = question_qs.needs_attention()
        if show == "responded":
            question_qs = question_qs.responded()
        if show == "done":
            question_qs = question_qs.done()

    question_qs = question_qs.select_related("creator", "last_answer",
                                             "last_answer__creator")
    question_qs = question_qs.prefetch_related("topic", "topic__product")

    question_qs = question_qs.filter(creator__is_active=1)

    if not request.user.has_perm("flagit.can_moderate"):
        question_qs = question_qs.filter(is_spam=False)

    if owner == "mine" and request.user.is_authenticated:
        criteria = Q(answers__creator=request.user) | Q(creator=request.user)
        question_qs = question_qs.filter(criteria).distinct()
    else:
        owner = None

    feed_urls = ((
        urlparams(reverse("questions.feed"),
                  product=product_slug,
                  topic=topic_slug),
        QuestionsFeed().title(),
    ), )

    if tagged:
        tag_slugs = tagged.split(",")
        tags = Tag.objects.filter(slug__in=tag_slugs)
        if tags:
            for t in tags:
                question_qs = question_qs.filter(tags__name__in=[t.name])
            if len(tags) == 1:
                feed_urls += ((
                    reverse("questions.tagged_feed", args=[tags[0].slug]),
                    TaggedQuestionsFeed().title(tags[0]),
                ), )
        else:
            question_qs = Question.objects.none()

    # Exclude questions over 90 days old without an answer.
    oldest_date = date.today() - timedelta(days=90)
    question_qs = question_qs.exclude(created__lt=oldest_date, num_answers=0)

    # Filter by products.
    if products:
        # This filter will match if any of the products on a question have the
        # correct id.
        question_qs = question_qs.filter(product__in=products).distinct()

    # Filter by topic.
    if topic:
        # This filter will match if any of the topics on a question have the
        # correct id.
        question_qs = question_qs.filter(topic__id=topic.id)

    # Filter by locale for AAQ locales, and by locale + default for others.
    if request.LANGUAGE_CODE in QuestionLocale.objects.locales_list():
        locale_query = Q(locale=request.LANGUAGE_CODE)
    else:
        locale_query = Q(locale=request.LANGUAGE_CODE)
        locale_query |= Q(locale=settings.WIKI_DEFAULT_LANGUAGE)

    question_qs = question_qs.filter(locale_query)

    # Set the order.
    # Set a default value if a user requested a non existing order parameter
    order_by = ORDER_BY.get(order, ["updated"])[0]
    question_qs = question_qs.order_by(order_by if sort == "asc" else "-%s" %
                                       order_by)

    try:
        questions_page = simple_paginate(request,
                                         question_qs,
                                         per_page=config.QUESTIONS_PER_PAGE)
    except (PageNotAnInteger, EmptyPage):
        # If we aren't on page 1, redirect there.
        # TODO: Is 404 more appropriate?
        if request.GET.get("page", "1") != "1":
            url = build_paged_url(request)
            return HttpResponseRedirect(urlparams(url, page=1))

    # Recent answered stats
    extra_filters = locale_query

    if products:
        extra_filters &= Q(product__in=products)

    recent_asked_count = Question.recent_asked_count(extra_filters)
    recent_unanswered_count = Question.recent_unanswered_count(extra_filters)
    if recent_asked_count:
        recent_answered_percent = int(
            (float(recent_asked_count - recent_unanswered_count) /
             recent_asked_count) * 100)
    else:
        recent_answered_percent = 0

    # List of products to fill the selector.
    product_list = Product.objects.filter(visible=True)

    # List of topics to fill the selector. Only shows if there is exactly
    # one product selected.
    if products and not multiple:
        topic_list = Topic.objects.filter(visible=True,
                                          product=products[0])[:10]
    else:
        topic_list = []

    # Store current filters in the session
    if request.user.is_authenticated:
        request.session["questions_owner"] = owner

    data = {
        "questions": questions_page,
        "feeds": feed_urls,
        "filter": filter_,
        "owner": owner,
        "show": show,
        "filters": FILTER_GROUPS[show],
        "order": order,
        "orders": ORDER_BY,
        "sort": sort,
        "tags": tags,
        "tagged": tagged,
        "recent_asked_count": recent_asked_count,
        "recent_unanswered_count": recent_unanswered_count,
        "recent_answered_percent": recent_answered_percent,
        "product_list": product_list,
        "products": products,
        "product_slug": product_slug,
        "multiple_products": multiple,
        "all_products": product_slug == "all",
        "topic_list": topic_list,
        "topic": topic,
    }

    return render(request, "questions/question_list.html", data)