<commit_before>import hashlib
import logging
import random
import re
import time
from datetime import datetime, timedelta

from django.conf import settings
from django.contrib.auth.models import User, Group
from django.contrib.sites.models import Site
from django.db import models

from celery.task import task
from statsd import statsd
from timezones.fields import TimeZoneField, zones, MAX_TIMEZONE_LENGTH
from tower import ugettext as _
from tower import ugettext_lazy as _lazy

from kitsune.customercare.models import Reply
from kitsune.lib.countries import COUNTRIES
from kitsune.search.es_utils import UnindexMeBro
from kitsune.search.models import (
    SearchMappingType, SearchMixin, register_for_indexing,
    register_mapping_type)
from kitsune.sumo import email_utils
from kitsune.sumo.models import ModelBase, LocaleField
from kitsune.sumo.urlresolvers import reverse
from kitsune.sumo.utils import auto_delete_files, chunked


log = logging.getLogger('k.users')


SHA1_RE = re.compile('^[a-f0-9]{40}$')
CONTRIBUTOR_GROUP = 'Registered as contributor'


# Add south introspection for timezones.fields.TimeZoneField
#
# We do this here because django-timezone is long in the tooth and
# they haven't fixed it there, yet. Need to do this before it gets
# used. If we end up using TimeZoneField elsewhere, then we should
# centralize this hack.
#
# See https://github.com/brosner/django-timezones/pull/19
from south.modelsinspector import add_introspection_rules
add_introspection_rules(rules=[(
    (TimeZoneField,),
    [],
    {
        "max_length": ["max_length", {"default": MAX_TIMEZONE_LENGTH}],
        "default": ["default", {"default": settings.TIME_ZONE}],
        "choices": ["choices", {"default": zones.PRETTY_TIMEZONE_CHOICES}],
    }
)], patterns=["^timezones\.fields\."])


@auto_delete_files
class Profile(ModelBase, SearchMixin):
    """Profile model for django users, get it with user.get_profile()."""

    user = models.OneToOneField(User, primary_key=True,
                                verbose_name=_lazy(u'User'))
    name = models.CharField(max_length=255, null=True, blank=True,
                            verbose_name=_lazy(u'Display name'))
    public_email = models.BooleanField(  # show/hide email
        default=False, verbose_name=_lazy(u'Make my email public'))
    avatar = models.ImageField(upload_to=settings.USER_AVATAR_PATH, null=True,
                               blank=True, verbose_name=_lazy(u'Avatar'),
                               max_length=settings.MAX_FILEPATH_LENGTH)
    bio = models.TextField(null=True, blank=True,
                           verbose_name=_lazy(u'Biography'))
    website = models.URLField(max_length=255, null=True, blank=True,
                              verbose_name=_lazy(u'Website'))
    twitter = models.URLField(max_length=255, null=True, blank=True,
                              verbose_name=_lazy(u'Twitter URL'))
    facebook = models.URLField(max_length=255, null=True, blank=True,
                               verbose_name=_lazy(u'Facebook URL'))
    irc_handle = models.CharField(max_length=255, null=True, blank=True,
                                  verbose_name=_lazy(u'IRC nickname'))
    timezone = TimeZoneField(null=True, blank=True,
                             verbose_name=_lazy(u'Timezone'))
    country = models.CharField(max_length=2, choices=COUNTRIES, null=True,
                               blank=True, verbose_name=_lazy(u'Country'))
    # No city validation
    city = models.CharField(max_length=255, null=True, blank=True,
                            verbose_name=_lazy(u'City'))
    locale = LocaleField(default=settings.LANGUAGE_CODE,
                         verbose_name=_lazy(u'Preferred language'))

    class Meta(object):
        permissions = (('view_karma_points', 'Can view karma points'),
                       ('deactivate_users', 'Can deactivate users'),)

    def __unicode__(self):
        return unicode(self.user)

    def get_absolute_url(self):
        return reverse('users.profile', args=[self.user_id])

    def clear(self):
        """Clears out the users profile"""
        self.name = ''
        self.public_email = False
        self.avatar = None
        self.bio = ''
        self.website = ''
        self.twitter = ''
        self.facebook = ''
        self.irc_handle = ''
        self.city = ''

    @property
    def display_name(self):
        return self.name if self.name else self.user.username

    @property
    def twitter_usernames(self):
        return list(
            Reply.objects.filter(user=self.user)
                         .values_list('twitter_username', flat=True)
                         .distinct())<commit_msg>Tweak the __unicode__ method to be more resilient<commit_after>import hashlib
import logging
import random
import re
import time
from datetime import datetime, timedelta

from django.conf import settings
from django.contrib.auth.models import User, Group
from django.contrib.sites.models import Site
from django.db import models

from celery.task import task
from statsd import statsd
from timezones.fields import TimeZoneField, zones, MAX_TIMEZONE_LENGTH
from tower import ugettext as _
from tower import ugettext_lazy as _lazy

from kitsune.customercare.models import Reply
from kitsune.lib.countries import COUNTRIES
from kitsune.search.es_utils import UnindexMeBro
from kitsune.search.models import (
    SearchMappingType, SearchMixin, register_for_indexing,
    register_mapping_type)
from kitsune.sumo import email_utils
from kitsune.sumo.models import ModelBase, LocaleField
from kitsune.sumo.urlresolvers import reverse
from kitsune.sumo.utils import auto_delete_files, chunked


log = logging.getLogger('k.users')


SHA1_RE = re.compile('^[a-f0-9]{40}$')
CONTRIBUTOR_GROUP = 'Registered as contributor'


# Add south introspection for timezones.fields.TimeZoneField
#
# We do this here because django-timezone is long in the tooth and
# they haven't fixed it there, yet. Need to do this before it gets
# used. If we end up using TimeZoneField elsewhere, then we should
# centralize this hack.
#
# See https://github.com/brosner/django-timezones/pull/19
from south.modelsinspector import add_introspection_rules
add_introspection_rules(rules=[(
    (TimeZoneField,),
    [],
    {
        "max_length": ["max_length", {"default": MAX_TIMEZONE_LENGTH}],
        "default": ["default", {"default": settings.TIME_ZONE}],
        "choices": ["choices", {"default": zones.PRETTY_TIMEZONE_CHOICES}],
    }
)], patterns=["^timezones\.fields\."])


@auto_delete_files
class Profile(ModelBase, SearchMixin):
    """Profile model for django users, get it with user.get_profile()."""

    user = models.OneToOneField(User, primary_key=True,
                                verbose_name=_lazy(u'User'))
    name = models.CharField(max_length=255, null=True, blank=True,
                            verbose_name=_lazy(u'Display name'))
    public_email = models.BooleanField(  # show/hide email
        default=False, verbose_name=_lazy(u'Make my email public'))
    avatar = models.ImageField(upload_to=settings.USER_AVATAR_PATH, null=True,
                               blank=True, verbose_name=_lazy(u'Avatar'),
                               max_length=settings.MAX_FILEPATH_LENGTH)
    bio = models.TextField(null=True, blank=True,
                           verbose_name=_lazy(u'Biography'))
    website = models.URLField(max_length=255, null=True, blank=True,
                              verbose_name=_lazy(u'Website'))
    twitter = models.URLField(max_length=255, null=True, blank=True,
                              verbose_name=_lazy(u'Twitter URL'))
    facebook = models.URLField(max_length=255, null=True, blank=True,
                               verbose_name=_lazy(u'Facebook URL'))
    irc_handle = models.CharField(max_length=255, null=True, blank=True,
                                  verbose_name=_lazy(u'IRC nickname'))
    timezone = TimeZoneField(null=True, blank=True,
                             verbose_name=_lazy(u'Timezone'))
    country = models.CharField(max_length=2, choices=COUNTRIES, null=True,
                               blank=True, verbose_name=_lazy(u'Country'))
    # No city validation
    city = models.CharField(max_length=255, null=True, blank=True,
                            verbose_name=_lazy(u'City'))
    locale = LocaleField(default=settings.LANGUAGE_CODE,
                         verbose_name=_lazy(u'Preferred language'))

    class Meta(object):
        permissions = (('view_karma_points', 'Can view karma points'),
                       ('deactivate_users', 'Can deactivate users'),)

    def __unicode__(self):
        try:
            return unicode(self.user)
        except Exception as exc:
            return unicode('%d (%r)' % (self.id, exc))

    def get_absolute_url(self):
        return reverse('users.profile', args=[self.user_id])

    def clear(self):
        """Clears out the users profile"""
        self.name = ''
        self.public_email = False
        self.avatar = None
        self.bio = ''
        self.website = ''
        self.twitter = ''
        self.facebook = ''
        self.irc_handle = ''
        self.city = ''

    @property
    def display_name(self):
        return self.name if self.name else self.user.username

    @property
    def twitter_usernames(self):
        return list(
            Reply.objects.filter(user=self.user)
                         .values_list('twitter_username', flat=True)
                         .distinct())
{'fraction_non_alphanumeric': 0.10160427807486631, 'fraction_numerical': 0.005452448359022754, 'mean_word_length': 2.867802108678021, 'pattern_counts': {'":': 12, '<': 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': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6851649', 'n_tokens_mistral': 2888, 'n_tokens_neox': 2757, 'n_words': 638}