From 217ae9e93319b66be0614512d7a54db81eeb5cdf Mon Sep 17 00:00:00 2001 From: aditeyabaral Date: Tue, 30 Apr 2024 07:05:03 +0000 Subject: [PATCH] Minor refactor and handle no seating bug --- pesuacademy/models/__init__.py | 3 +- ...seating_info.py => seating_information.py} | 6 +- pesuacademy/pages/__init__.py | 2 +- pesuacademy/pages/seating_info.py | 32 ---------- pesuacademy/pages/seating_information.py | 58 +++++++++++++++++++ pesuacademy/pesuacademy.py | 6 +- pesuacademy/util/__init__.py | 1 - pesuacademy/util/page.py | 2 +- pesuacademy/util/seating_info.py | 21 ------- 9 files changed, 67 insertions(+), 64 deletions(-) rename pesuacademy/models/{seating_info.py => seating_information.py} (81%) delete mode 100644 pesuacademy/pages/seating_info.py create mode 100644 pesuacademy/pages/seating_information.py delete mode 100644 pesuacademy/util/seating_info.py diff --git a/pesuacademy/models/__init__.py b/pesuacademy/models/__init__.py index 83f7087..297e623 100644 --- a/pesuacademy/models/__init__.py +++ b/pesuacademy/models/__init__.py @@ -9,5 +9,4 @@ AddressDetails, QualifyingExamination, ) - -from .seating_info import SeatingInfo \ No newline at end of file +from .seating_information import SeatingInformation diff --git a/pesuacademy/models/seating_info.py b/pesuacademy/models/seating_information.py similarity index 81% rename from pesuacademy/models/seating_info.py rename to pesuacademy/models/seating_information.py index cb1f5a0..7ffa414 100644 --- a/pesuacademy/models/seating_info.py +++ b/pesuacademy/models/seating_information.py @@ -1,4 +1,4 @@ -class SeatingInfo: +class SeatingInformation: def __init__( self, name: str, @@ -6,7 +6,7 @@ def __init__( date: str, time: str, terminal: str, - block: str + block: str, ): self.name = name self.course_code = course_code @@ -16,4 +16,4 @@ def __init__( self.block = block def __str__(self): - return f"{self.__dict__}" \ No newline at end of file + return f"{self.__dict__}" diff --git a/pesuacademy/pages/__init__.py b/pesuacademy/pages/__init__.py index 59cff9c..ec47eb2 100644 --- a/pesuacademy/pages/__init__.py +++ b/pesuacademy/pages/__init__.py @@ -1,4 +1,4 @@ from .attendance import AttendancePageHandler from .courses import CoursesPageHandler from .profile import ProfilePageHandler -from .seating_info import SeatingInfoHandler \ No newline at end of file +from .seating_information import SeatingInformationHandler diff --git a/pesuacademy/pages/seating_info.py b/pesuacademy/pages/seating_info.py deleted file mode 100644 index 7760248..0000000 --- a/pesuacademy/pages/seating_info.py +++ /dev/null @@ -1,32 +0,0 @@ -import datetime - -import requests_html -from bs4 import BeautifulSoup - -from pesuacademy import util -from pesuacademy.models import SeatingInfo - -# https://www.pesuacademy.com/Academy/s/studentProfilePESUAdmin?menuId=655&url=studentProfilePESUAdmin&controllerMode=6404&actionType=5&id=0&selectedData=0&_=1713930380582 -class SeatingInfoHandler: - @staticmethod - def get_page(session: requests_html.HTMLSession) -> list[SeatingInfo]: - try: - profile_url = ( - "https://www.pesuacademy.com/Academy/s/studentProfilePESUAdmin" - ) - query = { - "menuId": "655", - "url": "studentProfilePESUAdmin", - "controllerMode": "6404", - "actionType": "5", - "id": "0", - "selectedData": "0", - "_": str(int(datetime.datetime.now().timestamp() * 1000)), - } - response = session.get(profile_url, allow_redirects=False, params=query) - if response.status_code != 200: - raise ConnectionError("Unable to fetch seating info.") - soup = BeautifulSoup(response.text, "lxml") - return util.seating_info.get_seating_info_from_page(soup) - except Exception: - raise ConnectionError("Unable to fetch seating info.") diff --git a/pesuacademy/pages/seating_information.py b/pesuacademy/pages/seating_information.py new file mode 100644 index 0000000..131984a --- /dev/null +++ b/pesuacademy/pages/seating_information.py @@ -0,0 +1,58 @@ +import datetime + +import requests_html +from bs4 import BeautifulSoup + +from pesuacademy.models import SeatingInformation + + +class SeatingInformationHandler: + @staticmethod + def get_seating_information_from_page( + soup: BeautifulSoup, + ) -> list[SeatingInformation]: + info_table = soup.find("table", attrs={"id": "seatinginfo"}) + tablebody = info_table.find("tbody") + tablerows = tablebody.find_all("tr") + seating_info = list() + for row in tablerows: + columns = row.find_all("td") + assn_name = columns[0].text.strip() + course_code = columns[1].text.strip() + date = columns[2].text.strip() + time = columns[3].text.strip() + terminal = columns[4].text.strip() + block = columns[5].text.strip() + seating_info.append( + SeatingInformation(assn_name, course_code, date, time, terminal, block) + ) + return seating_info + + @staticmethod + def get_page(session: requests_html.HTMLSession) -> list[SeatingInformation]: + try: + profile_url = ( + "https://www.pesuacademy.com/Academy/s/studentProfilePESUAdmin" + ) + query = { + "menuId": "655", + "url": "studentProfilePESUAdmin", + "controllerMode": "6404", + "actionType": "5", + "id": "0", + "selectedData": "0", + "_": str(int(datetime.datetime.now().timestamp() * 1000)), + } + response = session.get(profile_url, allow_redirects=False, params=query) + if response.status_code != 200: + raise ConnectionError("Unable to fetch seating info.") + soup = BeautifulSoup(response.text, "lxml") + if ( + (no_seating_tag := soup.find("h5")) is not None + and no_seating_tag.text == "No Test Seating Info is available" + ): + return [] + else: + return SeatingInformationHandler.get_seating_information_from_page(soup) + except Exception: + raise ConnectionError("Unable to fetch seating info.") diff --git a/pesuacademy/pesuacademy.py b/pesuacademy/pesuacademy.py index 99e78ea..b019c95 100644 --- a/pesuacademy/pesuacademy.py +++ b/pesuacademy/pesuacademy.py @@ -4,7 +4,7 @@ from bs4 import BeautifulSoup from pesuacademy import util -from pesuacademy.models.seating_info import SeatingInfo +from pesuacademy.models.seating_information import SeatingInformation from pesuacademy.util.page import PageHandler from .exceptions import CSRFTokenError, AuthenticationError from .models import Profile, ClassAndSectionInfo, Course @@ -157,7 +157,7 @@ def attendance(self, semester: Optional[int] = None) -> dict[int, list[Course]]: attendance_info = self.page_handler.get_attendance(semester) return attendance_info - def seating_info(self) -> list[SeatingInfo]: + def seating_information(self) -> list[SeatingInformation]: """ Get the seating information of the currently authenticated user. @@ -166,4 +166,4 @@ def seating_info(self) -> list[SeatingInfo]: if not self._authenticated: raise AuthenticationError("You need to authenticate first.") seating_info = self.page_handler.get_seating_info() - return seating_info \ No newline at end of file + return seating_info diff --git a/pesuacademy/util/__init__.py b/pesuacademy/util/__init__.py index 129969e..44824cb 100644 --- a/pesuacademy/util/__init__.py +++ b/pesuacademy/util/__init__.py @@ -1,2 +1 @@ from pesuacademy.util import profile -from pesuacademy.util import seating_info \ No newline at end of file diff --git a/pesuacademy/util/page.py b/pesuacademy/util/page.py index 0d548a5..0abd282 100644 --- a/pesuacademy/util/page.py +++ b/pesuacademy/util/page.py @@ -82,4 +82,4 @@ def get_attendance(self, semester: Optional[int] = None): return self.attendance_page_handler.get_page(self.__session, semester_ids) def get_seating_info(self): - return pages.SeatingInfoHandler.get_page(self.__session) \ No newline at end of file + return pages.SeatingInformationHandler.get_page(self.__session) diff --git a/pesuacademy/util/seating_info.py b/pesuacademy/util/seating_info.py deleted file mode 100644 index 2f7b08d..0000000 --- a/pesuacademy/util/seating_info.py +++ /dev/null @@ -1,21 +0,0 @@ -from bs4 import BeautifulSoup - -from pesuacademy.models import SeatingInfo - -def get_seating_info_from_page(soup: BeautifulSoup) -> list[SeatingInfo]: - info_table = soup.find("table", attrs={"id": "seatinginfo"}) - tablebody = info_table.find("tbody") - tablerows = tablebody.find_all("tr") - seating_info = [] - for row in tablerows: - columns = row.find_all("td") - assn_name = columns[0].text.strip() - course_code = columns[1].text.strip() - date = columns[2].text.strip() - time = columns[3].text.strip() - terminal = columns[4].text.strip() - block = columns[5].text.strip() - seating_info.append( - SeatingInfo(assn_name, course_code, date, time, terminal, block) - ) - return seating_info \ No newline at end of file