<commit_before>from django import forms
from django.core.mail import send_mail
from django.template import Context, loader
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.sites.shortcuts import get_current_site

from .models import Team
from .fields import ClearableThumbnailImageInput
from .util import email_token_generator, get_country_names

FIVE_MB = 5 * 1024**2


class UserForm(forms.ModelForm):
    """
    The portion of the registration form which ends up in the 'User' model. Designed to be used in
    conjunction with TeamForm.
    As specifc fields are directly referred to, there's no advantage in using `get_user_model()`: This won't
    work with user models other than django.contrib.auth.models.User out-of-the-box.
    """

    # Don't automatically create the form field from the model field, as the model field's `max_length`
    # actually applies to the hashed passwords
    password = forms.CharField(widget=forms.PasswordInput)
    password_repetition = forms.CharField(widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ['username', 'password', 'password_repetition', 'email']
        labels = {
            'username': _('Name'),
            'email': _('Formal email')
        }
        widgets = {
            'password': forms.PasswordInput
        }
        help_texts = {
            'username': None,
            'email': _('Your authorative contact address. It will be used for sensitive requests, such as '
                       'password resets or prize pay-outs.')
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Make 'Formal email' field required, despite not being required in the User model
        self.fields['email'].required = True

        if self.instance.pk:
            # Editing an existing user
            self.fields['username'].widget.attrs['readonly'] = True
            self.fields['password'].required = False
            self.fields['password_repetition'].required = False

    def clean_username(self):
        if self.instance.pk:
            # Field is read-only, so discard its user-provided value
            return self.instance.username

        return self.cleaned_data['username']

    def clean_password_repetition(self):
        password = self.cleaned_data.get('password')
        repetition = self.cleaned_data.get('password_repetition')

        if password != repetition:
            raise forms.ValidationError(_("The passwords don't match!"), code='password_mismatch')

        return repetition

    def save(self, commit=True):
        """
        save() variant which hashes the password and sets the user to inactive when the email address has
        been changed. It should stay that way until the address is confirmed.
        """
        user = super().save(commit=False)

        if self.cleaned_data['password']:
            user.set_password(self.cleaned_data['password'])
        else:
            # Provide the correct change status to the view
            try:
                self.changed_data.remove('password')
            except ValueError:
                pass

        if 'email' in self.changed_data:
            user.is_active = False

        if commit:
            user.save()

        return user

    def send_confirmation_mail(self, request):
        """
        Sends an email containing the address confirmation link to the user associated with this form. As it
        requires a User instance, it should only be called after the object has initially been saved.

        Args:
            request: The HttpRequest from which this function is being called
        """
        context = Context({
            'competition_name': settings.COMPETITION_NAME,
            'protocol': 'https' if request.is_secure() else 'http',
            'domain': get_current_site(request),
            'user': self.instance.pk,
            'token': email_token_generator.make_token(self.instance)
        })
        message = loader.render_to_string('confirmation_mail.txt', context)

        send_mail(settings.COMPETITION_NAME+' email confirmation', message, settings.DEFAULT_FROM_EMAIL,
                  [self.instance.email])


class TeamForm(forms.ModelForm):
    """
    The portion of the registration form which ends up in the 'Team' model. Designed to be used in
    conjunction with UserForm.<commit_msg>Replace Context with dictionary for `loader.render_to_string()`<commit_after>from django import forms
from django.core.mail import send_mail
from django.template import loader
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.sites.shortcuts import get_current_site

from .models import Team
from .fields import ClearableThumbnailImageInput
from .util import email_token_generator, get_country_names

FIVE_MB = 5 * 1024**2


class UserForm(forms.ModelForm):
    """
    The portion of the registration form which ends up in the 'User' model. Designed to be used in
    conjunction with TeamForm.
    As specifc fields are directly referred to, there's no advantage in using `get_user_model()`: This won't
    work with user models other than django.contrib.auth.models.User out-of-the-box.
    """

    # Don't automatically create the form field from the model field, as the model field's `max_length`
    # actually applies to the hashed passwords
    password = forms.CharField(widget=forms.PasswordInput)
    password_repetition = forms.CharField(widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ['username', 'password', 'password_repetition', 'email']
        labels = {
            'username': _('Name'),
            'email': _('Formal email')
        }
        widgets = {
            'password': forms.PasswordInput
        }
        help_texts = {
            'username': None,
            'email': _('Your authorative contact address. It will be used for sensitive requests, such as '
                       'password resets or prize pay-outs.')
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Make 'Formal email' field required, despite not being required in the User model
        self.fields['email'].required = True

        if self.instance.pk:
            # Editing an existing user
            self.fields['username'].widget.attrs['readonly'] = True
            self.fields['password'].required = False
            self.fields['password_repetition'].required = False

    def clean_username(self):
        if self.instance.pk:
            # Field is read-only, so discard its user-provided value
            return self.instance.username

        return self.cleaned_data['username']

    def clean_password_repetition(self):
        password = self.cleaned_data.get('password')
        repetition = self.cleaned_data.get('password_repetition')

        if password != repetition:
            raise forms.ValidationError(_("The passwords don't match!"), code='password_mismatch')

        return repetition

    def save(self, commit=True):
        """
        save() variant which hashes the password and sets the user to inactive when the email address has
        been changed. It should stay that way until the address is confirmed.
        """
        user = super().save(commit=False)

        if self.cleaned_data['password']:
            user.set_password(self.cleaned_data['password'])
        else:
            # Provide the correct change status to the view
            try:
                self.changed_data.remove('password')
            except ValueError:
                pass

        if 'email' in self.changed_data:
            user.is_active = False

        if commit:
            user.save()

        return user

    def send_confirmation_mail(self, request):
        """
        Sends an email containing the address confirmation link to the user associated with this form. As it
        requires a User instance, it should only be called after the object has initially been saved.

        Args:
            request: The HttpRequest from which this function is being called
        """
        context = {
            'competition_name': settings.COMPETITION_NAME,
            'protocol': 'https' if request.is_secure() else 'http',
            'domain': get_current_site(request),
            'user': self.instance.pk,
            'token': email_token_generator.make_token(self.instance)
        }
        message = loader.render_to_string('confirmation_mail.txt', context)

        send_mail(settings.COMPETITION_NAME+' email confirmation', message, settings.DEFAULT_FROM_EMAIL,
                  [self.instance.email])


class TeamForm(forms.ModelForm):
    """
    The portion of the registration form which ends up in the 'Team' model. Designed to be used in
    conjunction with UserForm.
{'fraction_non_alphanumeric': 0.08577127659574468, 'fraction_numerical': 0.0013297872340425532, 'mean_word_length': 2.5615627466456194, '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': '3008090', 'n_tokens_mistral': 2367, 'n_tokens_neox': 2265, 'n_words': 762}