Пример #1
0
    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)
Пример #2
0
    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)
Пример #5
0
    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
Пример #6
0
    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
Пример #7
0
    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'])
        })
Пример #8
0
    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}
Пример #9
0
    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
Пример #11
0
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
Пример #12
0
    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()