<commit_before>"""
Django REST Framework serializers for the User API Accounts sub-application
"""
from rest_framework import serializers
from django.contrib.auth.models import User
from django.conf import settings
from django.core.urlresolvers import reverse
from openedx.core.djangoapps.user_api.accounts import NAME_MIN_LENGTH
from openedx.core.djangoapps.user_api.serializers import ReadOnlyFieldsSerializerMixin

from student.models import UserProfile, LanguageProficiency
from ..models import UserPreference
from .image_helpers import get_profile_image_urls_for_user
from . import (
    ACCOUNT_VISIBILITY_PREF_KEY, ALL_USERS_VISIBILITY, PRIVATE_VISIBILITY,
)
from certificates.api import get_certificates_for_user_basic

PROFILE_IMAGE_KEY_PREFIX = 'image_url'


class LanguageProficiencySerializer(serializers.ModelSerializer):
    """
    Class that serializes the LanguageProficiency model for account
    information.
    """
    class Meta(object):
        model = LanguageProficiency
        fields = ("code",)

    def get_identity(self, data):
        """
        This is used in bulk updates to determine the identity of an object.
        The default is to use the id of an object, but we want to override that
        and consider the language code to be the canonical identity of a
        LanguageProficiency model.
        """
        try:
            return data.get('code', None)
        except AttributeError:
            return None


class UserReadOnlySerializer(serializers.Serializer):
    """
    Class that serializes the User model and UserProfile model together.
    """
    def __init__(self, *args, **kwargs):
        # Don't pass the 'configuration' arg up to the superclass
        self.configuration = kwargs.pop('configuration', None)
        if not self.configuration:
            self.configuration = settings.ACCOUNT_VISIBILITY_CONFIGURATION

        # Don't pass the 'custom_fields' arg up to the superclass
        self.custom_fields = kwargs.pop('custom_fields', None)

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

    def to_representation(self, user):
        """
        Overwrite to_native to handle custom logic since we are serializing two models as one here
        :param user: User object
        :return: Dict serialized account
        """
        profile = user.profile

        data = {
            "username": user.username,
            "url": self.context.get('request').build_absolute_uri(
                reverse('accounts_api', kwargs={'username': user.username})
            ),
            "email": user.email,
            # For backwards compatibility: Tables created after the upgrade to Django 1.8 will save microseconds.
            # However, mobile apps are not expecting microsecond in the serialized value. If we set it to zero the
            # DRF JSONEncoder will not include it in the serialized value.
            # https://docs.djangoproject.com/en/1.8/ref/databases/#fractional-seconds-support-for-time-and-datetime-fields
            "date_joined": user.date_joined.replace(microsecond=0),
            "is_active": user.is_active,
            "bio": AccountLegacyProfileSerializer.convert_empty_to_None(profile.bio),
            "country": AccountLegacyProfileSerializer.convert_empty_to_None(profile.country.code),
            "profile_image": AccountLegacyProfileSerializer.get_profile_image(
                profile,
                user,
                self.context.get('request')
            ),
            "time_zone": None,
            "language_proficiencies": LanguageProficiencySerializer(
                profile.language_proficiencies.all(),
                many=True
            ).data,
            "name": profile.name,
            "gender": AccountLegacyProfileSerializer.convert_empty_to_None(profile.gender),
            "goals": profile.goals,
            "year_of_birth": profile.year_of_birth,
            "level_of_education": AccountLegacyProfileSerializer.convert_empty_to_None(profile.level_of_education),
            "mailing_address": profile.mailing_address,
            "requires_parental_consent": profile.requires_parental_consent(),
            "account_privacy": self._get_profile_visibility(profile, user),
        }

        filtered_data = self._filter_fields(
        self._visible_fields(profile, user),
        data
        )

        filtered_data['certificates'] = get_certificates_for_user_basic(user.username)
        return filtered_data

    def _visible_fields(self, user_profile, user):
        """
        Return what fields should be visible based on user settings

        :param user_profile: User profile object
        :param user: User object
        :return: whitelist List of fields to be shown
        """

        if self.custom_fields:
            return self.custom_fields<commit_msg>[#116954861] Fix indentation<commit_after>"""
Django REST Framework serializers for the User API Accounts sub-application
"""
from rest_framework import serializers
from django.contrib.auth.models import User
from django.conf import settings
from django.core.urlresolvers import reverse
from openedx.core.djangoapps.user_api.accounts import NAME_MIN_LENGTH
from openedx.core.djangoapps.user_api.serializers import ReadOnlyFieldsSerializerMixin

from student.models import UserProfile, LanguageProficiency
from ..models import UserPreference
from .image_helpers import get_profile_image_urls_for_user
from . import (
    ACCOUNT_VISIBILITY_PREF_KEY, ALL_USERS_VISIBILITY, PRIVATE_VISIBILITY,
)
from certificates.api import get_certificates_for_user_basic

PROFILE_IMAGE_KEY_PREFIX = 'image_url'


class LanguageProficiencySerializer(serializers.ModelSerializer):
    """
    Class that serializes the LanguageProficiency model for account
    information.
    """
    class Meta(object):
        model = LanguageProficiency
        fields = ("code",)

    def get_identity(self, data):
        """
        This is used in bulk updates to determine the identity of an object.
        The default is to use the id of an object, but we want to override that
        and consider the language code to be the canonical identity of a
        LanguageProficiency model.
        """
        try:
            return data.get('code', None)
        except AttributeError:
            return None


class UserReadOnlySerializer(serializers.Serializer):
    """
    Class that serializes the User model and UserProfile model together.
    """
    def __init__(self, *args, **kwargs):
        # Don't pass the 'configuration' arg up to the superclass
        self.configuration = kwargs.pop('configuration', None)
        if not self.configuration:
            self.configuration = settings.ACCOUNT_VISIBILITY_CONFIGURATION

        # Don't pass the 'custom_fields' arg up to the superclass
        self.custom_fields = kwargs.pop('custom_fields', None)

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

    def to_representation(self, user):
        """
        Overwrite to_native to handle custom logic since we are serializing two models as one here
        :param user: User object
        :return: Dict serialized account
        """
        profile = user.profile

        data = {
            "username": user.username,
            "url": self.context.get('request').build_absolute_uri(
                reverse('accounts_api', kwargs={'username': user.username})
            ),
            "email": user.email,
            # For backwards compatibility: Tables created after the upgrade to Django 1.8 will save microseconds.
            # However, mobile apps are not expecting microsecond in the serialized value. If we set it to zero the
            # DRF JSONEncoder will not include it in the serialized value.
            # https://docs.djangoproject.com/en/1.8/ref/databases/#fractional-seconds-support-for-time-and-datetime-fields
            "date_joined": user.date_joined.replace(microsecond=0),
            "is_active": user.is_active,
            "bio": AccountLegacyProfileSerializer.convert_empty_to_None(profile.bio),
            "country": AccountLegacyProfileSerializer.convert_empty_to_None(profile.country.code),
            "profile_image": AccountLegacyProfileSerializer.get_profile_image(
                profile,
                user,
                self.context.get('request')
            ),
            "time_zone": None,
            "language_proficiencies": LanguageProficiencySerializer(
                profile.language_proficiencies.all(),
                many=True
            ).data,
            "name": profile.name,
            "gender": AccountLegacyProfileSerializer.convert_empty_to_None(profile.gender),
            "goals": profile.goals,
            "year_of_birth": profile.year_of_birth,
            "level_of_education": AccountLegacyProfileSerializer.convert_empty_to_None(profile.level_of_education),
            "mailing_address": profile.mailing_address,
            "requires_parental_consent": profile.requires_parental_consent(),
            "account_privacy": self._get_profile_visibility(profile, user),
        }

        filtered_data = self._filter_fields(
            self._visible_fields(profile, user),
            data
        )

        filtered_data['certificates'] = get_certificates_for_user_basic(user.username)
        return filtered_data

    def _visible_fields(self, user_profile, user):
        """
        Return what fields should be visible based on user settings

        :param user_profile: User profile object
        :param user: User object
        :return: whitelist List of fields to be shown
        """

        if self.custom_fields:
            return self.custom_fields
{'fraction_non_alphanumeric': 0.07706554172239942, 'fraction_numerical': 0.0019549336351476487, 'mean_word_length': 2.7953924248340494, 'pattern_counts': {'":': 36, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, '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': '7656775', 'n_tokens_mistral': 2553, 'n_tokens_neox': 2460, 'n_words': 681}