initial commit

master
emamaker 2022-03-30 15:04:26 +02:00
commit 90776e2eaa
4 changed files with 141 additions and 0 deletions

5
README.md Normal file
View File

@ -0,0 +1,5 @@
Automatically book a place at a lesson on Sapienza's platform Prodigit, done with python, selenium and undetected chromedriver to avoid any possible rate limiting (if even there's any). <br>
Timetable is hardcoded in timetable.py as nested dictionaries of (palace, room, day, and a tuple with starting and ending hours).<br>
Credentials to the website are hardcoded in settings.py.
Written in like 1.5 hrs, do not plan on adding anything, maybe just capability of booking Study Rooms

101
prodigit_bot.py Normal file
View File

@ -0,0 +1,101 @@
import undetected_chromedriver as uc
import settings
import timetable
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException, NoSuchElementException, UnexpectedAlertPresentException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
def clickButton(browser, by, selector, timeout=2, after_delay=0.5):
WebDriverWait(browser, timeout).until(EC.element_to_be_clickable((by, selector))).click()
def inputText(browser, by, selector, text, timeout=5, interval=0.1, after_delay=0.5):
element = WebDriverWait(browser, timeout).until(EC.element_to_be_clickable((by, selector)))
for i in text:
element.send_keys(i)
time.sleep(interval)
time.sleep(after_delay)
def login_prodigit(driver):
driver.get(settings.SETTINGS_WEBPAGE_LOGIN_URL)
driver.implicitly_wait(2)
clickButton(driver, By.XPATH, settings.SETTINGS_WEBPAGE_COOKIES_ACCEPT_XPATH)
inputText(driver, By.XPATH, settings.SETTINGS_WEBPAGE_USERNAME_INPUT_XPATH, settings.SETTINGS_CREDS_MATRICOLA)
inputText(driver, By.XPATH, settings.SETTINGS_WEBPAGE_PASSWORD_INPUT_XPATH, settings.SETTINGS_CREDS_PASSWORD + '\n')
driver.implicitly_wait(4)
# assumes login_prodigit has been called before
def prenota_lezioni(driver, tm):
for edificio in tm:
driver.get(settings.SETTINGS_WEBPAGE_URL)
clickButton(driver, By.XPATH, settings.SETTINGS_WEBPAGE_PRENOTA_AULA_XPATH)
driver.implicitly_wait(2)
select = Select(driver.find_element(by=By.XPATH, value=settings.SETTINGS_PRENOTA_AULA_EDIFICIO_XPATH))
select.select_by_visible_text(edificio)
driver.implicitly_wait(2)
for aula in tm[edificio]:
select = Select(driver.find_element(by=By.XPATH, value=settings.SETTINGS_PRENOTA_AULA_AULA_XPATH))
select.select_by_visible_text(aula)
driver.implicitly_wait(2)
i = 2 # jump the first 2 lines
while True:
try:
element = driver.find_element(by=By.XPATH, value=f'/html/body/form/section/article/table[4]/tbody/tr[{i}]/td[1]/font')
#print(element.text)
giorno = element.text
if giorno in tm[edificio][aula]:
print(f'Prenoto il giorno {giorno} dalle {tm[edificio][aula][giorno][0]} alle {tm[edificio][aula][giorno][1]}')
try:
driver.find_element(by=By.XPATH, value=f'/html/body/form/section/article/table[4]/tbody/tr[{i}]/td[5]/div/font')
already_booked = True
print("Già prenotato per questo giorno")
except:
already_booked = False
if not already_booked:
select = Select(driver.find_element(by=By.XPATH, value=f'/html/body/form/section/article/table[4]/tbody/tr[{i}]/td[3]/div/font/select'))
select.select_by_visible_text(tm[edificio][aula][giorno][0])
driver.implicitly_wait(2)
select = Select(driver.find_element(by=By.XPATH, value=f'/html/body/form/section/article/table[4]/tbody/tr[{i}]/td[4]/div/font/select'))
select.select_by_visible_text(tm[edificio][aula][giorno][1])
driver.implicitly_wait(2)
i += 1
except NoSuchElementException as e:
break
# except UnexpectedAlertPresentException as alert_exception:
# if "sovrapposizione" in str(alert_exception).lower():
# print("Sovrapposizione di date rilevata, magari hai già prenotato in queste date?")
# print(str(alert_exception))
clickButton(driver, By.XPATH, settings.SETTINGS_PRENOTA_AULA_GP_XPATH)
driver.implicitly_wait(2)
clickButton(driver, By.XPATH, settings.SETTINGS_PRENOTA_AULA_PRENOTA)
def prenota_spaziostudio(driver, timetable):
pass
if __name__ == "__main__":
driver = uc.Chrome(version_main=99)
login_prodigit(driver)
driver.implicitly_wait(3)
prenota_lezioni(driver, timetable.get_lezioni())
time.sleep(5)
driver.quit()

14
settings.py Normal file
View File

@ -0,0 +1,14 @@
SETTINGS_CREDS_MATRICOLA=""
SETTINGS_CREDS_PASSWORD=""
SETTINGS_WEBPAGE_LOGIN_URL='https://prodigit.uniroma1.it'
SETTINGS_WEBPAGE_COOKIES_ACCEPT_XPATH='//*[@id="cookieChoiceDismiss"]'
SETTINGS_WEBPAGE_USERNAME_INPUT_XPATH='/html/body/form/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr[2]/td[2]/font/input'
SETTINGS_WEBPAGE_PASSWORD_INPUT_XPATH='/html/body/form/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr[2]/td[5]/font/input'
SETTINGS_WEBPAGE_URL='https://prodigit.uniroma1.it/prenotazioni/prenotaaule.nsf/home'
SETTINGS_WEBPAGE_PRENOTA_AULA_XPATH='/html/body/form/section/nav/ul/ul/li[2]/a'
SETTINGS_PRENOTA_AULA_EDIFICIO_XPATH='//*[@id="codiceedificio"]'
SETTINGS_PRENOTA_AULA_AULA_XPATH='/html/body/form/section/article/table[3]/tbody/tr[2]/td/font/select'
SETTINGS_PRENOTA_AULA_GP_XPATH='/html/body/form/section/article/table[5]/tbody/tr[3]/td/table/tbody/tr/td[1]/div/b/font/label/input'
SETTINGS_PRENOTA_AULA_PRENOTA='//*[@id="btnprenota"]'

21
timetable.py Normal file
View File

@ -0,0 +1,21 @@
def get_lezioni():
timetable = dict()
timetable["RM021"] = dict()
timetable["RM025"] = dict()
timetable["RM025"]["AULA INFORMATICA 15 -- RM025-E01PTEL024"] = dict()
timetable["RM021"]["AULA 204 -- RM021-P02L004"] = dict()
timetable["RM025"]["AULA INFORMATICA 15 -- RM025-E01PTEL024"]["Lunedi"] = ("10:00", "12:00")
timetable["RM021"]["AULA 204 -- RM021-P02L004"]["Lunedi"] = ("12:00", "19:00")
timetable["RM021"]["AULA 204 -- RM021-P02L004"]["Martedi"] = ("13:00", "19:00")
timetable["RM021"]["AULA 204 -- RM021-P02L004"]["Mercoledi"] = ("13:00", "19:00")
timetable["RM021"]["AULA 204 -- RM021-P02L004"]["Giovedi"] = ("15:00", "19:00")
return timetable
def get_spaziostudio():
timetable = dict()
timetable["RM021"] = dict()
return timetable