<commit_before>import functools
import six
from adminfilters.multiselect import UnionFieldListFilter
from adminsortable.admin import SortableTabularInline, NonSortableParentAdmin
from django.db import models
from django import forms
from django.conf.urls import url
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin, GroupAdmin
from django.contrib.auth.models import Group, Permission
from django.contrib.auth.tokens import default_token_generator
from django.core.urlresolvers import reverse
from django.db import connection
from django.forms.models import ModelFormMetaclass
from django.http.response import HttpResponseRedirect, HttpResponseForbidden
from django.template import loader
from django.utils.html import format_html
from django.utils.http import int_to_base36
from django.utils.translation import ugettext_lazy as _
from permissions_widget.forms import PermissionSelectMultipleField

from bluebottle.bb_accounts.models import UserAddress
from bluebottle.bb_accounts.utils import send_welcome_mail
from bluebottle.bb_follow.models import Follow
from bluebottle.clients import properties
from bluebottle.clients.utils import tenant_url
from bluebottle.donations.models import Donation
from bluebottle.geo.models import Location
from bluebottle.members.models import CustomMemberFieldSettings, CustomMemberField, MemberPlatformSettings
from bluebottle.projects.models import Project
from bluebottle.tasks.models import Task
from bluebottle.utils.admin import export_as_csv_action, BasePlatformSettingsAdmin

from bluebottle.utils.email_backend import send_mail
from bluebottle.utils.widgets import SecureAdminURLFieldWidget
from .models import Member


class MemberForm(forms.ModelForm):
    def __init__(self, data=None, files=None, current_user=None, *args, **kwargs):
        self.current_user = current_user
        super(MemberForm, self).__init__(data, files, *args, **kwargs)

        if self.current_user.is_superuser:
            # Super users can assign every group to a user
            group_queryset = Group.objects.all()
        else:
            # Normal staff users can only choose groups that they belong to.
            group_queryset = Group.objects.filter(
                pk__in=self.current_user.groups.all().only('pk')
            )

        self.fields['groups'] = forms.ModelMultipleChoiceField(
            queryset=group_queryset,
            required=False,
            initial=Group.objects.filter(name='Authenticated')
        )

    class Meta:
        model = Member
        # Mind you these fields are also set in MemberAdmin.add_fieldsets
        fields = '__all__'


class MemberCreationForm(MemberForm):
    """
    A form that creates a member.
    """
    error_messages = {
        'duplicate_email': _("A user with that email already exists."),
    }
    email = forms.EmailField(label=_("Email address"), max_length=254,
                             help_text=_("A valid, unique email address."))

    is_active = forms.BooleanField(label=_("Is active"), initial=True)

    def clean_email(self):
        # Since BlueBottleUser.email is unique, this check is redundant
        # but it sets a nicer error message than the ORM.
        email = self.cleaned_data["email"]
        try:
            Member._default_manager.get(email=email)
        except Member.DoesNotExist:
            return email
        raise forms.ValidationError(self.error_messages['duplicate_email'])

    def save(self, commit=True):
        user = super(MemberCreationForm, self).save(commit=False)
        if commit:
            user.save()
        return user


class CustomMemberFieldSettingsInline(SortableTabularInline):
    model = CustomMemberFieldSettings
    readonly_fields = ('slug',)
    extra = 0


class MemberPlatformSettingsAdmin(BasePlatformSettingsAdmin, NonSortableParentAdmin):

    inlines = [
        CustomMemberFieldSettingsInline
    ]


admin.site.register(MemberPlatformSettings, MemberPlatformSettingsAdmin)


class CustomAdminFormMetaClass(ModelFormMetaclass):
    def __new__(cls, name, bases, attrs):
        if connection.tenant.schema_name != 'public':
            for field in CustomMemberFieldSettings.objects.all():
                attrs[field.slug] = forms.CharField(required=False,
                                                    label=field.name,
                                                    help_text=field.description)

        return super(CustomAdminFormMetaClass, cls).__new__(cls, name, bases, attrs)


class MemberChangeForm(six.with_metaclass(CustomAdminFormMetaClass, MemberForm)):
    """
    Change Member form
    """

    email = forms.EmailField(label=_("email address"), max_length=254,
                             help_text=_("A valid, unique email address."))

    class Meta:
        model = Member
        exclude = ()

    def __init__(self, *args, **kwargs):
        super(MemberChangeForm, self).__init__(*args, **kwargs)
        f = self.fields.get('user_permissions', None)
        if f is not None:
            f.queryset = f.queryset.select_related('content_type')

        if connection.tenant.schema_name != 'public':
            for field in CustomMemberFieldSettings.objects.all():
                self.fields[field.slug] = forms.CharField(required=False,
                                                          label=field.name,
                                                          help_text=field.description)
                if CustomMemberField.objects.filter(member=self.instance, field=field).exists():
                    value = CustomMemberField.objects.filter(member=self.instance, field=field).get().value
                    self.initial[field.slug] = value

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]

    def save(self, commit=True):
        member = super(MemberChangeForm, self).save(commit=commit)
        for field in CustomMemberFieldSettings.objects.all():
            extra, created = CustomMemberField.objects.get_or_create(
                member=member,
                field=field
            )
            extra.value = self.cleaned_data.get(field.slug, None)
            extra.save()
        return member


class UserAddressInline(admin.StackedInline):
    model = UserAddress

    def has_delete_permission(self, request, obj=None):
        return False


class MemberAdmin(UserAdmin):
    raw_id_fields = ('partner_organization', )

    formfield_overrides = {
        models.URLField: {'widget': SecureAdminURLFieldWidget()},
    }

    def get_form(self, request, *args, **kwargs):
        Form = super(MemberAdmin, self).get_form(request, *args, **kwargs)
        return functools.partial(Form, current_user=request.user)

    def get_fieldsets(self, request, obj=None):
        if not obj:
            fieldsets = ((
                None, {
                    'classes': ('wide', ),
                    'fields': [
                        'first_name', 'last_name', 'email', 'is_active',
                        'is_staff', 'groups'
                    ]
                }
            ), )
        else:
            fieldsets = [
                [
                    _("Main"),
                    {
                        'fields': [
                            'email',
                            'remote_id',
                            'first_name',
                            'last_name',
                            'phone_number',
                            'reset_password',
                            'resend_welcome_link',
                            'last_login',
                            'date_joined',
                            'deleted',
                            'is_co_financer',
                            'can_pledge',
                            'partner_organization',
                            'campaign_notifications',
                            'newsletter',
                            'primary_language',
                        ]
                    }
                ],
                [
                    _("Profile"),
                    {
                        'fields':
                        ['picture', 'about_me', 'favourite_themes', 'skills']
                    }
                ],
                [
                    _('Permissions'),
                    {'fields': ['is_active', 'is_staff', 'is_superuser', 'groups']}
                ],
                [
                    _('Engagement'),
                    {
                        'fields':
                        ['projects_managed', 'tasks', 'donations', 'following']
                    }
                ],
            ]

            if Location.objects.count():
                fieldsets[1][1]['fields'].append('location')

            if 'Pledge' not in (
                item['name'] for item in properties.PAYMENT_METHODS
            ):
                fieldsets[0][1]['fields'].remove('can_pledge')

            if CustomMemberFieldSettings.objects.count():
                extra = (
                    _('Extra fields'), {
                        'fields': [
                            field.slug
                            for field in CustomMemberFieldSettings.objects.all()
                        ]
                    }
                )

                fieldsets.append(extra)

        return fieldsets

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = [
            'date_joined', 'last_login',
            'updated', 'deleted', 'login_as_user',
            'reset_password', '<PASSWORD>',
            'projects_managed', 'tasks', 'donations', 'following'
        ]

        user_groups = request.user.groups.all()

        if obj and hasattr(obj, 'groups'):
            for group in obj.groups.all():
                if group not in user_groups:
                    readonly_fields.append('email')

        if not request.user.is_superuser:
            readonly_fields.append('is_superuser')

        return readonly_fields

    export_fields = (
        ('username', 'username'),
        ('email', 'email'),
        ('remote_id', 'remote_id'),
        ('first_name', 'first_name'),
        ('last_name', 'last name'),
        ('date_joined', 'date joined'),
        ('is_initiator', 'is initiator'),
        ('is_supporter', 'is supporter'),
        ('amount_donated', 'amount donated'),
        ('is_volunteer', 'is volunteer'),
        ('time_spent', 'time spent'),
    )

    actions = (export_as_csv_action(fields=export_fields),)<commit_msg>Allow superuser to edit all emails<commit_after>import functools
import six
from adminfilters.multiselect import UnionFieldListFilter
from adminsortable.admin import SortableTabularInline, NonSortableParentAdmin
from django.db import models
from django import forms
from django.conf.urls import url
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin, GroupAdmin
from django.contrib.auth.models import Group, Permission
from django.contrib.auth.tokens import default_token_generator
from django.core.urlresolvers import reverse
from django.db import connection
from django.forms.models import ModelFormMetaclass
from django.http.response import HttpResponseRedirect, HttpResponseForbidden
from django.template import loader
from django.utils.html import format_html
from django.utils.http import int_to_base36
from django.utils.translation import ugettext_lazy as _
from permissions_widget.forms import PermissionSelectMultipleField

from bluebottle.bb_accounts.models import UserAddress
from bluebottle.bb_accounts.utils import send_welcome_mail
from bluebottle.bb_follow.models import Follow
from bluebottle.clients import properties
from bluebottle.clients.utils import tenant_url
from bluebottle.donations.models import Donation
from bluebottle.geo.models import Location
from bluebottle.members.models import CustomMemberFieldSettings, CustomMemberField, MemberPlatformSettings
from bluebottle.projects.models import Project
from bluebottle.tasks.models import Task
from bluebottle.utils.admin import export_as_csv_action, BasePlatformSettingsAdmin

from bluebottle.utils.email_backend import send_mail
from bluebottle.utils.widgets import SecureAdminURLFieldWidget
from .models import Member


class MemberForm(forms.ModelForm):
    def __init__(self, data=None, files=None, current_user=None, *args, **kwargs):
        self.current_user = current_user
        super(MemberForm, self).__init__(data, files, *args, **kwargs)

        if self.current_user.is_superuser:
            # Super users can assign every group to a user
            group_queryset = Group.objects.all()
        else:
            # Normal staff users can only choose groups that they belong to.
            group_queryset = Group.objects.filter(
                pk__in=self.current_user.groups.all().only('pk')
            )

        self.fields['groups'] = forms.ModelMultipleChoiceField(
            queryset=group_queryset,
            required=False,
            initial=Group.objects.filter(name='Authenticated')
        )

    class Meta:
        model = Member
        # Mind you these fields are also set in MemberAdmin.add_fieldsets
        fields = '__all__'


class MemberCreationForm(MemberForm):
    """
    A form that creates a member.
    """
    error_messages = {
        'duplicate_email': _("A user with that email already exists."),
    }
    email = forms.EmailField(label=_("Email address"), max_length=254,
                             help_text=_("A valid, unique email address."))

    is_active = forms.BooleanField(label=_("Is active"), initial=True)

    def clean_email(self):
        # Since BlueBottleUser.email is unique, this check is redundant
        # but it sets a nicer error message than the ORM.
        email = self.cleaned_data["email"]
        try:
            Member._default_manager.get(email=email)
        except Member.DoesNotExist:
            return email
        raise forms.ValidationError(self.error_messages['duplicate_email'])

    def save(self, commit=True):
        user = super(MemberCreationForm, self).save(commit=False)
        if commit:
            user.save()
        return user


class CustomMemberFieldSettingsInline(SortableTabularInline):
    model = CustomMemberFieldSettings
    readonly_fields = ('slug',)
    extra = 0


class MemberPlatformSettingsAdmin(BasePlatformSettingsAdmin, NonSortableParentAdmin):

    inlines = [
        CustomMemberFieldSettingsInline
    ]


admin.site.register(MemberPlatformSettings, MemberPlatformSettingsAdmin)


class CustomAdminFormMetaClass(ModelFormMetaclass):
    def __new__(cls, name, bases, attrs):
        if connection.tenant.schema_name != 'public':
            for field in CustomMemberFieldSettings.objects.all():
                attrs[field.slug] = forms.CharField(required=False,
                                                    label=field.name,
                                                    help_text=field.description)

        return super(CustomAdminFormMetaClass, cls).__new__(cls, name, bases, attrs)


class MemberChangeForm(six.with_metaclass(CustomAdminFormMetaClass, MemberForm)):
    """
    Change Member form
    """

    email = forms.EmailField(label=_("email address"), max_length=254,
                             help_text=_("A valid, unique email address."))

    class Meta:
        model = Member
        exclude = ()

    def __init__(self, *args, **kwargs):
        super(MemberChangeForm, self).__init__(*args, **kwargs)
        f = self.fields.get('user_permissions', None)
        if f is not None:
            f.queryset = f.queryset.select_related('content_type')

        if connection.tenant.schema_name != 'public':
            for field in CustomMemberFieldSettings.objects.all():
                self.fields[field.slug] = forms.CharField(required=False,
                                                          label=field.name,
                                                          help_text=field.description)
                if CustomMemberField.objects.filter(member=self.instance, field=field).exists():
                    value = CustomMemberField.objects.filter(member=self.instance, field=field).get().value
                    self.initial[field.slug] = value

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]

    def save(self, commit=True):
        member = super(MemberChangeForm, self).save(commit=commit)
        for field in CustomMemberFieldSettings.objects.all():
            extra, created = CustomMemberField.objects.get_or_create(
                member=member,
                field=field
            )
            extra.value = self.cleaned_data.get(field.slug, None)
            extra.save()
        return member


class UserAddressInline(admin.StackedInline):
    model = UserAddress

    def has_delete_permission(self, request, obj=None):
        return False


class MemberAdmin(UserAdmin):
    raw_id_fields = ('partner_organization', )

    formfield_overrides = {
        models.URLField: {'widget': SecureAdminURLFieldWidget()},
    }

    def get_form(self, request, *args, **kwargs):
        Form = super(MemberAdmin, self).get_form(request, *args, **kwargs)
        return functools.partial(Form, current_user=request.user)

    def get_fieldsets(self, request, obj=None):
        if not obj:
            fieldsets = ((
                None, {
                    'classes': ('wide', ),
                    'fields': [
                        'first_name', 'last_name', 'email', 'is_active',
                        'is_staff', 'groups'
                    ]
                }
            ), )
        else:
            fieldsets = [
                [
                    _("Main"),
                    {
                        'fields': [
                            'email',
                            'remote_id',
                            'first_name',
                            'last_name',
                            'phone_number',
                            'reset_password',
                            'resend_welcome_link',
                            'last_login',
                            'date_joined',
                            'deleted',
                            'is_co_financer',
                            'can_pledge',
                            'partner_organization',
                            'campaign_notifications',
                            'newsletter',
                            'primary_language',
                        ]
                    }
                ],
                [
                    _("Profile"),
                    {
                        'fields':
                        ['picture', 'about_me', 'favourite_themes', 'skills']
                    }
                ],
                [
                    _('Permissions'),
                    {'fields': ['is_active', 'is_staff', 'is_superuser', 'groups']}
                ],
                [
                    _('Engagement'),
                    {
                        'fields':
                        ['projects_managed', 'tasks', 'donations', 'following']
                    }
                ],
            ]

            if Location.objects.count():
                fieldsets[1][1]['fields'].append('location')

            if 'Pledge' not in (
                item['name'] for item in properties.PAYMENT_METHODS
            ):
                fieldsets[0][1]['fields'].remove('can_pledge')

            if CustomMemberFieldSettings.objects.count():
                extra = (
                    _('Extra fields'), {
                        'fields': [
                            field.slug
                            for field in CustomMemberFieldSettings.objects.all()
                        ]
                    }
                )

                fieldsets.append(extra)

        return fieldsets

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = [
            'date_joined', 'last_login',
            'updated', 'deleted', 'login_as_user',
            'reset_password', 'resend_welcome_link',
            'projects_managed', 'tasks', 'donations', 'following'
        ]

        user_groups = request.user.groups.all()

        if obj and hasattr(obj, 'groups') and not request.user.is_superuser:
            for group in obj.groups.all():
                if group not in user_groups:
                    readonly_fields.append('email')

        if not request.user.is_superuser:
            readonly_fields.append('is_superuser')

        return readonly_fields

    export_fields = (
        ('username', 'username'),
        ('email', 'email'),
        ('remote_id', 'remote_id'),
        ('first_name', 'first_name'),
        ('last_name', 'last name'),
        ('date_joined', 'date joined'),
        ('is_initiator', 'is initiator'),
        ('is_supporter', 'is supporter'),
        ('amount_donated', 'amount donated'),
        ('is_volunteer', 'is volunteer'),
        ('time_spent', 'time spent'),
    )

    actions = (export_as_csv_action(fields=export_fields),)
{'fraction_non_alphanumeric': 0.09247211895910781, 'fraction_numerical': 0.0012081784386617101, 'mean_word_length': 1.9054948022141218, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '212262', 'n_tokens_mistral': 5513, 'n_tokens_neox': 5332, 'n_words': 1227}