<commit_before>"""
Models for User Information (students, staff, etc)

Migration Notes

If you make changes to this model, be sure to create an appropriate migration
file and check it in at the same time as your model changes. To do that,

1. Go to the edx-platform dir
2. ./manage.py lms schemamigration student --auto description_of_your_change
3. Add the migration file created in edx-platform/common/djangoapps/student/migrations/
"""
from datetime import datetime
from random import randint
import hashlib
import json
import logging
import uuid


from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.forms import ModelForm, forms
from django.utils.translation import ugettext_lazy as _

import comment_client as cc
from pytz import UTC


log = logging.getLogger(__name__)
AUDIT_LOG = logging.getLogger("audit")


class UserProfile(models.Model):
    """This is where we store all the user demographic fields. We have a
    separate table for this rather than extending the built-in Django auth_user.

    Notes:
        * Some fields are legacy ones from the first run of 6.002, from which
          we imported many users.
        * Fields like name and address are intentionally open ended, to account
          for international variations. An unfortunate side-effect is that we
          cannot efficiently sort on last names for instance.

    Replication:
        * Only the Portal servers should ever modify this information.
        * All fields are replicated into relevant Course databases

    Some of the fields are legacy ones that were captured during the initial
    MITx fall prototype.
    """

    class Meta:
        db_table = "auth_userprofile"

    # CRITICAL TODO/SECURITY
    # Sanitize all fields.
    # This is not visible to other users, but could introduce holes later
    user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile')
    name = models.CharField(blank=True, max_length=255, db_index=True)
    
    lastname = models.CharField(blank=False, null=True, max_length=30, db_index=True)
    firstname = models.CharField(blank=False, null=True, max_length=30, db_index=True)
    middlename = models.CharField(blank=False, null=True, max_length=30, db_index=True)
    
    


    meta = models.TextField(blank=True)  # JSON dictionary for future expansion
    courseware = models.CharField(blank=True, max_length=255, default='course.xml')

    # Location is no longer used, but is held here for backwards compatibility
    # for users imported from our first class.
    language = models.CharField(blank=True, max_length=255, db_index=True)
    location = models.CharField(blank=True, max_length=255, db_index=True)

    # Optional demographic data we started capturing from Fall 2012
    this_year = datetime.now(UTC).year
    VALID_YEARS = range(this_year, this_year - 120, -1)
    year_of_birth = models.IntegerField(blank=True, null=True, db_index=True)
    
    GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'), ('o', 'Other'))
    gender = models.CharField(
        blank=True, null=True, max_length=6, db_index=True, choices=GENDER_CHOICES
    )

    # [03/21/2013] removed these, but leaving comment since there'll still be
    # p_se and p_oth in the existing data in db.
    # ('p_se', 'Doctorate in science or engineering'),
    # ('p_oth', 'Doctorate in another field'),
    LEVEL_OF_EDUCATION_CHOICES = (
        ('p', _("Doctorate")),
        ('m', _("Master's or professional degree")),
        ('b', _("Bachelor's degree")),
        ('a', _("Associate's degree")),
        ('hs', _("Secondary/high school")),
        ('jhs', _("Junior secondary/junior high/middle school")),
        ('el', _("Elementary/primary school")),
        ('none', _("None")),
        ('other', _("Other"))
    )
    level_of_education = models.CharField(
        blank=True, null=True, max_length=6, db_index=True,
        choices=LEVEL_OF_EDUCATION_CHOICES
    )
    
    education_place = models.CharField(blank=False, null=True, max_length=255, db_index=False)
    education_year = models.IntegerField(blank=False, null=True, db_index=True)
    education_qualification = models.CharField(blank=True, null=True, max_length=30)
    education_specialty = models.CharField(blank=True, null=True, max_length=30)
    
    
    WORK_TYPE_CHOICES = (
        ('sch', _("School")),
        ('lyc', _("Lyceum")),
        ('edc', _('Education Center')),
        ('gymn', _('Gymnasium')),
        ('edu', _('Educational complex')),
        ('kind', _('Kindergarten')),
        ('npe', _('Non-profit educational institution')),
        ('coll', _('College')),
        ('none', _('None')),
        ('other', _('Other'))
    )
    work_type = models.CharField(blank=False, null=True, max_length=6, choices=WORK_TYPE_CHOICES)
    work_number = models.IntegerField(blank=False, null=True, db_index=True)
    work_name = models.CharField(blank=False, null=True, max_length=255, db_index=False)
    work_login = models.CharField(blank=False, null=True, max_length=10, db_index=False)
    WORK_LOCATION_CHOICES = (
        ('CAO', 'Central Administrative Okrug'),
        ('EAO', 'Eastern Administrative Okrug'),
        ('WAO', 'Western Administrative Okrug'),
        ('NAO', 'Northern Administrative Okrug'),
        ('NEAO', 'North-Eastern Administrative Okrug'),
        ('NWAO', 'North-Western Administrative Okrug'),
        ('SWAO', 'South-Western Administrative Okrug'),
        ('SEAO', 'South-Eastern Administrative Okrug'),
        ('SAO', 'Southern Administrative Okrug'),
        ('zel', 'Zelenogradsky Administrative Okrug'),
        ('troi', 'Troitsky Administrative Okrug'),
        ('novo', 'Novomoskovsky Administrative Okrug'),
        ('city', 'Territorial units with special status'),
        ('non', 'None'),
        ('other', 'Other')
    )
    work_location = models.CharField(blank=False, null=True, max_length=6, db_index=False, choices=WORK_LOCATION_CHOICES)
    WORK_OCCUPATION_CHOICES = (<commit_msg>added okrug translation<commit_after>"""
Models for User Information (students, staff, etc)

Migration Notes

If you make changes to this model, be sure to create an appropriate migration
file and check it in at the same time as your model changes. To do that,

1. Go to the edx-platform dir
2. ./manage.py lms schemamigration student --auto description_of_your_change
3. Add the migration file created in edx-platform/common/djangoapps/student/migrations/
"""
from datetime import datetime
from random import randint
import hashlib
import json
import logging
import uuid


from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.forms import ModelForm, forms
from django.utils.translation import ugettext_lazy as _

import comment_client as cc
from pytz import UTC


log = logging.getLogger(__name__)
AUDIT_LOG = logging.getLogger("audit")


class UserProfile(models.Model):
    """This is where we store all the user demographic fields. We have a
    separate table for this rather than extending the built-in Django auth_user.

    Notes:
        * Some fields are legacy ones from the first run of 6.002, from which
          we imported many users.
        * Fields like name and address are intentionally open ended, to account
          for international variations. An unfortunate side-effect is that we
          cannot efficiently sort on last names for instance.

    Replication:
        * Only the Portal servers should ever modify this information.
        * All fields are replicated into relevant Course databases

    Some of the fields are legacy ones that were captured during the initial
    MITx fall prototype.
    """

    class Meta:
        db_table = "auth_userprofile"

    # CRITICAL TODO/SECURITY
    # Sanitize all fields.
    # This is not visible to other users, but could introduce holes later
    user = models.OneToOneField(User, unique=True, db_index=True, related_name='profile')
    name = models.CharField(blank=True, max_length=255, db_index=True)
    
    lastname = models.CharField(blank=False, null=True, max_length=30, db_index=True)
    firstname = models.CharField(blank=False, null=True, max_length=30, db_index=True)
    middlename = models.CharField(blank=False, null=True, max_length=30, db_index=True)
    
    


    meta = models.TextField(blank=True)  # JSON dictionary for future expansion
    courseware = models.CharField(blank=True, max_length=255, default='course.xml')

    # Location is no longer used, but is held here for backwards compatibility
    # for users imported from our first class.
    language = models.CharField(blank=True, max_length=255, db_index=True)
    location = models.CharField(blank=True, max_length=255, db_index=True)

    # Optional demographic data we started capturing from Fall 2012
    this_year = datetime.now(UTC).year
    VALID_YEARS = range(this_year, this_year - 120, -1)
    year_of_birth = models.IntegerField(blank=True, null=True, db_index=True)
    
    GENDER_CHOICES = (('m', 'Male'), ('f', 'Female'), ('o', 'Other'))
    gender = models.CharField(
        blank=True, null=True, max_length=6, db_index=True, choices=GENDER_CHOICES
    )

    # [03/21/2013] removed these, but leaving comment since there'll still be
    # p_se and p_oth in the existing data in db.
    # ('p_se', 'Doctorate in science or engineering'),
    # ('p_oth', 'Doctorate in another field'),
    LEVEL_OF_EDUCATION_CHOICES = (
        ('p', _("Doctorate")),
        ('m', _("Master's or professional degree")),
        ('b', _("Bachelor's degree")),
        ('a', _("Associate's degree")),
        ('hs', _("Secondary/high school")),
        ('jhs', _("Junior secondary/junior high/middle school")),
        ('el', _("Elementary/primary school")),
        ('none', _("None")),
        ('other', _("Other"))
    )
    level_of_education = models.CharField(
        blank=True, null=True, max_length=6, db_index=True,
        choices=LEVEL_OF_EDUCATION_CHOICES
    )

    education_place = models.CharField(blank=False, null=True, max_length=255, db_index=False)
    education_year = models.IntegerField(blank=False, null=True, db_index=True)
    education_qualification = models.CharField(blank=True, null=True, max_length=30)
    education_specialty = models.CharField(blank=True, null=True, max_length=30)

    WORK_TYPE_CHOICES = (
        ('sch', _("School")),
        ('lyc', _("Lyceum")),
        ('edc', _('Education Center')),
        ('gymn', _('Gymnasium')),
        ('edu', _('Educational complex')),
        ('kind', _('Kindergarten')),
        ('npe', _('Non-profit educational institution')),
        ('coll', _('College')),
        ('none', _('None')),
        ('other', _('Other'))
    )
    work_type = models.CharField(blank=False, null=True, max_length=6, choices=WORK_TYPE_CHOICES)
    work_number = models.IntegerField(blank=False, null=True, db_index=True)
    work_name = models.CharField(blank=False, null=True, max_length=255, db_index=False)
    work_login = models.CharField(blank=False, null=True, max_length=10, db_index=False)
    WORK_LOCATION_CHOICES = (
        ('CAO', _('Central Administrative Okrug')),
        ('EAO', _('Eastern Administrative Okrug')),
        ('WAO', _('Western Administrative Okrug')),
        ('NAO', _('Northern Administrative Okrug')),
        ('NEAO', _('North-Eastern Administrative Okrug')),
        ('NWAO', _('North-Western Administrative Okrug')),
        ('SWAO', _('South-Western Administrative Okrug')),
        ('SEAO', _('South-Eastern Administrative Okrug')),
        ('SAO', _('Southern Administrative Okrug')),
        ('zel', _('Zelenogradsky Administrative Okrug')),
        ('troi', _('Troitsky Administrative Okrug')),
        ('novo', _('Novomoskovsky Administrative Okrug')),
        ('city', _('Territorial units with special status')),
        ('non', _('None')),
        ('other', _('Other'))
    )
    work_location = models.CharField(blank=False, null=True, max_length=6, db_index=False, choices=WORK_LOCATION_CHOICES)
    WORK_OCCUPATION_CHOICES = (
{'fraction_non_alphanumeric': 0.11733462095605987, 'fraction_numerical': 0.009174311926605505, 'mean_word_length': 3.7649539877300615, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '4210054', 'n_tokens_mistral': 3893, 'n_tokens_neox': 3657, 'n_words': 1084}