def write_report(file_path, output, report_repo: Repository, commit_message='new submission'): try: with open(file_path, 'w') as f: f.write(output) except OSError as e: print('Error opening {0}:\n{1}'.format(file_path, e), file=sys.stderr) report_repo = None if report_repo is not None: report_repo.add_all_and_commit(commit_message) report_repo.push()
def upload_handout(class_name, local_handout_dir): local_handout_dir = os.path.expanduser(local_handout_dir) local_handout_dir = os.path.abspath(local_handout_dir) handout_name = os.path.basename(local_handout_dir.rstrip('/')) if handout_name.count(' ') != 0: sys.exit('NO spaces allowed in handout directory') if not os.path.isdir(local_handout_dir): sys.exit('{0} does not exist'.format(local_handout_dir)) try: config = GraderConfiguration(single_class_name=class_name) except ConfigurationError as e: sys.exit(e) if class_name not in config.students_by_class: sys.exit('Class {0} does not exist'.format(class_name)) remote_handout_repo_basename = handout_name + '.git' remote_handout_repo_dir = os.path.join('/home/git', class_name, remote_handout_repo_basename) if directory_exists(remote_handout_repo_dir, ssh=config.ssh): sys.exit( '{0} already exists on the grader'.format(remote_handout_repo_dir)) local_handout_repo = Repository(local_handout_dir, handout_name) if not local_handout_repo.is_initialized(): print('Initializing local git repository in {0}'.format( local_handout_dir)) try: local_handout_repo.init() local_handout_repo.add_all_and_commit('Initial commit') except CommandError as e: sys.exit('Error initializing local repository:\n{0}'.format(e)) else: print('{0} is already a git repository, it will be pushed'.format( local_handout_dir)) print('Creating a bare repository on the grader at this path:\n{0}'.format( remote_handout_repo_dir)) remote_handout_repo = Repository(remote_handout_repo_dir, handout_name, is_local=False, is_bare=True, remote_user=config.username, remote_host=config.host, ssh=config.ssh) try: remote_handout_repo.init() except CommandError as e: sys.exit('Error initializing remote bare repository:\n{0}'.format(e)) print('Setting the remote of the local repository') try: local_handout_repo.set_remote(remote_handout_repo) except CommandError as e: print('Error setting remote:\n{0}'.format(e)) print('Set the remote manually if need be') print('Pushing local handout to the grader') try: local_handout_repo.push(remote_handout_repo) except CommandError as e: sys.exit('Error pushing handout:\n{0}'.format(e)) email_queue = Queue() email_thread = Thread(target=process_email_queue, args=(email_queue, class_name, config)) email_thread.start() for student in config.students_by_class[class_name]: assert isinstance(student, Student) clone_url = '{0}@{1}:{2}'.format(student.username, config.host, remote_handout_repo_dir) body = 'Clone URL:\n{0}'.format(clone_url) subject = 'New handout: {0}'.format(handout_name) email_queue.put(Email(student.email_address, subject, body)) email_queue.put(None) email_thread.join()
def upload_handout(class_name, local_handout_dir): local_handout_dir = os.path.expanduser(local_handout_dir) local_handout_dir = os.path.abspath(local_handout_dir) handout_name = os.path.basename(local_handout_dir.rstrip('/')) if handout_name.count(' ') != 0: sys.exit('NO spaces allowed in handout directory') if not os.path.isdir(local_handout_dir): sys.exit('{0} does not exist'.format(local_handout_dir)) try: config = GraderConfiguration(single_class_name=class_name) except ConfigurationError as e: sys.exit(e) if class_name not in config.students_by_class: sys.exit('Class {0} does not exist'.format(class_name)) remote_handout_repo_basename = handout_name + '.git' remote_handout_repo_dir = os.path.join('/home/git', class_name, remote_handout_repo_basename) if directory_exists(remote_handout_repo_dir, ssh=config.ssh): sys.exit('{0} already exists on the grader' .format(remote_handout_repo_dir)) local_handout_repo = Repository(local_handout_dir, handout_name) if not local_handout_repo.is_initialized(): print('Initializing local git repository in {0}' .format(local_handout_dir)) try: local_handout_repo.init() local_handout_repo.add_all_and_commit('Initial commit') except CommandError as e: sys.exit('Error initializing local repository:\n{0}' .format(e)) else: print('{0} is already a git repository, it will be pushed' .format(local_handout_dir)) print('Creating a bare repository on the grader at this path:\n{0}' .format(remote_handout_repo_dir)) remote_handout_repo = Repository(remote_handout_repo_dir, handout_name, is_local=False, is_bare=True, remote_user=config.username, remote_host=config.host, ssh=config.ssh) try: remote_handout_repo.init() except CommandError as e: sys.exit('Error initializing remote bare repository:\n{0}'.format(e)) print('Setting the remote of the local repository') try: local_handout_repo.set_remote(remote_handout_repo) except CommandError as e: print('Error setting remote:\n{0}'.format(e)) print('Set the remote manually if need be') print('Pushing local handout to the grader') try: local_handout_repo.push(remote_handout_repo) except CommandError as e: sys.exit('Error pushing handout:\n{0}'.format(e)) email_queue = Queue() email_thread = Thread(target=process_email_queue, args=(email_queue, class_name, config)) email_thread.start() for student in config.students_by_class[class_name]: assert isinstance(student, Student) clone_url = '{0}@{1}:{2}'.format(student.username, config.host, remote_handout_repo_dir) body = 'Clone URL:\n{0}'.format(clone_url) subject = 'New handout: {0}'.format(handout_name) email_queue.put(Email(student.email_address, subject, body)) email_queue.put(None) email_thread.join()
def upload_assignment(class_name, grader_project): grader_project_path = os.path.dirname(sys.argv[0]) post_update_path = os.path.join(grader_project_path, 'post-update') local_assignment_dir = os.path.expanduser(grader_project) local_assignment_dir = os.path.abspath(local_assignment_dir) assignment = os.path.basename(local_assignment_dir.rstrip('/')) base_code_dir = os.path.join(local_assignment_dir, 'base_code') test_code_dir = os.path.join(local_assignment_dir, 'tests') if not os.path.isdir(base_code_dir): sys.exit('{0} does not exist'.format(base_code_dir)) if not os.path.isdir(test_code_dir): sys.exit('{0} does not exist'.format(test_code_dir)) action_file_path = os.path.join(test_code_dir, 'action.sh') if not os.path.isfile(action_file_path): sys.exit('No action.sh in {0}'.format(test_code_dir)) email_file_path = os.path.join(local_assignment_dir, 'email.txt') if not os.path.isfile(email_file_path): sys.exit('{0} does not exist'.format(email_file_path)) try: config = GraderConfiguration(single_class_name=class_name) except ConfigurationError as e: sys.exit(e) if class_name not in config.students_by_class: sys.exit('Class {0} does not exist'.format(class_name)) base_code_repo_tempdir = TemporaryDirectory() try: base_code_repo = copy_and_create_repo(base_code_dir, base_code_repo_tempdir.name, assignment, 'created assignment') except CommandError as e: error = 'Error copying base code repo:\n{0}'.format(e) sys.exit(error) test_code_repo_tempdir = TemporaryDirectory() try: test_code_repo = copy_and_create_repo(test_code_dir, test_code_repo_tempdir.name, assignment) except CommandError as e: error = 'Error copying test code repo:\n{0}'.format(e) sys.exit(error) try: remote_home_dir = home_dir_from_username(config.username, config.username, config.host) except CommandError as e: sys.exit('Error getting remote home dir for {0}:\n{1}'.format( config.username, e)) remote_assignment_dir = os.path.join(remote_home_dir, class_name, 'assignments', assignment) tests_bare_repo_dir = os.path.join(remote_assignment_dir, '{0}_tests.git'.format(assignment)) reports_bare_repo_dir = os.path.join(remote_assignment_dir, '{0}_reports.git'.format(assignment)) if directory_exists(tests_bare_repo_dir, config.username, config.host): sys.exit('{0} already exists on {1}'.format(tests_bare_repo_dir, config.host)) if directory_exists(reports_bare_repo_dir, config.username, config.host): sys.exit('{0} already exists on {1}'.format(reports_bare_repo_dir, config.host)) print('Uploading assignment', assignment) reports_repo_tempdir = TemporaryDirectory() reports_repo_dir = reports_repo_tempdir.name reports_repo = Repository(reports_repo_dir, assignment) reports_repo.init() for student in config.students_by_class[class_name]: assert isinstance(student, Student) bare_repo_dir = student.get_bare_repo_dir(class_name, assignment) if directory_exists(bare_repo_dir, config.username, config.host): sys.exit('{0} already exists on {1}'.format( bare_repo_dir, config.host)) student_repo = Repository(bare_repo_dir, assignment, is_local=False, is_bare=True, remote_user=config.username, remote_host=config.host, student_username=student.username) try: student_repo.init() student_repo.add_update_flag_hook(post_update_path) base_code_repo.push(student_repo) chmod_world_writable_recursive(student_repo.path, remote_user=config.username, remote_host=config.host) print('Pushed base code to', bare_repo_dir) except CommandError as e: sys.exit('Error creating {0} on {1}:\n{2}'.format( bare_repo_dir, config.host, e)) student_report_dir = os.path.join(reports_repo_dir, student.get_last_first_username()) os.makedirs(student_report_dir) placeholder_path = os.path.join(student_report_dir, '.placeholder') touch(placeholder_path) reports_bare_repo = Repository(reports_bare_repo_dir, assignment, is_local=False, is_bare=True, remote_user=config.username, remote_host=config.host) try: reports_repo.add_all_and_commit('added student directories') reports_bare_repo.init() reports_repo.push(reports_bare_repo) print('Created reports repository in', reports_bare_repo_dir) except CommandError as e: sys.exit('Error creating reports repository:\n{0}'.format(e)) tests_bare_repo = Repository(tests_bare_repo_dir, assignment, is_local=False, is_bare=True, remote_user=config.username, remote_host=config.host) try: tests_bare_repo.init() test_code_repo.push(tests_bare_repo) print('Pushed tests to', tests_bare_repo_dir) except CommandError as e: sys.exit('Error creating {0} on {1}\n{2}'.format( tests_bare_repo_dir, test_code_dir, e)) scp_file(email_file_path, config.username, config.host, remote_assignment_dir) print(assignment, 'uploaded successfully') print('Reports repo clone URL:', reports_bare_repo.url)