data.py 5.75 KB
Newer Older
1 2 3 4 5
"""
Data Aggregation Layer of the Enrollment API. Collects all enrollment specific data into a single
source to be used throughout the API.

"""
6
import logging
7 8
from django.contrib.auth.models import User
from opaque_keys.edx.keys import CourseKey
9
from xmodule.modulestore.django import modulestore
10 11
from enrollment.errors import CourseNotFoundError, CourseEnrollmentClosedError, CourseEnrollmentFullError, \
    CourseEnrollmentExistsError, UserNotFoundError
12
from enrollment.serializers import CourseEnrollmentSerializer, CourseField
13 14
from student.models import CourseEnrollment, NonExistentCourseError, CourseEnrollmentException, EnrollmentClosedError, \
    CourseFullError, AlreadyEnrolledError
15 16

log = logging.getLogger(__name__)
17 18


19 20
def get_course_enrollments(user_id):
    """Retrieve a list representing all aggregated data for a user's course enrollments.
21

22
    Construct a representation of all course enrollment data for a specific user.
23 24

    Args:
25
        user_id (str): The name of the user to retrieve course enrollment information for.
26 27

    Returns:
28
        A serializable list of dictionaries of all aggregated enrollment data for a user.
29 30

    """
31
    qset = CourseEnrollment.objects.filter(
32
        user__username=user_id, is_active=True
33
    ).order_by('created')
34
    return CourseEnrollmentSerializer(qset).data  # pylint: disable=no-member
35 36


37 38
def get_course_enrollment(username, course_id):
    """Retrieve an object representing all aggregated data for a user's course enrollment.
39

40
    Get the course enrollment information for a specific user and course.
41 42

    Args:
43
        username (str): The name of the user to retrieve course enrollment information for.
44 45 46 47 48 49
        course_id (str): The course to retrieve course enrollment information for.

    Returns:
        A serializable dictionary representing the course enrollment.

    """
50 51 52
    course_key = CourseKey.from_string(course_id)
    try:
        enrollment = CourseEnrollment.objects.get(
53
            user__username=username, course_id=course_key
54
        )
55
        return CourseEnrollmentSerializer(enrollment).data  # pylint: disable=no-member
56 57 58 59
    except CourseEnrollment.DoesNotExist:
        return None


60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
def create_course_enrollment(username, course_id, mode, is_active):
    """Create a new course enrollment for the given user.

    Creates a new course enrollment for the specified user username.

    Args:
        username (str): The name of the user to create a new course enrollment for.
        course_id (str): The course to create the course enrollment for.
        mode (str): (Optional) The mode for the new enrollment.
        is_active (boolean): (Optional) Determines if the enrollment is active.

    Returns:
        A serializable dictionary representing the new course enrollment.

    Raises:
        CourseNotFoundError
        CourseEnrollmentFullError
        EnrollmentClosedError
        CourseEnrollmentExistsError

    """
    course_key = CourseKey.from_string(course_id)

    try:
        user = User.objects.get(username=username)
    except User.DoesNotExist:
        msg = u"Not user with username '{username}' found.".format(username=username)
        log.warn(msg)
        raise UserNotFoundError(msg)

    try:
        enrollment = CourseEnrollment.enroll(user, course_key, check_access=True)
        return _update_enrollment(enrollment, is_active=is_active, mode=mode)
    except NonExistentCourseError as err:
        raise CourseNotFoundError(err.message)
    except EnrollmentClosedError as err:
        raise CourseEnrollmentClosedError(err.message)
    except CourseFullError as err:
        raise CourseEnrollmentFullError(err.message)
    except AlreadyEnrolledError as err:
        raise CourseEnrollmentExistsError(err.message)


def update_course_enrollment(username, course_id, mode=None, is_active=None):
    """Modify a course enrollment for a user.
105 106 107 108

    Allows updates to a specific course enrollment.

    Args:
109
        username (str): The name of the user to retrieve course enrollment information for.
110
        course_id (str): The course to retrieve course enrollment information for.
111
        mode (str): (Optional) If specified, modify the mode for this enrollment.
112 113 114 115 116 117
        is_active (boolean): (Optional) Determines if the enrollment is active.

    Returns:
        A serializable dictionary representing the modified course enrollment.

    """
118 119
    course_key = CourseKey.from_string(course_id)

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    try:
        user = User.objects.get(username=username)
    except User.DoesNotExist:
        msg = u"Not user with username '{username}' found.".format(username=username)
        log.warn(msg)
        raise UserNotFoundError(msg)

    try:
        enrollment = CourseEnrollment.objects.get(user=user, course_id=course_key)
        return _update_enrollment(enrollment, is_active=is_active, mode=mode)
    except CourseEnrollment.DoesNotExist:
        return None


def _update_enrollment(enrollment, is_active=None, mode=None):
135 136
    enrollment.update_enrollment(is_active=is_active, mode=mode)
    enrollment.save()
137
    return CourseEnrollmentSerializer(enrollment).data  # pylint: disable=no-member
138 139 140


def get_course_enrollment_info(course_id):
141
    """Returns all course enrollment information for the given course.
142

143
    Based on the course id, return all related course information..
144

145 146 147 148 149 150
    Args:
        course_id (str): The course to retrieve enrollment information for.

    Returns:
        A serializable dictionary representing the course's enrollment information.

151 152 153
    Raises:
        CourseNotFoundError

154 155 156 157
    """
    course_key = CourseKey.from_string(course_id)
    course = modulestore().get_course(course_key)
    if course is None:
158 159 160
        msg = u"Requested enrollment information for unknown course {course}".format(course=course_id)
        log.warning(msg)
        raise CourseNotFoundError(msg)
161
    return CourseField().to_native(course)