<commit_before>from django.contrib import messages as django_messages
from django.core.mail import send_mail
from django.core.urlresolvers import reverse, reverse_lazy
from django.http import Http404, HttpResponseRedirect
from django.template import engines
from django.template.loader import render_to_string
from django.views.generic import (CreateView, DetailView, FormView,
                                  TemplateView, UpdateView, View)

from oauth2_provider.models import AccessToken, RefreshToken

from common.mixins import LargePanelMixin, PrivateMixin
from common.utils import full_url, get_source_labels_and_configs
from common.views import BaseOAuth2AuthorizationView

from .forms import (MessageProjectMembersForm, OAuth2DataRequestProjectForm,
                    OnSiteDataRequestProjectForm)
from .models import (DataRequestProject, DataRequestProjectMember,
                     OAuth2DataRequestProject, OnSiteDataRequestProject)

MAX_UNAPPROVED_MEMBERS = 10


class CoordinatorOrActiveMixin(object):
    """
    - Always let the coordinator view this page
    - Only let members view it if the project is active
    - Only let members view it if the project is not approved and less than
      MAX_UNAPPROVED_MEMBERS have joined.
    """

    @property
    def project_members(self):
        return DataRequestProjectMember.objects.filter(
            project=self.get_object(), revoked=False).count()

    def dispatch(self, *args, **kwargs):
        project = self.get_object()

        if project.coordinator == self.request.user:
            return super(CoordinatorOrActiveMixin, self).dispatch(
                *args, **kwargs)

        if not project.active:
            raise Http404

        if (not project.approved and
                self.project_members > MAX_UNAPPROVED_MEMBERS):
            django_messages.error(self.request, (
                """Sorry, "{}" has not been approved and has exceeded the {}
                member limit for unapproved projects.""".format(
                    project.name, MAX_UNAPPROVED_MEMBERS)))

            return HttpResponseRedirect(reverse('my-member-research-data'))

        return super(CoordinatorOrActiveMixin, self).dispatch(
            *args, **kwargs)


class ProjectMemberMixin(object):
    """
    Add project_member and related helper methods.
    """

    @property
    def project_member(self):
        project = self.get_object()

        project_member, _ = DataRequestProjectMember.objects.get_or_create(
            member=self.request.member,
            project=project)

        return project_member

    @property
    def project_joined_by_member(self):
        return self.project_member and self.project_member.joined

    @property
    def project_authorized_by_member(self):
        return self.project_member and self.project_member.authorized

    def authorize_member(self):
        project = self.get_object()

        self.request.user.log('direct-sharing:{0}:authorize'.format(
            project.type), {'project-id': project.id})

        django_messages.success(self.request, (
            'You have successfully joined the project "{}".'.format(
                project.name)))

        project_member = self.project_member

        # The OAuth2 projects have join and authorize in the same step
        if project.type == 'oauth2':
            project_member.joined = True

        project_member.authorized = True
        project_member.message_permission = project.request_message_permission
        project_member.username_shared = project.request_username_access
        project_member.sources_shared = project.request_sources_access

        project_member.save()


class OnSiteDetailView(ProjectMemberMixin, CoordinatorOrActiveMixin,
                       DetailView):
    """
    A base DetailView for on-site projects.
    """

    model = OnSiteDataRequestProject


class JoinOnSiteDataRequestProjectView(PrivateMixin, LargePanelMixin,
                                       OnSiteDetailView):
    """
    Display the consent form for a project.
    """

    template_name = 'private_sharing/join-on-site.html'

    def dispatch(self, *args, **kwargs):
        """
        If the member has already accepted the consent form redirect them to
        the authorize page.
        """
        if self.project_joined_by_member:
            return HttpResponseRedirect(reverse_lazy(
                'direct-sharing:authorize-on-site',
                kwargs={'slug': self.get_object().slug}))

        return super(JoinOnSiteDataRequestProjectView, self).dispatch(
            *args, **kwargs)

    # pylint: disable=unused-argument
    def post(self, request, *args, **kwargs):
        project_member = self.project_member

        project_member.joined = True

        # if the user joins again after revoking the study then reset their
        # revoked and authorized status
        project_member.revoked = False
        project_member.authorized = False

        project_member.save()

        project = self.get_object()

        request.user.log('direct-sharing:on-site:consent', {
            'project-id': project.id
        })

        return HttpResponseRedirect(
            reverse_lazy('direct-sharing:authorize-on-site',
                         kwargs={'slug': project.slug}))


class ConnectedSourcesMixin(object):
    """
    Add context for connected/unconnected sources.
    """

    def get_context_data(self, **kwargs):
        context = super(ConnectedSourcesMixin, self).get_context_data(**kwargs)

        project = self.get_object()
        connections = self.request.member.connections<commit_msg>🐛 save the consent text the member agrees to<commit_after>from django.contrib import messages as django_messages
from django.core.mail import send_mail
from django.core.urlresolvers import reverse, reverse_lazy
from django.http import Http404, HttpResponseRedirect
from django.template import engines
from django.template.loader import render_to_string
from django.views.generic import (CreateView, DetailView, FormView,
                                  TemplateView, UpdateView, View)

from oauth2_provider.models import AccessToken, RefreshToken

from common.mixins import LargePanelMixin, PrivateMixin
from common.utils import full_url, get_source_labels_and_configs
from common.views import BaseOAuth2AuthorizationView

from .forms import (MessageProjectMembersForm, OAuth2DataRequestProjectForm,
                    OnSiteDataRequestProjectForm)
from .models import (DataRequestProject, DataRequestProjectMember,
                     OAuth2DataRequestProject, OnSiteDataRequestProject)

MAX_UNAPPROVED_MEMBERS = 10


class CoordinatorOrActiveMixin(object):
    """
    - Always let the coordinator view this page
    - Only let members view it if the project is active
    - Only let members view it if the project is not approved and less than
      MAX_UNAPPROVED_MEMBERS have joined.
    """

    @property
    def project_members(self):
        return DataRequestProjectMember.objects.filter(
            project=self.get_object(), revoked=False).count()

    def dispatch(self, *args, **kwargs):
        project = self.get_object()

        if project.coordinator == self.request.user:
            return super(CoordinatorOrActiveMixin, self).dispatch(
                *args, **kwargs)

        if not project.active:
            raise Http404

        if (not project.approved and
                self.project_members > MAX_UNAPPROVED_MEMBERS):
            django_messages.error(self.request, (
                """Sorry, "{}" has not been approved and has exceeded the {}
                member limit for unapproved projects.""".format(
                    project.name, MAX_UNAPPROVED_MEMBERS)))

            return HttpResponseRedirect(reverse('my-member-research-data'))

        return super(CoordinatorOrActiveMixin, self).dispatch(
            *args, **kwargs)


class ProjectMemberMixin(object):
    """
    Add project_member and related helper methods.
    """

    @property
    def project_member(self):
        project = self.get_object()

        project_member, _ = DataRequestProjectMember.objects.get_or_create(
            member=self.request.member,
            project=project)

        return project_member

    @property
    def project_joined_by_member(self):
        return self.project_member and self.project_member.joined

    @property
    def project_authorized_by_member(self):
        return self.project_member and self.project_member.authorized

    def authorize_member(self):
        project = self.get_object()

        self.request.user.log('direct-sharing:{0}:authorize'.format(
            project.type), {'project-id': project.id})

        django_messages.success(self.request, (
            'You have successfully joined the project "{}".'.format(
                project.name)))

        project_member = self.project_member

        # The OAuth2 projects have join and authorize in the same step
        if project.type == 'oauth2':
            project_member.joined = True

        project_member.authorized = True
        project_member.message_permission = project.request_message_permission
        project_member.username_shared = project.request_username_access
        project_member.sources_shared = project.request_sources_access

        project_member.save()


class OnSiteDetailView(ProjectMemberMixin, CoordinatorOrActiveMixin,
                       DetailView):
    """
    A base DetailView for on-site projects.
    """

    model = OnSiteDataRequestProject


class JoinOnSiteDataRequestProjectView(PrivateMixin, LargePanelMixin,
                                       OnSiteDetailView):
    """
    Display the consent form for a project.
    """

    template_name = 'private_sharing/join-on-site.html'

    def dispatch(self, *args, **kwargs):
        """
        If the member has already accepted the consent form redirect them to
        the authorize page.
        """
        if self.project_joined_by_member:
            return HttpResponseRedirect(reverse_lazy(
                'direct-sharing:authorize-on-site',
                kwargs={'slug': self.get_object().slug}))

        return super(JoinOnSiteDataRequestProjectView, self).dispatch(
            *args, **kwargs)

    # pylint: disable=unused-argument
    def post(self, request, *args, **kwargs):
        project = self.get_object()
        project_member = self.project_member

        project_member.joined = True

        # store the consent text that the user has consented to
        project_member.consent_text = project.consent_text

        # if the user joins again after revoking the study then reset their
        # revoked and authorized status
        project_member.revoked = False
        project_member.authorized = False

        project_member.save()

        request.user.log('direct-sharing:on-site:consent', {
            'project-id': project.id
        })

        return HttpResponseRedirect(
            reverse_lazy('direct-sharing:authorize-on-site',
                         kwargs={'slug': project.slug}))


class ConnectedSourcesMixin(object):
    """
    Add context for connected/unconnected sources.
    """

    def get_context_data(self, **kwargs):
        context = super(ConnectedSourcesMixin, self).get_context_data(**kwargs)

        project = self.get_object()
        connections = self.request.member.connections
{'fraction_non_alphanumeric': 0.07926935850375809, 'fraction_numerical': 0.0026219192448872575, 'mean_word_length': 2.7237227465017897, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '205524', 'n_tokens_mistral': 3045, 'n_tokens_neox': 2910, 'n_words': 729}