Files
solon/src/lib/schedule_week.py
T
2024-01-07 16:40:48 +00:00

377 lines
11 KiB
Python
Executable File

"""
Functions related to this
week's schedule.
"""
from solenlib import networking as nw
from solenlib import crypto as cr
from bs4 import BeautifulSoup
import os
not_login = 0
def fetch_locally(password, username) -> list:
"""
Helper function for extracting
data from a local file.
"""
global not_login
if not_login == 1:
not_login = 0
schedule = schedule_from_file(password, username)
return schedule
def sort_schedule(schedule: list[dict]) -> list[dict]:
"""
Helper function for sorting
the schedule correctly.
"""
sorted_schedule: list[dict] = [{}, {}, {}, {}, {}]
for i in range(len(schedule)):
if schedule[i]["DAY"] == "Po":
sorted_schedule[0] = schedule[i]
if schedule[i]["DAY"] == "Út":
sorted_schedule[1] = schedule[i]
if schedule[i]["DAY"] == "St":
sorted_schedule[2] = schedule[i]
if schedule[i]["DAY"] == "Čt":
sorted_schedule[3] = schedule[i]
if schedule[i]["DAY"] == "Pá":
sorted_schedule[4] = schedule[i]
return sorted_schedule
def get_schedule(password, url: str) -> list:
"""
Filters & extracts the schedule from
the HTML soup.
"""
try:
html = nw.get_html_from(url)
soup = BeautifulSoup(html.text, "lxml")
table = soup.find("table", id="CCADynamicCalendarTable")
rows_odd = table.find_all("tr", class_="RowOdd")
rows_even = table.find_all("tr", class_="RowEven")
rows = rows_odd + rows_even
schedule = []
for i in range(len(rows)):
if rows[i].find("td", class_="KuvSuplovanaHodina") is not None and rows[i].find("td", class_="KuvSuplujiciHodina") is None and rows[i].find("td", class_="KuvSkolniAkceHodina") is None and rows[i].find("td", class_="DctInnerTableType10DataTD") is None:
continue
subjects = []
wheres = []
cells = rows[i].find_all("td", attrs={"class": "DctCell"})
header_ = table.find("tr").find_all("td", class_="KuvHeaderNadpis")
header = []
for val in header_:
header.append(val.text)
for j in range(len(cells)):
if cells[j].text == "" and header[j] != " - ":
new_span = soup.new_tag("span", attrs={'class': 'KuvBunkaRozvrhNadpis'})
new_span.string = "Volno"
cells[j].append(new_span)
if rows[i].find("td", class_="KuvHeaderNadpis") is not None:
day = rows[i].find("td", class_="KuvHeaderNadpis").text
date = rows[i].find("td", class_="KuvHeaderText").text
subjects_ = rows[i].find_all("span", class_="KuvBunkaRozvrhNadpis")
temp = []
for j in range(len(subjects_)):
if "KuvSuplovanaHodina" not in subjects_[j].parent["class"]:
temp.append(subjects_[j].text)
else:
temp.append("Volno")
subjects = temp
F_continue = False
try:
while subjects[-1] == "Volno":
del subjects[-1]
if subjects == []:
F_continue = True
except IndexError:
pass
if subjects == []:
F_continue = True
wheres_ = rows[i].find_all("span", class_="KuvBunkaRozvrhText")
temp = []
for j in range(len(wheres_)):
try:
if len(subjects[j]) < 10:
if len(wheres_[j].text[4:]) > 10:
temp.append(" - ")
elif "KuvSuplovanaHodina" not in wheres_[j].parent["class"]:
temp.append(wheres_[j].text[4:])
else:
temp.append(" - ")
except IndexError:
pass
wheres = temp
for j in range(len(cells)):
if cells[j].get("colspan") is not None:
if int(cells[j].get("colspan")) == 2:
try:
subjects.insert(j, subjects[j])
wheres.insert(j, wheres[j])
except IndexError:
pass
for j in range(len(subjects)):
if subjects[j] == "Volno":
wheres.insert(j, " - ")
while True:
if len(subjects) > len(wheres):
del subjects[-1]
elif len(subjects) < len(wheres):
del wheres[-1]
else:
break
if F_continue == False:
schedule_row = {
"DAY": day,
"DATE": date,
"SUBJECTS": subjects,
"WHERES": wheres
}
schedule.append(schedule_row)
sorted_schedule = sort_schedule(schedule)
return sorted_schedule
except AttributeError:
global not_login
not_login = 1
schedule = fetch_locally()
return schedule
def schedule_from_file_to_list(password, username, strdata):
"""
Extracts the schedule from
a local file and returns
it in a list, which is better
for the get_whitespace() function.
"""
schedule = []
schedule_ = []
import csv
from io import StringIO
f = StringIO(strdata)
reader = csv.reader(f, delimiter=",")
for row in reader:
temp = []
for col in row:
temp.append(col.strip())
schedule_.append(temp)
for i in range(0, len(schedule_), 2):
del schedule_[i][0]
temp = []
for i in range(1, len(schedule_), 2):
temp.append(schedule_[i][0])
del schedule_[i][0]
schedule.append(temp)
for i in range(10):
temp = []
for j in range(10):
try:
temp.append(schedule_[j][0])
del schedule_[j][0]
except IndexError:
pass
schedule.append(temp)
return schedule
def get_whitespace(password, username, strdata, key: str, idx=0) -> int:
"""
Helper function that calculates
how much whitespaces are needed
in order to display the table grid
correctly.
"""
schedule = schedule_from_file_to_list(password, username, strdata)
max_len = 0
if key == "DATE":
try:
max_len = len(max(schedule[0], key=len))
except ValueError:
pass
elif key == "WHERES":
try:
max_len = len(max(schedule[idx], key=len))
except ValueError:
pass
print(max_len)
return max_len
def show_schedule(password, username, local=False):
"""
Shows the schedule on the
terminal in a pretty way.
"""
try:
strdata = cr.read_from_file_and_decrypt(password, f"{os.environ['HOME']}/.local/lib/solendata/{nw.get_user_hash(username)}-schedule_week")
except:
print("Could not read the file")
return
if local == False:
# if there is internet access, load stuff from the web
# if not, load the schedule.csv file
if nw.is_connected() == True:
schedule = get_schedule(password, "/SOL/App/Kalendar/KZK001_KalendarTyden.aspx")
schedule_to_file(password, username, schedule)
else:
schedule = schedule_from_file(password, username)
else:
schedule = schedule_from_file(password, username)
print("")
print("----------------")
print(" Týdenní rozvrh ")
print("----------------\n")
if schedule == []:
print("N/A\n")
return
for i in range(len(schedule)):
max_len = get_whitespace(password, username, strdata, "DATE")
whitespace = " " * (max_len - len(schedule[i]["DAY"]))
print(schedule[i]["DAY"] + whitespace, end=" ")
for j in range(len(schedule[i]["SUBJECTS"])):
max_len = get_whitespace(password, username, strdata, "WHERES", j+1)
whitespace = " " * (max_len - len(schedule[i]["SUBJECTS"][j]))
print("| " + schedule[i]["SUBJECTS"][j] + whitespace, end=" ")
print("")
max_len = get_whitespace(password, username, strdata, "DATE")
whitespace = " " * (max_len - len(schedule[i]["DATE"]))
print(schedule[i]["DATE"] + whitespace, end=" ")
for j in range(len(schedule[i]["WHERES"])):
max_len = get_whitespace(password, username, strdata, "WHERES", j+1)
whitespace = " " * (max_len - len(schedule[i]["WHERES"][j]))
print("| " + schedule[i]["WHERES"][j] + whitespace, end=" ")
print("")
def schedule_to_file(password, username, schedule=None):
"""
Writes the schedule to
a local file for later
use.
"""
if schedule is None:
try:
schedule = get_schedule(password, "/SOL/App/Kalendar/KZK001_KalendarTyden.aspx")
except:
print("An error occured, you probably can't access the internet right now")
return
lstrdata = []
for row in schedule:
lstrdata.append(row["DAY"])
lstrdata.append(",")
for i in row["SUBJECTS"]:
lstrdata.append(i)
lstrdata.append(",")
del lstrdata[-1]
lstrdata.append("\n")
lstrdata.append(row["DATE"])
lstrdata.append(",")
for i in row["WHERES"]:
lstrdata.append(i)
lstrdata.append(",")
del lstrdata[-1]
lstrdata.append("\n")
strdata = "".join(lstrdata)
cr.encrypt_and_write_to_file(password, strdata, f"{os.environ['HOME']}/.local/lib/solendata/{nw.get_user_hash(username)}-schedule_week")
def schedule_from_file(password, username) -> list:
"""
Fetches schedule data from a file.
"""
import csv
from io import StringIO
schedule = []
try:
strdata = cr.read_from_file_and_decrypt(password, f"{os.environ['HOME']}/.local/lib/solendata/{nw.get_user_hash(username)}-schedule_week")
except:
print("Could not read the file")
return
f = StringIO(strdata)
reader = csv.reader(f)
rows = []
for row in reader:
rows.append(row)
for row in range(0, len(rows), 2):
temp = {}
temp["DAY"] = rows[row][0]
try:
temp["DATE"] = rows[row+1][0]
except IndexError:
pass
subjects = []
for i in range(1, len(rows[row])):
subjects.append(rows[row][i])
temp["SUBJECTS"] = subjects
wheres = []
try:
for i in range(1, len(rows[row+1])):
wheres.append(rows[row+1][i])
except IndexError:
pass
temp["WHERES"] = wheres
schedule.append(temp)
print(schedule)
return schedule