diff --git a/src/Assignment.py b/src/Assignment.py index 5fc575f..9141530 100644 --- a/src/Assignment.py +++ b/src/Assignment.py @@ -5,10 +5,11 @@ 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__() - self.download = Downloadable(url, name, session, self) + 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}" diff --git a/src/Base.py b/src/Base.py index bad12ca..1096dd1 100644 --- a/src/Base.py +++ b/src/Base.py @@ -33,6 +33,28 @@ class Base: return submission + + # TODO: Fix + def getDownloadable(self, soup) -> list: + # Make sure we only get the ones that have a link + # We parse the cfg and check for the key "Downloads" + # Check if downloads are available + print(soup) + cfg = soup.find('div', class_='cfg-container round') + print(cfg) + cfg = self.__parseCfgBlock(cfg) + # Get the downloads + downloads = cfg.get("Downloads", None) + if downloads == None: + return [] + # Get the links + links = downloads.find_all('a') + files = [] + for link in links: + files.append(Base(link['href'], link.text, self.session, self)) + + return files + def getSubmissions(self): # We change the url where course becomes stats url = self.url.replace("course", "stats") diff --git a/src/Course.py b/src/Course.py index 15a1b57..9dfafc8 100644 --- a/src/Course.py +++ b/src/Course.py @@ -6,6 +6,12 @@ import re from Base import Base from exceptions.CourseUnavailable import CourseUnavailable +# PROBLEM: This implementation is bad due to inconsistencies in the website +# The way we can tell the difference between an assignment and an exercise is by the presence of an a with the class "ass-submitable" +# As opposed to folders which contain exercises which are marked with "ass-group" +# Therefore, we should take that into consideration and spawn the corresponding Exercise or Assignment class +# Naming becomes a bit inconsistent like that as well, as Assignments could be Exercises. Might opt to call the "assignments" "exerciseGroups" or some shit. + class Course(Base): # Extend the Base class init def __init__(self, url:str, name:str, session:Session, parent): @@ -18,6 +24,7 @@ class Course(Base): def __courseAvailable(self, r): # Check if we got an error + print(self.url) if "Something went wrong" in r.text: raise CourseUnavailable() @@ -45,7 +52,7 @@ class Course(Base): # 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, course=self) + return Assignment(url=assignment['href'], name=name, session=self.session, parent=self) def getAssignments(self) -> list[Assignment]: @@ -53,13 +60,13 @@ class Course(Base): r = self.session.get(self.url) soup = BeautifulSoup(r.text, 'lxml') # Find the big ul - print(soup) + # 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)) + # 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 diff --git a/src/Downloadable.py b/src/Downloadable.py index 873679d..c586e66 100644 --- a/src/Downloadable.py +++ b/src/Downloadable.py @@ -5,7 +5,8 @@ from bs4 import BeautifulSoup from Base import Base class Downloadable(Base): - def __init__(self, session:Session, parent): + def __init__(self, name, session:Session, parent): + self.name = name self.session = session self.parent = parent @@ -21,23 +22,9 @@ class Downloadable(Base): def files(self) -> list: # Create a list of files # They are all links in a span with class "cfg-val" - r = self.session.get(self.url) + r = self.session.get("https://themis.housing.rug.nl" + self.parent.url) soup = BeautifulSoup(r.text, 'lxml') - # Make sure we only get the ones that have a link - # We parse the cfg and check for the key "Downloads" - cfg = soup.find('div', class_='cfg-container round') - cfg = self.__parseCfgBlock(cfg) - # Get the downloads - downloads = cfg.get("Downloads", None) - if downloads == None: - return [] - # Get the links - links = downloads.find_all('a') - files = [] - for link in links: - files.append(File(link['href'], link.text, self.session, self)) - - return files + return self.getDownloadable(soup) def download(self, filename:str) -> str: # Download the file diff --git a/src/Exercise.py b/src/Exercise.py index 2f171fb..e48a7fb 100644 --- a/src/Exercise.py +++ b/src/Exercise.py @@ -13,6 +13,8 @@ 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 submit(self, file:str, comment:str) -> str: # Submit a file diff --git a/src/Themis.py b/src/Themis.py index d01ef3e..00d338e 100644 --- a/src/Themis.py +++ b/src/Themis.py @@ -59,12 +59,4 @@ class Themis: year = li.a.text.split("-") years.append(Year(self.session, self, int(year[0]), int(year[1]))) - return years # Return a list of year objects - - -# This is the main file, so we have to run the main function - -def main(): - themis = Themis() - year = themis.getYear(2019, 2020) - print(year.getCourses()) + return years # Return a list of year objects \ No newline at end of file diff --git a/src/Year.py b/src/Year.py index 126d2d9..52e2350 100644 --- a/src/Year.py +++ b/src/Year.py @@ -5,6 +5,7 @@ from Course import Course from requests import Session from exceptions.CourseUnavailable import CourseUnavailable +# Works class Year: def __init__(self, session:Session, parent, start_year:int, end_year:int): self.start = start_year @@ -25,9 +26,10 @@ class Year: courses = [] for li in lis: try: + suffix = (li.a['href'].replace(f"course/{self.start}-{self.year}", "")) courses.append( Course( - self.url + li.a['href'], + self.url + suffix, li.a.text, self.session, self @@ -37,7 +39,8 @@ class Year: if errors: raise CourseUnavailable(f"Course {li.a.text} in year {self.start}-{self.year} is not available") else: - pass + print("error with course", li.a.text) + continue return courses @@ -47,6 +50,6 @@ class Year: r = self.session.get(self.url) soup = BeautifulSoup(r.text, 'lxml') # Search by name - course = soup.find('a', text=name) + course = self.url + soup.find('a', text=name)['href'].replace(f"course/{self.start}-{self.year}", "") # Get the url and transform it into a course object - return Course(url=course['href'], name=name, session=self.session, year=self) \ No newline at end of file + return Course(url=course, name=name, session=self.session, parent=self) \ No newline at end of file