Files
edx-platform/common/djangoapps/user_api/api/profile.py
2014-10-16 10:24:00 -04:00

158 lines
4.1 KiB
Python

"""Python API for user profiles.
Profile information includes a student's demographic information and preferences,
but does NOT include basic account information such as username, password, and
email address.
"""
from user_api.models import User, UserProfile, UserPreference
from user_api.helpers import intercept_errors
class ProfileRequestError(Exception):
""" The request to the API was not valid. """
pass
class ProfileUserNotFound(ProfileRequestError):
""" The requested user does not exist. """
pass
class ProfileInvalidField(ProfileRequestError):
""" The proposed value for a field is not in a valid format. """
def __init__(self, field, value):
self.field = field
self.value = value
def __str__(self):
return u"Invalid value '{value}' for profile field '{field}'".format(
value=self.value,
field=self.field
)
class ProfileInternalError(Exception):
""" An error occurred in an API call. """
pass
FULL_NAME_MAX_LENGTH = 255
@intercept_errors(ProfileInternalError, ignore_errors=[ProfileRequestError])
def profile_info(username):
"""Retrieve a user's profile information.
Searches either by username or email.
At least one of the keyword args must be provided.
Args:
username (unicode): The username of the account to retrieve.
Returns:
dict: If profile information was found.
None: If the provided username did not match any profiles.
"""
try:
profile = UserProfile.objects.get(user__username=username)
except UserProfile.DoesNotExist:
return None
profile_dict = {
"username": profile.user.username,
"email": profile.user.email,
"full_name": profile.name,
"level_of_education": profile.level_of_education,
"mailing_address": profile.mailing_address,
"year_of_birth": profile.year_of_birth,
"goals": profile.goals,
"city": profile.city,
"country": unicode(profile.country),
}
return profile_dict
@intercept_errors(ProfileInternalError, ignore_errors=[ProfileRequestError])
def update_profile(username, full_name=None):
"""Update a user's profile.
Args:
username (unicode): The username associated with the account.
Keyword Args:
full_name (unicode): If provided, set the user's full name to this value.
Returns:
None
Raises:
ProfileRequestError: If there is no profile matching the provided username.
"""
try:
profile = UserProfile.objects.get(user__username=username)
except UserProfile.DoesNotExist:
raise ProfileUserNotFound
if full_name is not None:
name_length = len(full_name)
if name_length > FULL_NAME_MAX_LENGTH or name_length == 0:
raise ProfileInvalidField("full_name", full_name)
else:
profile.update_name(full_name)
@intercept_errors(ProfileInternalError, ignore_errors=[ProfileRequestError])
def preference_info(username):
"""Retrieve information about a user's preferences.
Args:
username (unicode): The username of the account to retrieve.
Returns:
dict: Empty if there is no user
"""
preferences = UserPreference.objects.filter(user__username=username)
preferences_dict = {}
for preference in preferences:
preferences_dict[preference.key] = preference.value
return preferences_dict
@intercept_errors(ProfileInternalError, ignore_errors=[ProfileRequestError])
def update_preferences(username, **kwargs):
"""Update a user's preferences.
Sets the provided preferences for the given user.
Args:
username (unicode): The username of the account to retrieve.
Keyword Args:
**kwargs (unicode): Arbitrary key-value preference pairs
Returns:
None
Raises:
ProfileUserNotFound
"""
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise ProfileUserNotFound
else:
for key, value in kwargs.iteritems():
UserPreference.set_preference(user, key, value)