pittcsc / PittAPI

An API to easily get data from the University of Pittsburgh
https://pittapi.pittcsc.org
GNU General Public License v2.0
105 stars 30 forks source link

Adding new implementation of Course API using PeopleSoft Mobile #100

Closed azharichenko closed 5 years ago

azharichenko commented 5 years ago

Switching over to PeopleSoft

This pull request is meant to complete issue #98.

There are a few new changes that should improve the overall feel and usage of the API.

Feature 1: Using PeopleSoft's Mobile APIs

The replacement search site for classes is now https://psmobile.pitt.edu/app/catalog/classSearch/. The main advantage for us on this new site is that when you search it makes an API call to fetch information about courses, and with it, we can use very custom search criteria.

I quickly exploited it, just needed to create a custom payload and be able to generate a CSRFToken for it on the fly and we are in business. The output from the calls is, unfortunately, HTML, but the extra neat thing is that the payloads can be tweaked and customized to narrow down a specific search for a particular course or time that course occurs. And allow future implementation of allowing other students on other Pitt campuses to search(though currently don't care enough to bother to support that :joy:)

Feature 2: Consistent Course Naming Convention

The goal was trying to minimize confusion on how PeopleSoft structures things. The most confusing term being used in the previous version is class so it's been avoided. What I'm saying it the official structure is a subject contains many courses and a course contains many various sections (sections could be a lecture, recitation, tec.).

So the set of functions are now...

Feature 3: Object-oriented Design

There is a new introduction to using three new classes PittSubject, PittCourse and PittSection. I felt that an object-oriented approach may make that library much more easily usable so.

For example, to get courses for a subject (during a certain term) will look like this...

from PittAPI import course
cs = course.get_term_courses(term='2194', subject='CS')
cs # < Pitt Subject | 2194 | CS | 52 courses >

to access a certain course... (the object will correct the course enter for all courses are 4 digit numbers)

cs['0007'] # < Pitt Course | 2194 | CS 0007 >
cs['7'] # < Pitt Course | 2194 | CS 0007 >
cs['449'] #  < Pitt Course | 2194 | CS 0449 >
cs['1501'] # < Pitt Course | 2194 | CS 1501 >

cs['443'] # ValueError: Course 0443 not present in subject

With getting sections from a course being as simple as this...

cs['1501'].sections

"""
[<Pitt Section | CS 1501 | LEC 27740 | Nicholas Farnan >,
 <Pitt Section | CS 1501 | LEC 27741 | Nicholas Farnan >,
 <Pitt Section | CS 1501 | REC 27742 | Staff >,
 <Pitt Section | CS 1501 | REC 27743 | Staff >,
 <Pitt Section | CS 1501 | REC 27744 | Staff >,
 <Pitt Section | CS 1501 | REC 27745 | Staff >,
 <Pitt Section | CS 1501 | LEC 27746 | Nicholas Farnan >,
 <Pitt Section | CS 1501 | REC 27747 | Staff >,
 <Pitt Section | CS 1501 | REC 27748 | Staff >,
 <Pitt Section | CS 1501 | LEC 27749 | Nicholas Farnan >,
 <Pitt Section | CS 1501 | REC 27750 | Staff >,
 <Pitt Section | CS 1501 | REC 27751 | Staff >]
"""

And with all the more details on a section

cs['1501'].sections[0].to_dict()

"""
{'days': ['Mo', 'We'],
 'end_date': datetime.datetime(2019, 4, 19, 0, 0),
 'instructor': 'Nicholas Farnan',
 'number': '27740',
 'room': '5129 Sennott Square',
 'section': '1040',
 'start_date': datetime.datetime(2019, 1, 7, 0, 0),
 'subject': 'CS',
 'term': '2194',
 'times': ['9:30am', '10:45am']}
"""

And a minor mention all classes have a to_dict() method, allowing a user to get away from the object-oriented approach when necessary.

azharichenko commented 5 years ago

Yeah, I'm currently working on them. Just wanted to make sure that what I built seems reasonable.