def handle(self, *args, **options): term_sis_id = options.get('term_sis_id') report_client = Reports() term = report_client.get_term_by_sis_id(term_sis_id) user_report = report_client.create_course_provisioning_report( settings.RESTCLIENTS_CANVAS_ACCOUNT_ID, term_id=term.term_id) sis_data = report_client.get_report_data(user_report) report_client.delete_report(user_report) ind_study_regexp = re.compile("-[A-F0-9]{32}$") course_client = Courses() for row in csv.reader(sis_data): if not len(row): continue sis_course_id = row[1] status = row[8] try: valid_academic_course_sis_id(sis_course_id) except CoursePolicyException: continue if ind_study_regexp.match(sis_course_id): continue if status is not None and status == "active": print(sis_course_id)
def _user_in_course(self, group, member): # academic course? try: valid_academic_course_sis_id(group.course_id) except CoursePolicyException: return False # provisioned to academic section? try: user = UserModel.objects.get(net_id=member.name) EnrollmentModel.objects.get( reg_id=user.reg_id, course_id__startswith=group.course_id, status='active') return True except UserModel.DoesNotExist: return False except EnrollmentModel.DoesNotExist: pass # inspect Canvas Enrollments try: canvas_enrollments = get_sis_enrollments_for_user_in_course( user.reg_id, group.course_id) if len(canvas_enrollments): return True except DataFailureException as err: if err.status == 404: pass # No enrollment else: raise return False
def handle(self, *args, **options): sis_term_id = options.get('term_sis_id') report_client = Reports() term = report_client.get_term_by_sis_id(sis_term_id) user_report = report_client.create_course_sis_export_report( settings.RESTCLIENTS_CANVAS_ACCOUNT_ID, term_id=term.term_id) sis_data = report_client.get_report_data(user_report) report_client.delete_report(user_report) ind_study_regexp = re.compile("-[A-F0-9]{32}$") course_client = Courses() print(["course_id", "name", "published", "public_syllabus"]) row_count = sum(1 for row in csv.reader(sis_data)) curr_row = 0 for row in csv.reader(sis_data): curr_row += 1 if not len(row): continue sis_course_id = row[0] course_name = row[1] try: valid_academic_course_sis_id(sis_course_id) except CoursePolicyException: continue if ind_study_regexp.match(sis_course_id): continue try: course = course_client.get_course_by_sis_id( sis_course_id, params={"include": "syllabus_body"}) except DataFailureException as ex: print(ex) continue if course.syllabus_body is None: continue csv_line = [ sis_course_id, course_name, str(course.workflow_state), course.public_syllabus, ] print(csv_line) print("Remaining: {}".format(row_count - curr_row)) print(csv_line) sleep(1)
def handle(self, *args, **options): if len(args): sis_term_id = args[0] else: raise CommandError("term_sis_id is required") report_client = Reports() term = report_client.get_term_by_sis_id(sis_term_id) user_report = report_client.create_course_sis_export_report( settings.RESTCLIENTS_CANVAS_ACCOUNT_ID, term_id=term.term_id ) sis_data = report_client.get_report_data(user_report) report_client.delete_report(user_report) ind_study_regexp = re.compile("-[A-F0-9]{32}$") course_client = Courses() print ["course_id", "name", "published", "public_syllabus"] row_count = sum(1 for row in csv.reader(sis_data)) curr_row = 0 for row in csv.reader(sis_data): curr_row += 1 if not len(row): continue sis_course_id = row[0] course_name = row[1] try: valid_academic_course_sis_id(sis_course_id) except CoursePolicyException: continue if ind_study_regexp.match(sis_course_id): continue try: course = course_client.get_course_by_sis_id(sis_course_id, params={"include": "syllabus_body"}) except DataFailureException as ex: print ex continue if course.syllabus_body is None: continue csv_line = [sis_course_id, course_name, str(course.workflow_state), course.public_syllabus] print csv_line print "Remaining: %s" % (row_count - curr_row) print csv_line sleep(1)
def _normalize(self, course): """ normalize course id case """ course = course.strip() try: valid_academic_course_sis_id(course) except CoursePolicyException: try: valid_adhoc_course_sis_id(course.lower()) return course.lower() except CoursePolicyException: pass return course
def GET(self, request, **kwargs): sections = [] course_id = kwargs['canvas_course_id'] blti_data = self.get_session(request) user_id = blti_data.get('custom_canvas_user_id') course_name = blti_data.get('context_title') course_sis_id = blti_data.get('lis_course_offering_sourcedid', '') @retry(SSLError, tries=3, delay=1, logger=logger) def _get_sections(course_id, user_id): return Sections(as_user=user_id).get_sections_in_course(course_id) try: for s in _get_sections(course_id, user_id): if not (s.sis_section_id and re.match(r'.*-groups$', s.sis_section_id)): sections.append({ 'id': s.section_id, 'sis_id': s.sis_section_id, 'name': s.name }) if not len(sections): try: valid_academic_course_sis_id(course_sis_id) return self.error_response( 401, 'Adding users to this course not allowed') except CoursePolicyException: sections.append({ 'id': 0, 'sis_id': '', 'name': course_name }) except DataFailureException as err: return self.error_response(500, message=err.msg) except Exception as err: return self.error_response(500, message=traceback.format_exc(err)) return self.json_response({ 'sections': sorted(sections, key=lambda k: k['name']) })
def get_context_data(self, **kwargs): blti_data = kwargs['blti_params'] canvas_login_id = blti_data.get('custom_canvas_user_login_id') canvas_course_id = blti_data.get('custom_canvas_course_id') sis_course_id = blti_data.get('lis_course_offering_sourcedid', 'course_%s' % canvas_course_id) subaccount_id = blti_data.get('custom_canvas_account_sis_id', '') if 'uwcourse:tacoma' in subaccount_id: campus = 'tacoma' elif 'uwcourse:bothell' in subaccount_id: campus = 'bothell' else: campus = 'seattle' subject_guide = None try: valid_academic_course_sis_id(sis_course_id) try: subject_guide = get_subject_guide_for_canvas_course_sis_id( sis_course_id) # Library service only returns Seattle campus default guide if (subject_guide.is_default_guide and subject_guide.default_guide_campus.lower() != campus): subject_guide = None except DataFailureException as err: pass except CoursePolicyException as err: pass if subject_guide is None: try: subject_guide = get_default_subject_guide(campus=campus) except DataFailureException as err: return {'error': ( 'UW Libraries Subject Guides are not available: %s' % ( err.msg))} return {'campus': campus, 'subject_guide': subject_guide}
def prioritize_active_courses_for_term(self, term): canvas_term = get_term_by_sis_id(term.canvas_sis_id()) canvas_account_id = getattr(settings, 'RESTCLIENTS_CANVAS_ACCOUNT_ID', None) # Canvas report of "unused" courses for the term unused_course_report = create_unused_courses_report( canvas_account_id, term_id=canvas_term.term_id) unused_courses = {} for row in csv.reader(get_report_data(unused_course_report)): # Create a lookup by unused course_sis_id try: unused_courses[row[1]] = True except Exception as ex: continue # Canvas report of all courses for the term all_course_report = create_course_provisioning_report( canvas_account_id, term_id=canvas_term.term_id) for row in csv.reader(get_report_data(all_course_report)): try: sis_course_id = row[1] valid_academic_course_sis_id(sis_course_id) except Exception as ex: continue if sis_course_id not in unused_courses: try: course = Course.objects.get(course_id=sis_course_id) course.priority = PRIORITY_HIGH course.save() except Course.DoesNotExist: continue delete_report(unused_course_report) delete_report(all_course_report)
def handle(self, *args, **options): if len(args): sis_term_id = args[0] else: raise CommandError("term_sis_id is required") report_client = Reports() term = report_client.get_term_by_sis_id(sis_term_id) user_report = report_client.create_course_provisioning_report( settings.RESTCLIENTS_CANVAS_ACCOUNT_ID, term_id=term.term_id) sis_data = report_client.get_report_data(user_report) report_client.delete_report(user_report) ind_study_regexp = re.compile("-[A-F0-9]{32}$") course_client = Courses() for row in csv.reader(sis_data): if not len(row): continue sis_course_id = row[1] status = row[8] try: valid_academic_course_sis_id(sis_course_id) except CoursePolicyException: continue if ind_study_regexp.match(sis_course_id): continue if status is not None and status == "active": print sis_course_id
def get_active_courses_for_term(term, account_id=None): if account_id is None: account_id = getattr(settings, 'RESTCLIENTS_CANVAS_ACCOUNT_ID', None) canvas_term = get_term_by_sis_id(term.canvas_sis_id()) reports = Reports() # Canvas report of "unused" courses for the term unused_course_report = reports.create_unused_courses_report( account_id, canvas_term.term_id) unused_courses = {} for row in reader(reports.get_report_data(unused_course_report)): try: sis_course_id = row[1] valid_academic_course_sis_id(sis_course_id) unused_courses[sis_course_id] = True except (IndexError, CoursePolicyException): pass # Canvas report of all courses for the term all_course_report = reports.create_course_provisioning_report( account_id, canvas_term.term_id) active_courses = [] for row in reader(reports.get_report_data(all_course_report)): try: sis_course_id = row[1] valid_academic_course_sis_id(sis_course_id) if sis_course_id not in unused_courses: active_courses.append(sis_course_id) except (IndexError, CoursePolicyException): pass reports.delete_report(unused_course_report) reports.delete_report(all_course_report) return active_courses
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()