<commit_before># -*- coding: utf-8 -*-
from collections import defaultdict
import itertools
from operator import itemgetter

from ckeditor.widgets import CKEditorWidget
from django.contrib import admin
from django.db.models import Q, Count
from django.template.defaultfilters import striptags
from django.utils.encoding import smart_text

from django.utils.translation import ugettext_lazy as _

from . import models
from scheduler import models as shiftmodels
from organizations.models import Membership

DEFAULT_FILTER_ROLES = (models.Membership.Roles.ADMIN,
                        models.Membership.Roles.MANAGER)


def get_memberships_by_role(membership_queryset):
    memberships_by_role = defaultdict(lambda: [])
    membership_queryset = membership_queryset.filter(
        membership__status__gte=Membership.Status.APPROVED
    )
    qs = membership_queryset.order_by('membership__role') \
        .values_list('membership__role', 'pk')
    for role, group in itertools.groupby(qs, itemgetter(0)):
        memberships_by_role[role] = list(map(itemgetter(1), group))
    return memberships_by_role


def get_cached_memberships(user, roles=DEFAULT_FILTER_ROLES):
    user_memberships = getattr(user, '__memberships', None)
    if not user_memberships:
        user_memberships = {
            'facilities': get_memberships_by_role(user.account.facility_set),
            'organizations': get_memberships_by_role(
                user.account.organization_set),
        }
        setattr(user, '__memberships', user_memberships)

    user_orgs = list(itertools.chain.from_iterable(
        user_memberships['organizations'][role] for role in roles))

    user_facilities = list(itertools.chain.from_iterable(
        user_memberships['facilities'][role] for role in roles))

    return user_orgs, user_facilities


def filter_queryset_by_membership(qs, user,
                                  facility_filter_fk=None,
                                  organization_filter_fk=None,
                                  roles=DEFAULT_FILTER_ROLES,
                                  skip_superuser=True):
    if facility_filter_fk and organization_filter_fk:
        raise Exception(
            'facility_filter_fk and organization_filter_fk are mutually exclusive.')

    if skip_superuser and user.is_superuser:
        return qs

    user_orgs, user_facilities = get_cached_memberships(user, roles)

    if qs.model == models.Organization:
        qs = qs.filter(pk__in=user_orgs)
    elif qs.model == models.Facility:
        qs = qs.filter(
            Q(pk__in=user_facilities) |
            Q(organization_id__in=user_orgs)
        )
    else:
        if facility_filter_fk is None and organization_filter_fk is None:
            facility_filter_fk = 'facility'

        if qs.model == models.OrganizationMembership:
            if organization_filter_fk:
                qs = qs.filter(**{organization_filter_fk + '_id__in': user_orgs})
        elif qs.model == shiftmodels.ShiftHelper:
            qs = qs.filter(
                Q(**{'shift__' + facility_filter_fk + '_id__in': user_facilities}) |
                Q(**{'shift__' + facility_filter_fk + '__organization_id__in': user_orgs})
            )
        else:
            if organization_filter_fk:
                qs = qs.filter(**{organization_filter_fk + '_id__in': user_orgs})
            elif facility_filter_fk:
                qs = qs.filter(
                    Q(**{facility_filter_fk + '_id__in': user_facilities}) |
                    Q(**{facility_filter_fk + '__organization_id__in': user_orgs})
                )
    return qs


class MembershipFilteredAdmin(admin.ModelAdmin):
    facility_filter_fk = 'facility'
    widgets = None

    def get_readonly_fields(self, request, obj=None):
        readonly = super(MembershipFilteredAdmin, self).get_readonly_fields(
            request=request, obj=obj)
        if request.user.is_superuser:
            return readonly
        else:
            if not ('facility' in readonly and 'organization' in readonly):
                user_orgs, user_facilities = get_cached_memberships(
                    request.user)
                if len(user_facilities) <= 1 and hasattr(obj, 'facility') \
                        and 'facility' not in readonly:
                    readonly += ('facility',)
                if len(user_orgs) <= 1 and hasattr(obj, 'organization') \
                        and 'organization' not in readonly:
                    readonly += ('organization',)
        return readonly

    def get_list_display(self, request):
        list_display = list(
            super(MembershipFilteredAdmin, self).get_list_display(request))
        if request.user.is_superuser:
            return list_display
        if 'facility' in list_display or 'organization' in list_display:
            user_orgs, user_facilities = get_cached_memberships(request.user)
            if len(user_facilities) <= 1 and 'facility' in list_display:
                list_display.remove('facility')
            if len(user_orgs) <= 1 and 'organization' in list_display:
                list_display.remove('organization')
        return list_display

    def get_list_display_links(self, request, list_display):
        list_display_links = list(
            super(MembershipFilteredAdmin, self).get_list_display_links(request,
                                                                        list_display))
        return list(filter(lambda i: i in list_display, list_display_links))

    def get_edit_link(self, obj):
        return _(u'edit')

    get_edit_link.short_description = _(u'edit')

    def get_form(self, request, obj=None, **kwargs):
        form = super(MembershipFilteredAdmin, self).get_form(
            request, obj, widgets=self.widgets, **kwargs)

        if 'facility' in form.base_fields:
            facilities = models.Facility.objects.all()
            user_facilities = filter_queryset_by_membership(facilities,
                                                            request.user)
            if len(user_facilities) == 1:
                form.base_fields['facility'].initial = user_facilities.get()

        return form

    def get_queryset(self, request):
        qs = super(MembershipFilteredAdmin, self).get_queryset(request)
        return filter_queryset_by_membership(
            qs, user=request.user, facility_filter_fk=self.facility_filter_fk)

    def get_field_queryset(self, db, db_field, request):
        qs = super(MembershipFilteredAdmin, self).get_field_queryset(
            db, db_field, request)
        if db_field.remote_field.model in (models.Facility,<commit_msg>Filter by own organization or facility<commit_after># -*- coding: utf-8 -*-
from collections import defaultdict
import itertools
from operator import itemgetter

from ckeditor.widgets import CKEditorWidget
from django.contrib import admin
from django.db.models import Q, Count
from django.template.defaultfilters import striptags
from django.utils.encoding import smart_text

from django.utils.translation import ugettext_lazy as _

from . import models
from scheduler import models as shiftmodels
from organizations.models import Membership

DEFAULT_FILTER_ROLES = (models.Membership.Roles.ADMIN,
                        models.Membership.Roles.MANAGER)


def get_memberships_by_role(membership_queryset):
    memberships_by_role = defaultdict(lambda: [])
    membership_queryset = membership_queryset.filter(
        membership__status__gte=Membership.Status.APPROVED
    )
    qs = membership_queryset.order_by('membership__role') \
        .values_list('membership__role', 'pk')
    for role, group in itertools.groupby(qs, itemgetter(0)):
        memberships_by_role[role] = list(map(itemgetter(1), group))
    return memberships_by_role


def get_cached_memberships(user, roles=DEFAULT_FILTER_ROLES):
    user_memberships = getattr(user, '__memberships', None)
    if not user_memberships:
        user_memberships = {
            'facilities': get_memberships_by_role(user.account.facility_set),
            'organizations': get_memberships_by_role(
                user.account.organization_set),
        }
        setattr(user, '__memberships', user_memberships)

    user_orgs = list(itertools.chain.from_iterable(
        user_memberships['organizations'][role] for role in roles))

    user_facilities = list(itertools.chain.from_iterable(
        user_memberships['facilities'][role] for role in roles))

    return user_orgs, user_facilities


def filter_queryset_by_membership(qs, user,
                                  facility_filter_fk=None,
                                  organization_filter_fk=None,
                                  roles=DEFAULT_FILTER_ROLES,
                                  skip_superuser=True):
    if facility_filter_fk and organization_filter_fk:
        raise Exception(
            'facility_filter_fk and organization_filter_fk are mutually exclusive.')

    if skip_superuser and user.is_superuser:
        return qs

    user_orgs, user_facilities = get_cached_memberships(user, roles)

    if qs.model == models.Organization:
        qs = qs.filter(pk__in=user_orgs)
    elif qs.model == models.Facility:
        qs = qs.filter(
            Q(pk__in=user_facilities) |
            Q(organization_id__in=user_orgs)
        )
    else:
        if facility_filter_fk is None and organization_filter_fk is None:
            facility_filter_fk = 'facility'

        if qs.model == models.OrganizationMembership:
            if organization_filter_fk:
                qs = qs.filter(**{organization_filter_fk + '_id__in': user_orgs})
        elif qs.model == shiftmodels.ShiftHelper:
            qs = qs.filter(
                Q(**{'shift__' + facility_filter_fk + '_id__in': user_facilities}) |
                Q(**{'shift__' + facility_filter_fk + '__organization_id__in': user_orgs})
            )
        else:
            if organization_filter_fk:
                qs = qs.filter(**{organization_filter_fk + '_id__in': user_orgs})
            elif facility_filter_fk:
                qs = qs.filter(
                    Q(**{facility_filter_fk + '_id__in': user_facilities}) |
                    Q(**{facility_filter_fk + '__organization_id__in': user_orgs})
                )
    return qs


class MembershipFilteredAdmin(admin.ModelAdmin):
    facility_filter_fk = 'facility'
    organization_filter_fk = 'organization'
    widgets = None

    def get_readonly_fields(self, request, obj=None):
        readonly = super(MembershipFilteredAdmin, self).get_readonly_fields(
            request=request, obj=obj)
        if request.user.is_superuser:
            return readonly
        else:
            if not ('facility' in readonly and 'organization' in readonly):
                user_orgs, user_facilities = get_cached_memberships(
                    request.user)
                if len(user_facilities) <= 1 and hasattr(obj, 'facility') \
                        and 'facility' not in readonly:
                    readonly += ('facility',)
                if len(user_orgs) <= 1 and hasattr(obj, 'organization') \
                        and 'organization' not in readonly:
                    readonly += ('organization',)
        return readonly

    def get_list_display(self, request):
        list_display = list(
            super(MembershipFilteredAdmin, self).get_list_display(request))
        if request.user.is_superuser:
            return list_display
        if 'facility' in list_display or 'organization' in list_display:
            user_orgs, user_facilities = get_cached_memberships(request.user)
            if len(user_facilities) <= 1 and 'facility' in list_display:
                list_display.remove('facility')
            if len(user_orgs) <= 1 and 'organization' in list_display:
                list_display.remove('organization')
        return list_display

    def get_list_display_links(self, request, list_display):
        list_display_links = list(
            super(MembershipFilteredAdmin, self).get_list_display_links(request,
                                                                        list_display))
        return list(filter(lambda i: i in list_display, list_display_links))

    def get_edit_link(self, obj):
        return _(u'edit')

    get_edit_link.short_description = _(u'edit')

    def get_form(self, request, obj=None, **kwargs):
        form = super(MembershipFilteredAdmin, self).get_form(
            request, obj, widgets=self.widgets, **kwargs)

        if 'facility' in form.base_fields:
            facilities = models.Facility.objects.all()
            user_facilities = filter_queryset_by_membership(facilities,
                                                            request.user)
            if len(user_facilities) == 1:
                form.base_fields['facility'].initial = user_facilities.get()

        return form

    def get_queryset(self, request):
        qs = super(MembershipFilteredAdmin, self).get_queryset(request)
        fac_filter = self.facility_filter_fk
        org_filter = None
        if qs.model.__name__.startswith('Organization'):
            fac_filter = None
            org_filter = self.organization_filter_fk
        return filter_queryset_by_membership(
            qs, user=request.user, facility_filter_fk=fac_filter, organization_filter_fk=org_filter)

    def get_field_queryset(self, db, db_field, request):
        qs = super(MembershipFilteredAdmin, self).get_field_queryset(
            db, db_field, request)
        if db_field.remote_field.model in (models.Facility,
{'fraction_non_alphanumeric': 0.08305159488460973, 'fraction_numerical': 0.001175951785976775, 'mean_word_length': 2.4764946346448644, 'pattern_counts': {'":': 0, '<': 11, '<?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': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6502187', 'n_tokens_mistral': 3993, 'n_tokens_neox': 3820, 'n_words': 785}