<commit_before>from django import forms
from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse_lazy
from django.core.validators import validate_email
from django.utils.translation import ugettext as _

from lily.accounts.models import Account
from lily.contacts.models import Contact, Function
from lily.socialmedia.connectors import Twitter
from lily.socialmedia.models import SocialMedia
from lily.tags.forms import TagsFormMixin
from lily.utils.forms import HelloLilyModelForm
from lily.utils.forms.fields import TagsField
from lily.utils.forms.widgets import ShowHideWidget, BootstrapRadioFieldRenderer, AddonTextInput, AjaxSelect2Widget
from lily.utils.forms.mixins import FormSetFormMixin
from lily.utils.models import EmailAddress
from lily.socialmedia.connectors import Twitter, LinkedIn


class AddContactQuickbuttonForm(HelloLilyModelForm):
    """
    Form to add an account with the absolute minimum of information.
    """
    account = forms.ModelChoiceField(
        label=_('Works at'),
        required=False,
        queryset=Account.objects,
        empty_label=_('Select an account'),
        widget=AjaxSelect2Widget(
            url=reverse_lazy('json_account_list'),
            model=Account,
        ),
    )
    emails = TagsField(
        label=_('E-mail addresses'),
        required=False,
    )

    phone = forms.CharField(label=_('Phone number'), max_length=40, required=False)

    def __init__(self, *args, **kwargs):
        """
        Overload super().__init__ to change auto_id to prevent clashing form field id's with
        other forms.
        """
        kwargs.update({
            'auto_id': 'id_contact_quickbutton_%s'
        })

        super(AddContactQuickbuttonForm, self).__init__(*args, **kwargs)

        # Provide filtered query set
        self.fields['account'].queryset = Account.objects.all()

    def clean_emails(self):
        """
        Prevent multiple contacts with the same email address when adding
        """
        for email in self.cleaned_data['emails']:
            # Check if input is a real email address
            validate_email(email)
            # Check if email address already exists under different account
            if Contact.objects.filter(email_addresses__email_address__iexact=email).exists():
                raise ValidationError(
                    _('E-mail address already in use.'),
                    code='invalid',
                )
        return self.cleaned_data['emails']

    def clean(self):
        """
        Form validation: all fields should be unique.
        """
        cleaned_data = super(AddContactQuickbuttonForm, self).clean()

        # Check if at least first or last name has been provided.
        if not cleaned_data.get('first_name') and not cleaned_data.get('last_name'):
            self._errors['first_name'] = self._errors['last_name'] = self.error_class([_('Name can\'t be empty')])

        return cleaned_data

    def save(self, commit=True):
        """
        Save Many2Many email addresses to instance.
        """
        instance = super(AddContactQuickbuttonForm, self).save(commit=commit)

        if commit:
            first = True
            for email in self.cleaned_data['emails']:
                email_address = EmailAddress.objects.create(
                    email_address=email,
                    is_primary=first,
                    tenant=instance.tenant
                )
                instance.email_addresses.add(email_address)
                first = False

        return instance

    class Meta:
        model = Contact
        fields = ('first_name', 'preposition', 'last_name', 'account', 'emails', 'phone')


class CreateUpdateContactForm(FormSetFormMixin, TagsFormMixin):
    """
    Form to add a contact which all fields available.
    """
    account = forms.ModelChoiceField(
        label=_('Works at'),
        required=False,
        queryset=Account.objects,
        empty_label=_('Select an account'),
        widget=AjaxSelect2Widget(
            url=reverse_lazy('json_account_list'),
            model=Account,
        ),
    )

    twitter = forms.CharField(label=_('Twitter'), required=False, widget=AddonTextInput(icon_attrs={
        'class': 'icon-twitter',
        'position': 'left',
        'is_button': False
    }))
    linkedin = forms.CharField(label=_('LinkedIn'), required=False, widget=AddonTextInput(icon_attrs={
        'class': 'icon-linkedin',
        'position': 'left',
        'is_button': False
    }))

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

        # Try providing initial account info
        is_working_at = Function.objects.filter(contact=self.instance).values_list('account_id', flat=True)
        if len(is_working_at) == 1:
            self.fields['account'].initial = is_working_at[0]

        twitter = self.instance.social_media.filter(name='twitter').first()
        self.fields['twitter'].initial = twitter.username if twitter else ''
        linkedin = self.instance.social_media.filter(name='linkedin').first()
        self.fields['linkedin'].initial = linkedin.username if linkedin else ''

        self.fields['addresses'].form_attrs = {
            'exclude_address_types': ['visiting'],
            'extra_form_kwargs': {
                'initial': {
                    'type': 'home',
                }
            }
        }

    def clean_twitter(self):
        """
        Check if added twitter name is a valid twitter name.

        Returns:
            string: twitter username or empty string.<commit_msg>Finished hotfix 0.2.25.3.<commit_after>from django import forms
from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse_lazy
from django.core.validators import validate_email
from django.utils.translation import ugettext as _

from lily.accounts.models import Account
from lily.contacts.models import Contact, Function
from lily.socialmedia.connectors import Twitter
from lily.socialmedia.models import SocialMedia
from lily.tags.forms import TagsFormMixin
from lily.utils.forms import HelloLilyModelForm
from lily.utils.forms.fields import TagsField
from lily.utils.forms.widgets import ShowHideWidget, BootstrapRadioFieldRenderer, AddonTextInput, AjaxSelect2Widget
from lily.utils.forms.mixins import FormSetFormMixin
from lily.utils.models import EmailAddress
from lily.socialmedia.connectors import Twitter, LinkedIn


class AddContactQuickbuttonForm(HelloLilyModelForm):
    """
    Form to add an account with the absolute minimum of information.
    """
    account = forms.ModelChoiceField(
        label=_('Works at'),
        required=False,
        queryset=Account.objects,
        empty_label=_('Select an account'),
        widget=AjaxSelect2Widget(
            url=reverse_lazy('json_account_list'),
            model=Account,
        ),
    )
    emails = TagsField(
        label=_('E-mail addresses'),
        required=False,
    )

    phone = forms.CharField(label=_('Phone number'), max_length=40, required=False)

    def __init__(self, *args, **kwargs):
        """
        Overload super().__init__ to change auto_id to prevent clashing form field id's with
        other forms.
        """
        kwargs.update({
            'auto_id': 'id_contact_quickbutton_%s'
        })

        super(AddContactQuickbuttonForm, self).__init__(*args, **kwargs)

        # Provide filtered query set
        self.fields['account'].queryset = Account.objects.all()

    def clean_emails(self):
        """
        Prevent multiple contacts with the same email address when adding
        """
        for email in self.cleaned_data['emails']:
            # Check if input is a real email address
            validate_email(email)
            # Check if email address already exists under different account
            if Contact.objects.filter(email_addresses__email_address__iexact=email).exists():
                raise ValidationError(
                    _('E-mail address already in use.'),
                    code='invalid',
                )
        return self.cleaned_data['emails']

    def clean(self):
        """
        Form validation: all fields should be unique.
        """
        cleaned_data = super(AddContactQuickbuttonForm, self).clean()

        # Check if at least first or last name has been provided.
        if not cleaned_data.get('first_name') and not cleaned_data.get('last_name'):
            self._errors['first_name'] = self._errors['last_name'] = self.error_class([_('Name can\'t be empty')])

        return cleaned_data

    def save(self, commit=True):
        """
        Save Many2Many email addresses to instance.
        """
        instance = super(AddContactQuickbuttonForm, self).save(commit=commit)

        if commit:
            first = True
            for email in self.cleaned_data['emails']:
                email_address = EmailAddress.objects.create(
                    email_address=email,
                    is_primary=first,
                    tenant=instance.tenant
                )
                instance.email_addresses.add(email_address)
                first = False

        return instance

    class Meta:
        model = Contact
        fields = ('first_name', 'preposition', 'last_name', 'account', 'emails', 'phone')


class CreateUpdateContactForm(FormSetFormMixin, TagsFormMixin):
    """
    Form to add a contact which all fields available.
    """
    account = forms.ModelChoiceField(
        label=_('Works at'),
        required=False,
        queryset=Account.objects,
        empty_label=_('Select an account'),
        widget=AjaxSelect2Widget(
            url=reverse_lazy('json_account_list'),
            model=Account,
        ),
    )

    twitter = forms.CharField(label=_('Twitter'), required=False, widget=AddonTextInput(icon_attrs={
        'class': 'icon-twitter',
        'position': 'left',
        'is_button': False
    }))
    linkedin = forms.CharField(label=_('LinkedIn'), required=False, widget=AddonTextInput(icon_attrs={
        'class': 'icon-linkedin',
        'position': 'left',
        'is_button': False
    }))

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

        # Try providing initial account info
        is_working_at = Function.objects.filter(contact=self.instance).values_list('account_id', flat=True)
        if len(is_working_at) == 1:
            self.fields['account'].initial = is_working_at[0]

        if self.instance.pk:
            twitter = self.instance.social_media.filter(name='twitter').first()
            self.fields['twitter'].initial = twitter.username if twitter else ''
            linkedin = self.instance.social_media.filter(name='linkedin').first()
            self.fields['linkedin'].initial = linkedin.username if linkedin else ''

        self.fields['addresses'].form_attrs = {
            'exclude_address_types': ['visiting'],
            'extra_form_kwargs': {
                'initial': {
                    'type': 'home',
                }
            }
        }

    def clean_twitter(self):
        """
        Check if added twitter name is a valid twitter name.

        Returns:
            string: twitter username or empty string.
{'fraction_non_alphanumeric': 0.1013982939055492, 'fraction_numerical': 0.001846803271480081, 'mean_word_length': 2.5305805650419124, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, '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': '2321634', 'n_tokens_mistral': 3093, 'n_tokens_neox': 3000, 'n_words': 729}