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()
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()
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()
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 )
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)