school-portal-substitution-.../main.py

171 lines
5.6 KiB
Python
Executable File

import base64
from datetime import datetime
import json
import os
import threading
import time
import schedule
from dotenv import load_dotenv
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
load_dotenv()
def check_exists_by_xpath(self, xpath):
try:
self.driver.find_element(By.XPATH, xpath)
except NoSuchElementException:
return False
return True
class Bot:
def __init__(self):
dt = datetime.now()
# saturday, sunday
if dt.isoweekday() == 6 or dt.isoweekday() == 7:
print("No request required today")
return
options = webdriver.ChromeOptions()
if os.environ.get("browserDebug") == "false":
options.add_argument('--no-sandbox')
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1920x1080')
self.driver = webdriver.Chrome(options=options, executable_path=os.path.dirname(os.path.realpath(__file__)) + "/chromedriver")
self.driver.get(os.environ.get("schoolUrl"))
time.sleep(1)
# fill user login fields
username_input = self.driver.find_element(By.XPATH, '/html/body/div[2]/div[5]/div/div[4]/div[4]/div['
'1]/div/div/form/a/div[2]/div/input[1]')
username_input.send_keys(os.environ.get("username"))
password_input = self.driver.find_element(By.XPATH, '/html/body/div[2]/div[5]/div/div[4]/div[4]/div['
'1]/div/div/form/a/div[3]/div/input')
password_input.send_keys(os.environ.get("password"))
# click on login button
login_button = self.driver.find_element(By.XPATH, '/html/body/div[2]/div[5]/div/div[4]/div[4]/div['
'1]/div/div/form/div/div/a[1]/button')
login_button.submit()
# wait for login redirecting
time.sleep(2)
# open representation schedule
self.driver.get('https://start.schulportal.hessen.de/vertretungsplan.php')
time.sleep(2)
# today - table primary
table_no_entries_alert_warning = check_exists_by_xpath(self, '/html/body/div[1]/div[5]/div['
'2]/div/div/div[2]/div[2]/div[1]/div['
'2]/div[2]/table/tbody/tr/td/div')
today_school_day = []
if table_no_entries_alert_warning is False: # there are entries
print('today - there are entries')
table_tr = self.driver.find_elements(By.XPATH, '/html/body/div[1]/div[5]/div[2]/div/div/div[2]/div['
'2]/div[1]/div[2]/div[2]/table/tbody/tr')
for tr in table_tr:
td = tr.find_elements(By.TAG_NAME, 'td')
data = {
'hour': td[0].text,
'class': td[1].text,
'representative': td[2].text,
'teacher': td[3].text,
'subject': td[4].text,
'room': td[5].text,
'note': td[6].text
}
today_school_day.append(data)
else: # there are no entries
print('today - no entries')
# next school day
next_school_day = []
button_next_day = self.driver.find_element(By.XPATH,
'/html/body/div[1]/div[5]/div[2]/div/div/div[1]/div/button[2]')
button_next_day.click()
time.sleep(2)
table_no_entries_alert_warning = check_exists_by_xpath(self, '/html/body/div[1]/div[5]/div['
'2]/div/div/div[3]/div[2]/div[1]/div['
'2]/div[2]/table/tbody/tr/td/div')
if table_no_entries_alert_warning is False: # there are entries
print('next day - there are entries')
table_tr = self.driver.find_elements(By.XPATH,
'/html/body/div[1]/div[5]/div[2]/div/div/div[3]/div[2]/div[1]/div[2]/div[2]/table/tbody/tr')
for tr in table_tr:
td = tr.find_elements(By.TAG_NAME, 'td')
data = {
'hour': td[0].text,
'class': td[1].text,
'representative': td[2].text,
'teacher': td[3].text,
'subject': td[4].text,
'room': td[5].text,
'note': td[6].text
}
next_school_day.append(data)
else: # there are no entries
print('next day - no entries')
todayEncodedBytes = base64.b64encode(json.dumps(today_school_day).encode("utf-8"))
nextDayEncodedBytes = base64.b64encode(json.dumps(next_school_day).encode("utf-8"))
txt = "../school-portal-substitution-plan-matrix-chat-bot/main {} {}".format(str(todayEncodedBytes, "utf-8"), str(nextDayEncodedBytes, "utf-8"))
self.driver.close()
os.popen(txt)
time.sleep(5)
def run_threaded(job_func):
job_thread = threading.Thread(target=job_func)
job_thread.start()
def start_bot():
bot = Bot()
schedule.every().day.at("05:00").do(run_threaded, start_bot)
schedule.every().day.at("19:00").do(run_threaded, start_bot)
while True:
schedule.run_pending()
time.sleep(1)