diff --git a/api/composite_user.py b/api/composite_user.py index 44fa8ca839136a3a37e6ff3e5420ff9020e62be5..c8f6eaebdb47f752748cf817a6fa7e7a32165e71 100644 --- a/api/composite_user.py +++ b/api/composite_user.py @@ -57,6 +57,12 @@ class CompositeUser: 'GitlabEmail': gitlab_student.get_email()} return CompositeUser(student, {}, set()) + def get_name(self) -> str: + return self.readable_name + + def get_canvas_username(self) -> str: + return self.canvas_username + def get_canvas_user(self) -> CanvasUser: if self.canvas_user is None: # self.canvas_user = CanvasUser(self.NUID) # n.b., can retrieve own user but not arbitrary user diff --git a/prep_assignment.py b/prep_assignment.py index 8701a076d68390899638632b0720b2e62ea31bf5..ff4c53cacbb75637296d4377780f773365825056 100644 --- a/prep_assignment.py +++ b/prep_assignment.py @@ -23,6 +23,53 @@ def get_students() -> Set[CompositeUser]: return students +def validate_roster_against_canvas(course_roster: Set[CompositeUser]) -> bool: + print('Validating course roster against Canvas.') + course = CanvasCourse(Course.canvas_course_id) + students_in_canvas = course.get_students() + roster_names: Set[str] = set(map(lambda s: s.get_canvas_username(), course_roster)) + canvas_names: Set[str] = set(map(lambda s: s.get_username(), students_in_canvas)) + roster_is_valid: bool = True + difference: Set[str] = roster_names - canvas_names + if len(difference) > 0: + roster_is_valid = False + print('\tStudent(s) are in roster but not in Canvas. The roster is invalid:') + extra_students: Set[CompositeUser] = set(filter(lambda s: s.get_canvas_username() in difference, course_roster)) + for student in extra_students: + print(f'\t\t{student}') + difference = canvas_names - roster_names + if len(difference) > 0: + roster_is_valid = False + print('\tStudent(s) are in Canvas but not in roster. The roster is invalid:') + extra_students: Set[CanvasUser] = set(filter(lambda s: s.get_username() in difference, students_in_canvas)) + for student in extra_students: + print(f'\t\t{student.get_name()} ({student})') + if roster_is_valid: + print(f'\t{len(roster_names)} names match. The roster is valid.') + return roster_is_valid + + +def validate_roster_against_gitlab(course_roster: Set[CompositeUser]) -> bool: + print('Validating course roster against GitLab.') + roster_is_valid: bool = True + invalid_users: Set[CompositeUser] = set() + for student in course_roster: + username: str = student.gitlab_username + try: + print(f'\t{student.get_name()}'.ljust(30, '.'), end=' ') + GitlabUser(username) + print('✅') + except IndexError: + print('❌') + invalid_users.add(student) + if len(invalid_users) > 0: + roster_is_valid = False + print('\tStudent(s) have invalid GitLab usernames (may have changed usernames):') + for student in invalid_users: + print(f'\t\t{student}') + return roster_is_valid + + # TODO: assign_partners for arbitrarily-sized teams # TODO: break this up into bite-sized chunks # TODO: manage multiple sections @@ -233,17 +280,20 @@ def create_groups(groupset_name: str, if __name__ == '__main__': groupset: str = input('Please provide the name of the student groupset: ') student_set: Set[CompositeUser] = get_students() - # TODO: check for changes to course roster - # TODO: check for changes to gitlab usernames - partners: List[Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]]] = create_pairs(student_set, - groupset) - print() - save_student_roster(student_set) - create_contact_list(groupset, partners) - print() - create_repositories(groupset, partners) - print() - create_groups(groupset, partners) - print() - print('TODO:\tAdd issues') - print('\tCommit starter code') + course_roster_matches_canvas: bool = validate_roster_against_canvas(student_set) + course_roster_matches_gitlab: bool = validate_roster_against_gitlab(student_set) + if course_roster_matches_canvas and course_roster_matches_gitlab: + partners: List[Tuple[int, CompositeUser, CompositeUser, Optional[CompositeUser]]] = create_pairs(student_set, + groupset) + print() + save_student_roster(student_set) + create_contact_list(groupset, partners) + print() + create_repositories(groupset, partners) + print() + create_groups(groupset, partners) + print() + print('TODO:\tAdd issues') + print('\tCommit starter code') + else: + print('No partners assigned due to invalid roster. Please update student roster file.')