Compare commits

..

3 Commits

Author SHA1 Message Date
Yigit Colakoglu
083ea29c21 Fix dockerfile, switch to firefox 2024-10-01 14:05:37 +02:00
Yigit Colakoglu
10fb02c90d Switch to firefox 2024-09-30 15:10:09 +02:00
Yigit Colakoglu
00f3bc4ffd Fixed dockerfile issues 2024-09-30 14:44:56 +02:00
4 changed files with 245 additions and 228 deletions

View File

@ -19,20 +19,13 @@ RUN apt-get update && \
build-essential \
libsqlite3-dev \
sqlite3 \
chromium \
firefox-esr \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install the required Python packages
RUN pip install --no-cache-dir -r requirements.txt
# Set up Chrome WebDriver for Selenium
RUN wget -q -O /app/chromedriver.zip https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.70/linux64/chromedriver-linux64.zip && \
unzip /app/chromedriver.zip && \
mv /app/chromedriver-linux64/chromedriver /app && \
chmod +x /app/chromedriver && \
rm -rf /app/chromedriver.zip /app/chromedriver-linux64
# Set environment variables for Chrome and ChromeDriver
ENV PATH=/app:$PATH
ENV DISPLAY=:99

View File

@ -2,8 +2,6 @@ import os
TELEGRAM_TOKEN = os.environ.get("SECRETARX_TG_TOKEN", None)
DB_PATH = "data.db"
CHROMEDRIVER_PATH = "chromedriver"
LISTEN_PORT = 9090
GOOGLE_CLIENT_SECRET_FILE = "credentials.json"

View File

@ -71,6 +71,10 @@ class TelegramBot:
def calendar_auth(message):
self.calendar_auth(message)
@self.bot.message_handler(commands=["login"])
def cancel_booking(message):
self.process_login(message)
def init_db(self):
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
@ -229,9 +233,6 @@ class TelegramBot:
def make_booking(self, message):
try:
xclient = self.get_xclient(message.chat.id)
except Exception as e:
self.bot.reply_to(message, f"Error: {str(e)}")
return
if not xclient:
self.bot.reply_to(
@ -250,7 +251,9 @@ class TelegramBot:
# Create a button for each slot
status = "Available" if slot.available else "FULL"
button_text = f"Slot {i + 1}: {slot.start_stamp} ({status})"
markup.add(InlineKeyboardButton(button_text, callback_data=f"book_{i}"))
markup.add(
InlineKeyboardButton(button_text, callback_data=f"book_{i}")
)
self.bot.reply_to(
message, "Select a slot to book or watch:", reply_markup=markup
@ -259,12 +262,13 @@ class TelegramBot:
else:
self.bot.reply_to(message, "No slots found.")
except Exception as e:
self.bot.reply_to(message, f"Error: {str(e)}")
return
def callback_booking(self, call):
try:
xclient = self.get_xclient(call.message.chat.id)
except Exception as e:
self.bot.reply_to(call.message, f"Error: {str(e)}")
return
if not xclient:
self.bot.reply_to(
@ -316,8 +320,12 @@ class TelegramBot:
f"Booking confirmed for: {selected_slot.start_stamp}",
)
except Exception as e:
self.bot.answer_callback_query(call.id, "Failed to book slot.")
self.bot.send_message(call.message.chat.id, f"Error: {str(e)}")
self.bot.answer_callback_query(
call.id, "Failed to book slot."
)
self.bot.send_message(
call.message.chat.id, f"Error: {str(e)}"
)
else:
# Slot is full, add to watchlist
self.add_to_watchlist(call.message.chat.id, selected_slot)
@ -338,12 +346,13 @@ class TelegramBot:
call.message.chat.id, call.message.message_id
)
except Exception as e:
self.bot.reply_to(call.message, f"Error: {str(e)}")
return
def cancel_booking(self, message):
try:
xclient = self.get_xclient(message.chat.id)
except Exception as e:
self.bot.reply_to(message, f"Error: {str(e)}")
return
if not xclient:
self.bot.reply_to(
@ -373,12 +382,13 @@ class TelegramBot:
else:
self.bot.reply_to(message, "You have no bookings to cancel.")
except Exception as e:
self.bot.reply_to(message, f"Error: {str(e)}")
return
def callback_cancel_booking(self, call):
try:
xclient = self.get_xclient(call.message.chat.id)
except Exception as e:
self.bot.reply_to(call.message, f"Error: {str(e)}")
return
if not xclient:
self.bot.reply_to(
@ -422,10 +432,14 @@ class TelegramBot:
call.id, "Failed to cancel booking."
)
except Exception as e:
self.bot.answer_callback_query(call.id, "Failed to cancel booking.")
self.bot.answer_callback_query(
call.id, "Failed to cancel booking."
)
self.bot.send_message(call.message.chat.id, f"Error: {str(e)}")
else:
self.bot.answer_callback_query(call.id, "Invalid booking selection.")
self.bot.answer_callback_query(
call.id, "Invalid booking selection."
)
except (IndexError, ValueError):
self.bot.answer_callback_query(call.id, "Invalid data.")
@ -434,6 +448,10 @@ class TelegramBot:
call.message.chat.id, call.message.message_id
)
except Exception as e:
self.bot.reply_to(call.message, f"Error: {str(e)}")
return
def manage_watchlist(self, message):
chat_id = message.chat.id
@ -495,8 +513,6 @@ class TelegramBot:
for chat_id, slots in list(self.watchlist.items()):
try:
xclient = self.get_xclient(chat_id)
except Exception as e:
print(f"Error polling watchlist: {str(e)}")
available_slots = []
for slot in slots:
@ -534,12 +550,18 @@ class TelegramBot:
chat_id,
f"Slot {slot.start_stamp} is now available and has been booked for you.",
)
available_slots.append(slot) # Mark it to remove from watchlist
available_slots.append(
slot
) # Mark it to remove from watchlist
except Exception as e:
self.bot.send_message(
chat_id, f"Error booking slot {slot.start_stamp}: {str(e)}"
chat_id,
f"Error booking slot {slot.start_stamp}: {str(e)}",
)
except Exception as e:
print(f"Error polling watchlist: {str(e)}")
# Remove the expired or booked slots from the watchlist
self.watchlist[chat_id] = [
slot for slot in slots if slot not in available_slots

View File

@ -1,4 +1,5 @@
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from models import Booking
import json
from selenium.webdriver.common.by import By
@ -6,12 +7,12 @@ from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import requests
import config
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
service = Service(ChromeDriverManager().install())
class LoginFailedException(Exception):
def __init__(self, *args: object) -> None:
super().__init__(*args)
class XClient:
@ -31,20 +32,13 @@ class XClient:
)
def fetch_access_token(self):
# Set up the WebDriver (make sure to use the correct path for your WebDriver)
print("starting chromedriver")
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options = webdriver.FirefoxOptions()
options.add_argument("--headless")
print("started chromedriver")
driver = webdriver.Chrome(options=options, service=service)
driver = webdriver.Firefox(options=options)
driver.get("https://x.tudelft.nl")
print("Check1")
button = WebDriverWait(driver, 30).until(
EC.element_to_be_clickable(
(By.XPATH, "//span[contains(text(), 'TUDelft')]")
@ -61,7 +55,6 @@ class XClient:
)
)
print("Check2")
button.click()
# Input the username
@ -73,13 +66,24 @@ class XClient:
password_input.submit()
time.sleep(1)
time.sleep(2)
delcom_auth = json.loads(
driver.execute_script("return window.localStorage.getItem('delcom_auth');")
cookie = driver.execute_script(
"return window.localStorage.getItem('delcom_auth');"
)
if cookie is None:
raise LoginFailedException("Logging in to X has failed")
delcom_auth = json.loads(cookie)
driver.quit()
if delcom_auth.get("tokenResponse") is None:
raise LoginFailedException(
"Logging in to X has failed, missing tokenResponse"
)
access_token = delcom_auth["tokenResponse"].get("accessToken", None)
return access_token