Example #1
0
    def get_enrollments_for_regid(self, regid, params={},
                                  include_courses=True):
        """
        Return a list of enrollments for the passed user regid.

        https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.index
        """
        url = "/api/v1/users/%s/enrollments" % (
            self._sis_id(regid, sis_field="user"))

        courses = Courses() if include_courses else None

        enrollments = []
        for datum in self._get_paged_resource(url, params=params):
            if include_courses:
                course_id = datum["course_id"]
                course = courses.get_course(course_id)

                if course.sis_course_id is not None:
                    enrollment = self._enrollment_from_json(datum)
                    enrollment.course = course
                    # the following 3 lines are not removed
                    # to be backward compatible.
                    enrollment.course_url = course.course_url
                    enrollment.course_name = course.name
                    enrollment.sis_course_id = course.sis_course_id
                    enrollments.append(enrollment)
            else:
                enrollment = self._enrollment_from_json(datum)
                enrollment.course_url = re.sub(
                    r'/users/\d+$', '', enrollment.html_url)
                enrollments.append(enrollment)

        return enrollments
Example #2
0
    def get_enrollments_for_regid(self, regid, params={}):
        """
        Return a list of enrollments for the passed user regid.

        https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.index
        """
        url = "/api/v1/users/%s/enrollments" % (
            self._sis_id(regid, sis_field="user"))

        courses = Courses()

        enrollments = []
        for datum in self._get_paged_resource(url, params=params):
            course_id = datum["course_id"]
            course = courses.get_course(course_id)

            if course.sis_course_id is not None:
                enrollment = self._enrollment_from_json(datum)
                enrollment.course = course
                # the following 3 lines are not removed
                # to be backward compatible.
                enrollment.course_url = course.course_url
                enrollment.course_name = course.name
                enrollment.sis_course_id = course.sis_course_id
                enrollments.append(enrollment)

        return enrollments
    def get_enrollments_for_regid(self, regid, params={}):
        """
        Return a list of enrollments for the passed user regid.

        https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.index
        """
        url = "/api/v1/users/%s/enrollments%s" % (
            self._sis_id(regid, sis_field="user"),
            self._params(params))

        courses = Courses()

        enrollments = []
        for datum in self._get_resource(url):
            course_id = datum["course_id"]
            course = courses.get_course(course_id)

            if course.sis_course_id is not None:
                enrollment = self._enrollment_from_json(datum)
                enrollment.course_url = course.course_url
                enrollment.course_name = course.name
                enrollment.sis_course_id = course.sis_course_id
                enrollments.append(enrollment)

        return enrollments
    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)
Example #5
0
    def test_update_sis_id(self):
        with self.settings(
                RESTCLIENTS_CANVAS_DAO_CLASS='restclients.dao_implementation.canvas.File'):
            canvas = Courses()

            course = canvas.update_sis_id(149650, "NEW_SIS_ID")

            self.assertEquals(course.course_id, 149650, "Has proper course id")
            self.assertEquals(course.course_url, "https://canvas.uw.edu/courses/149650", "Has proper course url")
            self.assertEquals(course.sis_course_id, "NEW_SIS_ID")
Example #6
0
    def test_create_course(self):
        with self.settings(
                RESTCLIENTS_CANVAS_DAO_CLASS='restclients.dao_implementation.canvas.File'):
            canvas = Courses()

            account_id = 88888
            name = "Created Course"

            course = canvas.create_course(account_id, name)

            self.assertEquals(course.course_id, 18881, "Correct course ID")
            self.assertEquals(course.name, name, "Correct course name")
            self.assertEquals(course.account_id, account_id, "Correct account ID")
Example #7
0
    def test_course_with_params(self):
        with self.settings(
                RESTCLIENTS_CANVAS_DAO_CLASS='restclients.dao_implementation.canvas.File'):
            canvas = Courses()
            course1 = canvas.get_course(149650, params={"include":"term"})

            self.assertEquals(course1.term.term_id, 810, "Course contains term data")
            self.assertEquals(course1.syllabus_body, None, "Course doesn't contain syllabus_body")

            course2 = canvas.get_course(149650, params={"include":"syllabus_body"})

            self.assertEquals(course2.syllabus_body, "Syllabus", "Course contains syllabus_body")
            self.assertEquals(course2.term, None, "Course doesn't contain term")
Example #8
0
    def test_courses_by_regid(self):
        with self.settings(
                RESTCLIENTS_CANVAS_DAO_CLASS='restclients.dao_implementation.canvas.File'):
            canvas = Courses()

            # Javerage's regid
            courses = canvas.get_courses_for_regid("9136CCB8F66711D5BE060004AC494FFE")

            self.assertEquals(len(courses), 1, "Has 1 canvas enrollment")

            course = courses[0]

            self.assertEquals(course.course_url, "https://canvas.uw.edu/courses/149650", "Has proper course url")
            self.assertEquals(course.sis_course_id, "2013-spring-PHYS-121-A", "Course doesnt contain SIS ID")
            self.assertEquals(course.sws_course_id(), "2013,spring,PHYS,121/A", "Course doesnt contain SIS ID")
            self.assertEquals(course.account_id, 84378, "Has proper account id")
Example #9
0
    def test_course(self):
        with self.settings(
                RESTCLIENTS_CANVAS_DAO_CLASS='restclients.dao_implementation.canvas.File'):
            canvas = Courses()

            course = canvas.get_course(149650)

            self.assertEquals(course.course_id, 149650, "Has proper course id")
            self.assertEquals(course.course_url, "https://canvas.uw.edu/courses/149650", "Has proper course url")
            self.assertEquals(course.sis_course_id, "2013-spring-PHYS-121-A")
            self.assertEquals(course.sws_course_id(), "2013,spring,PHYS,121/A")
            self.assertEquals(course.account_id, 84378, "Has proper account id")
            self.assertEquals(course.term.sis_term_id, "2013-spring", "SIS term id")
            self.assertEquals(course.term.term_id, 810, "Term id")
            self.assertEquals(course.public_syllabus, False, "public_syllabus")
            self.assertEquals(course.workflow_state, "unpublished", "workflow_state")
    def handle(self, *args, **options):
        self._canvas = Canvas()
        self._tools = ExternalTools()
        self._accounts = Accounts()
        self._courses = Courses()
        self._options = options

        csv.register_dialect("unix_newline", lineterminator="\n")
        self._writer = csv.writer(sys.stdout, dialect="unix_newline")

        self._headers = ['tool_name', 'tool_id', 'tool_type', 'account_name', 'account_id']

        if self._options['courses']:
            self._headers.append('course_name')
            self._headers.append('course_id')
            self._headers.append('term')

        if options['sessionless']:
            self._headers.append('sessionless url')

        accounter = self._accounts.get_account if re.match(r'^\d+$', options['account_id']) \
                        else self._accounts.get_account_by_sis_id
        try:
            self.report_external_tools(accounter(options['account_id']))

        except DataFailureException as err:
            if err.status == 404:
                print >> sys.stderr, 'Unknown Sub-Account \"%s\"' % (options['account_id'])
Example #11
0
def get_indexed_by_decrosslisted(by_primary, sws_sections):
    for section in sws_sections:
        base_id = section.section_label()
        alternate_id = None
        try:
            sis_id = section.canvas_section_sis_id()
            canvas_section = Sections().get_section_by_sis_id(sis_id)
            primary_course = Courses().get_course(canvas_section.course_id)
            alternate_id = primary_course.sws_course_id()
        except Exception as ex:
            # primary section doesn't have canvas_section_sis_id
            alternate_id = base_id

        if base_id not in by_primary:
            if alternate_id in by_primary:
                by_primary[base_id] = by_primary[alternate_id]
    return by_primary
Example #12
0
def get_indexed_by_decrosslisted(by_primary, sws_sections):
    for section in sws_sections:
        base_id = section.section_label()
        alternate_id = None
        try:
            sis_id = section.canvas_section_sis_id()
            canvas_section = Sections().get_section_by_sis_id(sis_id)
            primary_course = Courses().get_course(canvas_section.course_id)
            alternate_id = primary_course.sws_course_id()
        except Exception as ex:
            # primary section doesn't have canvas_section_sis_id
            alternate_id = base_id

        if base_id not in by_primary:
            if alternate_id in by_primary:
                by_primary[base_id] = by_primary[alternate_id]
    return by_primary
Example #13
0
    def test_published_courses(self):
        with self.settings(
                RESTCLIENTS_CANVAS_DAO_CLASS='restclients.dao_implementation.canvas.File'):
            canvas = Courses()

            courses = canvas.get_published_courses_in_account_by_sis_id(
                'uwcourse:seattle:arts-&-sciences:amath:amath')

            self.assertEquals(len(courses), 7, "Too few courses")

            course = courses[2]

            self.assertEquals(course.course_id, 141414, "Has proper course id")
            self.assertEquals(course.sis_course_id, "2013-spring-AMATH-403-A")
            self.assertEquals(course.sws_course_id(), "2013,spring,AMATH,403/A")
            self.assertEquals(course.name, "AMATH 403 A: Methods For Partial Differential Equations")
            self.assertEquals(course.account_id, 333333, "Has proper account id")
            self.assertEquals(course.course_url, "https://canvas.uw.edu/courses/141414", "Has proper course url")
    def handle(self, *args, **options):
        if options['print'] or options['dry_run']:
            print "section_id,canvas_enrollments,sws_enrollments,delta"

        canvas_courses = CanvasCourses(per_page=50)
        canvas_sections = CanvasSections(per_page=50)
        canvas_accounts = CanvasAccounts(per_page=50)
        for account in canvas_accounts.get_all_sub_accounts_by_sis_id(options['root_account']):

            if options['print']:
                print '# Account: "%s" (%s, %s)' % (account.name,
                                                    account.sis_account_id,
                                                    account.account_id)

            if (account.sis_account_id is not None
                and re.match(r'^(([^:]+:){4}|curriculum-).*$', str(account.sis_account_id))):

                n_courses = 0
                n_sections = 0
                n_bad_sections = 0

                if options['all_courses']:
                    courses = canvas_courses.get_courses_in_account_by_sis_id(account.sis_account_id)
                else:
                    courses = canvas_courses.get_published_courses_in_account_by_sis_id(account.sis_account_id)

                for course in courses:
                    if (course.sis_course_id is not None
                        and re.match('^%s-' % options['term'], course.sis_course_id)
                        and not self._is_independent_study(course.sis_course_id)):
                        n_courses += 1
                        sections = canvas_sections.get_sections_with_students_in_course_by_sis_id(course.sis_course_id) 
                        for section in sections:
                            if section.sis_section_id is not None:
                                section_id = section.sis_section_id
                                n_sections += 1

                                try:
                                    s = self.get_section_by_id(section_id)
                                except DataFailureException, err:
                                    print '# BAD SECTION: %s' % err
                                    continue

                                enrollments = (s.current_enrollment + s.auditors)
                                delta = len(section.students) - enrollments
                                if delta >= options['threshold']:
                                    n_bad_sections += 1
                                    if options['print'] or options['dry_run']:
                                        print "%s,%s,%s,%s" % (section_id, len(section.students), enrollments, delta)

                                    if not options['dry_run']:
                                        try:
                                            section_model_id = re.sub(r'--$', '', section_id)
                                            section_model = Course.objects.get(course_id=section_model_id)
                                        except Course.DoesNotExist:
                                            section_model = Course(course_id=section_model_id)

                                        if not section_model.queue_id and section_model.priority < PRIORITY_HIGH:
                                            section_model.priority = PRIORITY_HIGH
                                            section_model.save()

                if options['print']:
                    if n_courses and n_sections and n_bad_sections:
                        print('# %s of %s (%.3s%%) sections in %s courses for %s'
                              % (n_bad_sections, n_sections,
                                 ((n_bad_sections/float(n_sections)) * 100),
                                 n_courses, options['term']))
class Command(BaseCommand):
    help = "Report externals tools in account"

    option_list = BaseCommand.option_list + (
        make_option('-a', '--account', action='store', dest='account_id', type="string",
                    default=default_account,
                    help='show external tools in account by id or sis_id (default: %s)' % default_account),
        make_option('-r', '--recurse', action='store_true', dest='recurse',
                    default=False, help='recurse through subaccounts'),
        make_option('-c', '--courses', action='store_true', dest='courses',
                    default=False, help='include account courses in report'),
        make_option('-t', '--term', action='store', dest='term', type="string",
                    default='', help='include only courses in given term'),
        make_option('-s', '--sessionless-url', action='store_true', dest='sessionless',
                    default=False, help='show sessionless url with each external tool'),
    )

    def handle(self, *args, **options):
        self._canvas = Canvas()
        self._tools = ExternalTools()
        self._accounts = Accounts()
        self._courses = Courses()
        self._options = options

        csv.register_dialect("unix_newline", lineterminator="\n")
        self._writer = csv.writer(sys.stdout, dialect="unix_newline")

        self._headers = ['tool_name', 'tool_id', 'tool_type', 'account_name', 'account_id']

        if self._options['courses']:
            self._headers.append('course_name')
            self._headers.append('course_id')
            self._headers.append('term')

        if options['sessionless']:
            self._headers.append('sessionless url')

        accounter = self._accounts.get_account if re.match(r'^\d+$', options['account_id']) \
                        else self._accounts.get_account_by_sis_id
        try:
            self.report_external_tools(accounter(options['account_id']))

        except DataFailureException as err:
            if err.status == 404:
                print >> sys.stderr, 'Unknown Sub-Account \"%s\"' % (options['account_id'])

    def report_external_tools(self, account):
        tools = self._tools.get_external_tools_in_account(account.account_id)
        self._print_tools(tools, account)

        if self._options['courses']:
            params = {
                "by_subaccounts":[account.account_id],
                "include": ["term"]
            }

            if self._options['term']:
                params['enrollment_term_id'] = self._canvas.get_term_by_sis_id(self._options['term']).term_id

            courses = self._courses.get_published_courses_in_account(account.account_id,
                                                                     params=params)
            for course in courses:
                tools = self._tools.get_external_tools_in_course(course.course_id)
                self._print_tools(tools, account, course)
                
        if self._options['recurse']:
            subaccounts = self._accounts.get_sub_accounts(account.account_id)
            for account in subaccounts:
                self.report_external_tools(account)

    def _print_tools(self, tools, account, course=None):
        if len(tools):
            if self._headers:
                self._writer.writerow(self._headers)
                self._headers = None
            
            for tool in tools:
                tool_types = []
                for tt in ['account', 'course', 'user']:
                    if tool.get("%s_navigation" % tt):
                        tool_types.append(tt)

                tool_type = ' & '.join(tool_types)
                line = [tool['name'], tool['id'], tool_type, account.name, account.account_id]

                if self._options['courses']:
                    if course:
                        line.extend([course.name, course.course_id, course.term.name if course.term else ''])
                    else:
                        line.extend(['','',''])

                if self._options['sessionless']:
                    try:
                        sessionless = self._tools.get_sessionless_launch_url_from_account(tool['id'], account.account_id)
                        line.append(sessionless['url'])
                    except DataFailureException as ex:
                        line.append('')

                self._writer.writerow(line)
Example #16
0
 def get_courses_for_regid(self, regid):
     deprecation("Use restclients.canvas.courses.get_courses_for_regid")
     from restclients.canvas.courses import Courses
     return Courses().get_courses_for_regid(regid)