@@ -32,7 +32,12 @@ class Exam:
3232
3333
3434class CampusNetSession :
35- def __init__ (self , username : str = None , password : str = None , base_url = "https://dualis.dhbw.de/" ):
35+ def __init__ (
36+ self ,
37+ username : str = None ,
38+ password : str = None ,
39+ base_url = "https://dualis.dhbw.de/" ,
40+ ):
3641 """
3742 Initialize a new CampusNetSession.
3843 :param username: The username of the user.
@@ -81,20 +86,23 @@ def _login(self):
8186 :raises:
8287 LoginError: If the login failed.
8388 """
84- response = self .session .post (self .mgrqispi , data = {
85- 'usrname' : self .username ,
86- 'pass' : self .password ,
87- 'APPNAME' : 'CampusNet' ,
88- 'PRGNAME' : 'LOGINCHECK' ,
89- 'ARGUMENTS' : 'clino,usrname,pass,menuno,menu_type,browser,platform' ,
90- 'clino' : '000000000000001' ,
91- 'menuno' : '000324' ,
92- 'menu_type' : 'classic' ,
93- 'browser' : '' ,
94- 'platform' : '' ,
95- })
89+ response = self .session .post (
90+ self .mgrqispi ,
91+ data = {
92+ "usrname" : self .username ,
93+ "pass" : self .password ,
94+ "APPNAME" : "CampusNet" ,
95+ "PRGNAME" : "LOGINCHECK" ,
96+ "ARGUMENTS" : "clino,usrname,pass,menuno,menu_type,browser,platform" ,
97+ "clino" : "000000000000001" ,
98+ "menuno" : "000324" ,
99+ "menu_type" : "classic" ,
100+ "browser" : "" ,
101+ "platform" : "" ,
102+ },
103+ )
96104 if len (response .cookies ) == 0 : # We didn't get a session token in response
97- raise LoginError (' Login failed.' )
105+ raise LoginError (" Login failed." )
98106
99107 # The header looks like this
100108 # 0; URL=/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=STARTPAGE_DISPATCH&ARGUMENTS=-N954433323189667,-N000019,-N000000000000000
@@ -110,16 +118,16 @@ def _get_semesters(self):
110118 Get the semesters from the CampusNet.
111119 :return: A list of semesters.
112120 """
113- response = self .session .get (self .create_url (' COURSERESULTS' ))
121+ response = self .session .get (self .create_url (" COURSERESULTS" ))
114122 # The webservice doesn't correctly set Content-Type: text/html; charset=utf-8
115123 # so requests uses ISO-8859-1 which is not correct. Requests is smart enough to
116124 # convert the response to UTF-8 if we tell it to take a guess at the real encoding.
117125 # also see https://stackoverflow.com/a/52615216
118126 response .encoding = response .apparent_encoding
119- soup = BeautifulSoup (response .text , ' html.parser' )
127+ soup = BeautifulSoup (response .text , " html.parser" )
120128 semesters = {}
121- for semester in soup .find_all (' option' ):
122- semesters [semester .text ] = semester .get (' value' )
129+ for semester in soup .find_all (" option" ):
130+ semesters [semester .text ] = semester .get (" value" )
123131 return semesters
124132
125133 @property
@@ -139,24 +147,27 @@ def _get_modules(self):
139147 """
140148 modules = []
141149 for semester in self .semesters :
142- response = self .session .post (self .mgrqispi , data = {
143- 'APPNAME' : 'CampusNet' ,
144- 'semester' : self .semesters [semester ],
145- 'Refresh' : 'Aktualisieren' ,
146- 'PRGNAME' : 'COURSERESULTS' ,
147- 'ARGUMENTS' : 'sessionno,menuno,semester' ,
148- 'sessionno' : self .session_number ,
149- 'menuno' : '000307'
150- })
150+ response = self .session .post (
151+ self .mgrqispi ,
152+ data = {
153+ "APPNAME" : "CampusNet" ,
154+ "semester" : self .semesters [semester ],
155+ "Refresh" : "Aktualisieren" ,
156+ "PRGNAME" : "COURSERESULTS" ,
157+ "ARGUMENTS" : "sessionno,menuno,semester" ,
158+ "sessionno" : self .session_number ,
159+ "menuno" : "000307" ,
160+ },
161+ )
151162 # The webservice doesn't correctly set Content-Type: text/html; charset=utf-8
152163 # so requests uses ISO-8859-1 which is not correct. Requests is smart enough to
153164 # convert the response to UTF-8 if we tell it to take a guess at the real encoding.
154165 # also see https://stackoverflow.com/a/52615216
155166 response .encoding = response .apparent_encoding
156- soup = BeautifulSoup (response .text , ' html.parser' )
157- table = soup .find (' table' , {' class' : ' nb list' })
158- for row in table .find_all ('tr' )[1 :]:
159- cells = row .find_all ('td' )
167+ soup = BeautifulSoup (response .text , " html.parser" )
168+ table = soup .find (" table" , {" class" : " nb list" })
169+ for row in table .find_all ("tr" )[1 :]:
170+ cells = row .find_all ("td" )
160171 if len (cells ) == 7 :
161172 try :
162173 grade = float (cells [2 ].text .strip ().replace ("," , "." ))
@@ -167,25 +178,25 @@ def _get_modules(self):
167178 exams_id = exams_button .get ("href" ).split (",-N" )[- 2 ]
168179 num = cells [0 ].text .strip ()
169180 if not any (module .num == num for module in modules ):
170- modules .append (Module (
171- num = num ,
172- name = cells [1 ].text .strip (),
173- credits = float (
174- cells [3 ].text .strip ().replace (',' , '.' )),
175- status = cells [4 ].text .strip (),
176- semesters = [semester ],
177- id = exams_id ,
178- grade = grade
179- ))
181+ modules .append (
182+ Module (
183+ num = num ,
184+ name = cells [1 ].text .strip (),
185+ credits = float (cells [3 ].text .strip ().replace ("," , "." )),
186+ status = cells [4 ].text .strip (),
187+ semesters = [semester ],
188+ id = exams_id ,
189+ grade = grade ,
190+ )
191+ )
180192 else :
181193 for module in modules :
182194 if module .num == num :
183195 module .semesters .append (semester )
184196 break
185197 elif len (cells ) != 0 :
186198 # FIXME: proper logging
187- print ("Unexpected number of cells:" ,
188- len (cells ), file = sys .stderr )
199+ print ("Unexpected number of cells:" , len (cells ), file = sys .stderr )
189200 return modules
190201
191202 @property
@@ -204,31 +215,32 @@ def get_exams_for_module(self, module: Module):
204215 :param module: The module.
205216 :return: A list of exams.
206217 """
207- response = self .session .get (self .create_url (
208- 'RESULTDETAILS' , f",-N{ module .id } " ))
218+ response = self .session .get (self .create_url ("RESULTDETAILS" , f",-N{ module .id } " ))
209219 # The webservice doesn't correctly set Content-Type: text/html; charset=utf-8
210220 # so requests uses ISO-8859-1 which is not correct. Requests is smart enough to
211221 # convert the response to UTF-8 if we tell it to take a guess at the real encoding.
212222 # also see https://stackoverflow.com/a/52615216
213223 response .encoding = response .apparent_encoding
214- soup = BeautifulSoup (response .text , ' html.parser' )
215- exam_table = soup .find (' table' , {' class' : 'tb' })
224+ soup = BeautifulSoup (response .text , " html.parser" )
225+ exam_table = soup .find (" table" , {" class" : "tb" })
216226 exams = []
217227 current_heading = None
218228 for row in exam_table .find_all ("tr" ):
219- cells = row .find_all ('td' )
220- if len (cells ) == 1 and ' level02' in cells [0 ]["class" ]:
229+ cells = row .find_all ("td" )
230+ if len (cells ) == 1 and " level02" in cells [0 ]["class" ]:
221231 # variable to persist header into the next iteration
222232 current_heading = cells [0 ].text .strip ()
223233 if len (cells ) == 6 and all ("tbdata" in cell ["class" ] for cell in cells ):
224234 try :
225235 grade = float (cells [3 ].text .strip ().replace ("," , "." ))
226236 except ValueError :
227237 grade = None
228- exams .append (Exam (
229- name = current_heading ,
230- semester = cells [0 ].text .strip (),
231- description = cells [1 ].text .strip (),
232- grade = grade ,
233- ))
238+ exams .append (
239+ Exam (
240+ name = current_heading ,
241+ semester = cells [0 ].text .strip (),
242+ description = cells [1 ].text .strip (),
243+ grade = grade ,
244+ )
245+ )
234246 return exams
0 commit comments