171 lines
5.6 KiB
Python
Executable File
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)
|