<commit_before>from django.shortcuts import reverse
from django.db.models import Q
from django.db.models.functions import Lower
from django.contrib.auth.models import Group

from django.views import generic
from django.utils.text import slugify
from guardian.mixins import LoginRequiredMixin
from guardian.shortcuts import get_objects_for_user

from accounts.forms import UserStudiesForm
from accounts.models import User
from studies.models import Response, Study


class ParticipantListView(LoginRequiredMixin, generic.ListView):
    '''
    ParticipantListView shows a list of participants that have participated in studies
    related to organizations that the current user has permissions to.
    '''
    template_name = 'accounts/participant_list.html'
    queryset = User.objects.exclude(demographics__isnull=True)
    model = User

    def get_queryset(self):
        qs = super(ParticipantListView, self).get_queryset()
        return qs.filter(response__study__organization=self.request.user.organization)


class ParticipantDetailView(LoginRequiredMixin, generic.UpdateView):
    '''
    ParticipantDetailView shows information about a participant that has participated in studies
    related to organizations that the current user has permission to.
    '''
    queryset = User.objects.exclude(demographics__isnull=True).select_related('organization')
    fields = ('is_active', )
    template_name = 'accounts/participant_detail.html'
    model = User

    def get_queryset(self):
        qs = super(ParticipantDetailView, self).get_queryset()
        return qs.filter(response__study__organization=self.request.user.organization)

    def get_success_url(self):
        return reverse('exp:participant-detail', kwargs={'pk': self.object.id})


class ResponseListView(LoginRequiredMixin, generic.ListView):
    '''
    Displays a list of responses for studies that the current user can view.
    '''
    template_name = 'accounts/response_list.html'

    def get_queryset(self):
        studies = get_objects_for_user(self.request.user, 'studies.can_view')
        return Response.objects.filter(study__in=studies).order_by('study__name')


class ResponseDetailView(LoginRequiredMixin, generic.DetailView):
    '''
    Displays a response.
    '''
    template_name = 'accounts/response_detail.html'

    def get_queryset(self):
        studies = get_objects_for_user(self.request.user, 'studies.can_view')
        return Response.objects.filter(study__in=studies).order_by('study__name')


class ResearcherListView(LoginRequiredMixin, generic.ListView):
    '''
    Displays a list of researchers in the same organization as the current user.
    '''
    template_name = 'accounts/researcher_list.html'
    queryset = User.objects.filter(demographics__isnull=True)
    model = User

    def get_queryset(self):
        qs = super(ResearcherListView, self).get_queryset()
        # TODO this should probably use permissions eventually, just to be safe
        queryset = qs.filter(organization=self.request.user.organization)
        match = self.request.GET.get('match')
        if match:
            queryset = queryset.filter(Q(family_name__icontains=match) | Q(given_name__icontains=match)| Q(middle_name__icontains=match))
        sort = self.request.GET.get('sort')
        if sort:
            if 'family_name' in sort:
                queryset = queryset.order_by(Lower('family_name').desc()) if '-' in sort else queryset.order_by(Lower('family_name').asc())
        return queryset

    def post(self, request, *args, **kwargs):
        retval = super(ResearcherListView, self).get(request, *args, **kwargs)
        if 'delete' in self.request.POST:
            User.objects.get(pk=self.request.POST['delete']).delete()
        return retval

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['match'] = self.request.GET.get('match') or ''
        context['sort'] = self.request.GET.get('sort') or ''
        return context


class ResearcherDetailView(LoginRequiredMixin, generic.UpdateView):
    '''
    ResearcherDetailView shows information about a researcher and allows enabling or disabling
    a user.
    '''
    queryset = User.objects.filter(demographics__isnull=True)
    fields = ('is_active', )
    template_name = 'accounts/researcher_detail.html'
    model = User

    def get_success_url(self):
        return reverse('exp:researcher-detail', kwargs={'pk': self.object.id})

    def post(self, request, *args, **kwargs):
        retval = super(ResearcherDetailView, self).post(request, *args, **kwargs)
        if 'enable' in self.request.POST:
            self.object.is_active = True
        elif 'disable' in self.request.POST:
            self.object.is_active = False

        if self.request.POST.get('name') == 'given_name':
            self.object.given_name = self.request.POST['value']
        if self.request.POST.get('name') == 'middle_name':
            self.object.middle_name = self.request.POST['value']
        if self.request.POST.get('name') == 'family_name':
            self.object.family_name = self.request.POST['value']
        if self.request.POST.get('name') == 'user_permissions':
            new_perm_short = self.request.POST['value']
            admin_group = Group.objects.get(name=f'{slugify(self.get_object().organization.name)}_ORG_ADMIN'.upper())
            read_group = Group.objects.get(name=f'{slugify(self.get_object().organization.name)}_ORG_READ'.upper())
            researcher = self.get_object()

            if new_perm_short == 'org_admin':
                admin_group.user_set.add(researcher)
            elif new_perm_short == 'org_read':<commit_msg>Can only view researcher list and researcher detail pages if at least org_read.<commit_after>from django.shortcuts import reverse
from django.db.models import Q
from django.db.models.functions import Lower
from django.contrib.auth.models import Group
from django.core.exceptions import PermissionDenied

from django.views import generic
from django.utils.text import slugify
from guardian.mixins import LoginRequiredMixin
from guardian.shortcuts import get_objects_for_user

from accounts.forms import UserStudiesForm
from accounts.models import User
from studies.models import Response, Study


class ParticipantListView(LoginRequiredMixin, generic.ListView):
    '''
    ParticipantListView shows a list of participants that have participated in studies
    related to organizations that the current user has permissions to.
    '''
    template_name = 'accounts/participant_list.html'
    queryset = User.objects.exclude(demographics__isnull=True)
    model = User

    def get_queryset(self):
        qs = super(ParticipantListView, self).get_queryset()
        return qs.filter(response__study__organization=self.request.user.organization)


class ParticipantDetailView(LoginRequiredMixin, generic.UpdateView):
    '''
    ParticipantDetailView shows information about a participant that has participated in studies
    related to organizations that the current user has permission to.
    '''
    queryset = User.objects.exclude(demographics__isnull=True).select_related('organization')
    fields = ('is_active', )
    template_name = 'accounts/participant_detail.html'
    model = User

    def get_queryset(self):
        qs = super(ParticipantDetailView, self).get_queryset()
        return qs.filter(response__study__organization=self.request.user.organization)

    def get_success_url(self):
        return reverse('exp:participant-detail', kwargs={'pk': self.object.id})


class ResponseListView(LoginRequiredMixin, generic.ListView):
    '''
    Displays a list of responses for studies that the current user can view.
    '''
    template_name = 'accounts/response_list.html'

    def get_queryset(self):
        studies = get_objects_for_user(self.request.user, 'studies.can_view')
        return Response.objects.filter(study__in=studies).order_by('study__name')


class ResponseDetailView(LoginRequiredMixin, generic.DetailView):
    '''
    Displays a response.
    '''
    template_name = 'accounts/response_detail.html'

    def get_queryset(self):
        studies = get_objects_for_user(self.request.user, 'studies.can_view')
        return Response.objects.filter(study__in=studies).order_by('study__name')


class ResearcherListView(LoginRequiredMixin, generic.ListView):
    '''
    Displays a list of researchers in the same organization as the current user.
    '''
    template_name = 'accounts/researcher_list.html'
    queryset = User.objects.filter(demographics__isnull=True)
    model = User

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_org_read or request.user.is_superuser:
            return super().dispatch(request, *args, **kwargs)
        else:
            raise PermissionDenied # HTTP 403


    def get_queryset(self):
        qs = super(ResearcherListView, self).get_queryset()
        # TODO this should probably use permissions eventually, just to be safe
        queryset = qs.filter(organization=self.request.user.organization)
        match = self.request.GET.get('match')
        if match:
            queryset = queryset.filter(Q(family_name__icontains=match) | Q(given_name__icontains=match)| Q(middle_name__icontains=match))
        sort = self.request.GET.get('sort')
        if sort:
            if 'family_name' in sort:
                queryset = queryset.order_by(Lower('family_name').desc()) if '-' in sort else queryset.order_by(Lower('family_name').asc())
        return queryset

    def post(self, request, *args, **kwargs):
        retval = super(ResearcherListView, self).get(request, *args, **kwargs)
        if 'delete' in self.request.POST:
            User.objects.get(pk=self.request.POST['delete']).delete()
        return retval

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['match'] = self.request.GET.get('match') or ''
        context['sort'] = self.request.GET.get('sort') or ''
        return context


class ResearcherDetailView(LoginRequiredMixin, generic.UpdateView):
    '''
    ResearcherDetailView shows information about a researcher and allows enabling or disabling
    a user.
    '''
    queryset = User.objects.filter(demographics__isnull=True)
    fields = ('is_active', )
    template_name = 'accounts/researcher_detail.html'
    model = User

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_org_read or request.user.is_superuser:
            return super().dispatch(request, *args, **kwargs)
        else:
            raise PermissionDenied # HTTP 403

    def get_success_url(self):
        return reverse('exp:researcher-detail', kwargs={'pk': self.object.id})

    def post(self, request, *args, **kwargs):
        retval = super(ResearcherDetailView, self).post(request, *args, **kwargs)
        if 'enable' in self.request.POST:
            self.object.is_active = True
        elif 'disable' in self.request.POST:
            self.object.is_active = False

        if self.request.POST.get('name') == 'given_name':
            self.object.given_name = self.request.POST['value']
        if self.request.POST.get('name') == 'middle_name':
            self.object.middle_name = self.request.POST['value']
        if self.request.POST.get('name') == 'family_name':
            self.object.family_name = self.request.POST['value']
        if self.request.POST.get('name') == 'user_permissions':
            new_perm_short = self.request.POST['value']
            admin_group = Group.objects.get(name=f'{slugify(self.get_object().organization.name)}_ORG_ADMIN'.upper())
            read_group = Group.objects.get(name=f'{slugify(self.get_object().organization.name)}_ORG_READ'.upper())
            researcher = self.get_object()

            if new_perm_short == 'org_admin':
                admin_group.user_set.add(researcher)
            elif new_perm_short == 'org_read':
{'fraction_non_alphanumeric': 0.10816445667584021, 'fraction_numerical': 0.0005003752814610958, 'mean_word_length': 3.5407042786823175, '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': '7174475', 'n_tokens_mistral': 3513, 'n_tokens_neox': 3372, 'n_words': 745}