def verify_canvas_course(self, course_id): """ Verify that the Canvas course still exists, has a correct sis_id, and contains a UW Group section. """ try: valid_adhoc_course_sis_id(course_id) (prefix, canvas_course_id) = course_id.split('_') canvas_course = get_course_by_id(canvas_course_id) except CoursePolicyException: canvas_course = get_course_by_sis_id(course_id) if canvas_course.sis_course_id is None: update_course_sis_id(canvas_course.course_id, course_id) group_section_id = group_section_sis_id(course_id) try: section = get_section_by_sis_id(group_section_id) except DataFailureException as err: if err.status == 404: self.data.add( SectionCSV(section_id=group_section_id, course_id=course_id, name=group_section_name())) else: raise
def _process(self, member): section_id = group_section_sis_id(member.course_id) status = Enrollment.DELETED_STATUS if ( member.is_deleted) else Enrollment.ACTIVE_STATUS if member.is_eppn(): member.login = member.name try: self.add_group_enrollment_data(member, section_id, member.role, status) except Exception as err: self.logger.info("Skip group member %s (%s)" % (member.name, err))
def all_course_enrollments(self, course_id): group_section_id = group_section_sis_id(course_id) sis_enrollments = {} group_enrollments = set() for enr in get_enrollments_for_course_by_sis_id(course_id): # Split the enrollments into sis and group enrollments, # discarding enrollments for adhoc sections try: valid_academic_section_sis_id(enr.sis_section_id) sis_enrollments[enr.login_id.lower()] = enr.sis_section_id except CoursePolicyException: if enr.sis_section_id == group_section_id: group_enrollments.add(SetMember(enr.login_id, enr.role)) return (sis_enrollments, group_enrollments)
def _process(self, course_id): try: self._verify_canvas_course(course_id) except DataFailureException as err: if err.status == 404: Group.objects.deprioritize_course(course_id) self.logger.info("Drop group sync for deleted course %s" % (course_id)) else: self._requeue_course(course_id, err) return group_section_id = group_section_sis_id(course_id) self.data.add(SectionCSV(section_id=group_section_id, course_id=course_id, name=group_section_name())) # Get the enrollments for academic courses from Canvas, excluding # ad-hoc and group sections try: valid_academic_course_sis_id(course_id) if course_id not in self.cached_course_enrollments: canvas_enrollments = get_sis_enrollments_for_course(course_id) self.cached_course_enrollments[course_id] = canvas_enrollments except CoursePolicyException: self.cached_course_enrollments[course_id] = [] except DataFailureException as err: self._requeue_course(course_id, err) return current_members = [] for group in Group.objects.get_active_by_course(course_id): try: current_members.extend(self._get_current_members(group)) except DataFailureException as err: self._requeue_course(course_id, err) return # skip on any group policy exception except GroupPolicyException as err: self.logger.info("Skip group %s (%s)" % (group.group_id, err)) cached_members = CourseMember.objects.get_by_course(course_id) for member in cached_members: match = next((m for m in current_members if m == member), None) if match is None: if not self.delta or not member.is_deleted: try: self.add_group_enrollment_data( member, group_section_id, member.role, status=Enrollment.DELETED_STATUS ) except Exception as err: self.logger.info("Skip group member %s (%s)" % (member.name, err)) member.deactivate() for member in current_members: match = next((m for m in cached_members if m == member), None) # new or previously removed member if not self.delta or match is None or match.is_deleted: try: self.add_group_enrollment_data( member, group_section_id, member.role, status=Enrollment.ACTIVE_STATUS ) except Exception as err: self.logger.info("Skip group member %s (%s)" % (member.name, err)) if match is None: member.save() elif match.is_deleted: match.activate()
def _process(self, course_id): group_section_id = group_section_sis_id(course_id) try: self.verify_canvas_course(course_id) except DataFailureException as err: if err.status == 404: Group.objects.deprioritize_course(course_id) self.logger.info( "Drop group sync for deleted course {}".format(course_id)) else: self._requeue_course(course_id, err) return try: # Get the enrollments for SIS and Group sections in this course (sis_enrollments, group_enrollments) = self.all_course_enrollments(course_id) # Build a flattened set of current group memberships from GWS current_members = self.all_group_memberships(course_id) except DataFailureException as err: self._requeue_course(course_id, err) return # Remove enrollments not in the current group membership from # the groups section for member in (group_enrollments - current_members): try: self.add_group_enrollment_data(member.login, group_section_id, member.role, status=ENROLLMENT_DELETED) except DataFailureException as err: self.logger.info("Skip remove group member {}: {}".format( member.login, err)) # Add group members not already enrolled to the groups section, # unless the user already has an sis enrollment in the course for member in (current_members - group_enrollments): if member.login in sis_enrollments: self.logger.info( "Skip add group member {} (present in {})".format( member.login, sis_enrollments[member.login])) continue try: self.add_group_enrollment_data(member.login, group_section_id, member.role, status=ENROLLMENT_ACTIVE) except DataFailureException as err: self.logger.info("Skip add group member {}: {}".format( member.login, err)) # Remove any existing group enrollments that also have an # sis enrollment in the course for member in group_enrollments: if member.login in sis_enrollments: self.add_group_enrollment_data(member.login, group_section_id, member.role, status=ENROLLMENT_DELETED) self.logger.info( "Remove group enrollment {} (present in {})".format( member.login, sis_enrollments[member.login]))