def feedback_create(request): """ Function Summary: This function can be used to create a new Feedback object. Path: '/api/feedback/submit' Request Type: POST Required Login: False Args: request -- The request made to the server by the client Required GET Parameters: feedback -- The text feedback from the user Possible Error Codes: 601, 603 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(601, FEEDBACK_ERRORS)) # Ensure the POST parameters have enough data if 'feedback' not in request.POST: return JsonResponse(Response.get_error_status(603, FEEDBACK_ERRORS)) # Create new Feedback object new_feedback = Feedback.objects.create(feedback=request.POST['feedback']) new_feedback.save() return JsonResponse(Response.get_success_status())
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 login(request): """ Function Summary: This function will login a user and return a session_id to use to authenticate into the API. Path: '/api/auth/login' Request Type: POST Required Login: False Args: request -- The request made to the server by the client Required POST parameters: username -- The username for the user password -- The password for the user Possible Error Codes: 101, 103, 104, 105 Return: Type: JSON Data: A JSON object with a 'status' at the top level. If successful, it will have a data object containing the 'session_id' for authentication """ # Make sure the request is using POST to pass data if request.method != "POST": return JsonResponse(Response.get_error_status(101, AUTH_ERRORS)) # Make sure that the POST data contains a username and password if 'username' not in request.POST or 'password' not in request.POST: return JsonResponse(Response.get_error_status(103, AUTH_ERRORS)) # Lookup the user in the DB user_lookup = User.objects.filter(username=request.POST['username']) # Check that the user exists in the DB if len(user_lookup) == 0: return JsonResponse(Response.get_error_status(104, AUTH_ERRORS)) # Check the password of the user user = user_lookup[0] is_password_correct = user.check_password(request.POST['password']) if not is_password_correct: return JsonResponse(Response.get_error_status(105, AUTH_ERRORS)) # Check to see if the user already has a session token active session_lookup = Session.objects.filter(user=user) if len(session_lookup) == 0: current_session = Session.objects.create(user=user) current_session.save() else: current_session = session_lookup[0] success_dict = Response.get_success_status() success_dict['data'] = {'session_id': current_session.id} return JsonResponse(success_dict)
def logout(request): """ Function Summary: This function is used to logout a User and remove their session_id if it exists. Path: '/api/auth/logout' Request Type: GET Required Login: True Args: request -- The request made to the server from the client Required GET parameters: session_id -- The Session ID of the User to be logged out Possible Error Codes: 100, 101 Return: Type: JSON Data: A JSON object with a 'status' at the top level. """ # Make sure the request is using POST to pass data if request.method != "GET": return JsonResponse(Response.get_error_status(101, AUTH_ERRORS)) # Ensure that the 'session_id' exists in the GET parameters if 'session_id' not in request.GET: return JsonResponse(Response.get_error_status(100, AUTH_ERRORS)) # Lookup Session objects using the 'session_id' provided session_lookup = Session.objects.filter(id=request.GET['session_id']) # Return error if there are no Session objects with the provided 'session_id' if len(session_lookup) == 0: return JsonResponse(Response.get_success_status()) # Delete the Session object and return a success current_session = session_lookup[0] current_session.delete() return JsonResponse(Response.get_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 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 demographic_form(request): """ Function Summary": This function is used to build a Demographic form. Path: 'api/demographic/form' Request Type: GET Required Login: False Args: request -- The request made to the server by the client Possible Error Codes: 201 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)) form_values = {} # Get all the GenderLookup objects. genders = GenderLookup.objects.all() form_values['genders'] = [g.to_dict() for g in genders] # Get all the GradeYearLookup objects. grade_years = GradeYearLookup.objects.all() form_values['grade_years'] = [g.to_dict() for g in grade_years] # Get all the EthnicityLookup objects. ethnicities = EthnicityLookup.objects.all() form_values['ethnicities'] = [e.to_dict() for e in ethnicities] # Get all the RaceLookup objects. races = RaceLookup.objects.all() form_values['races'] = [r.to_dict() for r in races] # Return all of the values and success status success_status = Response.get_success_status() success_status['data'] = form_values return JsonResponse(success_status)
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_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 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)
def reset_password(request, reset_code): """ Function Summary: This function is used to reset a password. The function requires a new password in the POST parameters and the proper reset code to reset the password. The user will receive an email notification that their password has been changed. Path: '/api/auth/reset_password/<RESET CODE>' Request Type: POST Required Login: False Args: request -- The request made to the server by the client reset_code -- The reset code emailed to the user Required POST parameters: new_password -- The new password for the User Possible Error Codes: 101, 103, 108 Return: Type: JSON Data: A JSON object with a 'status' at the top level. """ # Check that the request was made using POST if request.method != "POST": return JsonResponse(Response.get_error_status(101, AUTH_ERRORS)) # Check that the POST data contains new password if 'new_password' not in request.POST: return JsonResponse(Response.get_error_status(103, AUTH_ERRORS)) # Check that the reset code is registered to a user student_lookup = Student.objects.filter(reset_password_code=reset_code) if len(student_lookup) == 0: return JsonResponse(Response.get_error_status(108, AUTH_ERRORS)) student_account = student_lookup[0] # Change the user's password new_password = request.POST['new_password'] student_account.reset_password_code = None student_account.user.set_password(new_password) student_account.user.save() student_account.save() # Send the user a notification email email_html = render_to_string( 'reset_password_notification_email.html', { 'user': { 'first_name': student_account.user.first_name, 'last_name': student_account.user.last_name } }) text_content = strip_tags(email_html) email = EmailMultiAlternatives('ICBA - Password Changed', text_content, 'ICBA-NO-REPLY', [student_account.user.email]) email.attach_alternative(email_html, 'text/html') email.send() return JsonResponse(Response.get_success_status())
def request_password_reset(request, username): """ Function Summary: This function is used to request a password reset for a User. The user will receive an email containing a reset code if successful. This is only to be used for resetting Student passwords. The reset code is only active for one hour. Path: '/api/auth/request_password_reset/<USERNAME>' Request Type: GET Required Login: False Args: request -- The request made to the server by the client username -- The username provided to request the password reset for Possible Error Codes: 101, 104, 107 Return: Type: JSON Data: A JSON object with a 'status' at the top level. """ # Ensure the API call is using GET method if request.method != "GET": return JsonResponse(Response.get_error_status(101, AUTH_ERRORS)) # Lookup the user with the provided username user_lookup = User.objects.filter(username=username) if len(user_lookup) == 0: return JsonResponse(Response.get_error_status(104, AUTH_ERRORS)) user_account = user_lookup[0] student_account = Student.objects.get(user=user_account) # Check if the student already has a reset code if student_account.reset_password_code is not None: return JsonResponse(Response.get_error_status(107, AUTH_ERRORS)) # Generate a reset code reset_code = generate_reset_code() student_account.reset_password_code = reset_code student_account.save() # Schedule the removal of the reset code after 1 hour expire_reset_code(str(student_account.id), _schedule=timezone.now() + datetime.timedelta(hours=1)) # Render the email template email_html = render_to_string( 'reset_code_email.html', { 'user': { 'first_name': user_account.first_name, 'last_name': user_account.last_name }, 'reset_code': reset_code }) text_content = strip_tags(email_html) # Send the email to the user's email email = EmailMultiAlternatives('ICBA - Reset Code', text_content, 'ICBA-NO-REPLY', [user_account.email]) email.attach_alternative(email_html, 'text/html') email.send() return JsonResponse(Response.get_success_status())
def register(request): """ Function Summary: This function is used to create a new User and Student. Path: '/api/auth/register' Request Type: POST Required Login: False Args: request -- The request made to the server from the client Required POST parameters: username -- The username to be created password -- The password to be created. This will be hashed by the server email -- The email associated with the new account first_name -- The first name on the new account last_name -- The last name on the new account Possible Error Codes: 101, 103, 106 Return: Type: JSON Data: A JSON object with a 'status' at the top level. """ # Make sure the request is using POST to pass data if request.method != "POST": return JsonResponse(Response.get_error_status(101, AUTH_ERRORS)) # Make sure that the POST data contains a username, password, email, first name, and last name if 'username' not in request.POST or 'password' not in request.POST or 'email' not in request.POST \ or 'first_name' not in request.POST or 'last_name' not in request.POST: return JsonResponse(Response.get_error_status(103, AUTH_ERRORS)) # Make sure the username isn't already taken user_lookup = User.objects.filter(username=request.POST['username']) if len(user_lookup) is not 0: return JsonResponse(Response.get_error_status(106, AUTH_ERRORS)) # Validate that the password provided is strong enough try: validate_password(request.POST['password']) except ValidationError: return JsonResponse(Response.get_error_status(111, AUTH_ERRORS)) # Create new user new_user = User.objects.create(username=request.POST['username'], email=request.POST['email'], first_name=request.POST['first_name'], last_name=request.POST['last_name']) new_user.set_password(request.POST['password']) new_user.save() # Create student object new_student = Student.objects.create(user=new_user) new_student.save() # Render the email template email_html = render_to_string( 'welcome_email.html', { 'user': { 'first_name': new_user.first_name, 'last_name': new_user.last_name } }) text_content = strip_tags(email_html) # Send the email to the user's email email = EmailMultiAlternatives('Welcome to ICBA!', text_content, 'ICBA-NO-REPLY', [new_user.email]) email.attach_alternative(email_html, 'text/html') email.send() return JsonResponse(Response.get_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 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)