def list_assignments(db, course_id):
    '''
		GET /api/assignments/<course_id>
		List all assignments for a course (students+instructors)
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    check_course_user(db, course, user)
    assignments = course.assignments
    return json_success(assignments=list(map(lambda x: x.id, assignments)))
def download_assignment(db, course_id, assignment_id):
    '''
		GET /api/assignment/<course_id>/<assignment_id>
		Download a copy of an assignment (students+instructors)
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    check_course_user(db, course, user)
    assignment = find_assignment(db, course, assignment_id)
    list_only = request.args.get('list_only', 'false') == 'true'
    return json_success(files=json_files_pack(assignment.files, list_only))
def submit_assignment(db, course_id, assignment_id):
    '''
		POST /api/submission/<course_id>/<assignment_id>
		Submit a copy of an assignment (students+instructors)
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    check_course_user(db, course, user)
    assignment = find_assignment(db, course, assignment_id)
    submission = Submission(user, assignment)
    json_files_unpack(request.form.get('files'), submission.files)
    db.commit()
    return json_success()
def release_assignment(db, course_id, assignment_id):
    '''
		POST /api/assignment/<course_id>/<assignment_id>
		Release an assignment (instructors only)
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    check_course_instructor(db, course, user)
    if db.query(Assignment).filter(Assignment.id == assignment_id,
                                   Assignment.course == course).one_or_none():
        raise JsonError('Assignment already exists')
    assignment = Assignment(assignment_id, course)
    json_files_unpack(request.form.get('files'), assignment.files)
    db.commit()
    return json_success()
def download_submission(db, course_id, assignment_id, student_id):
    '''
		GET /api/submission/<course_id>/<assignment_id>/<student_id>
		Download a student's submitted assignment (instructors only)
		TODO: maybe allow student to see their own submissions?
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    check_course_instructor(db, course, user)
    assignment = find_assignment(db, course, assignment_id)
    student = find_course_user(db, course, student_id)
    submission = find_student_latest_submission(db, assignment, student)
    list_only = request.args.get('list_only', 'false') == 'true'
    return json_success(files=json_files_pack(submission.files, list_only),
                        timestamp=strftime(submission.timestamp))
def list_submissions(db, course_id, assignment_id):
    '''
		GET /api/submissions/<course_id>/<assignment_id>
		List all submissions for an assignment from all students
		 (instructors only)
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    check_course_instructor(db, course, user)
    assignment = find_assignment(db, course, assignment_id)
    submissions = []
    for submission in assignment.submissions:
        submissions.append({
            'student_id': submission.student.id,
            'timestamp': strftime(submission.timestamp),
            # TODO: "notebooks": [],
        })
    return json_success(submissions=submissions)
def download_feedback(db, course_id, assignment_id, student_id):
    '''
		GET /api/feedback/<course_id>/<assignment_id>/<student_id>
		Download feedback on a student's assignment
		 (instructors+students, students restricted to their own submissions)
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    if user.id != student_id:
        check_course_instructor(db, course, user)
    assignment = find_assignment(db, course, assignment_id)
    student = find_course_user(db, course, student_id)
    if 'timestamp' not in request.args:
        raise JsonError('Please supply timestamp')
    timestamp = strptime(request.args.get('timestamp'))
    submission = find_student_submission(db, assignment, student, timestamp)
    list_only = request.args.get('list_only', 'false') == 'true'
    return json_success(files=json_files_pack(submission.feedbacks, list_only),
                        timestamp=strftime(submission.timestamp))
def upload_feedback(db, course_id, assignment_id, student_id):
    '''
		POST /api/feedback/<course_id>/<assignment_id>/<student_id>
		Upload feedback on a student's assignment (instructors only)
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    check_course_instructor(db, course, user)
    assignment = find_assignment(db, course, assignment_id)
    student = find_course_user(db, course, student_id)
    if 'timestamp' not in request.form:
        raise JsonError('Please supply timestamp')
    timestamp = strptime(request.form.get('timestamp'))
    submission = find_student_submission(db, assignment, student, timestamp)
    submission.feedbacks.clear()
    # TODO: does this automatically remove the files?
    json_files_unpack(request.form.get('files'), submission.feedbacks)
    db.commit()
    return json_success()
def list_student_submission(db, course_id, assignment_id, student_id):
    '''
		GET /api/submissions/<course_id>/<assignment_id>/<student_id>
		List all submissions for an assignment from a particular student 
		 (instructors+students, students restricted to their own submissions)
	'''
    user = get_user(db)
    course = find_course(db, course_id)
    if user.id != student_id:
        check_course_instructor(db, course, user)
    assignment = find_assignment(db, course, assignment_id)
    student = find_course_user(db, course, student_id)
    submissions = []
    for submission in find_student_submissions(db, assignment, student):
        submissions.append({
            'student_id': submission.student.id,
            'timestamp': strftime(submission.timestamp),
            # TODO: "notebooks": [],
        })
    return json_success(submissions=submissions)