def test_delete_report(self, mock_delete):
        canvas = Reports()

        report = Report(data=self.report_json_data)
        canvas.delete_report(report)
        mock_delete.assert_called_with(
            '/api/v1/accounts/12345/reports/some_type/1')
 def test_create_enrollments_provisioning_report(self, mock_post):
     canvas = Reports()
     canvas.create_enrollments_provisioning_report('12345')
     mock_post.assert_called_with(
         '/api/v1/accounts/12345/reports/provisioning_csv',
         {'parameters': {
             'enrollments': True
         }})
 def test_create_unused_courses_report(self, mock_post):
     canvas = Reports()
     canvas.create_unused_courses_report('12345', term_id='2015-summer')
     mock_post.assert_called_with(
         '/api/v1/accounts/12345/reports/unused_courses_csv',
         {'parameters': {
             'enrollment_term_id': '2015-summer'
         }})
 def test_create_course_sis_export_report(self, mock_post):
     canvas = Reports()
     canvas.create_course_sis_export_report('12345')
     mock_post.assert_called_with(
         '/api/v1/accounts/12345/reports/sis_export_csv',
         {'parameters': {
             'courses': True
         }})
    def test_get_reports_by_type(self, mock_get):
        mock_get.return_value = [self.report_json_data]
        canvas = Reports()
        ret = canvas.get_reports_by_type('12345', 'sis_import')
        mock_get.assert_called_with(
            '/api/v1/accounts/12345/reports/sis_import')

        report = ret[0]
        self.assertEqual(report.type, self.report_json_data["report"])
        self.assertEqual(report.account_id, '12345')
    def test_get_report_data(self, mock_get):
        mock_get.return_value = "a\nb\nc\nd\ne"
        canvas = Reports()

        report = Report(report_id=1)
        self.assertRaises(ReportFailureException, canvas.get_report_data,
                          report)

        report = Report(data=self.report_json_data)
        self.assertEqual(canvas.get_report_data(report),
                         ['a', 'b', 'c', 'd', 'e'])
    def test_get_available_reports(self, mock_get):
        mock_get.return_value = [self.report_type_json_data]
        canvas = Reports()
        ret = canvas.get_available_reports('12345')

        mock_get.assert_called_with('/api/v1/accounts/12345/reports')

        report = ret[0]
        self.assertEqual(report.name, self.report_type_json_data["report"])
        self.assertEqual(report.title, self.report_type_json_data["title"])
        self.assertEqual(report.last_run.type, self.report_json_data["report"])
        self.assertEqual(report.last_run.account_id, '12345')
    def test_get_report_status(self):
        canvas = Reports()

        # Bad report, missing account_id
        report = Report(report_id=1)
        self.assertRaises(ReportFailureException, canvas.get_report_status,
                          report)

        report = Report(data=self.report_json_data)
        report = canvas.get_report_status(report)
        self.assertEquals(report.report_id, 1)
        self.assertEquals(report.status, "complete")
        self.assertEquals(report.progress, "100")
Exemplo n.º 9
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)
    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)
Exemplo n.º 11
0
def create_report():
    settings_path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                                 'settings.cfg')
    use_configparser_backend(settings_path, 'Canvas')

    account_id = getattr(settings, 'RESTCLIENTS_CANVAS_ACCOUNT_ID')
    term = Terms().get_term_by_sis_id('2013-autumn')

    report_client = Reports()
    report = report_client.create_course_sis_export_report(
        account_id, term.term_id)

    print('Report created. Report ID: %s, progress: %s%%' % (
        report.report_id, report.progress))

    # Fetch the report data.  This method will poll Canvas until the
    # report has been generated, and then download the data file
    data = report_client.get_report_data(report)


    # Do something with the data...


    # Delete the report
    report_client.delete_report(report)
Exemplo n.º 12
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
Exemplo n.º 13
0
def get_unused_course_report_data(term_sis_id):
    term = Terms().get_term_by_sis_id(term_sis_id)
    account_id = getattr(settings, 'RESTCLIENTS_CANVAS_ACCOUNT_ID', None)

    reports = Reports()
    unused_course_report = reports.create_unused_courses_report(
        account_id, term_id=term.term_id)

    report_data = reports.get_report_data(unused_course_report)

    reports.delete_report(unused_course_report)
    return report_data
Exemplo n.º 14
0
    def test_create_course_provisioning_report(self, mock_post):
        canvas = Reports()
        canvas.create_course_provisioning_report('12345')
        mock_post.assert_called_with(
            '/api/v1/accounts/12345/reports/provisioning_csv',
            {'parameters': {
                'courses': True
            }})

        # With a term_id
        canvas.create_course_provisioning_report('12345',
                                                 term_id='2013-spring')
        mock_post.assert_called_with(
            '/api/v1/accounts/12345/reports/provisioning_csv', {
                'parameters': {
                    'courses': True,
                    'enrollment_term_id': '2013-spring'
                }
            })
Exemplo n.º 15
0
 def test_create_report(self, mock_post):
     canvas = Reports()
     canvas.create_report('some_type', '12345')
     mock_post.assert_called_with(
         '/api/v1/accounts/12345/reports/some_type', {'parameters': {}})
    def handle(self, *args, **options):
        subaccount_id = options.get('subaccount_id')
        sis_term_id = options.get('term_id')

        accounts = Accounts()
        reports = Reports()
        pws = PWS()

        outpath = "{}/{}-{}-{}.csv".format(
            dirname(__file__), "active-instructors", subaccount_id,
            sis_term_id)
        outfile = open(outpath, "w")
        csv.register_dialect('unix_newline', lineterminator='\n')
        writer = csv.writer(outfile, dialect='unix_newline')
        writer.writerow(['email', 'first_name', 'last_name'])

        account = accounts.get_account(subaccount_id)
        term = reports.get_term_by_sis_id(sis_term_id)

        enrollment_report = reports.create_enrollments_provisioning_report(
            account.account_id, term.term_id)
        enrollment_data = reports.get_report_data(enrollment_report)

        all_instructors = {}

        enrollment_csv_data = csv.reader(enrollment_data)
        header = next(enrollment_csv_data)
        course_id_idx = header.index("course_id")
        sis_user_id_idx = header.index("user_id")
        role_idx = header.index("role")
        status_idx = header.index("status")

        for row in enrollment_csv_data:
            if not len(row):
                continue

            course_id = row[course_id_idx]
            sis_user_id = row[sis_user_id_idx]
            role = row[role_idx]
            status = row[status_idx]

            if (sis_user_id != "" and role.lower() == "teacher" and
                    status.lower() == "active"):
                if course_id not in all_instructors:
                    all_instructors[course_id] = []

                all_instructors[course_id].append(sis_user_id)

        course_report = reports.create_course_provisioning_report(
            account.account_id, term.term_id)
        course_data = reports.get_report_data(course_report)

        course_csv_data = csv.reader(course_data)
        header = next(course_csv_data)
        course_id_idx = header.index("course_id")
        sis_account_id_idx = header.index("account_id")
        status_idx = header.index("status")

        active_instructors = {}
        for row in course_csv_data:
            if not len(row):
                continue

            course_id = row[course_id_idx]
            sis_account_id = row[sis_account_id_idx]
            status = row[status_idx]

            if (sis_account_id != "" and status.lower() == "active" and
                    course_id in all_instructors):
                for sis_user_id in all_instructors[course_id]:
                    if sis_user_id in active_instructors:
                        continue

                    try:
                        person = pws.get_person_by_regid(sis_user_id)
                        active_instructors[sis_user_id] = [
                            person.uwnetid + "@uw.edu",
                            person.preferred_first_name or person.first_name,
                            person.preferred_surname or person.surname]
                    except InvalidRegID:
                        continue
                    except DataFailureException as err:
                        if err.status == 404:
                            continue
                        else:
                            raise

        for csv_data in active_instructors.values():
            writer.writerow(csv_data)
        outfile.close()

        reports.delete_report(enrollment_report)
        reports.delete_report(course_report)

        print(outpath)