예제 #1
0
def activate_account(token: str):
    """Activates the account (while not authenticated)

    Parameters
    ----------
    token : str
        The activation token

    Returns
    -------
    dict
        The view response
    """
    student = Student.verify_activation_token(token)
    if student is None:
        return error("That is an expired or incorrect link."), 400
    else:
        if request.form["password_confirmation"] == request.form["password"]:
            if student.activate() and student.set_password(
                    request.form["password"]):
                logger.info(f"Student {student._id} activated their account")
                return response(["Account activated!", "Password set!"]), 200
            else:
                return error("Unknown error while activating account"), 400

        else:
            return response(["Passwords don't match!"]), 400
        db.students.update({"id": ObjectId(student._id)},
                           {"$set": {
                               "activated": True
                           }})
        return response(["Account activated!"]), 200
예제 #2
0
def register_courses():
    """Adds a course to the system.
    Returns
    -------
    dict
        Flashes, course data from the form
    """

    flashes = list()

    try:
        if Course.get_by_department_number(request.form["number"]):
            course = Course(request.form["department"], request.form["number"],
                            request.form["name"])
        else:
            return error("Course already exists"), 400
    except KeyError:
        return error("Not all fields satisfied."), 400

    if Admin.add_course(course=course):
        logger.info(f"Course {request.form['number']} added")
        flashes.append("Course added!")
        return response(flashes), 200
    else:
        flashes.append("There was a problem adding your course")
        return response(flashes), 400
예제 #3
0
def get_calendar_events():
    """Gets dictionary of calendar events for teacher

    Returns
    -------
    dict
        The view response
    """

    req_data = request.get_json()
    if req_data:
        title = req_data["title"]
        start = req_data["start"]
        end = req_data["end"]
        color = req_data["color"]
        url = req_data["url"]

        newEvent = {
            "title": title,
            "start": start,
            "end": end,
            "color": color,
            "url": url,
        }

        teacherDict = current_user.to_dict()
        teacher = Teacher.get_by_email(teacherDict["email"])
        current_user.add_calendar_event(teacher.id, newEvent)

    events = current_user.get_calendar()
    return response(data={"events": events})
예제 #4
0
def add_assignment():
    """Adds new assignment for the class

    Returns
    -------
    dict
        The view response
    """
    request.form["assigned_to"].choices = current_user.get_class_names()

    try:
        file_list = get_existing_assignment_files()

        new_assignment = Assignment(
            date_assigned=datetime.utcnow(),
            assigned_by=current_user.ID,
            assigned_to=request.form["assigned_to"],
            due_by=request.form["due_by"],
            title=request.form["title"],
            content=request.form["content"],
            filenames=file_list,
            estimated_time=request.form["estimated_time"],
            # weight=request.form['weight']
        )

        Course.get_by_id(
            request.form["assigned_to"]).add_assignment(new_assignment)

        logger.info(f"Assignment {request.form['title']} added")
        return response(flashes=["Assignment sent!"])

    except KeyError:
        return error("Not all fields satisfied"), 400
예제 #5
0
def get_info_for_new_course():
    """Gets department and teacher info for adding a new course to the database.
    Returns
    -------
    dict
        Flashes, department and teacher data from the database
    """

    flashes = list()

    try:
        departments = db.courses.find({}, {"department": 1, "_id": 0})
        teachers = db.courses.find({}, {
            "name": 1,
            "email": 1,
            "department": 1,
            "_id": 0
        })
    except:
        return (
            error(
                "Unknown error while getting info for departments and teachers"
            ),
            400,
        )

    return response(flashes, {
        "departments": departments,
        "teachers": teachers
    }), 200
예제 #6
0
def password_reset(token: str):
    """Resets the password (while not authenticated)

    Parameters
    ----------
    token : str
        The reset token

    Returns
    -------
    dict
        The view response
    """
    if current_user.is_authenticated:
        return error(
            f"Wrong route, use {url_for('auth.change_password')}."), 303

    user = User.verify_reset_token(token)
    if user is None:
        return error("That is an expired or incorrect link."), 410

    user = User.from_dict(user)
    try:
        new_password = request.form["new_password"]
        user.password = new_password

        if not user.add():
            return error("Unknown error while changing the password."), 500
    except KeyError:
        return error("Not all fields satisfied"), 400
    else:
        return response(["Password changed"]), 200
예제 #7
0
def get_schedule_assignments():
    """Gets name and dates for assignments

    Returns
    -------
    dict
        The view response
    """

    assignments = current_user.get_assignments()
    events = []
    for assignment in assignments:
        assignment_data = {
            "title": assignment.title,
            "date": assignment.due_by
        }
        events.append(assignment_data)

    # Dummy event for testing
    dummy_data = [{
        "title": "Test assignment",
        "date": "2020-08-09",
    }]
    events.append(dummy_data)

    return response(data={"events": events})
예제 #8
0
def view_submissions_by_assignment(course_id: str, assignment_id: str):
    """Collects all submissions for a specific assignment of a class

    Parameters
    -------
    course_id: str
        The course ID to look up in the database

    assignment_id: str
        The assignment ID to look up in the database

    Returns
    -------
    dict
        Assignment submissions
    """
    course = Course.get_by_id(course_id)
    assignments = course.get_assignments()

    assignment: Assignment = list(
        filter(lambda a: str(a.id) == assignment_id, assignments))[0]

    if assignment is None:
        return error("Could not find assignment"), 400

    else:
        return response(data={"submissions": assignment.submissions})
예제 #9
0
def manage_courses():
    """Returns a list of all courses in the school.
    Returns
    -------
    dict
        All course data
    """
    return response({"courses": Admin.get_courses()}), 200
예제 #10
0
def edit_assignment(course_id: str, assignment_id: str):
    """Edits assignment for the class

    Parameters
    -------
    course_id: str
        The course ID to look up in the database

    assignment_id: str
        The assignment ID to look up in the database

    Returns
    -------
    dict
        Edited assignment data
    """

    course = Course.get_by_id(course_id)
    assignments = course.get_assignments()

    assignment: Assignment = list(
        filter(lambda a: str(a.id) == assignment_id, assignments))[0]

    if assignment is None:
        return error("Could not find assignment"), 400

    try:
        file_list = get_existing_assignment_files()

        edited_assignment = Assignment(
            date_assigned=assignment.date_assigned,
            assigned_by=assignment.assigned_by,
            assigned_to=request.form["assigned_to"],
            due_by=request.form["due_by"],
            title=request.form["title"],
            content=request.form["content"],
            filenames=file_list,
            estimated_time=request.form["estimated_time"],
            # weight=request.form['weight']
        )
        edited_assignment.id = assignment.id
        course.edit_assignment(edited_assignment)
        # Assign to 'assignment' so form has new details
        assignment = edited_assignment

    except KeyError:
        return error("Not all fields satisfied"), 400

    # Set default values for form.
    request.form["assigned_to"].default = assignment.assigned_to
    request.form["due_by"].default = assignment.due_by
    request.form["estimated_time"].default = assignment.estimated_time
    request.form["title"].default = assignment.title
    request.form["content"].default = assignment.content
    # request.form['weight'].default = assignment.weight
    request.files.default = assignment.filenames

    return response(data={"assignment": assignment.to_json()})
예제 #11
0
def submit(course_id: str, assignment_id: str):
    """Submit work for an assignment
    Parameters
    ----------
    course_id : str
        The ID of the class for which the assignment was set
    assignment_id : str
        The ID of the assignment
    Returns
    -------
    dict
        The view response
    """

    assignment = db.courses.find_one(
        {"assignments._id": ObjectId(assignment_id)},
        {
            "_id": 0,
            "assignments": {
                "$elemMatch": {
                    "_id": ObjectId(assignment_id)
                }
            }
        },
    )["assignments"][0]

    if assignment is not None and course_id in current_user.courses:
        try:
            file_list = []
            files = request.files.getlist("files")
            if files[0].filename:
                for file_ in files:
                    filename = file_.filename
                    blob = upload_blob(
                        uuid.uuid4().hex + "." +
                        file_.content_type.split("/")[-1],
                        file_,
                    )
                    file_list.append((blob.name, filename))

            submission = Submission(
                date_submitted=datetime.utcnow(),
                content=request.form["content"],
                filenames=file_list,
                student_id=current_user.id,
                assignment_id=assignment_id,
            )

            current_user.add_submission(current_user.id,
                                        course_id,
                                        submission=submission)
        except KeyError:
            return error("Not all fields satisfied"), 400
        else:
            logger.info(f"Submission {submission.id} made")
            return response(["Submission was a success"]), 200
    else:
        return error("No assignment found"), 404
예제 #12
0
def assignments():
    """Get all assignments for the signed in user
    Returns
    -------
    dict
        The view response
    """
    logger.info("Accessed all assignments")
    return response(data={"assignments": current_user.get_assignments()})
예제 #13
0
def add_student():
    """Adds a student account to the system and sends an activation email.
    Returns
    -------
    dict
        Flashes, student data from the form
    """

    flashes = list()

    try:
        if not Student.get_by_email(request.form["email"]):
            student = Student(
                request.form["email"],
                request.form["first_name"],
                request.form["last_name"],
            )
            student.password(request.form["password"])
    except KeyError:
        return error("Not all fields satisfied"), 400

    if student.add():
        flashes.append("Student added!")
        logger.info(f"Student {student.email} added")
        token = current_user.get_activation_token()
        app = current_app._get_current_object()
        msg = Message(
            app.config["MAIL_SUBJECT_PREFIX"] + " " +
            "Account Activation Link",
            sender=app.config["MAIL_SENDER"],
            recipients=[student.email],
        )
        msg.body = f"""Here is your account activation link:
            { url_for('student.activate_account', token=token, _external=True) }
            If you did not register for this account, you can ignore this email. If you need any further assistance, please contact [email protected].
            """
        mail.send(msg)
        return response(flashes), 200
    else:
        logger.info(f"Error adding Student {student.email}")
        flashes.append("There was a problem adding this account"), 400
        return response(flashes), 400
예제 #14
0
def student_search_info():
    r"""This method is called when the user clicks on a result on the search bar
    Returns
    -------
    dict
        Flashes, student data
    """
    try:
        return response(None, Student.get_by_id(request.form["user_id"])), 200
    except:
        return error("There was a problem finding this user"), 404
예제 #15
0
def logout():
    """Logout the user

    Returns
    -------
    dict
        The view response
    """
    logger.info("LOGGED OUT: {} {} - ACCESS: {}".format(
        current_user.first_name, current_user.last_name, current_user._type))
    logout_user()
    return response(["You have been logged out"]), 200
예제 #16
0
def add_student_to_parent():
    r"""Adds a student to a parent.
    Returns
    -------
    dict
        Flashes
    """

    if Admin.add_student_to_parent(request.form["parent_id"],
                                   request.form["student_id"]):
        return response(["Added student to parent"]), 200
    else:
        return error("There was an error adding this student"), 400
예제 #17
0
def add_teacher_to_course():
    """Adds a teacher to a course.
    Returns
    -------
    dict
        Flashes, teacher data from the form
    """

    flashes = list()

    try:
        if Teacher.get_by_email(request.form["email"]):
            Admin.add_teacher(
                Course.get_by_department_number(request.form["number"])._id,
                request.form["email"],
            )
        else:
            flashes.append("Account doesn't exist!")
            return response(flashes), 400

    except KeyError:
        return response(flashes), 400
예제 #18
0
def remove_student_from_parent():
    r"""Removes a student from a parent.
    Returns
    -------
    dict
        Flashes
    """

    if Admin.remove_student_from_parent(request.form["parent_id"],
                                        request.form["student_id"]):
        return response(["Removed student from parent"]), 200
    else:
        return error("There was an error removing this student"), 400
예제 #19
0
def assignments_by_class(course_id: str):
    """Get assignments for a specific class
    Parameters
    ----------
    course_id : str
        The ID of the class
    Returns
    -------
    dict
        The view response
    """

    course_assignments = Course.get_by_id(course_id).get_assignments()
    logger.info(f"All assignments from {course_id}.")
    return response(data={"assignments": course_assignments})
예제 #20
0
def mark_submission(course_id: str, assignment_id: str, submission_id: str):
    flashes = []

    course = Course.get_by_id(course_id)
    assignments = course.get_assignments()
    assignment: Assignment = get(assignments, id=assignment_id)
    submission: Submission = get(assignment.submissions, id=submission_id)

    min_, max_ = course.grade_range
    if min_ < request.form["grade"] < max_:
        submission.update_grade(request.form["grade"])
        flashes.append("Grade updated!")
        return response(flashes), 200

    return error("Grade outside course grade boundary")
예제 #21
0
def get_course_info(course_id: str):
    """Gets all info for course.
    Returns
    -------
    dict
        Flashes, all course info
    """

    flashes = list()

    try:
        course_info = db.courses.find({"_id": ObjectId(course_id)})
    except:
        return error("Unknown error while getting course info"), 400

    return response(flashes, {"course_info": course_info}), 200
예제 #22
0
def get_names_by_search():
    """Shows full names of people the user is searching
    Returns
    -------
    dict
        Admin names
    """
    try:
        admins = Admin.get_by_keyword(request.form["first_name"])
        possible_admins = list()
        for admin in admins:
            admin_data = {
                "full_name": admin.first_name + " " + admin.last_name,
            }
            possible_admins.append(admin_data)
        return response(data={"possible_admins": possible_admins}), 200
    except:
        return error("There are no admins by that name"), 404
예제 #23
0
def get_names_by_search():
    """Shows full names of people the user is searching
    Returns
    -------
    dict
        Teacher names
    """
    try:
        teachers = Teacher.get_by_keyword(request.form["first_name"])
        possible_teachers = list()
        for teacher in teachers:
            teacher_data = {
                "full_name": teacher.first_name + " " + teacher.last_name,
            }
            possible_teachers.append(teacher_data)
        return response(data={"possible_teachers": possible_teachers}), 200
    except:
        return error("There are no teachers by that name"), 404
예제 #24
0
def get_names_by_search():
    """Shows full names of people the user is searching
    Returns
    -------
    dict
        Student names
    """
    try:
        students = Student.get_by_keyword(request.form["first_name"])
        possible_students = list()
        for student in students:
            student_data = {
                "full_name": student.first_name + " " + student.last_name,
            }
            possible_students.append(student_data)
        return response(data={"possible_students": possible_students}), 200
    except:
        return error("There are no students by that name"), 404
예제 #25
0
def delete_calendar_events():
    """Gets dictionary of calendar events for teacher

    Returns
    -------
    dict
        The view response
    """

    req_data = request.get_json()

    if req_data:
        title = req_data["title"]
        teacherDict = current_user.to_dict()
        teacher = Teacher.get_by_email(teacherDict["email"])
        current_user.remove_calendar_event(teacher.id, title)

    events = current_user.get_calendar()
    return response(data={"events": events})
예제 #26
0
def assignment_by_id(course_id: str, assignment_id: str):
    """Get an assignment by its ID
    Parameters
    ----------
    course_id : str
        The ID of the class
    assignment_id : str
        The ID of the assignment
    Returns
    -------
    dict
        The view response
    """
    assignments = current_user.get_assignments()
    assignment = get(assignments, id=assignment_id)
    logger.info(
        f"All assignments from {course_id} with assignment id {assignment_id}."
    )
    return response(data={"assignment": assignment})
예제 #27
0
def view_assignment_by_class_id(course_id: str):
    """Collects assignments from a specific class

    Parameters
    -------
    class_id: str
        The class ID to look up in the database

    Returns
    -------
    dict
        The specified class and its respective data (id, name, and assignments)
    """
    course_assignments = Course.get_by_id(course_id).get_assignments()

    return response(
        data={
            "assignments": list(map(lambda a: a.to_dict(), course_assignments))
        })
예제 #28
0
def request_password_reset():
    """Request a password reset (while not authenticated)

    Returns
    -------
    dict
        The view response
    """
    if current_user.is_authenticated:
        return error(
            f"Wrong route, use {url_for('auth.change_password')}."), 303

    try:
        email = request.form["email"].lower()
        send_reset_email(User.from_dict(User.get_by_email(email)))
    except KeyError:
        return error("Not all fields satisfied"), 400
    else:
        return response(["An email has been sent to reset your password."
                         ]), 200
예제 #29
0
def change_password():
    """Changes the user password (while authenticated)

    Returns
    -------
    dict
        The view response
    """

    try:
        new_password = request.form["new_password"]

        current_user.password = new_password

        # TODO: I think this should definitely be update, not add, because add() can potentially add a new one
        if not current_user.add():
            return error("Unknown error while changing the password."), 500
    except KeyError:
        return error("Not all fields satisfied"), 400
    else:
        return response(["Password changed"]), 200
예제 #30
0
def get_schedule_classes():
    """Gets name, dates, and times for classes

    Returns
    -------
    dict
        The view response
    """

    student_course_ids = current_user.get_course_ids()
    class_schedule = list()
    for student_course in student_course_ids:
        data = Course.get_by_id(student_course)
        course_data = {
            "name": data.name,
            "daysOfWeek": data.schedule_days,
            "startTime": data.schedule_time,
        }
        class_schedule.append(course_data)

    return response(data={"class_schedule": class_schedule})