Beispiel #1
0
    def redirect_url(self, source_locale=settings.LANGUAGE_CODE):
        """If I am a redirect, return the URL to which I redirect.

        Otherwise, return None.

        """
        # If a document starts with REDIRECT_HTML and contains any <a> tags
        # with hrefs, return the href of the first one. This trick saves us
        # from having to parse the HTML every time.
        if self.html.startswith(REDIRECT_HTML):
            anchors = PyQuery(self.html)('a[href]')
            if anchors:
                # Articles with a redirect have a link that has the locale
                # hardcoded into it, and so by simply redirecting to the given
                # link, we end up possibly losing the locale. So, instead,
                # we strip out the locale and replace it with the original
                # source locale only in the case where an article is going
                # from one locale and redirecting it to a different one.
                # This only applies when it's a non-default locale because we
                # don't want to override the redirects that are forcibly
                # changing to (or staying within) a specific locale.
                full_url = anchors[0].get('href')
                (dest_locale, url) = split_path(full_url)
                if (source_locale != dest_locale
                    and dest_locale == settings.LANGUAGE_CODE):
                    return '/' + source_locale + '/' + url
                return full_url
Beispiel #2
0
    def redirect_url(self, source_locale=settings.LANGUAGE_CODE):
        """If I am a redirect, return the URL to which I redirect.

        Otherwise, return None.

        """
        # If a document starts with REDIRECT_HTML and contains any <a> tags
        # with hrefs, return the href of the first one. This trick saves us
        # from having to parse the HTML every time.
        if self.html.startswith(REDIRECT_HTML):
            anchors = PyQuery(self.html)('a[href]')
            if anchors:
                # Articles with a redirect have a link that has the locale
                # hardcoded into it, and so by simply redirecting to the given
                # link, we end up possibly losing the locale. So, instead,
                # we strip out the locale and replace it with the original
                # source locale only in the case where an article is going
                # from one locale and redirecting it to a different one.
                # This only applies when it's a non-default locale because we
                # don't want to override the redirects that are forcibly
                # changing to (or staying within) a specific locale.
                full_url = anchors[0].get('href')
                (dest_locale, url) = split_path(full_url)
                if (source_locale != dest_locale
                    and dest_locale == settings.LANGUAGE_CODE):
                    return '/' + source_locale + '/' + url
                return full_url
Beispiel #3
0
def _doc_components_from_url(url, required_locale=None, check_host=True):
    """Return (locale, path, slug) if URL is a Document, False otherwise.

    If URL doesn't even point to the document view, raise _NotDocumentView.

    """
    # Extract locale and path from URL:
    parsed = urlparse(url)  # Never has errors AFAICT
    if check_host and parsed.netloc:
        return False
    locale, path = split_path(parsed.path)
    if required_locale and locale != required_locale:
        return False
    path = "/" + path

    try:
        view, view_args, view_kwargs = resolve(path)
    except Http404:
        return False

    import kitsune.wiki.views  # Views import models; models import views.

    if view != kitsune.wiki.views.document:
        raise _NotDocumentView
    return locale, path, view_kwargs["document_slug"]
Beispiel #4
0
    def from_url(cls, url, id_only=False):
        """Returns the question that the URL represents.

        If the question doesn't exist or the URL isn't a question URL,
        this returns None.

        If id_only is requested, we just return the question id and
        we don't validate the existence of the question (this saves us
        from making a million or so db calls).
        """
        parsed = urlparse(url)
        locale, path = split_path(parsed.path)

        path = '/' + path

        try:
            view, view_args, view_kwargs = resolve(path)
        except Http404:
            return None

        import kitsune.questions.views  # Views import models; models import views.
        if view != kitsune.questions.views.answers:
            return None

        question_id = view_kwargs['question_id']

        if id_only:
            return int(question_id)

        try:
            question = cls.objects.get(id=question_id)
        except cls.DoesNotExist:
            return None

        return question
Beispiel #5
0
def _doc_components_from_url(url, required_locale=None, check_host=True):
    """Return (locale, path, slug) if URL is a Document, False otherwise.

    If URL doesn't even point to the document view, raise _NotDocumentView.

    """
    # Extract locale and path from URL:
    parsed = urlparse(url)  # Never has errors AFAICT
    if check_host and parsed.netloc:
        return False
    locale, path = split_path(parsed.path)
    if required_locale and locale != required_locale:
        return False
    path = "/" + unquote(path)

    try:
        view, view_args, view_kwargs = resolve(path)
    except Http404:
        return False

    import kitsune.wiki.views  # Views import models; models import views.

    if view != kitsune.wiki.views.document:
        raise _NotDocumentView
    return locale, path, view_kwargs["document_slug"]
Beispiel #6
0
    def from_url(cls, url, id_only=False):
        """Returns the question that the URL represents.

        If the question doesn't exist or the URL isn't a question URL,
        this returns None.

        If id_only is requested, we just return the question id and
        we don't validate the existence of the question (this saves us
        from making a million or so db calls).
        """
        parsed = urlparse(url)
        locale, path = split_path(parsed.path)

        path = '/' + path

        try:
            view, view_args, view_kwargs = resolve(path)
        except Http404:
            return None

        import kitsune.questions.views  # Views import models; models import views.
        if view != kitsune.questions.views.answers:
            return None

        question_id = view_kwargs['question_id']

        if id_only:
            return int(question_id)

        try:
            question = cls.objects.get(id=question_id)
        except cls.DoesNotExist:
            return None

        return question
Beispiel #7
0
 def request(self, **request):
     """Make a request, but prepend a locale if there isn't one already."""
     # Fall back to defaults as in the superclass's implementation:
     path = request.get("PATH_INFO", self.defaults.get("PATH_INFO", "/"))
     locale, shortened = split_path(path)
     if not locale:
         request["PATH_INFO"] = "/%s/%s" % (settings.LANGUAGE_CODE, shortened)
     return super(LocalizingClient, self).request(**request)
Beispiel #8
0
 def request(self, **request):
     """Make a request, but prepend a locale if there isn't one already."""
     # Fall back to defaults as in the superclass's implementation:
     path = request.get('PATH_INFO', self.defaults.get('PATH_INFO', '/'))
     locale, shortened = split_path(path)
     if not locale:
         request['PATH_INFO'] = '/%s/%s' % (settings.LANGUAGE_CODE,
                                            shortened)
     return super(LocalizingClient, self).request(**request)
Beispiel #9
0
    def process_request(self, request):
        try:
            urlname = resolve(request.path_info).url_name
        except Resolver404:
            urlname = None

        if settings.OIDC_ENABLE and urlname in settings.OIDC_EXEMPT_URLS:
            translation.activate(settings.LANGUAGE_CODE)
            return

        prefixer = Prefixer(request)
        set_url_prefixer(prefixer)
        full_path = prefixer.fix(prefixer.shortened_path)

        if request.GET.get('lang', '') in settings.SUMO_LANGUAGES:
            # Blank out the locale so that we can set a new one. Remove lang
            # from the query params so we don't have an infinite loop.

            prefixer.locale = ''
            new_path = prefixer.fix(prefixer.shortened_path)
            query = dict((smart_str(k), v) for k, v in request.GET.iteritems()
                         if k != 'lang')

            # 'lang' is only used on the language selection page. If this is
            # present it is safe to set language preference for the current
            # user.
            if request.user.is_anonymous():
                cookie = settings.LANGUAGE_COOKIE_NAME
                request.session[cookie] = request.GET['lang']

            return HttpResponseRedirect(urlparams(new_path, **query))

        if full_path != request.path:
            query_string = request.META.get('QUERY_STRING', '')
            full_path = urllib.quote(full_path.encode('utf-8'))

            if query_string:
                full_path = '%s?%s' % (full_path, query_string)

            response = HttpResponseRedirect(full_path)

            # Vary on Accept-Language if we changed the locale
            old_locale = prefixer.locale
            new_locale, _ = split_path(full_path)
            if old_locale != new_locale:
                response['Vary'] = 'Accept-Language'

            return response

        request.path_info = '/' + prefixer.shortened_path
        request.LANGUAGE_CODE = prefixer.locale
        translation.activate(prefixer.locale)
Beispiel #10
0
    def process_request(self, request):
        prefixer = Prefixer(request)
        set_url_prefixer(prefixer)
        full_path = prefixer.fix(prefixer.shortened_path)

        if request.GET.get('lang', '') in settings.SUMO_LANGUAGES:
            # Blank out the locale so that we can set a new one. Remove lang
            # from the query params so we don't have an infinite loop.

            prefixer.locale = ''
            new_path = prefixer.fix(prefixer.shortened_path)
            query = dict((smart_str(k), v) for
                         k, v in request.GET.iteritems() if k != 'lang')

            # 'lang' is only used on the language selection page. If this is
            # present it is safe to set language preference for the current
            # user.
            if request.user.is_anonymous():
                cookie = settings.LANGUAGE_COOKIE_NAME
                request.session[cookie] = request.GET['lang']

            return HttpResponseRedirect(urlparams(new_path, **query))

        if full_path != request.path:
            query_string = request.META.get('QUERY_STRING', '')
            full_path = urllib.quote(full_path.encode('utf-8'))

            if query_string:
                full_path = '%s?%s' % (full_path, query_string)

            response = HttpResponseRedirect(full_path)

            # Vary on Accept-Language if we changed the locale
            old_locale = prefixer.locale
            new_locale, _ = split_path(full_path)
            if old_locale != new_locale:
                response['Vary'] = 'Accept-Language'

            return response

        request.path_info = '/' + prefixer.shortened_path
        request.LANGUAGE_CODE = prefixer.locale
        translation.activate(prefixer.locale)
Beispiel #11
0
def aaq(request, product_key=None, category_key=None, step=1):
    """Ask a new question."""

    template = "questions/new_question.html"

    # Check if any product forum has a locale in the user's current locale
    if (request.LANGUAGE_CODE not in QuestionLocale.objects.locales_list()
            and request.LANGUAGE_CODE != settings.WIKI_DEFAULT_LANGUAGE):

        locale, path = split_path(request.path)
        path = "/" + settings.WIKI_DEFAULT_LANGUAGE + "/" + path

        old_lang = settings.LANGUAGES_DICT[request.LANGUAGE_CODE.lower()]
        new_lang = settings.LANGUAGES_DICT[
            settings.WIKI_DEFAULT_LANGUAGE.lower()]
        msg = _(
            "The questions forum isn't available in {old_lang}, we "
            "have redirected you to the {new_lang} questions forum.").format(
                old_lang=old_lang, new_lang=new_lang)
        messages.add_message(request, messages.WARNING, msg)

        return HttpResponseRedirect(path)

    # Check if the user is using a mobile device,
    # render step 2 if they are
    product_key = product_key or request.GET.get("product")
    if product_key is None:

        change_product = False
        if request.GET.get("q") == "change_product":
            change_product = True

        is_mobile_device = get_user_agent(request).is_mobile

        if is_mobile_device and not change_product:
            user_agent = request.META.get("HTTP_USER_AGENT", "")
            product_key = get_mobile_product_from_ua(user_agent)
            if product_key:
                # redirect needed for InAAQMiddleware
                step_2 = reverse("questions.aaq_step2",
                                 kwargs={"product_key": product_key})
                return HttpResponseRedirect(step_2)

    # Return 404 if the product doesn't exist in config
    product_config = config.products.get(product_key)
    if product_key and not product_config:
        raise Http404

    # If the selected product doesn't exist in DB, render a 404
    if step > 1:
        try:
            product = Product.objects.get(slug=product_config["product"])
        except Product.DoesNotExist:
            raise Http404
        else:
            # Check if the selected product has a forum in the user's locale
            if not product.questions_locales.filter(
                    locale=request.LANGUAGE_CODE).count():
                locale, path = split_path(request.path)
                path = "/" + settings.WIKI_DEFAULT_LANGUAGE + "/" + path

                old_lang = settings.LANGUAGES_DICT[
                    request.LANGUAGE_CODE.lower()]
                new_lang = settings.LANGUAGES_DICT[
                    settings.WIKI_DEFAULT_LANGUAGE.lower()]
                msg = _(
                    "The questions forum isn't available for {product} in {old_lang}, we "
                    "have redirected you to the {new_lang} questions forum."
                ).format(product=product.title,
                         old_lang=old_lang,
                         new_lang=new_lang)
                messages.add_message(request, messages.WARNING, msg)

                return HttpResponseRedirect(path)

    context = {
        "products": config.products,
        "current_product": product_config,
        "current_step": step,
        "host": Site.objects.get_current().domain,
    }

    if step == 2:
        context["featured"] = get_featured_articles(
            product, locale=request.LANGUAGE_CODE)
        context["topics"] = topics_for(product, parent=None)
    elif step == 3:
        form = NewQuestionForm(
            product=product_config,
            data=request.POST or None,
            initial={"category": category_key},
        )
        context["form"] = form

        # NOJS: upload image
        if "upload_image" in request.POST:
            upload_imageattachment(request, request.user)

        if form.is_valid() and not is_ratelimited(request, "aaq-day", "5/d"):

            question = form.save(
                user=request.user,
                locale=request.LANGUAGE_CODE,
                product=product,
                product_config=product_config,
            )

            if form.cleaned_data.get("is_spam"):
                _add_to_moderation_queue(request, question)

            # Submitting the question counts as a vote
            question_vote(request, question.id)

            my_questions_url = reverse("users.questions",
                                       args=[request.user.username])
            messages.add_message(
                request,
                messages.SUCCESS,
                _("Done! Your question is now posted on the Mozilla community support forum. "
                  +
                  "You can see your post anytime by visiting the {a_open}My Questions"
                  + "{a_close} page in your profile.").format(
                      a_open="<a href='" + my_questions_url + "'>",
                      a_close="</a>"),
                extra_tags="safe",
            )

            request.session["aaq-final-step"] = True

            url = reverse("questions.details",
                          kwargs={"question_id": question.id})
            return HttpResponseRedirect(url)

        if getattr(request, "limited", False):
            raise PermissionDenied

        user_ct = ContentType.objects.get_for_model(request.user)
        context["images"] = ImageAttachment.objects.filter(
            creator=request.user,
            content_type=user_ct,
        ).order_by("-id")[:IMG_LIMIT]

    return render(request, template, context)