Working
This commit is contained in:
98
master-bot/tiss.py
Normal file
98
master-bot/tiss.py
Normal file
@@ -0,0 +1,98 @@
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user