Source code for abcclassroom.feedback

"""
abc-classroom.feedback
======================
"""

from pathlib import Path
import csv
import shutil

from . import config as cf
from . import git as abcgit

# or import just the function we need?
from . import scrub_feedback as sf


[docs]def copy_feedback_files(assignment_name, push_to_github=False, scrub=False): """Copies feedback reports to local student repositories, commits the changes, and (optionally) pushes to github. Assumes files are in the directory course_materials/feedback/student/assignment. Copies all html files in the source directory. Parameters ----------- assignment_name: string Name of the assignment for which feedback is being processed. push_to_github: boolean (default = False) ``True`` if you want to automagically push feedback to GitHub after committing changes scrub: boolean If true, and we are moving an html file this will clean the html file before copying it over. Returns ------- Moves feedback html files from the student feedback directory to the cloned_repos directory. Will commit to git and if ``push_to_github`` is ``True``, it will also run ``git push``. """ print("Loading configuration from config.yml") try: config = cf.get_config() except (FileNotFoundError, RuntimeError) as err: print(err) return # Get various paths from config # I think we do this a bunch so is it worth a helper for it? roster_filename = cf.get_config_option(config, "roster", True) course_dir = cf.get_config_option(config, "course_directory", True) clone_dir = cf.get_config_option(config, "clone_dir", True) materials_dir = cf.get_config_option(config, "course_materials", True) try: feedback_dir = Path(course_dir, materials_dir, "feedback") with open(roster_filename, newline="") as csvfile: reader = csv.DictReader(csvfile) for row in reader: student = row["github_username"] feedback_path = Path(feedback_dir, student, assignment_name) source_files = list(feedback_path.glob("*.html")) repo_name = "{}-{}".format(assignment_name, student) # The repos now live in clone_dir/assignment-name/repo-name destination_dir = Path(clone_dir, assignment_name, repo_name) if not destination_dir.is_dir(): print( "Local student repository {} does not exist; skipping " "student".format(destination_dir) ) continue # TODO: Turn this into a helper function lines 46 - 64 here # Don't copy any system related files -- not this is exactly # the same code used in the template.py copy files function. # this could become a helper that just moves files. I think # we'd call it a few times so it's worth doing... and when / # if we add support to move directories we could just add it # in one place. files_to_ignore = cf.get_config_option( config, "files_to_ignore", True ) # This won't work when the entire path is provided # TODO: either parse files first and then create the site # and paths or figure out another approach with generator # objects? maybe a list comprehension? files_to_move = set(source_files).difference(files_to_ignore) for f in files_to_move: if scrub: # If f has an html extension and scrub is true # Clean the file and overwrite existing html sf.scrub_feedback(f) print("Removing hidden tests before copying") print( "Copying {} to {}".format( f.relative_to(course_dir), destination_dir ) ) shutil.copy(f, destination_dir) abcgit.commit_all_changes( destination_dir, msg="Adding feedback for assignment {}".format( assignment_name ), ) if push_to_github: try: abcgit.push_to_github(destination_dir) except RuntimeError as e: print(e) print( "Push to GitHub failed for repo {}".format( destination_dir ) ) except FileNotFoundError as err: abs_roster_path = Path(roster_filename).resolve() raise FileNotFoundError( "Cannot find roster file: {}".format(abs_roster_path) ) print(err)
[docs]def copy_feedback(args): """ Copies feedback reports to local student repositories, commits the changes, and (optionally) pushes to github. Assumes files are in the directory course_materials/feedback/student/assignment. Copies all files in the source directory. This is the command line implementation. Parameters ---------- args : string Command line argument for the copy_feedback function. Options include: assignment: Assignment name github : boolean (default = False) If true, or --github used, push to GitHub. Otherwise only commit the change scrub : boolean (default = False) If true (exists), remove hidden tests from the html output before moving it to the student directory Returns ------- Moves feedback html files from the student feedback directory to the cloned_repos directory. Will commit to git and if ``push_to_github`` is ``True``, it will also run ``git push``. """ assignment_name = args.assignment push_to_github = args.github scrub = args.scrub copy_feedback_files(assignment_name, push_to_github, scrub)