99 lines
2.8 KiB
Python
99 lines
2.8 KiB
Python
import requests
|
|
|
|
from urllib.parse import urlparse, parse_qs
|
|
import re
|
|
|
|
from bs4 import BeautifulSoup, NavigableString
|
|
import random
|
|
|
|
|
|
session = requests.Session()
|
|
|
|
session.headers.update({
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0'
|
|
})
|
|
|
|
|
|
class LVA:
|
|
def __init__(self, id: str, name: str, ects: float, curricula: list[str], type: str):
|
|
self.id = id
|
|
self.name = name
|
|
self.ects = ects
|
|
self.curricula = curricula
|
|
self.type = type
|
|
|
|
def id_pretty(self):
|
|
# format 123123 -> 123.123
|
|
return f'{self.id[:3]}.{self.id[3:]}'
|
|
|
|
def __str__(self):
|
|
return f'{self.name} ({self.id}) - {self.ects} ECTS'
|
|
|
|
def __repr__(self):
|
|
return f'{self.name} ({self.id})'
|
|
|
|
def get_direct_text_clean(element):
|
|
text = ''.join(child for child in element.children if isinstance(child, NavigableString))
|
|
return re.sub(r'\s+', ' ', text).strip()
|
|
|
|
|
|
def gen_request_tokens():
|
|
request_token = str(random.randint(0, 999))
|
|
window_id = str(random.randint(0, 999))
|
|
|
|
session.cookies.set(f"dsrwid-{request_token}", window_id)
|
|
return (request_token, window_id)
|
|
|
|
|
|
class TISS:
|
|
@staticmethod
|
|
def get_anonymous_tiss_link(code: str):
|
|
return f"https://tiss.tuwien.ac.at/course/courseDetails.xhtml?courseNr={code}"
|
|
|
|
@staticmethod
|
|
def get_lva(code: str):
|
|
tokens = gen_request_tokens()
|
|
|
|
res = session.get(f"https://tiss.tuwien.ac.at/course/courseDetails.xhtml?courseNr={code}&dsrid={tokens[0]}&dswid={tokens[1]}")
|
|
soup = BeautifulSoup(res.text, 'html.parser')
|
|
|
|
course_name = get_direct_text_clean(soup.select('#contentInner > h1')[0])
|
|
|
|
subheader = soup.select('#subHeader')[0].text
|
|
ects = float(re.search(r'(\d+\.\d+)EC', subheader).group(1))
|
|
# extract "VU" from "2024W, VU, 2.0h, 3.0EC"
|
|
type = subheader.split(",")[1].strip()
|
|
|
|
|
|
table = soup.select('th[aria-label="Studienkennzahl"]')[0].parent.parent.parent
|
|
curricula = [re.sub("\D", "", tr.find("td").text) for tr in table.find("tbody").find_all("tr")]
|
|
|
|
lva = LVA(code, course_name, ects, curricula, type)
|
|
|
|
return lva
|
|
|
|
|
|
@staticmethod
|
|
def get_code_from_any(any: str):
|
|
# Example: https://tiss.tuwien.ac.at/course/courseDetails.xhtml?dswid=5304&dsrid=381&courseNr=180771&semester=2024W
|
|
any = any.strip()
|
|
url = urlparse(any)
|
|
|
|
if all([url.scheme, url.netloc]):
|
|
# Yes, this was an URL
|
|
params = parse_qs(url.query)
|
|
|
|
course_nr = params.get('courseNr', [None])[0]
|
|
return course_nr
|
|
else:
|
|
if len(any) == 6:
|
|
return any
|
|
|
|
match = re.search(r'\w{3}\.\w{3}', any)
|
|
|
|
if match:
|
|
return match.group(0).replace(".", "")
|
|
else:
|
|
return None
|
|
|