Exemplo n.º 1
0
def _delete_assignments(ids, delete_class):
    if delete_class:
        delete_class = ObjectId(delete_class)

    # Convert all of the IDs we were given to ObjectIDs in one go
    ids = [ObjectId(i) for i in ids]

    logger.info("Deleting assignments %s.", str(ids))

    # Query the database for all the assignments we are supposed to delete
    assignments = list(Assignment.objects(id__in = ids))

    # Query the database for all the submissions we are supposed to delete, this
    # will potentially be an absolutely massive list, so we do not want to
    # place all the results into a list immediately like we did for the
    # assignments.
    submissions = Submission.objects(assignment__in = ids)

    # Delete assignments directory on the filesystem
    for i in assignments:
        try:
            shutil.rmtree(
                os.path.join(config["SUBMISSION_DIRECTORY"], str(i.id))
            )
        except OSError as e:
            # We don't want to explode if the directory has been deleted for us
            # but it is weird so log a warning.
            if e.errno == errno.ENOENT:
                logger.warning("Assignment directory missing for %s",
                    str(i.id))
            else:
                raise

    # Actually delete the submissions from the database
    Submission.objects(assignment__in = ids).delete()

    # Delete the assignments
    Assignment.objects(id__in = ids).delete()

    if delete_class:
        # Unenroll all students in the class
        User.objects(classes = delete_class).update(
            pull__classes = delete_class
        )

        # Delete the class
        Class.objects(id = delete_class).delete()
Exemplo n.º 2
0
def _delete_assignments(ids, delete_class):
    if delete_class:
        delete_class = ObjectId(delete_class)

    # Convert all of the IDs we were given to ObjectIDs in one go
    ids = [ObjectId(i) for i in ids]

    logger.info("Deleting assignments %s.", str(ids))

    # Query the database for all the assignments we are supposed to delete
    assignments = list(Assignment.objects(id__in = ids))

    # Query the database for all the submissions we are supposed to delete, this
    # will potentially be an absolutely massive list, so we do not want to
    # place all the results into a list immediately like we did for the
    # assignments.
    submissions = Submission.objects(assignment__in = ids)

    # Delete assignments directory on the filesystem
    for i in assignments:
        try:
            shutil.rmtree(
                os.path.join(config["SUBMISSION_DIRECTORY"], str(i.id))
            )
        except OSError as e:
            # We don't want to explode if the directory has been deleted for us
            # but it is weird so log a warning.
            if e.errno == errno.ENOENT:
                logger.warning("Assignment directory missing for %s",
                    str(i.id))
            else:
                raise

    # Actually delete the submissions from the database
    Submission.objects(assignment__in = ids).delete()

    # Delete the assignments
    Assignment.objects(id__in = ids).delete()

    if delete_class:
        # Unenroll all students in the class
        User.objects(classes = delete_class).update(
            pull__classes = delete_class
        )

        # Delete the class
        Class.objects(id = delete_class).delete()
Exemplo n.º 3
0
def _delete_assignments(ids, delete_class):
    if delete_class:
        delete_class = ObjectId(delete_class)

    # Convert all of the IDs we were given to ObjectIDs in one go
    ids = [ObjectId(i) for i in ids]

    logger.debug("Deleting assignments %s.", ids)

    # Query the database for all the assignments we are supposed to delete
    assignments = list(Assignment.objects(id__in = ids))

    # Query the database for all the submissions we are supposed to delete, this
    # will potentially be an absolutely massive list, so we do not want to
    # place all the results into a list immediately like we did for the
    # assignments.
    submissions = Submission.objects(assignment__in = ids)

    # Go through all of the submissions and delete the files from the
    # filesystem. We will tell the database to delete all of the submissions
    # in one go afterwards.
    for i in submissions:
        # Delete the submission on the filesystem.
        try:
            shutil.rmtree(
                os.path.join(config["SUBMISSION_DIRECTORY"], str(i.id))
            )
        except OSError as e:
            logger.warn(
                "Failed to delete submission with id %s: %s", str(i.id), str(e)
            )

    # Actually delete the submissions from the database
    Submission.objects(assignment__in = ids).delete()

    # Delete the assignments
    Assignment.objects(id__in = ids).delete()

    if delete_class:
        # Unenroll all students in the class
        User.objects(classes = delete_class).update(
            pull__classes = delete_class
        )

        # Delete the class
        Class.objects(id = delete_class).delete()
Exemplo n.º 4
0
def _delete_assignments(ids, delete_class):
    if delete_class:
        delete_class = ObjectId(delete_class)

    # Convert all of the IDs we were given to ObjectIDs in one go
    ids = [ObjectId(i) for i in ids]

    logger.debug("Deleting assignments %s.", ids)

    # Query the database for all the assignments we are supposed to delete
    assignments = list(Assignment.objects(id__in=ids))

    # Query the database for all the submissions we are supposed to delete, this
    # will potentially be an absolutely massive list, so we do not want to
    # place all the results into a list immediately like we did for the
    # assignments.
    submissions = Submission.objects(assignment__in=ids)

    # Go through all of the submissions and delete the files from the
    # filesystem. We will tell the database to delete all of the submissions
    # in one go afterwards.
    for i in submissions:
        # Delete the submission on the filesystem.
        try:
            shutil.rmtree(
                os.path.join(config["SUBMISSION_DIRECTORY"], str(i.id)))
        except OSError as e:
            logger.warn("Failed to delete submission with id %s: %s",
                        str(i.id), str(e))

    # Actually delete the submissions from the database
    Submission.objects(assignment__in=ids).delete()

    # Delete the assignments
    Assignment.objects(id__in=ids).delete()

    if delete_class:
        # Unenroll all students in the class
        User.objects(classes=delete_class).update(pull__classes=delete_class)

        # Delete the class
        Class.objects(id=delete_class).delete()
Exemplo n.º 5
0
def browse_assignments():
    # Grab all the current user's classes
    classes = Class.objects(id__in = current_user.classes).only("name")
    
    # Get the current time so we don't have to do it over and over again.
    now = datetime.datetime.today()

    if "show_all" in request.args:
        assignments = list(Assignment.objects(
            Q(for_class__in = current_user.classes) &
            (Q(hide_until = None) | Q(hide_until__lt = now))
        ).only("name", "due", "due_cutoff", "for_class"))
    else:
        assignments = list(Assignment.objects(
            Q(for_class__in = current_user.classes) &
            (Q(due__gt = now - datetime.timedelta(weeks = 1)) |
            Q(due_cutoff__gt = now - datetime.timedelta(weeks = 1))) &
            (Q(hide_until = None) | Q(hide_until__lt = now))
        ).only("name", "due", "due_cutoff", "for_class"))

    assignments = [i for i in assignments if
            not i.hide_until or i.hide_until < now]

    # Get the number of assignments that we could have gotten if we didn't
    # limit based on due date.
    all_assignments_count = Assignment.objects(
        Q(for_class__in = current_user.classes) &
        (Q(hide_until = None) | Q(hide_until__lt = now))
    ).count()

    submissions = list(Submission.objects(
        user = current_user.email,
        assignment__in = [i.id for i in assignments],
        most_recent = True
    ))

    # Add a property to all the assignments so the template can display their
    # respective class easier. Additionally, add a plain text version of the
    # due date
    for i in assignments:
        try:
            i.class_name = next((j.name for j in classes if j.id == i.for_class))
        except StopIteration:
            logger.error(
                "Assignment with id %s references non-existant class with id "
                "%s." % (str(i.id, i.for_class))
            )
            
            i.class_name = "DNE"

        # Figure out the status messages that we want to display to the user.
        submitted = next((j for j in submissions if j.assignment == i.id), None)
        i.status = i.status_color = None
        if submitted:
            i.status = (
                "You made a submission " +
                create_time_element(submitted.timestamp, now)
            )

            i.status_color = "#84B354"
        elif now < i.due:
            i.status = "You have not submitted yet"

            i.status_color = "#877150"
        elif now > i.due and i.due_cutoff and now > i.due_cutoff:
            i.status = "You have not submitted yet, and it is too late to do so"

            i.status_color = "#E9A400"
        elif now > i.due:
            i.status = "You have not submitted yet!"

            i.status_color = "#FB4313"

    # Sort the assignments by due_cutoff or due date if due_cutoff is not
    # assigned.
    assignments.sort(
        key = lambda i: i.due_cutoff if i.due_cutoff else i.due,
        reverse = True
    )

    return render_template(
        "assignments.html",
        assignments = assignments,
        hidden_assignments = -1 if "show_all" in request.args
                else all_assignments_count - len(assignments),
        create_time_element = create_time_element
    )
Exemplo n.º 6
0
def browse_assignments():
    # Grab all the current user's classes
    classes = Class.objects(id__in=current_user.classes).only("name")

    # Get the current time so we don't have to do it over and over again.
    now = datetime.datetime.today()

    if "show_all" in request.args:
        assignments = list(
            Assignment.objects(
                Q(for_class__in=current_user.classes)
                & (Q(hide_until=None) | Q(hide_until__lt=now))).only(
                    "name", "due", "due_cutoff", "for_class"))
    else:
        assignments = list(
            Assignment.objects(
                Q(for_class__in=current_user.classes)
                & (Q(due__gt=now - datetime.timedelta(weeks=1))
                   | Q(due_cutoff__gt=now - datetime.timedelta(weeks=1)))
                & (Q(hide_until=None) | Q(hide_until__lt=now))).only(
                    "name", "due", "due_cutoff", "for_class"))

    assignments = [
        i for i in assignments if not i.hide_until or i.hide_until < now
    ]

    # Get the number of assignments that we could have gotten if we didn't
    # limit based on due date.
    all_assignments_count = Assignment.objects(
        Q(for_class__in=current_user.classes)
        & (Q(hide_until=None) | Q(hide_until__lt=now))).count()

    submissions = list(
        Submission.objects(assignment__in=[i.id for i in assignments],
                           most_recent=True))

    # Add a property to all the assignments so the template can display their
    # respective class easier. Additionally, add a plain text version of the
    # due date
    for i in assignments:
        try:
            i.class_name = next(
                (j.name for j in classes if j.id == i.for_class))
        except StopIteration:
            app.logger.error("Assignment with id %s references non-existant "
                             "class with id %s." % (str(i.id, i.for_class)))

            i.class_name = "DNE"

        # Figure out the status messages that we want to display to the user.
        submitted = next((j for j in submissions if j.assignment == i.id),
                         None)
        i.status = i.status_color = None
        if submitted:
            i.status = ("You made a submission " +
                        create_time_element(submitted.timestamp, now))

            i.status_color = "#84B354"
        elif now < i.due:
            i.status = "You have not submitted yet"

            i.status_color = "#877150"
        elif now > i.due and i.due_cutoff and now > i.due_cutoff:
            i.status = "You have not submitted yet, and it is too late to do so"

            i.status_color = "#E9A400"
        elif now > i.due:
            i.status = "You have not submitted yet!"

            i.status_color = "#FB4313"

    # Sort the assignments by due_cutoff or due date if due_cutoff is not
    # assigned.
    assignments.sort(key=lambda i: i.due_cutoff if i.due_cutoff else i.due,
                     reverse=True)

    return render_template("assignments.html",
                           assignments=assignments,
                           hidden_assignments=-1 if "show_all" in request.args
                           else all_assignments_count - len(assignments),
                           create_time_element=create_time_element)