<commit_before>import rest_framework
from django.shortcuts import get_object_or_404
from django.utils.http import urlunquote
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import authentication, status
from rest_framework.generics import (
    ListAPIView, ListCreateAPIView, RetrieveUpdateDestroyAPIView
)
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_extensions.cache.mixins import CacheResponseMixin

from api.activity.views import ActivityList
from api.cache import QueryParamsKeyConstructor
from api.generics.views import (
    DynamicDetailCRUDView, DynamicDetailView, DynamicListCRUDView,
    DynamicListView
)
from api.organisation import serializers
from api.organisation.validators import organisation_required_fields
from api.publisher.permissions import PublisherPermissions
from api.renderers import OrganisationIATIXMLRenderer
from api.transaction.views import TransactionList
from iati_organisation.models import (
    DocumentLinkRecipientCountry, Organisation, OrganisationDocumentLink,
    OrganisationDocumentLinkCategory, OrganisationDocumentLinkLanguage,
    RecipientCountryBudget, RecipientCountryBudgetLine, RecipientOrgBudget,
    RecipientOrgBudgetLine, RecipientRegionBudget, RecipientRegionBudgetLine,
    TotalBudget, TotalBudgetLine, TotalExpenditure, TotalExpenditureLine
)


def custom_get_object(self):
    """
    a custom version of view.get_object, to decode the url encoded by the
    OrganisationSerializer
    """
    queryset = self.filter_queryset(self.get_queryset())
    return custom_get_object_from_queryset(self, queryset)


def custom_get_object_from_queryset(self, queryset):
    lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
    lookup_url = self.kwargs[lookup_url_kwarg]

    decoded_lookup_url = urlunquote(lookup_url)
    filter_kwargs = {self.lookup_field: decoded_lookup_url}
    return get_object_or_404(queryset, **filter_kwargs)


class FilterPublisherMixin(object):
    authentication_classes = (authentication.TokenAuthentication,)
    permission_classes = (PublisherPermissions, )

    def get_queryset(self):
        publisher_id = self.kwargs.get('publisher_id')

        return Organisation.objects.filter(publisher__id=publisher_id)


class OrganisationList(CacheResponseMixin, DynamicListView):
    """
    Returns a list of IATI Organisations stored in OIPA.

    ## Result details

    Each result item contains short information about organisation
    including URI to organisation details.

    URI is constructed as follows: `/api/organisations/{organisation_id}`

    """
    renderer_classes = (
        rest_framework.renderers.BrowsableAPIRenderer,
        rest_framework.renderers.JSONRenderer,
        OrganisationIATIXMLRenderer,
    )
    queryset = Organisation.objects.all()
    serializer_class = serializers.OrganisationSerializer
    fields = ('url', 'organisation_identifier',
              'last_updated_datetime', 'name')
    list_cache_key_func = QueryParamsKeyConstructor()


class OrganisationDetail(CacheResponseMixin, DynamicDetailView):
    """
    Returns detailed information about Organisation.

    ## URI Format

    ```
    /api/organisations/{organisation_id}
    ```

    ### URI Parameters

    - `organisation_id`: Numerical ID of desired Organisation

    ## Request parameters

    - `fields` (*optional*): List of fields to display<commit_msg>add `selectable_field` for organisation endpoint.<commit_after>import rest_framework
from django.shortcuts import get_object_or_404
from django.utils.http import urlunquote
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import authentication, status
from rest_framework.generics import (
    ListAPIView, ListCreateAPIView, RetrieveUpdateDestroyAPIView
)
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_extensions.cache.mixins import CacheResponseMixin

from api.activity.views import ActivityList
from api.cache import QueryParamsKeyConstructor
from api.generics.views import (
    DynamicDetailCRUDView, DynamicDetailView, DynamicListCRUDView,
    DynamicListView
)
from api.organisation import serializers
from api.organisation.validators import organisation_required_fields
from api.publisher.permissions import PublisherPermissions
from api.renderers import OrganisationIATIXMLRenderer
from api.transaction.views import TransactionList
from iati_organisation.models import (
    DocumentLinkRecipientCountry, Organisation, OrganisationDocumentLink,
    OrganisationDocumentLinkCategory, OrganisationDocumentLinkLanguage,
    RecipientCountryBudget, RecipientCountryBudgetLine, RecipientOrgBudget,
    RecipientOrgBudgetLine, RecipientRegionBudget, RecipientRegionBudgetLine,
    TotalBudget, TotalBudgetLine, TotalExpenditure, TotalExpenditureLine
)


def custom_get_object(self):
    """
    a custom version of view.get_object, to decode the url encoded by the
    OrganisationSerializer
    """
    queryset = self.filter_queryset(self.get_queryset())
    return custom_get_object_from_queryset(self, queryset)


def custom_get_object_from_queryset(self, queryset):
    lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
    lookup_url = self.kwargs[lookup_url_kwarg]

    decoded_lookup_url = urlunquote(lookup_url)
    filter_kwargs = {self.lookup_field: decoded_lookup_url}
    return get_object_or_404(queryset, **filter_kwargs)


class FilterPublisherMixin(object):
    authentication_classes = (authentication.TokenAuthentication,)
    permission_classes = (PublisherPermissions, )

    def get_queryset(self):
        publisher_id = self.kwargs.get('publisher_id')

        return Organisation.objects.filter(publisher__id=publisher_id)


class OrganisationList(CacheResponseMixin, DynamicListView):
    """
    Returns a list of IATI Organisations stored in OIPA.

    ## Result details

    Each result item contains short information about organisation
    including URI to organisation details.

    URI is constructed as follows: `/api/organisations/{organisation_id}`

    """
    renderer_classes = (
        rest_framework.renderers.BrowsableAPIRenderer,
        rest_framework.renderers.JSONRenderer,
        OrganisationIATIXMLRenderer,
    )
    queryset = Organisation.objects.all()
    serializer_class = serializers.OrganisationSerializer
    selectable_fields = ()
    fields = ('url', 'organisation_identifier',
              'last_updated_datetime', 'name')
    list_cache_key_func = QueryParamsKeyConstructor()


class OrganisationDetail(CacheResponseMixin, DynamicDetailView):
    """
    Returns detailed information about Organisation.

    ## URI Format

    ```
    /api/organisations/{organisation_id}
    ```

    ### URI Parameters

    - `organisation_id`: Numerical ID of desired Organisation

    ## Request parameters

    - `fields` (*optional*): List of fields to display
{'fraction_non_alphanumeric': 0.0633147113594041, 'fraction_numerical': 0.0017189514396218307, 'mean_word_length': 5.162400706090026, 'pattern_counts': {'":': 0, '<': 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': '2243213', 'n_tokens_mistral': 1958, 'n_tokens_neox': 1835, 'n_words': 434}