Validate student account and profile form fields. Use RequireJS for Jasmine tests of account and profile JS.
152 lines
3.8 KiB
Python
152 lines
3.8 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 = {
|
|
u'username': profile.user.username,
|
|
u'email': profile.user.email,
|
|
u'full_name': profile.name,
|
|
}
|
|
|
|
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)
|