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")
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)
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)
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 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
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' } })
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)