From 078034faf28c9a586402ca80985b8ff1acde8648 Mon Sep 17 00:00:00 2001 From: Boyan Date: Fri, 5 Apr 2024 19:27:24 +0200 Subject: [PATCH] =?UTF-8?q?Some=20work.=20Too=20confused=20to=20work=20tod?= =?UTF-8?q?ay.=F0=9F=98=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Folder.py | 30 ++++++++++++++++++++++++++++++ src/Base.py | 21 --------------------- src/Course.py | 39 ++++++--------------------------------- src/Exercise.py | 6 +++--- src/ExerciseGroup.py | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 57 deletions(-) create mode 100644 Folder.py create mode 100644 src/ExerciseGroup.py diff --git a/Folder.py b/Folder.py new file mode 100644 index 0000000..11a0fdc --- /dev/null +++ b/Folder.py @@ -0,0 +1,30 @@ +# Module to handle each assignment (most difficult part) + +from Base import Base +from Exercise import Exercise +from requests import Session + + +class Assignment(Base): + def __init__(self, url:str, name:str, session:Session, parent): + super().__init__(url, name, session, parent) + self.download = Downloadable(name, session, self) + + def __str__(self): + return f"Assignment {self.name} in course {self.parent.name}" + + def getExercises(self) -> list[Exercise]: + # Find li large + ul = self.soup.find('ul', class_='round') + + # Turn each li to an exercise instance + return self.liLargeToExercises(ul, self.session, self) + + def getExercise(self, name:str) -> Exercise: + # Get the exercise + r = self.session.get(self.url) + soup = BeautifulSoup(r.text, 'lxml') + # Search by name + exercise = soup.find('a', text=name) + # Get the url and transform it into an exercise object + return Exercise(url=exercise['href'], name=name, session=self.session, assignment=self) \ No newline at end of file diff --git a/src/Base.py b/src/Base.py index 1096dd1..a10dcf0 100644 --- a/src/Base.py +++ b/src/Base.py @@ -69,25 +69,4 @@ class Base: for div in divs[1:]: submissions.append(self.__parseCfgBlock(div)) return self.__parseCfgBlock(divs[0]), submissions - - def liLargeToAssignments(self, ul:BeautifulSoup) -> list: - # Assume that ul is the block surrounding the li elements - # Get all the li elements - lis = ul.find_all('li', class_='large') - # Turn each to an assignment instance - assignments = [] - for li in lis: - assignments.append(Base(li.a['href'], li.a.text, self.session, self.parent)) - return assignments - - def liLargeToExercises(self, ul:BeautifulSoup) -> list: - # Assume that ul is the block surrounding the li elements - # Get all the li elements - lis = ul.find_all('li', class_='large') - # Turn each to an exercise instance - exercises = [] - for li in lis: - exercises.append(Base(li.a['href'], li.a.text, self.session, self.parent)) - return exercises - \ No newline at end of file diff --git a/src/Course.py b/src/Course.py index 9dfafc8..3492c7e 100644 --- a/src/Course.py +++ b/src/Course.py @@ -1,7 +1,7 @@ # Class to handle courses from bs4 import BeautifulSoup from requests import Session -from Assignment import Assignment +from ExerciseGroup import ExerciseGroup import re from Base import Base from exceptions.CourseUnavailable import CourseUnavailable @@ -24,12 +24,12 @@ class Course(Base): def __courseAvailable(self, r): # Check if we got an error - print(self.url) + # print(self.url) if "Something went wrong" in r.text: raise CourseUnavailable() @property - def courseInfo(self): + def info(self): return { "name": self.name, "year": self.parent.year, @@ -37,36 +37,9 @@ class Course(Base): "assignments": [x.name for x in self.assignments] } - def getAssignment(self, name:str) -> Assignment: - # Optimization: if we already have the assignments, don't get them again - try: - if name in [x.name for x in self.assignments]: - return name - except AttributeError: - pass - - # Get the assignment + def getExerciseGroups(self): r = self.session.get(self.url) soup = BeautifulSoup(r.text, 'lxml') - - # Search by name - assignment = soup.find('a', text=name) - # Get the url and transform it into an assignment object - return Assignment(url=assignment['href'], name=name, session=self.session, parent=self) - - - def getAssignments(self) -> list[Assignment]: - # For each link in the course page, get the assignment - r = self.session.get(self.url) - soup = BeautifulSoup(r.text, 'lxml') - # Find the big ul - # print(soup) section = soup.find('div', class_="ass-children") - ul = section.find('ul', class_='round') - - # IDEA: They sometimes put other stuff in these li's, so we have to filter them out - # print(ul) - # print(type(ul)) - # Transform them into Assignment objects - # I want to call the __liLargeToAssignments method from the Base class - return self.liLargeToAssignments(ul) \ No newline at end of file + entries = section.find_all('a', href=True) + return [ExerciseGroup(f"https://themis.housing.rug.nl{x['href']}", x.text, self.session, self) for x in entries] \ No newline at end of file diff --git a/src/Exercise.py b/src/Exercise.py index e48a7fb..fee557f 100644 --- a/src/Exercise.py +++ b/src/Exercise.py @@ -13,9 +13,9 @@ class Exercise(Base): def __str__(self): return f"Exercise {self.name} in assignment {self.parent.name}" - # IDEA: Implement test case downloading - - # IDEA : Make this async, so we don't have to wait for the whole output to load + def getTests(self) -> list[str]: + pass + def submit(self, file:str, comment:str) -> str: # Submit a file # The form is in the page with class "cfg-container round" diff --git a/src/ExerciseGroup.py b/src/ExerciseGroup.py new file mode 100644 index 0000000..4bb23f8 --- /dev/null +++ b/src/ExerciseGroup.py @@ -0,0 +1,39 @@ +from Base import Base +from bs4 import BeautifulSoup\ + +class ExerciseGroup(Base): + # I can't tell if I'm already an exercise :C + + def __init__(self, url:str, name:str, session, parent): + super().__init__(url, name, session, parent) + self.exercises = self.getExercises() + self.folders = self.getFolders() + + def __str__(self): + return f"ExerciseGroup {self.name} in course {self.parent.name}" + + def getExercises(self) -> list: + r = self.session.get(self.url) + soup = BeautifulSoup(r.text, 'lxml') + section = soup.find('div', class_="ass-children") + try: + submittables = section.find_all('a', class_="ass-submitable") + except AttributeError: + return None + + return submittables + + # Returns a list of names of the folders + def getFolders(self) -> list: + r = self.session.get(self.url) + soup = BeautifulSoup(r.text, 'lxml') + section = soup.find('div', class_="ass-children") + try: + folders = section.find_all('a', class_="ass-group") + except AttributeError: + return None + + return [x.text for x in folders] + + def recurse(self, folder:str): + print(self.url) \ No newline at end of file