def position_select_id(request):
    """
        Function Summary: This function is used to get a single Position object's information.
        Path: 'api/position/select'
        Request Type: GET
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user
            position_id -- The Position ID to be looked up

        Possible Error Codes:
            300, 301, 302, 303, 304

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using a GET request.
    if request.method != "GET":
        return JsonResponse(Response.get_error_status(301, POSITION_ERRORS))

    # Ensure the user is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(300, POSITION_ERRORS))

    # Get the currently logged in Student object.
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Ensure that the request's GET parameters include 'position_id'.
    if 'position_id' not in request.GET:
        return JsonResponse(Response.get_error_status(302, POSITION_ERRORS))

    # Lookup the Position using the provided 'position_id'.
    position_lookup = Position.objects.filter(id=request.GET['position_id'])

    # If no Position object exists, return an error status.
    if len(position_lookup) == 0:
        return JsonResponse(Response.get_error_status(303, POSITION_ERRORS))

    # Get the current Position.
    current_position = position_lookup[0]

    # If the logged in User is not the User listed in the Position, return an error status
    if current_position.student != current_student:
        return JsonResponse(Response.get_error_status(304, POSITION_ERRORS))

    # Return a success status with the Position data.
    success_status = Response.get_success_status()
    success_status['data'] = current_position.to_dict()
    return JsonResponse(success_status)
def position_create(request):
    """
        Function Summary: This function is used to create a Position object.
        Path: 'api/position/create'
        Request Type: GET
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user
            x -- The x position of the user
            y -- The y position of the user

        Possible Error Codes:
            300, 301, 302

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using a GET request.
    if request.method != "GET":
        return JsonResponse(Response.get_error_status(301, POSITION_ERRORS))

    # Ensure that the user is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(300, POSITION_ERRORS))

    # Get the currently logged in Student object.
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Try to create a new Position object and return a success status.
    try:
        x = request.GET['x']
        y = request.GET['y']
        time = datetime.datetime.now()
        new_position = Position.objects.create(student=current_student,
                                               x=x,
                                               y=y,
                                               timestamp=time)
        new_position.save()

        success_status = Response.get_success_status()
        success_status['data'] = new_position.to_dict()
        return JsonResponse(success_status)

    except KeyError:
        return JsonResponse(Response.get_error_status(302, POSITION_ERRORS))
def get_all_open_survey_instances(request):
    """
        Function Summary: This function is used to get all of the open SurveyInstance objects for a Student.
        Path: '/api/survey/open_surveys'
        Request Type: POST
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The session ID of the logged in user

        Possible Error Codes:
            500, 501

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a 'data' JSON object.
    """
    # Ensure that the API call is using POST request.
    if request.method != "POST":
        return JsonResponse(Response.get_error_status(501, SURVEY_ERRORS))

    # Ensure that the user is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(500, SURVEY_ERRORS))

    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Get all of the Survey Instance objects with a question or position without response objects.
    open_surveys = set()
    for survey in SurveyInstance.objects.filter(student=current_student):
        for question in SurveyQuestionInstance.objects.filter(
                survey_instance=survey):
            if len(SurveyResponse.objects.filter(
                    survey_entry_id=question.id)) == 0:
                open_surveys.add(survey)

        for position in SurveyPositionInstance.objects.filter(
                survey_instance=survey):
            if len(SurveyResponse.objects.filter(
                    survey_entry_id=position.id)) == 0:
                open_surveys.add(survey)

    success_object = Response.get_success_status()
    success_object['data'] = [x.to_dict() for x in open_surveys]
    return JsonResponse(success_object)
def demographic_select(request):
    """
        Function Summary: This function is used to get a Student's Demographic information
        Path: 'api/demographic/select'
        Request Type: GET
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user

        Possible Error Codes:
            200, 201, 206

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using GET request.
    if request.method != "GET":
        return JsonResponse(Response.get_error_status(201, DEMO_ERRORS))

    # Ensure the user is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(200, DEMO_ERRORS))

    # Get the currently logged in Student object.
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Get the Demographic object associated with the Student and return it.
    try:
        demo_instance = Demographic.objects.get(student=current_student)
        object_dict = demo_instance.to_dict()
        success_object = Response.get_success_status()
        success_object['data'] = object_dict
        return JsonResponse(success_object)

    # Return error status if the Demographic object does not exist for the Student.
    except Demographic.DoesNotExist:
        return JsonResponse(Response.get_error_status(206, DEMO_ERRORS))
def position_select_all(request):
    """
        Function Summary: This function is used to get all of the Positions objects for a Student.
        Path: 'api/position/all'
        Request Type: GET
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user

        Possible Error Codes:
            300, 301

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using a GET request.
    if request.method != "GET":
        return JsonResponse(Response.get_error_status(301, POSITION_ERRORS))

    # Ensure the user is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(300, POSITION_ERRORS))

    # Get the currently logged in Student object.
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Get all of the dictionary objects of the Position objects for the current Student.
    positions = [
        x.to_dict() for x in Position.objects.filter(student=current_student)
    ]

    # Return the success status with the Position objects.
    success_status = Response.get_success_status()
    success_status['data'] = positions

    return JsonResponse(success_status)
def demographic_delete(request):
    """
        Function Summary: This function is used to delete a Demographic object.
        Path: 'api/demographic/delete'
        Request Type: GET
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user

        Possible Error Codes:
            200, 201, 206

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level.
    """
    # Ensure the API call is using GET
    if request.method != "GET":
        return JsonResponse(Response.get_error_status(201, DEMO_ERRORS))

    # Ensure that the user is logged in
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(200, DEMO_ERRORS))

    # Get the Student object
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Try to delete the Demographic object associated with the logged in Student object.
    try:
        demo_instance = Demographic.objects.get(student=current_student)
        demo_instance.delete()
        return JsonResponse(Response.get_success_status())

    # Return an error status if the Demographic object does not exist.
    except Demographic.DoesNotExist:
        return JsonResponse(Response.get_error_status(206, DEMO_ERRORS))
def class_select_all(request):
    """
        Function Summary: This function is used to get all the Class objects of a Student.
        Path: '/api/class/select/all'
        Request Type: GET
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user

        Possible Error Codes:
            400, 401

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using GET request.
    if request.method != "GET":
        return JsonResponse(Response.get_error_status(401, CLASS_ERRORS))

    # Ensure the User is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(400, CLASS_ERRORS))

    current_user = get_user_by_session(request.GET['session_id'])
    current_student = Student.objects.get(user=current_user)

    # Return success status and all Class objects associated with Student.
    success_status = Response.get_success_status()
    class_lookup = [
        x.class_enrolled
        for x in ClassEnrollment.objects.filter(student=current_student)
    ]
    success_status['data'] = [x.to_dict() for x in class_lookup]

    return JsonResponse(success_status)
def demographic_update(request):
    """
        Function Summary: This function is used to update an existing demographic object. A success status will be returned with the updated Demographic object's information.
        Path: 'api/demographic/update'
        Request Type: POST
        Required Login: True

        Args:
            request -- the HTTP request made to the url

        Required GET Parameters:
            session_id -- The Session ID of the logged in user

        Optional Request Parameters:
            age -- The age of the user
            gender -- The gender of the user
            grade_year -- The grade year of the user
            ethnicity -- The ethnicity of the user
            race -- The race of the user
            major -- The major of the user

        Possible Error Codes:
            200, 201, 205, 206

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using POST
    if request.method != "POST":
        return JsonResponse(Response.get_error_status(201, DEMO_ERRORS))

    # Ensure the user is logged in. Return an error status if the user is not logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(200, DEMO_ERRORS))

    # Get the logged in Student object
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Try to get the Demographic object registered to the student. Return an error status if the user has not created a Demographic object yet.
    try:
        demo_instance = Demographic.objects.get(student=current_student)

    except Demographic.DoesNotExist:
        return JsonResponse(Response.get_error_status(206, DEMO_ERRORS))

    # If the age is provided in POST data, update the age in the Demographic object.
    if 'age' in request.POST:
        demo_instance.age = request.POST['age']

    # If the gender is provided in POST data, update the gender in the Demographic object.
    if 'gender' in request.POST:
        try:
            demo_instance.gender = GenderLookup.objects.get(
                id=request.POST['gender'])
        except GenderLookup.DoesNotExist:
            return JsonResponse(Response.get_error_status(205, DEMO_ERRORS))

    # If the grade_year is provided in POST data, update the grade_year in the Demographic object.
    if 'grade_year' in request.POST:
        try:
            demo_instance.grade_year = GradeYearLookup.objects.get(
                id=request.POST['grade_year'])
        except GradeYearLookup.DoesNotExist:
            return JsonResponse(Response.get_error_status(205, DEMO_ERRORS))

    # If the ethnicity is provided in POST data, update the ethnicity in the Demographic object.
    if 'ethnicity' in request.POST:
        try:
            demo_instance.ethnicity = EthnicityLookup.objects.get(
                id=request.POST['ethnicity'])
        except EthnicityLookup.DoesNotExist:
            return JsonResponse(Response.get_error_status(205, DEMO_ERRORS))

    # If the race is provided in POST data, update the race in the Demographic object.
    if 'race' in request.POST:
        try:
            demo_instance.race = RaceLookup.objects.get(
                id=request.POST['race'])
        except RaceLookup.DoesNotExist:
            return JsonResponse(Response.get_error_status(205, DEMO_ERRORS))

    # If the major is provided in POST data, update the major in the Demographic object.
    if 'major' in request.POST:
        demo_instance.major = request.POST['major']

    # Save the updated Demographic object and return a success status.
    demo_instance.save()
    success_status = Response.get_success_status()
    success_status['data'] = demo_instance.to_dict()
    return JsonResponse(Response.get_success_status())
def demographic_create(request):
    """
        Function Summary: This function is used to create a new demographic object. A success status will be returned with the new Demographic object's information.
        Path: 'api/demographic/create'
        Request Type: POST
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET parameters:
            session_id -- The Session ID of the user making the request

        Required POST Parameters:
            age -- the age of the user
            gender -- the gender of the user
            grade_year -- the grade year of the user
            ethnicity -- the ethnicity of the user
            race -- the race of the user
            major -- the major of the user

        Possible Error Codes:
            200, 201, 203, 204, 205

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the request is using POST
    if request.method != "POST":
        return JsonResponse(Response.get_error_status(201, DEMO_ERRORS))

    # If the user is not logged in, return an error status
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(200, DEMO_ERRORS))

    # Get the logged in Student
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # If a Demographic object already exists, return an error status
    if len(Demographic.objects.filter(student=current_student)) != 0:
        return JsonResponse(Response.get_error_status(204, DEMO_ERRORS))

    # Try to create a new demographic object. Error status will be returned in the data does not validate.
    try:
        new_demographic = Demographic.objects.create(
            student=current_student,
            age=request.POST['age'],
            gender=GenderLookup.objects.get(id=request.POST['gender']),
            grade_year=GradeYearLookup.objects.get(
                id=request.POST['grade_year']),
            ethnicity=EthnicityLookup.objects.get(
                id=request.POST['ethnicity']),
            race=RaceLookup.objects.get(id=request.POST['race']),
            major=request.POST['major'])
        new_demographic.save()
        success_status = Response.get_success_status()
        success_status['data'] = new_demographic.to_dict()
        return JsonResponse(Response.get_success_status())

    except KeyError:
        return JsonResponse(Response.get_error_status(203, DEMO_ERRORS))

    except GenderLookup.DoesNotExist:
        return JsonResponse(Response.get_error_status(205, DEMO_ERRORS))

    except GradeYearLookup.DoesNotExist:
        return JsonResponse(Response.get_error_status(205, DEMO_ERRORS))

    except EthnicityLookup.DoesNotExist:
        return JsonResponse(Response.get_error_status(205, DEMO_ERRORS))

    except RaceLookup.DoesNotExist:
        return JsonResponse(Response.get_error_status(205, DEMO_ERRORS))
def end_session_create_survey_instance(request):
    """
        Function Summary: This function is used to end a Student's session and to create a Survey Instance for them to add responses to.
        Path: '/api/survey/generate
        Request Type: POST
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The session ID of the logged in user

        Required POST Parameters:
            class -- The class from which the student was in during the session

        Possible Error Codes:
            500, 501, 503, 504, 506, 510

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level.
    """
    # Ensure that the API call is using POST request.
    if request.method != "POST":
        return JsonResponse(Response.get_error_status(501, SURVEY_ERRORS))

    # Ensure that the user is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(500, SURVEY_ERRORS))

    # Ensure 'class' is in POST parameters
    if 'class' not in request.POST:
        return JsonResponse(Response.get_error_status(503, SURVEY_ERRORS))

    # Lookup Class objects with 'class' parameter.
    class_lookup = Class.objects.filter(id=request.POST['class'])

    # Ensure that the Class object exists.
    if len(class_lookup) == 0:
        return JsonResponse(Response.get_error_status(506, SURVEY_ERRORS))

    # Find Survey object based on Class object.
    current_class = class_lookup[0]
    survey_lookup = Survey.objects.filter(associated_class=current_class)

    # Ensure Survey object exists.
    if len(survey_lookup) == 0:
        return JsonResponse(Response.get_error_status(504, SURVEY_ERRORS))

    # Add the SurveyQuestions from Survey object.
    current_survey = survey_lookup[0]
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    if len(
            SurveyInstance.objects.filter(
                survey=current_survey,
                student=current_student,
                date_generated=datetime.datetime.now().date())) != 0:
        return JsonResponse(Response.get_error_status(510, SURVEY_ERRORS))

    # Create a new SurveyInstance object.
    new_survey_instance = SurveyInstance.objects.create(
        survey=current_survey, student=current_student)
    new_survey_instance.save()

    # Create SurveyQuestionInstance objects for each question associated with the Survey.
    for question in SurveyQuestion.objects.filter(survey=current_survey):
        new_question_instance = SurveyQuestionInstance.objects.create(
            survey_instance=new_survey_instance, question=question)
        new_question_instance.save()

    start_time_stamp = datetime.datetime.now().replace(
        hour=current_class.start_time.hour,
        minute=current_class.start_time.minute)
    end_time_stamp = datetime.datetime.now().replace(
        hour=current_class.end_time.hour, minute=current_class.end_time.minute)

    # Get all of the positions between the start and end timestamp and create position questions.
    for position in Position.objects.filter(student=current_student,
                                            timestamp__lte=end_time_stamp,
                                            timestamp__gte=start_time_stamp):
        new_position_instance = SurveyPositionInstance.objects.create(
            survey_instance=new_survey_instance, position=position)
        new_position_instance.save()

    return JsonResponse(Response.get_success_status())
def add_responses_to_survey(request):
    """
        Function Summary: This function is used to add SurveyResponse objects.
        Path: '/api/survey/respond'
        Request Type: POST
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user

        Required POST Parameters:
            survey_id -- The Class ID of the associated Survey Instance object

        Optional POST Parameters:
            <SURVEYQUESTION_ID> -- The ID of a SurveyQuestion to attach a response to

        Possible Error Codes:
            500, 501, 503, 504, 509

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using POST request.
    if request.method != "POST":
        return JsonResponse(Response.get_error_status(501, SURVEY_ERRORS))

    # Ensure the User is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(500, SURVEY_ERRORS))

    # Ensure 'survey' in POST parameters.
    if 'survey_id' not in request.POST:
        return JsonResponse(Response.get_error_status(503, SURVEY_ERRORS))

    survey_lookup = SurveyInstance.objects.filter(id=request.POST['survey_id'])

    # Return an error if the survey instance does not exist
    if len(survey_lookup) == 0:
        return JsonResponse(Response.get_error_status(504, SURVEY_ERRORS))

    survey_instance = survey_lookup[0]
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Return an error if the survey instance
    if current_student != survey_instance.student:
        return JsonResponse(Response.get_error_status(509, SURVEY_ERRORS))

    # Make a copy of the POST parameters and remove the 'survey' parameter.
    post_data = request.POST.copy()
    del post_data['survey_id']

    data_object = {}

    for entry_id, response in post_data.items():
        response_exists = len(
            SurveyResponse.objects.filter(survey_entry_id=entry_id)) != 0

        if len(SurveyEntryInstance.objects.filter(id=entry_id)) == 0:
            data_object[entry_id] = "bad id"
            continue

        if response_exists:
            SurveyResponse.objects.get(
                survey_entry_id=entry_id).response = response
            data_object[entry_id] = "updated"
        else:
            new_response = SurveyResponse.objects.create(
                survey_entry_id=entry_id, response=response)
            new_response.save()
            data_object[entry_id] = "created"

    success_object = Response.get_success_status()
    success_object['data'] = data_object
    return JsonResponse(success_object)
def get_survey_by_id(request):
    """
        Function Summary: This function is used to get the information about a SurveyInstance given an id.
        Path: '/api/survey/get'
        Request Type: POST
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The session ID of the logged in user

        Required POST Parameters:
            survey_id -- The ID of the SurveyInstance object

        Possible Error Codes:
            500, 501, 503, 504, 509

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a 'data' JSON object.
    """
    # Ensure that the API call is using POST request.
    if request.method != "POST":
        return JsonResponse(Response.get_error_status(501, SURVEY_ERRORS))

    # Ensure that the user is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(500, SURVEY_ERRORS))

    # Ensure 'class' is in POST parameters
    if 'survey_id' not in request.POST:
        return JsonResponse(Response.get_error_status(503, SURVEY_ERRORS))

    survey_lookup = SurveyInstance.objects.filter(id=request.POST['survey_id'])

    if len(survey_lookup) == 0:
        return JsonResponse(Response.get_error_status(504, SURVEY_ERRORS))

    current_survey = survey_lookup[0]
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Check that the Survey object belongs to the student logged in.
    if current_student != current_survey.student:
        return JsonResponse(Response.get_error_status(509, SURVEY_ERRORS))

    # Get all open question instance objects and append it to the question list
    questions = []
    for question_instance in SurveyQuestionInstance.objects.filter(
            survey_instance=current_survey):
        question_dict = question_instance.to_dict()
        question_dict['question'] = question_instance.question.to_dict()
        questions.append(question_dict)

    # Get all open position instance objects and append it to the position list
    positions = []
    for position_instance in SurveyPositionInstance.objects.filter(
            survey_instance=current_survey):
        position_dict = position_instance.to_dict()
        position_dict['position'] = position_instance.position.to_dict()
        positions.append(position_dict)

    survey = current_survey.to_dict()

    # Return the survey information
    success_object = Response.get_success_status()
    success_object['data'] = {
        'survey_instance': survey,
        'questions': questions,
        'positions': positions
    }
    return JsonResponse(success_object)
def position_summary(request):
    """
        Function Summary: This function is used to get the Position history of a User.
        Path: 'api/position/summary'
        Request Type: GET
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user
            start_time -- The start time to search for
            end_time -- The end time to search for

        Possible Error Codes:
            300, 301, 302, 305, 306

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using a GET request.
    if request.method != "GET":
        return JsonResponse(Response.get_error_status(301, POSITION_ERRORS))

    # Ensure the user is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(300, POSITION_ERRORS))

    # Get the currently logged in Student object.
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))

    # Ensure that 'start_time' and 'end_time' are in the GET parameters.
    if 'start_time' not in request.GET or 'end_time' not in request.GET:
        return JsonResponse(Response.get_error_status(302, POSITION_ERRORS))

    # Try to parse the start and end times into DateTime objects. Return error status if the string is invalid.
    try:
        start_datetime = datetime.datetime.strptime(request.GET['start_time'],
                                                    '%Y-%m-%d %H:%M:%S')
        end_datetime = datetime.datetime.strptime(request.GET['end_time'],
                                                  '%Y-%m-%d %H:%M:%S')

    except ValueError:
        return JsonResponse(Response.get_error_status(305, POSITION_ERRORS))

    if start_datetime is None or end_datetime is None:
        return JsonResponse(Response.get_error_status(306, POSITION_ERRORS))

    # Return a success status with the position summary information.
    success_object = Response.get_success_status()
    success_object['data'] = [
        x.to_dict() for x in Position.objects.filter(
            student=current_student,
            timestamp__gt=start_datetime,
            timestamp__lt=end_datetime).order_by('timestamp')
    ]

    return JsonResponse(success_object)
def class_summarize_movement(request):
    """
        Function Summary: This function is used to get all the Class objects of a Student
        Path: '/api/class/movement_summary'
        Request Type: POST
        Required Login: True

        Args:
            request -- The request made to the server by the client

        Required GET Parameters:
            session_id -- The Session ID of the logged in user

        Required POST Parameters:
            class -- The Class ID for the Class object
            start_date -- The start date of the summary
            end_date -- The end date of the summary

        Possible Error Codes:
            400, 401, 403, 407

        Return:
            Type: JSON
            Data: A JSON object with a 'status' at the top level. Will contain a "data" JSON object.
    """
    # Ensure the API call is using POST request.
    if request.method != "POST":
        return JsonResponse(Response.get_error_status(401, CLASS_ERRORS))

    # Ensure the User is logged in.
    if not get_user_logged_in(request):
        return JsonResponse(Response.get_error_status(400, CLASS_ERRORS))

    # Ensure POST parameters contain required data.
    if 'class' not in request.POST or 'start_date' not in request.POST or 'end_date' not in request.POST:
        return JsonResponse(Response.get_error_status(403, CLASS_ERRORS))

    # Lookup the Class objects. based on the Class ID.
    current_student = Student.objects.get(
        user=get_user_by_session(request.GET['session_id']))
    class_lookup = Class.objects.filter(id=request.POST['class'])

    # Ensure the Class object exists.
    if len(class_lookup) == 0:
        return JsonResponse(Response.get_error_status(407, CLASS_ERRORS))

    # Parse the start and end date into DateTime objects.
    current_class = class_lookup[0]
    start_date = datetime.datetime.strptime(request.POST['start_date'],
                                            '%m/%d/%Y').date()
    end_date = datetime.datetime.strptime(request.POST['end_date'],
                                          '%m/%d/%Y').date()
    days_of_the_week = [x.id for x in current_class.days_of_the_week.all()]

    summary = {}

    # Go through each day between the start and end date.
    for n in range((end_date - start_date).days + 1):
        current_date = start_date + datetime.timedelta(days=n)
        # Ensure that the date we are currently on is a day the class falls on.
        if current_date.weekday() not in days_of_the_week:
            continue

        # Create start and end times to filter Position objects.
        start_timestamp = datetime.datetime(
            year=current_date.year,
            month=current_date.month,
            day=current_date.day,
            hour=current_class.start_time.hour,
            minute=current_class.start_time.minute)

        end_timestamp = datetime.datetime(year=current_date.year,
                                          month=current_date.month,
                                          day=current_date.day,
                                          hour=current_class.end_time.hour,
                                          minute=current_class.end_time.minute)

        # Get all positions that fall within the day, start time, and end time
        positions = Position.objects.filter(student=current_student,
                                            timestamp__gte=start_timestamp,
                                            timestamp__lte=end_timestamp)
        summary[str(current_date)] = [p.to_dict() for p in positions]

    # Return success status with movement summary.
    success_status = Response.get_success_status()
    success_status['data'] = summary
    return JsonResponse(success_status)