Example #1
0
def next_semester_courses(offered_courses, remaining_courses):
    # Dictionary to store all the courses
    future_options = {}
    # Loop through the offered_courses and store their info
    for courses in __parse_xml(offered_courses).findall(".//LIST_G_COURSE_NO"):
        for course in courses:
            id = course.find("COURSE_NO").text.replace("-", "")
            if id in remaining_courses:
                course_details = {
                    "CRN": course.find("SSBSECT_CRN").text,
                    "title": course.find("SCBCRSE_TITLE").text,
                    "crd_hr": course.find("SCBCRSE_CREDIT_HR_LOW").text,
                    "max": course.find("SSBSECT_MAX_ENRL").text,
                    "actual": course.find("SSBSECT_ENRL").text
                }
                sec_no = 0

                for section in __parse_xml(offered_courses).findall(".//LIST_G_SSBSECT_SCHD_CODE"):
                    section_details = {
                        "building": section.find(".//SSRMEET_BLDG_CODE").text,
                        "room": section.find(".//SSRMEET_ROOM_CODE").text,
                        "time": section.find(".//TIME").text,
                        "days": section.find(".//DAYES").text
                    }
                    course_details["section_" + str(sec_no+1)] = section_details
                future_options[id] = course_details
    return future_options
Example #2
0
def courses_list(response, url=lambda x: x):
    terms = {}
    # Loop through courses registered in Blackboard
    for course in __parse_xml(response).findall(
            ".//course[@roleIdentifier='S']"):
        # Extract course key, crn and term string from course identifier
        course_key, crn, term_string = course.get("courseid").split("_")
        # Make sure that term id is of the following format "FALL2017"
        term_string = term_string.split("-")[0]
        # Split term id to year and semester
        year, semester = term_string[-4:], __terms[term_string[:3]]
        # Get term full name of the following format "Fall 2017-2018"
        term_name = f"{semester['name']} {year}-{int(year) + 1}"
        # If term hasn't been added yet
        if term_name not in terms:
            # Initialize it with an empty dictionary
            terms[term_name] = {}
        # Add course to the correspondent term
        terms[term_name][__clean(course.get("name"))] = {
            # Content links to Blackboard's documents and deadlines
            "Content": url(course_key + "/" + course.get("bbid")[1:-2]),
            # Details links to MyUDC's course details
            "Details": url(f"{course_key}/{crn}/{year + semester['code']}")
        }
    return terms
Example #3
0
def schedule(response):
    # Dictionary to store schedule details
    details = {}
    # Loop through courses in the schedule report to get its details
    for course in __parse_xml(response).find(".//LIST_G_SSBSECT_CRN"):
        course_id = course.find("SSBSECT_SUBJ_CODE").text + course.find("SSBSECT_CRSE_NUMB").text
        # Scrape and store data dictionary in details["course id"]
        details[course_id] = {
            "crn": course.find("SSBSECT_CRN").text,
            "section": course.find("SSBSECT_SEQ_NUMB").text,
            "type": course.find("SSBSECT_SCHD_CODE").text,
            "credits": course.find("SFRSTCR_CREDIT_HR").text,
            "title": course.find("SCBCRSE_TITLE").text.strip(),
            # Initialize an empty classes array for later
            "classes": []
        }
        # Loop through days in the current course
        for day in course.find("LIST_G_DAYES"):
            # Add a class dictionary of data for every day in course
            details[course_id]["classes"].append({
                "days": day.find("DAYES").text.split(),
                "time": day.find("TIME").text.split(" - "),
                "building": day.find("SSRMEET_BLDG_CODE").text,
                "room": day.find("SSRMEET_ROOM_CODE").text,
                # Place doctors in an array as there might be many
                "doctor": [
                    doctor.find("CF_INSTRUCTOR_NAME").text
                    # Loop through doctor in the current day
                    for doctor in day.find("LIST_G_SIRASGN_PIDM")
                ]
            })
    return details
Example #4
0
def values_of_majors(schedules):
    return {
        # Add student's major from his schedule as {"major name": "major initials"}
        schedule.find("CF_MAJR_DESC").text: schedule.find("SGBSTDN_MAJR_CODE_1").text
        # Loop through each schedule from schedules report
        for schedule in __parse_xml(schedules).find("LIST_G_STVCOLL_DESC")
    }
Example #5
0
def grades_and_gpa(transcript, term_code):
    # Parse xml and declare variables
    xml = __parse_xml(transcript)
    try:
        quality = float(xml.find(".//SHRLGPA_QUALITY_POINTS").text)
        hours = int(xml.find(".//SHRLGPA_GPA_HOURS").text)
    except AttributeError: quality, hours = 0, 0
    all_hours = hours
    term_quality = 0
    grades = []
    # Loop through the available terms in transcript
    terms = xml.find(".//LIST_G_ACADEMIC_HIST_TERM")
    for term in terms if terms is not None else ():
        # If the term is the selected one
        if term.find("TERM_CODE_KEY").text == term_code:
            # Loop through courses in that term
            for course in term.find("LIST_G_ACADEMIC_HIST_DETAILS"):
                # Store its credit hours, grade and key
                crhrs = int(course.find("CREDIT_HOURS").text)
                grade = course.find("GRDE_CODE_FINAL").text
                key = course.find("SUBJ_CODE").text[-7:]
                # Add them to total hours and term quality
                all_hours += crhrs
                term_quality += __to_gpa(grade, 0) * crhrs
                # Add course's (key, title, grade) to the grades list
                grades.append((key, course.find("COURSE_TITLE").text, grade))
    # Calculate and return new grades and (term, new and old GPA)
    return grades, {
        "term": term_quality / (all_hours - hours) if all_hours != hours else 0,
        "new": (term_quality + quality) / all_hours if all_hours else 0,
        "old": quality / hours if hours else 0
    }
Example #6
0
def courses_dictionary(response):
    return {
        # Store courses ids in {Blackboard id: MyUDC id} pairs
        course.get("bbid")[1:-2]: course.get("courseid").split("_", 1)[0]
        # Loop through all courses in Blackboard in which the user is a student
        for course in __parse_xml(response).findall(
            ".//course[@roleIdentifier='S']")
    }
Example #7
0
def study_plan_courses(study_plan):
    # Dictionary to store all the courses
    all_courses = set()
    # Loop through the study_plan and store their info
    for term in __parse_xml(study_plan).findall(".//LIST_G_GROUP_COURSES"):
        for course in term:
            if course.find("CF_IS_PASSED").text == 'N':
                all_courses.add(course.find("COURSE_NUMB1").text)

    return all_courses
Example #8
0
def remaining_courses(study_plan):
    plan = __parse_xml(study_plan)
    return {
        "crhrs": int(plan.find(".//SMBPOGN_REQ_CREDITS_OVERALL").text)
            - int(plan.find(".//SMBPOGN_ACT_CREDITS_OVERALL").text),
        "courses": [
            course.find("COURSE_NUMB1").text
            for course in plan.findall(".//G_GROUP_COURSES")
            if course.find("CF_IS_PASSED").text == "N"
        ]
    }
Example #9
0
def terms_list(response):
    terms = {}
    # Loop through courses registered in Blackboard
    for course in __parse_xml(response).findall(
            ".//course[@roleIdentifier='S']"):
        # Extract term's string from course id in "FALL2017" format
        term_string = course.get("courseid").rsplit("_", 1)[-1].split("-")[0]
        # Split term id to year and term semester
        year, semester = term_string[-4:], __terms[term_string[:3]]
        # Store term in terms in {"Fall 2017-2018": "201710"} pairs
        terms[f"{semester['name']} {year}-{int(year) + 1}"] = year + semester[
            "code"]
    return terms
Example #10
0
def values_of(courses, *params):
    # For each supported value, create an empty dictionary in values for later use
    values = {param: {} for param in params if param in ["Campus", "College", "Department"]}
    # Loop through courses to get the required values
    for course in __parse_xml(courses).find("LIST_G_SSBSECT_TERM_CODE"):
        # If campus values are required
        if "Campus" in values:
            # Add course's campus to values as {"campus name": "campus abbreviation"}
            values["Campus"].update({course.find("CAMPUS_DESC").text: course.find("SSBSECT_CAMP_CODE").text})
        # If college values are required
        if "College" in values:
            # Add course's college to values as {"college name": "college number"}
            values["College"].update({course.find("COLLEGE_NAME").text: course.find("SCBCRSE_COLL_CODE").text})
        # If department values are required
        if "Department" in values:
            # Add course's department to values as {"department name": "department initials"}
            values["Department"].update({course.find("DEPT_NAME").text: course.find("SCBCRSE_DEPT_CODE").text})
    return values
Example #11
0
def courses_by_term(response, term_code):
    courses = {}
    # Get Blackboard term string in "FALL2017" format from term code
    term_string = re.compile("^" + __terms[term_code[4:]]["name"] + "[A-Z]*" +
                             term_code[:4])
    # Loop through list of courses in parsed XML
    for course in __parse_xml(response).find("courses"):
        # Store course's MyUDC id, CRN and term name
        key, crn, full_term = course.get("courseid").split("_")
        # Only add courses in the requested term and in which the user is a student
        if term_string.match(full_term) and course.get(
                "roleIdentifier") == "S":
            # Add course ids in {MyUDC id: Blackboard id} pairs
            courses[key] = {
                # Store course's Blackboard id
                "courseId": course.get("bbid")[1:-2],
                "crn": crn
            }
    return courses
Example #12
0
def course_data(response, course_key, course_id, data_type=None):
    # Store parsed course and returned object structure
    course = __parse_xml(response)
    data = {"deadlines": [], "documents": []}
    # If requested data type isn't "documents"
    if data_type != "documents":
        # Scrape deadlines and add them to data
        data["deadlines"] = [
            {  # Store deadline's title, due date & other information
                "title": deadline.get("name"),
                "dueDate": deadline.get("dueDate"),
                "time": deadline.get("createdDate"),
                "course": course_key,
                "courseId": course_id,
                "contentId": deadline.get("contentid")[1:-2]
            }  # Loop through all course items which have a due date
            for deadline in course.findall(".//*[@dueToday]")
        ]
        # If requested data type is "deadlines"
        if data_type == "deadlines":
            # Only return the deadlines
            return data["deadlines"]
    # If requested data type isn't "deadlines"
    if data_type != "deadlines":
        # Scrape documents and add them to data
        data["documents"] = [
            {  # Extract document xid and content id using Regex from its URL
                "id": "_".join(__document_ids.search(document.get("url")).groups()),
                # Store document's title, upload date & course key
                "course": course_key,
                "title": document.getparent().getparent().get("name"),
                "file": document.get("name"),
                "time": document.get("modifiedDate"),
            }   # Loop through all course documents (not more than 25)
            for document in (course.findall(".//attachment") or [])[:25]
        ]
        # If requested data type is "documents"
        if data_type == "documents":
            # Only return the documents
            return data["documents"]
    # Return everything if data type isn't specified or invalid
    return data
Example #13
0
def scrape_course_grades(response, course_key):
    grades = []
    # Loop through grades in available in course
    for grade in __parse_xml(response).find("grades"):
        print(grade.get("name"))
        # Store last modified time
        time = grade.get("lastInstructorActivity")
        # If it's a graded items
        if time:
            # Add grade dictionary to grades
            grades.append({
                # Add item's title, grade & course key
                "course": course_key,
                "title": grade.get("name"),
                "grade": ceil(float(grade.get("grade"))),
                # Add total grade and uploaded time
                "outOf": ceil(float(grade.get("pointspossible"))),
                "time": time
            })
    return grades
Example #14
0
def core_details(transcript):
    # Find and store the element which contains the required info
    soup = __parse_xml(transcript).find(".//G_SGBSTDN")
    # Create a dictionary of straight forward to reach info
    details = {
        # Store student's name, college, major and terms
        "name": soup.find("STUDENT_NAME").text.strip(),
        "college": soup.find("CURR_COLL_CODE").text,
        "major": soup.find("CURR_MAJR_CODE").text,
        "terms": {
            # Initialize in progress term
            "in_progress": {},
            # Store all terms key
            "all_keys": [
                # Place term key in the array
                term.find("TERM_CODE_KEY").text
                # Loop through terms which aren't in progress
                for term in soup.find(".//LIST_G_ACADEMIC_HIST_TERM")
            ]
        },
        # Store student's first term to be used in offered_courses()
        "first_term": soup.find("FIRST_TERM_ADMIT").text
    }
    # Loop through in progress terms and keep the index of looping
    for index, term in enumerate(soup.find("LIST_G_SFRSTCR_PIDM")):
        # Add in progress term's key to all terms key
        details["terms"]["all_keys"].append(term.find("SFRSTCR_TERM_CODE").text)
        # If it's the first in progress term
        if index == 0:
            # Store its key and courses as the "in_progress" term
            details["terms"]["in_progress"][term.find("SFRSTCR_TERM_CODE").text] = {
                # Combine course's subject code and section code to get its key
                course.find("SSBSECT_SUBJ_CODE").text + course.find("SSBSECT_CRSE_NUMB").text:
                    # With the line above, form {"course key": "course name"} pairs
                    course.find("SFRSTCR_COURSE_TITLE").text.strip()
                # Loop through courses in that term
                for course in term.find("LIST_G_SFRSTCR_DETAIL")
            }
    return details