Newer
Older
"""
Provides Python APIs exposed from Student models.
"""
import logging
from pytz import UTC
Kyle McCormick
committed
from common.djangoapps.student.models import CourseAccessRole as _CourseAccessRole
from common.djangoapps.student.models import CourseEnrollment as _CourseEnrollment
from common.djangoapps.student.models import ManualEnrollmentAudit as _ManualEnrollmentAudit
from common.djangoapps.student.models import (
ENROLLED_TO_ENROLLED as _ENROLLED_TO_ENROLLED,
ENROLLED_TO_UNENROLLED as _ENROLLED_TO_UNENROLLED,
UNENROLLED_TO_ENROLLED as _UNENROLLED_TO_ENROLLED,
UNENROLLED_TO_UNENROLLED as _UNENROLLED_TO_UNENROLLED,
UNENROLLED_TO_ALLOWEDTOENROLL as _UNENROLLED_TO_ALLOWEDTOENROLL,
ALLOWEDTOENROLL_TO_ENROLLED as _ALLOWEDTOENROLL_TO_ENROLLED,
ALLOWEDTOENROLL_TO_UNENROLLED as _ALLOWEDTOENROLL_TO_UNENROLLED,
DEFAULT_TRANSITION_STATE as _DEFAULT_TRANSITION_STATE,
)
from common.djangoapps.student.models import PendingNameChange as _PendingNameChange
Kyle McCormick
committed
from common.djangoapps.student.models import UserProfile as _UserProfile
# This is done so that if these strings change within the app, we can keep exported constants the same
ENROLLED_TO_ENROLLED = _ENROLLED_TO_ENROLLED
ENROLLED_TO_UNENROLLED = _ENROLLED_TO_UNENROLLED
UNENROLLED_TO_ENROLLED = _UNENROLLED_TO_ENROLLED
UNENROLLED_TO_UNENROLLED = _UNENROLLED_TO_UNENROLLED
UNENROLLED_TO_ALLOWEDTOENROLL = _UNENROLLED_TO_ALLOWEDTOENROLL
ALLOWEDTOENROLL_TO_ENROLLED = _ALLOWEDTOENROLL_TO_ENROLLED
ALLOWEDTOENROLL_TO_UNENROLLED = _ALLOWEDTOENROLL_TO_UNENROLLED
DEFAULT_TRANSITION_STATE = _DEFAULT_TRANSITION_STATE
log = logging.getLogger(__name__)
def create_manual_enrollment_audit( # lint-amnesty, pylint: disable=missing-function-docstring
enrolled_by,
user_email,
state_transition,
reason,
course_enrollment
):
_ManualEnrollmentAudit.create_manual_enrollment_audit(
user=enrolled_by,
email=user_email,
state_transition=state_transition,
reason=reason,
enrollment=course_enrollment,
)
def get_course_enrollment(user, course_run_key):
return _CourseEnrollment.get_enrollment(user, course_run_key)
def get_phone_number(user_id):
"""
Christie Rice
committed
Get a user's phone number from the profile, if
one exists. Otherwise, return None.
"""
try:
student = _UserProfile.objects.get(user_id=user_id)
except _UserProfile.DoesNotExist as exception:
log.exception(exception)
return None
return student.phone_number or None
Michael Roytman
committed
Christie Rice
committed
def get_name(user_id):
"""
Get a user's name from their profile, if one exists. Otherwise, return None.
"""
try:
student = _UserProfile.objects.get(user_id=user_id)
except _UserProfile.DoesNotExist:
log.exception(f'Could not find UserProfile for id {user_id}')
return None
return student.name or None
Michael Roytman
committed
def get_course_access_role(user, org, course_id, role):
"""
Get a specific CourseAccessRole object. Return None if
it does not exist.
Arguments:
user: User object for the user who has access in a course
org: the org the course is in
course_id: the course_id of the CourseAccessRole
role: the role type of the role
"""
try:
course_access_role = _CourseAccessRole.objects.get(
user=user,
org=org,
course_id=course_id,
role=role,
)
except _CourseAccessRole.DoesNotExist:
log.exception('No CourseAccessRole found for user_id=%(user_id)s, org=%(org)s, '
'course_id=%(course_id)s, and role=%(role)s.', {
'user': user.id,
'org': org,
'course_id': course_id,
'role': role,
})
return None
return course_access_role
def get_pending_name_change(user):
"""
Return a string representing the user's pending name change, or None if it does not exist.
"""
try:
pending_name_change = _PendingNameChange.objects.get(user=user)
return pending_name_change.new_name
except _PendingNameChange.DoesNotExist:
return None
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
def do_name_change_request(user, new_name, rationale):
"""
Create a name change request. This either updates the user's current PendingNameChange, or creates
a new one if it doesn't exist. Returns the PendingNameChange object and a boolean describing whether
or not a new one was created.
"""
user_profile = _UserProfile.objects.get(user=user)
if user_profile.name == new_name:
log_msg = (
'user_id={user_id} requested a name change, but the requested name is the same as'
'their current profile name. Not taking any action.'.format(user_id=user.id)
)
log.warning(log_msg)
return None, False
pending_name_change, created = _PendingNameChange.objects.update_or_create(
user=user,
defaults={
'new_name': new_name,
'rationale': rationale
}
)
return pending_name_change, created
def confirm_name_change(user, pending_name_change):
"""
Confirm a pending name change. This updates the user's profile name and deletes the
PendingNameChange object.
"""
user_profile = _UserProfile.objects.get(user=user)
# Store old name in profile metadata
meta = user_profile.get_meta()
if 'old_names' not in meta:
meta['old_names'] = []
meta['old_names'].append(
[user_profile.name, pending_name_change.rationale, datetime.datetime.now(UTC).isoformat()]
)
user_profile.set_meta(meta)
user_profile.name = pending_name_change.new_name
user_profile.save()
pending_name_change.delete()