def test_compare_persons(self): pws = PWS() person1 = pws.get_person_by_regid("7718EB38AE3411D689DA0004AC494FFE") person2 = pws.get_person_by_regid("7718EB38AE3411D689DA0004AC494FFE") person3 = pws.get_person_by_regid("9136CCB8F66711D5BE060004AC494FFE") self.assertEquals(person1 == person2, True, "persons are equal") self.assertEquals(person1 == person3, False, "persons are inequal")
def test_compare_persons(self): with self.settings( RESTCLIENTS_PWS_DAO_CLASS='restclients.dao_implementation.pws.File'): pws = PWS() person1 = pws.get_person_by_regid("7718EB38AE3411D689DA0004AC494FFE") person2 = pws.get_person_by_regid("7718EB38AE3411D689DA0004AC494FFE") person3 = pws.get_person_by_regid("9136CCB8F66711D5BE060004AC494FFE") self.assertEquals(person1 == person2, True, "persons are equal") self.assertEquals(person1 == person3, False, "persons are inequal")
def test_pws_regid_500(self): with self.settings(RESTCLIENTS_PWS_DAO_CLASS='restclients.dao_implementation.errors.Always500'): pws = PWS() self.assertRaises(DataFailureException, pws.get_person_by_regid, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") try: pws.get_person_by_regid("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") self.fail("This needs to be an exception") except DataFailureException as ex: self.assertEqual(ex.status, 500, "Exception has the right status") self.assertEqual(ex.url, "/identity/v1/person/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/full.json", "Exception has the right url")
def test_pws_regid_500(self): with self.settings(RESTCLIENTS_PWS_DAO_CLASS= 'restclients.dao_implementation.errors.Always500'): pws = PWS() self.assertRaises(DataFailureException, pws.get_person_by_regid, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") try: pws.get_person_by_regid("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") self.fail("This needs to be an exception") except DataFailureException as ex: self.assertEqual(ex.status, 500, "Exception has the right status") self.assertEqual( ex.url, "/identity/v1/person/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/full.json", "Exception has the right url")
def _test_regid(self, netid, regid): with self.settings( RESTCLIENTS_PWS_DAO_CLASS='restclients.dao_implementation.pws.File'): pws = PWS() person = pws.get_person_by_regid(regid) self.assertEquals(person.uwnetid, netid, netid + "'s netid") self.assertEquals(person.uwregid, regid, netid + "'s regid")
def get_person_by_regid(regid): pws = PWS() try: person = pws.get_person_by_regid(regid) valid_net_id(person.uwnetid) except DataFailureException as err: if err.status == 404: # Non-personal regid? person = pws.get_entity_by_regid(regid) valid_nonpersonal_net_id(person.netid) else: raise return person
def _test_regid(self, netid, regid): pws = PWS() person = pws.get_person_by_regid(regid) self.assertEquals(person.uwnetid, netid, netid + "'s netid") self.assertEquals(person.uwregid, regid, netid + "'s regid")
def graderoster_from_xhtml(data, section, instructor): pws = PWS() people = {instructor.uwregid: instructor} graderoster = GradeRoster() graderoster.section = section graderoster.instructor = instructor graderoster.authorized_grade_submitters = [] graderoster.grade_submission_delegates = [] graderoster.items = [] tree = etree.fromstring(data.strip()) nsmap = {"xhtml": "http://www.w3.org/1999/xhtml"} root = tree.xpath(".//xhtml:div[@class='graderoster']", namespaces=nsmap)[0] default_section_id = None el = root.xpath("./xhtml:div/xhtml:a[@rel='section']/*[@class='section_id']", namespaces=nsmap)[0] default_section_id = el.text.upper() el = root.xpath("./xhtml:div/*[@class='section_credits']", namespaces=nsmap)[0] if el.text is not None: graderoster.section_credits = el.text.strip() el = root.xpath("./xhtml:div/*[@class='writing_credit_display']", namespaces=nsmap)[0] if el.get("checked", "") == "checked": graderoster.allows_writing_credit = True for el in root.xpath("./xhtml:div//*[@rel='authorized_grade_submitter']", namespaces=nsmap): reg_id = el.xpath(".//*[@class='reg_id']")[0].text.strip() if reg_id not in people: people[reg_id] = pws.get_person_by_regid(reg_id) graderoster.authorized_grade_submitters.append(people[reg_id]) for el in root.xpath("./xhtml:div//*[@class='grade_submission_delegate']", namespaces=nsmap): reg_id = el.xpath(".//*[@class='reg_id']")[0].text.strip() delegate_level = el.xpath(".//*[@class='delegate_level']")[0].text.strip() if reg_id not in people: people[reg_id] = pws.get_person_by_regid(reg_id) delegate = GradeSubmissionDelegate(person=people[reg_id], delegate_level=delegate_level) graderoster.grade_submission_delegates.append(delegate) for item in root.xpath("./*[@class='graderoster_items']/*[@class='graderoster_item']"): gr_item = GradeRosterItem(section_id=default_section_id) gr_item.grade_choices = [] for el in item.xpath(".//xhtml:a[@rel='student']/*[@class='reg_id']", namespaces=nsmap): gr_item.student_uwregid = el.text.strip() for el in item.xpath(".//xhtml:a[@rel='student']/*[@class='name']", namespaces=nsmap): full_name = el.text.strip() try: (surname, first_name) = full_name.split(",", 1) gr_item.student_first_name = first_name gr_item.student_surname = surname except ValueError: pass for el in item.xpath(".//*[@class]"): classname = el.get("class") if classname == "duplicate_code" and el.text is not None: duplicate_code = el.text.strip() if len(duplicate_code): gr_item.duplicate_code = duplicate_code elif classname == "section_id" and el.text is not None: gr_item.section_id = el.text.strip() elif classname == "student_former_name" and el.text is not None: student_former_name = el.text.strip() if len(student_former_name): gr_item.student_former_name = student_former_name elif classname == "student_number": gr_item.student_number = el.text.strip() elif classname == "student_credits" and el.text is not None: gr_item.student_credits = el.text.strip() elif "date_withdrawn" in classname and el.text is not None: gr_item.date_withdrawn = el.text.strip() elif classname == "incomplete": if el.get("checked", "") == "checked": gr_item.has_incomplete = True if el.get("disabled", "") != "disabled": gr_item.allows_incomplete = True elif classname == "writing_course": if el.get("checked", "") == "checked": gr_item.has_writing_credit = True elif classname == "auditor": if el.get("checked", "") == "checked": gr_item.is_auditor = True elif classname == "no_grade_now": if el.get("checked", "") == "checked": gr_item.no_grade_now = True elif classname == "grades": if el.get("disabled", "") != "disabled": gr_item.allows_grade_change = True elif classname == "grade": grade = el.text.strip() if el.text is not None else "" gr_item.grade_choices.append(grade) if el.get("selected", "") == "selected": gr_item.grade = grade elif classname == "grade_document_id" and el.text is not None: gr_item.grade_document_id = el.text.strip() elif "date_graded" in classname and el.text is not None: gr_item.date_graded = el.text.strip() elif classname == "grade_submitter_source" and el.text is not None: gr_item.grade_submitter_source = el.text.strip() elif classname == "code" and el.text is not None: gr_item.status_code = el.text.strip() elif classname == "message" and el.text is not None: gr_item.status_message = el.text.strip() for el in item.xpath(".//xhtml:a[@rel='grade_submitter_person']/*[@class='reg_id']", namespaces=nsmap): reg_id = el.text.strip() if reg_id not in people: people[reg_id] = pws.get_person_by_regid(reg_id) gr_item.grade_submitter_person = people[reg_id] graderoster.items.append(gr_item) return graderoster
def _json_to_section(section_data, term=None, include_instructor_not_on_time_schedule=True): """ Returns a section model created from the passed json. """ pws = PWS() section = Section() if term is not None and (term.year == int(section_data["Course"]["Year"]) and term.quarter == section_data["Course"]["Quarter"]): section.term = term else: section.term = get_term_by_year_and_quarter( section_data["Course"]["Year"], section_data["Course"]["Quarter"]) section.curriculum_abbr = section_data["Course"]["CurriculumAbbreviation"] section.course_number = section_data["Course"]["CourseNumber"] section.course_title = section_data["CourseTitle"] section.course_title_long = section_data["CourseTitleLong"] section.course_campus = section_data["CourseCampus"] section.section_id = section_data["SectionID"] section.institute_name = section_data.get("InstituteName", "") section.primary_lms = section_data.get("PrimaryLMS", None) section.lms_ownership = section_data.get("LMSOwnership", None) section.is_independent_start = section_data.get("IsIndependentStart", False) section.section_type = section_data["SectionType"] if "independent study" == section.section_type: section.is_independent_study = True else: section.is_independent_study = False section.class_website_url = section_data["ClassWebsiteUrl"] section.sln = section_data["SLN"] if "SummerTerm" in section_data: section.summer_term = section_data["SummerTerm"] else: section.summer_term = "" section.delete_flag = section_data["DeleteFlag"] if "withdrawn" == section.delete_flag: section.is_withdrawn = True else: section.is_withdrawn = False section.current_enrollment = int(section_data['CurrentEnrollment']) section.auditors = int(section_data['Auditors']) section.allows_secondary_grading = section_data["SecondaryGradingOption"] primary_section = section_data["PrimarySection"] if (primary_section is not None and primary_section["SectionID"] != section.section_id): section.is_primary_section = False section.primary_section_href = primary_section["Href"] section.primary_section_id = primary_section["SectionID"] section.primary_section_curriculum_abbr = primary_section[ "CurriculumAbbreviation"] section.primary_section_course_number = primary_section["CourseNumber"] else: section.is_primary_section = True section.linked_section_urls = [] for linked_section_type in section_data["LinkedSectionTypes"]: for linked_section_data in linked_section_type["LinkedSections"]: url = linked_section_data["Section"]["Href"] section.linked_section_urls.append(url) section.joint_section_urls = [] for joint_section_data in section_data.get("JointSections", []): url = joint_section_data["Href"] section.joint_section_urls.append(url) section.grade_submission_delegates = [] for del_data in section_data["GradeSubmissionDelegates"]: delegate = GradeSubmissionDelegate( person=pws.get_person_by_regid(del_data["Person"]["RegID"]), delegate_level=del_data["DelegateLevel"]) section.grade_submission_delegates.append(delegate) section.meetings = [] for meeting_data in section_data["Meetings"]: meeting = SectionMeeting() meeting.section = section meeting.term = section.term meeting.meeting_index = meeting_data["MeetingIndex"] meeting.meeting_type = meeting_data["MeetingType"] meeting.building = meeting_data["Building"] if meeting_data["BuildingToBeArranged"]: meeting.building_to_be_arranged = True else: meeting.building_to_be_arranged = False meeting.room_number = meeting_data["RoomNumber"] if meeting_data["RoomToBeArranged"]: meeting.room_to_be_arranged = True else: meeting.room_to_be_arranged = False if meeting_data["DaysOfWeekToBeArranged"]: meeting.days_to_be_arranged = True else: meeting.days_to_be_arranged = False for day_data in meeting_data["DaysOfWeek"]["Days"]: attribute = "meets_%s" % day_data["Name"].lower() setattr(meeting, attribute, True) meeting.start_time = meeting_data["StartTime"] meeting.end_time = meeting_data["EndTime"] meeting.instructors = [] for instructor_data in meeting_data["Instructors"]: # TSPrint: True # Instructor information currently listed on the Time Schedule if instructor_data[ "TSPrint"] or include_instructor_not_on_time_schedule: pdata = instructor_data["Person"] if "RegID" in pdata and pdata["RegID"] is not None: try: instructor = pws.get_person_by_regid(pdata["RegID"]) except: instructor = Person(uwregid=pdata["RegID"], display_name=pdata["Name"]) instructor.TSPrint = instructor_data["TSPrint"] meeting.instructors.append(instructor) section.meetings.append(meeting) section.final_exam = None if "FinalExam" in section_data and section_data["FinalExam"] is not None: if "MeetingStatus" in section_data["FinalExam"]: final_exam = FinalExam() final_data = section_data["FinalExam"] status = final_data["MeetingStatus"] final_exam.no_exam_or_nontraditional = False final_exam.is_confirmed = False if (status == "2") or (status == "3"): final_exam.is_confirmed = True elif status == "1": final_exam.no_exam_or_nontraditional = True final_exam.building = final_data["Building"] final_exam.room_number = final_data["RoomNumber"] final_format = "%Y-%m-%d : %H:%M" strptime = datetime.strptime if final_data["Date"] and final_data["Date"] != "0000-00-00": if final_data["StartTime"]: start_string = "%s : %s" % (final_data["Date"], final_data["StartTime"]) final_exam.start_date = strptime(start_string, final_format) if final_data["EndTime"]: end_string = "%s : %s" % (final_data["Date"], final_data["EndTime"]) final_exam.end_date = strptime(end_string, final_format) final_exam.clean_fields() section.final_exam = final_exam return section
def _json_to_section(section_data, term=None, include_instructor_not_on_time_schedule=True): """ Returns a section model created from the passed json. """ pws = PWS() section = Section() if term is not None and ( term.year == int(section_data["Course"]["Year"]) and term.quarter == section_data["Course"]["Quarter"]): section.term = term else: section.term = get_term_by_year_and_quarter( section_data["Course"]["Year"], section_data["Course"]["Quarter"]) section.curriculum_abbr = section_data["Course"][ "CurriculumAbbreviation"] section.course_number = section_data["Course"]["CourseNumber"] section.course_title = section_data["CourseTitle"] section.course_title_long = section_data["CourseTitleLong"] section.course_campus = section_data["CourseCampus"] section.section_id = section_data["SectionID"] section.institute_name = section_data.get("InstituteName", "") section.primary_lms = section_data.get("PrimaryLMS", None) section.lms_ownership = section_data.get("LMSOwnership", None) section.is_independent_start = section_data.get("IsIndependentStart", False) # Some section data sources have different formats for these dates. try: date_format = "%Y-%m-%d" if section_data.get("StartDate", None): str_date = section_data["StartDate"] start_date = datetime.strptime(str_date, date_format).date() section.start_date = start_date if section_data.get("EndDate", None): str_date = section_data["EndDate"] section.end_date = datetime.strptime(str_date, date_format).date() except Exception as ex: pass section.section_type = section_data["SectionType"] if "independent study" == section.section_type: section.is_independent_study = True else: section.is_independent_study = False section.class_website_url = section_data["ClassWebsiteUrl"] section.sln = section_data["SLN"] if "SummerTerm" in section_data: section.summer_term = section_data["SummerTerm"] else: section.summer_term = "" section.delete_flag = section_data["DeleteFlag"] if "withdrawn" == section.delete_flag: section.is_withdrawn = True else: section.is_withdrawn = False section.current_enrollment = int(section_data['CurrentEnrollment']) section.auditors = int(section_data['Auditors']) section.allows_secondary_grading = section_data["SecondaryGradingOption"] primary_section = section_data["PrimarySection"] if (primary_section is not None and primary_section["SectionID"] != section.section_id): section.is_primary_section = False section.primary_section_href = primary_section["Href"] section.primary_section_id = primary_section["SectionID"] section.primary_section_curriculum_abbr = primary_section[ "CurriculumAbbreviation"] section.primary_section_course_number = primary_section[ "CourseNumber"] else: section.is_primary_section = True section.linked_section_urls = [] for linked_section_type in section_data["LinkedSectionTypes"]: for linked_section_data in linked_section_type["LinkedSections"]: url = linked_section_data["Section"]["Href"] section.linked_section_urls.append(url) section.joint_section_urls = [] for joint_section_data in section_data.get("JointSections", []): url = joint_section_data["Href"] section.joint_section_urls.append(url) section.grade_submission_delegates = [] for del_data in section_data["GradeSubmissionDelegates"]: delegate = GradeSubmissionDelegate( person=pws.get_person_by_regid(del_data["Person"]["RegID"]), delegate_level=del_data["DelegateLevel"]) section.grade_submission_delegates.append(delegate) section.meetings = [] for meeting_data in section_data["Meetings"]: meeting = SectionMeeting() meeting.section = section meeting.term = section.term meeting.meeting_index = meeting_data["MeetingIndex"] meeting.meeting_type = meeting_data["MeetingType"] meeting.building = meeting_data["Building"] if meeting_data["BuildingToBeArranged"]: meeting.building_to_be_arranged = True else: meeting.building_to_be_arranged = False meeting.room_number = meeting_data["RoomNumber"] if meeting_data["RoomToBeArranged"]: meeting.room_to_be_arranged = True else: meeting.room_to_be_arranged = False if meeting_data["DaysOfWeekToBeArranged"]: meeting.days_to_be_arranged = True else: meeting.days_to_be_arranged = False for day_data in meeting_data["DaysOfWeek"]["Days"]: attribute = "meets_%s" % day_data["Name"].lower() setattr(meeting, attribute, True) meeting.start_time = meeting_data["StartTime"] meeting.end_time = meeting_data["EndTime"] meeting.instructors = [] for instructor_data in meeting_data["Instructors"]: # TSPrint: True # Instructor information currently listed on the Time Schedule if (instructor_data["TSPrint"] or include_instructor_not_on_time_schedule): pdata = instructor_data["Person"] if "RegID" in pdata and pdata["RegID"] is not None: try: instructor = pws.get_person_by_regid(pdata["RegID"]) except: instructor = Person(uwregid=pdata["RegID"], display_name=pdata["Name"]) instructor.TSPrint = instructor_data["TSPrint"] meeting.instructors.append(instructor) section.meetings.append(meeting) section.final_exam = None if "FinalExam" in section_data and section_data["FinalExam"] is not None: if "MeetingStatus" in section_data["FinalExam"]: final_exam = FinalExam() final_data = section_data["FinalExam"] status = final_data["MeetingStatus"] final_exam.no_exam_or_nontraditional = False final_exam.is_confirmed = False if (status == "2") or (status == "3"): final_exam.is_confirmed = True elif status == "1": final_exam.no_exam_or_nontraditional = True final_exam.building = final_data["Building"] final_exam.room_number = final_data["RoomNumber"] final_format = "%Y-%m-%d : %H:%M" strptime = datetime.strptime if final_data["Date"] and final_data["Date"] != "0000-00-00": if final_data["StartTime"]: start_string = "%s : %s" % (final_data["Date"], final_data["StartTime"]) final_exam.start_date = strptime(start_string, final_format) if final_data["EndTime"]: end_string = "%s : %s" % (final_data["Date"], final_data["EndTime"]) final_exam.end_date = strptime(end_string, final_format) final_exam.clean_fields() section.final_exam = final_exam return section
def handle(self, *args, **options): if len(args) == 2: subaccount_id = args[0] sis_term_id = args[1] else: raise CommandError("find_active_instructors <subaccount_id> <term_id>") accounts = Accounts() reports = Reports() pws = PWS() 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 = enrollment_csv_data.next() 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 = course_csv_data.next() 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 not in active_instructors: try: person = pws.get_person_by_regid(sis_user_id) email = person.uwnetid + "@uw.edu" active_instructors[sis_user_id] = email except InvalidRegID: continue except DataFailureException as err: if err.status == 404: continue else: raise filename = "-".join(["active-instructors", subaccount_id, sis_term_id]) outpath = dirname(__file__) + "/" + filename + ".txt" f = open(outpath, "w") data = active_instructors.values() data.sort() f.write("\n".join(data)) f.close() reports.delete_report(enrollment_report) reports.delete_report(course_report) print outpath