<commit_before>"""
Page middleware (``feincms3.root.middleware``)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The guide recommends using a middleware for the feincms3 pages app. This module
offers helpers and utilities to reduce the amount of code you have to write.
The reason why this module is called ``root`` is that the page app's mountpoint
has to be the Python app's mountpoint when using this. If that's not the case
you may want to write your own :ref:`urls-and-views`.

Example code for using this module (e.g. ``app.pages.middleware``):

.. code-block:: python

    from django.shortcuts import render
    from feincms3.root.middleware import add_redirect_handler, create_page_if_404_middleware

    from app.pages.models import Page
    from app.pages.utils import page_context

    # The page handler receives the request and the page.
    # ``add_redirect_handler`` wraps the handler function with support for the
    # RedirectMixin.
    @add_redirect_handler
    def handler(request, page):
        return render(request, page.type.template_name, page_context(request, page=page))

    # This is the middleware which you want to add to ``MIDDLEWARE`` as
    # ``app.pages.middleware.page_if_404_middleware``. The middleware should be
    # added in the last position except if you have a very good reason not to
    # do this.
    page_if_404_middleware = create_page_if_404_middleware(
        # queryset=Page.objects.active() works too (if .active() doesn't use
        # get_language or anything similar)
        queryset=lambda request: Page.objects.active(),

        handler=handler,
    )
"""

from functools import wraps

from django.http import HttpResponseNotFound, HttpResponseRedirect


class _UseRootMiddlewareResponse(HttpResponseNotFound):
    """Used by feincms3.root.passthru to tell the middleware to do its thing"""

    pass


def create_page_if_404_middleware(*, queryset, handler, language_code_redirect=False):
    """
    Create a middleware for handling pages

    This utility is there for your convenience, you do not have to use it. The
    returned middleware already handles returning non-404 responses as-is,
    fetching a page instance from the database and calling a user-defined
    handler on success. It optionally also supports redirecting requests to the
    root of the app to a language-specific landing page.

    Required arguments:

    - ``queryset``: A page queryset or a callable accepting the request and
      returning a page queryset.
    - ``handler``: A callable accepting the request and a page and returning a
      response.

    Optional arguments:

    - ``language_code_redirect`` (``False``): Redirect visitor to the language
      code prefix (e.g. ``/en/``, ``/de-ch/``) if request path equals the
      script prefix (generally ``/``) and no active page for ``/`` exists.
    """

    def outer(get_response):
        def inner(request):
            response = get_response(request)
            if response.status_code != 404 or (
                request.resolver_match
                and not isinstance(response, _UseRootMiddlewareResponse)
            ):
                # Response is not a 404 OR the path can be resolved and running
                # the middleware hasn't been requested explicitly.
                return response
            qs = queryset(request) if callable(queryset) else queryset._clone()
            if page := qs.filter(path=request.path_info).first():
                return handler(request, page)
            if language_code_redirect and request.path_info == "/":
                target = f"/{request.LANGUAGE_CODE}/"
                if qs.filter(path=target).exists():
                    return HttpResponseRedirect(target)<commit_msg>Update the comment for clarity<commit_after>"""
Page middleware (``feincms3.root.middleware``)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The guide recommends using a middleware for the feincms3 pages app. This module
offers helpers and utilities to reduce the amount of code you have to write.
The reason why this module is called ``root`` is that the page app's mountpoint
has to be the Python app's mountpoint when using this. If that's not the case
you may want to write your own :ref:`urls-and-views`.

Example code for using this module (e.g. ``app.pages.middleware``):

.. code-block:: python

    from django.shortcuts import render
    from feincms3.root.middleware import add_redirect_handler, create_page_if_404_middleware

    from app.pages.models import Page
    from app.pages.utils import page_context

    # The page handler receives the request and the page.
    # ``add_redirect_handler`` wraps the handler function with support for the
    # RedirectMixin.
    @add_redirect_handler
    def handler(request, page):
        return render(request, page.type.template_name, page_context(request, page=page))

    # This is the middleware which you want to add to ``MIDDLEWARE`` as
    # ``app.pages.middleware.page_if_404_middleware``. The middleware should be
    # added in the last position except if you have a very good reason not to
    # do this.
    page_if_404_middleware = create_page_if_404_middleware(
        # queryset=Page.objects.active() works too (if .active() doesn't use
        # get_language or anything similar)
        queryset=lambda request: Page.objects.active(),

        handler=handler,
    )
"""

from functools import wraps

from django.http import HttpResponseNotFound, HttpResponseRedirect


class _UseRootMiddlewareResponse(HttpResponseNotFound):
    """Used by feincms3.root.passthru to tell the middleware to do its thing"""

    pass


def create_page_if_404_middleware(*, queryset, handler, language_code_redirect=False):
    """
    Create a middleware for handling pages

    This utility is there for your convenience, you do not have to use it. The
    returned middleware already handles returning non-404 responses as-is,
    fetching a page instance from the database and calling a user-defined
    handler on success. It optionally also supports redirecting requests to the
    root of the app to a language-specific landing page.

    Required arguments:

    - ``queryset``: A page queryset or a callable accepting the request and
      returning a page queryset.
    - ``handler``: A callable accepting the request and a page and returning a
      response.

    Optional arguments:

    - ``language_code_redirect`` (``False``): Redirect visitor to the language
      code prefix (e.g. ``/en/``, ``/de-ch/``) if request path equals the
      script prefix (generally ``/``) and no active page for ``/`` exists.
    """

    def outer(get_response):
        def inner(request):
            response = get_response(request)
            if response.status_code != 404 or (
                request.resolver_match
                and not isinstance(response, _UseRootMiddlewareResponse)
            ):
                # Response is not a 404 OR the 404 comes from a resolved view
                # which also didn't return a _UseRootMiddlewareResponse.
                return response
            qs = queryset(request) if callable(queryset) else queryset._clone()
            if page := qs.filter(path=request.path_info).first():
                return handler(request, page)
            if language_code_redirect and request.path_info == "/":
                target = f"/{request.LANGUAGE_CODE}/"
                if qs.filter(path=target).exists():
                    return HttpResponseRedirect(target)
{'fraction_non_alphanumeric': 0.08901288694034808, 'fraction_numerical': 0.007838448252956026, 'mean_word_length': 3.075798592311857, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2944943', 'n_tokens_mistral': 2057, 'n_tokens_neox': 1951, 'n_words': 759}