Ejemplo n.º 1
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
Ejemplo n.º 2
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
Ejemplo n.º 3
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
def download_blob(filename, actual_filename):
    storage_client = storage.Client()
    bucket = storage_client.bucket("gradder-storage")
    blob = bucket.blob(filename)
    blob.download_to_filename(actual_filename)

    logger.info(f"File {actual_filename} - {filename}  downloaded")
Ejemplo n.º 5
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
def get_signed_url(filename):
    storage_client = storage.Client()
    bucket = storage_client.get_bucket("gradder-storage")
    blob = bucket.get_blob(filename)

    logger.info(f"File {filename} opened from assignment")

    return blob.generate_signed_url(expiration=datetime.utcnow() +
                                    timedelta(seconds=3600))
Ejemplo n.º 7
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()})
def upload_blob(filename: str, file_obj):
    storage_client = storage.Client()
    bucket = storage_client.bucket("gradder-storage")
    blob = bucket.blob(filename)
    blob.upload_from_file(file_obj, content_type=file_obj.content_type)

    logger.info(f"File {filename} uploaded")

    return blob
Ejemplo n.º 9
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
Ejemplo n.º 10
0
    def get_by_email(email: str) -> Teacher:
        r"""Returns Teacher with a specified email.

        Parameters
        ---------
        email : str

        Returns
        ------
        Teacher
        """
        try:
            return Teacher.from_dict(db.teachers.find_one({"email": email}))
        except:
            logger.info(f"Error when returning Teacher by email {email}")
Ejemplo n.º 11
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})
Ejemplo n.º 12
0
    def to_dict(self) -> Dict[str, str]:
        r"""Converts the object to a dictionary."""
        dictionary = {
            "email": self.email,
            "first_name": self.first_name,
            "last_name": self.last_name,
            "password": self.password,
            "activated": self.activated,
        }

        try:
            dictionary["_id"] = ObjectId(self.id)
        except Exception:
            logger.info("This user has not been initialized yet.")

        return dictionary
Ejemplo n.º 13
0
    def get_by_id(id: str) -> Teacher:
        r"""Returns a Teacher object with a specified id.

        Parameters
        ---------
        id : str
            ID to look up in the database

        Returns
        -------
        Teacher
        """
        try:
            return Teacher.from_dict(
                db.teachers.find_one({"_id": ObjectId(id)}))
        except:
            logger.info(f"Error when returning Teacher by id {id}")
Ejemplo n.º 14
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})
Ejemplo n.º 15
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
Ejemplo n.º 16
0
def manage_courses_by_id(course_id: str):
    """Provides options to edit the course.
    Returns
    -------
    dict
        Flashes, course data from the form
    """

    flashes = list()

    course = Course.get_by_id(course_id)
    if course:
        if request.form.get("file"):
            syllabus_file = request.form["file"]
            filename = syllabus_file.filename
            blob = upload_blob(
                uuid.uuid4().hex + "." +
                syllabus_file.content_type.split("/")[-1],
                syllabus_file,
            )
            syllabus = (blob.name, filename)
            course.update_syllabus(syllabus)
            logger.info(f"Course {course._id} updated")
        Course.update(
            request.form.get("department"),
            request.form.get("number"),
            request.form.get("name"),
            request.form.get("teacher"),
            request.form.get("teacher"),
            request.form.get("description"),
            request.form.get("schedule_time"),
            request.form.get("schedule_days"),
            request.form.get("syllabus"),
            request.form.get("student"),
        )
        flashes.append("Course information successfully updated!")
        return response(flashes), 200
    else:
        return error("Course does not exist"), 404
Ejemplo n.º 17
0
def enter_info():
    """Enters description, date of birth and profile picture for student

    Returns
    -------
    dict
        Flashes, student data from the form
    """

    flashes = list()
    user = Student.get_by_id(current_user.id)

    if request.form.get("description"):
        user.description = request.form["description"]
        flashes.append("Description updated")

    if request.form.get("date_of_birth"):
        user.date_of_birth = request.form["date_of_birth"]
        flashes.append("Date of birth updated")

    try:
        profile_picture_file = request.files["profile_picture"]
        filename = profile_picture_file.filename
        blob = upload_blob(
            uuid.uuid4().hex + "." +
            profile_picture_file.content_type.split("/")[-1],
            profile_picture_file,
        )
        profile_picture = (blob.name, filename)

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

    user.profile_picture = profile_picture
    flashes.append("Profile picture updated")

    logger.info(f"User info {user.id} updated")
    return response(flashes), 200
Ejemplo n.º 18
0
def login():
    """Login endpoint. Handles user logins with LoginForm

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

    if current_user.is_authenticated:
        logger.info(f"The user {current_user.id} is already authenticated.")
        # TODO: this should definitely be a method in a class
        current_user_info = {
            "userName": current_user.first_name + " " + current_user.last_name,
            "userType": current_user._type,
            "loggedIn": True,
            "dob": "",
        }
        return response(user_info=current_user_info), 200
    elif request.method == "GET":
        # If it's a GET (i.e., a user hasn't entered any info yet, the user is not logged in)
        logger.info("The user is not logged in.")
        return response(user_info={"loggedIn": False}), 200

    try:
        req_data = request.get_json()
        email = req_data["email"].lower()
        password = req_data["password"]
        remember_me = req_data["remember_me"]

        for scope in [Student, Teacher, Admin, Parent]:
            logger.info(
                f"Trying to find {scope.__name__} with email {email}...")
            user = scope.get_by_email(email)
            if user is not None:
                logger.info(f"User: {user.first_name}")
                if user.validate_password(password):
                    login_user(user, remember_me)
                    logger.info(
                        f"LOGGED IN: {user.first_name} {user.last_name} - ACCESS: {user._type}"
                    )

                    current_user_info = {
                        "userName":
                        current_user.first_name + " " + current_user.last_name,
                        "userType": current_user._type,
                        "loggedIn": True,
                        "dob": "",
                    }
                    return (
                        response(
                            flashes=[
                                "Log in succesful! Redirecting to dashboard..."
                            ],
                            user_info=current_user_info,
                        ),
                        200,
                    )

                logger.info(
                    f"Failed to validate the password for the {scope.__name__} with email {email}"
                )
                return error("Invalid password,"), 400

            logger.info(f"Could not find {str(scope)} with email {email}")

        logger.info(f"Could not find any users with email {email}")
        return error("The user with this email does not exist."), 400
    except (KeyError, TypeError):
        logger.info("Not all fields satisfied")
        return error("Not all fields satisfied"), 400
Ejemplo n.º 19
0
def manage_classes_by_id(course_id: str):
    """Updates a specified course's information

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

    Returns
    -------
    dict
        Class data (id and name)
        Current class description
    """
    course = Course.get_by_id(course_id)
    syllabus_name = course.get_syllabus_name()

    try:
        syllabus = []
        if request.form and request.files:
            syllabus_file = request.files["syllabus_file"]
            syllabus_name = request.form.get("syllabus_name")
            description = request.form.get("description")

            if syllabus_file is not None:

                blob = upload_blob(
                    uuid.uuid4().hex + "." +
                    syllabus_file.content_type.split("/")[-1],
                    syllabus_file,
                )
                syllabus = [blob.name, syllabus_name]

                course.update_description(description)
                course.update_syllabus(syllabus)

                logger.info(f"Syllabus updated")
                return response(
                    flashes=["Course information successfully updated!"])

            else:
                print("Specify syllabus information")
                return error("Please specify the syllabus information"), 400

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

    courses = []
    for course_id in current_user.courses:
        course_data = {
            "id": str(course_id),
            "name": Course.get_by_id(course_id).name,
        }
        courses.append(course_data)

    return response(
        flashes=["Course information successfully updated!"],
        data={
            "courses": courses,
            "current_description": course.description
        },
    )