Compare commits
No commits in common. "083ea29c21814310a438263aa4bb7f62ddef39bf" and "d63a39b49adfc8837a505d31811e225c4621f836" have entirely different histories.
083ea29c21
...
d63a39b49a
@ -19,13 +19,20 @@ RUN apt-get update && \
|
|||||||
build-essential \
|
build-essential \
|
||||||
libsqlite3-dev \
|
libsqlite3-dev \
|
||||||
sqlite3 \
|
sqlite3 \
|
||||||
firefox-esr \
|
chromium \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Install the required Python packages
|
# Install the required Python packages
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
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
|
# Set environment variables for Chrome and ChromeDriver
|
||||||
ENV PATH=/app:$PATH
|
ENV PATH=/app:$PATH
|
||||||
ENV DISPLAY=:99
|
ENV DISPLAY=:99
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import os
|
|||||||
|
|
||||||
TELEGRAM_TOKEN = os.environ.get("SECRETARX_TG_TOKEN", None)
|
TELEGRAM_TOKEN = os.environ.get("SECRETARX_TG_TOKEN", None)
|
||||||
DB_PATH = "data.db"
|
DB_PATH = "data.db"
|
||||||
|
CHROMEDRIVER_PATH = "chromedriver"
|
||||||
|
|
||||||
|
|
||||||
LISTEN_PORT = 9090
|
LISTEN_PORT = 9090
|
||||||
GOOGLE_CLIENT_SECRET_FILE = "credentials.json"
|
GOOGLE_CLIENT_SECRET_FILE = "credentials.json"
|
||||||
|
|||||||
64
tgbot.py
64
tgbot.py
@ -71,10 +71,6 @@ class TelegramBot:
|
|||||||
def calendar_auth(message):
|
def calendar_auth(message):
|
||||||
self.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):
|
def init_db(self):
|
||||||
with sqlite3.connect(self.db_path) as conn:
|
with sqlite3.connect(self.db_path) as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
@ -233,6 +229,9 @@ class TelegramBot:
|
|||||||
def make_booking(self, message):
|
def make_booking(self, message):
|
||||||
try:
|
try:
|
||||||
xclient = self.get_xclient(message.chat.id)
|
xclient = self.get_xclient(message.chat.id)
|
||||||
|
except Exception as e:
|
||||||
|
self.bot.reply_to(message, f"Error: {str(e)}")
|
||||||
|
return
|
||||||
|
|
||||||
if not xclient:
|
if not xclient:
|
||||||
self.bot.reply_to(
|
self.bot.reply_to(
|
||||||
@ -251,9 +250,7 @@ class TelegramBot:
|
|||||||
# Create a button for each slot
|
# Create a button for each slot
|
||||||
status = "Available" if slot.available else "FULL"
|
status = "Available" if slot.available else "FULL"
|
||||||
button_text = f"Slot {i + 1}: {slot.start_stamp} ({status})"
|
button_text = f"Slot {i + 1}: {slot.start_stamp} ({status})"
|
||||||
markup.add(
|
markup.add(InlineKeyboardButton(button_text, callback_data=f"book_{i}"))
|
||||||
InlineKeyboardButton(button_text, callback_data=f"book_{i}")
|
|
||||||
)
|
|
||||||
|
|
||||||
self.bot.reply_to(
|
self.bot.reply_to(
|
||||||
message, "Select a slot to book or watch:", reply_markup=markup
|
message, "Select a slot to book or watch:", reply_markup=markup
|
||||||
@ -262,13 +259,12 @@ class TelegramBot:
|
|||||||
else:
|
else:
|
||||||
self.bot.reply_to(message, "No slots found.")
|
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):
|
def callback_booking(self, call):
|
||||||
try:
|
try:
|
||||||
xclient = self.get_xclient(call.message.chat.id)
|
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:
|
if not xclient:
|
||||||
self.bot.reply_to(
|
self.bot.reply_to(
|
||||||
@ -320,12 +316,8 @@ class TelegramBot:
|
|||||||
f"Booking confirmed for: {selected_slot.start_stamp}",
|
f"Booking confirmed for: {selected_slot.start_stamp}",
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.bot.answer_callback_query(
|
self.bot.answer_callback_query(call.id, "Failed to book slot.")
|
||||||
call.id, "Failed to book slot."
|
self.bot.send_message(call.message.chat.id, f"Error: {str(e)}")
|
||||||
)
|
|
||||||
self.bot.send_message(
|
|
||||||
call.message.chat.id, f"Error: {str(e)}"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# Slot is full, add to watchlist
|
# Slot is full, add to watchlist
|
||||||
self.add_to_watchlist(call.message.chat.id, selected_slot)
|
self.add_to_watchlist(call.message.chat.id, selected_slot)
|
||||||
@ -346,13 +338,12 @@ class TelegramBot:
|
|||||||
call.message.chat.id, call.message.message_id
|
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):
|
def cancel_booking(self, message):
|
||||||
try:
|
try:
|
||||||
xclient = self.get_xclient(message.chat.id)
|
xclient = self.get_xclient(message.chat.id)
|
||||||
|
except Exception as e:
|
||||||
|
self.bot.reply_to(message, f"Error: {str(e)}")
|
||||||
|
return
|
||||||
|
|
||||||
if not xclient:
|
if not xclient:
|
||||||
self.bot.reply_to(
|
self.bot.reply_to(
|
||||||
@ -382,13 +373,12 @@ class TelegramBot:
|
|||||||
else:
|
else:
|
||||||
self.bot.reply_to(message, "You have no bookings to cancel.")
|
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):
|
def callback_cancel_booking(self, call):
|
||||||
try:
|
try:
|
||||||
xclient = self.get_xclient(call.message.chat.id)
|
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:
|
if not xclient:
|
||||||
self.bot.reply_to(
|
self.bot.reply_to(
|
||||||
@ -432,14 +422,10 @@ class TelegramBot:
|
|||||||
call.id, "Failed to cancel booking."
|
call.id, "Failed to cancel booking."
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.bot.answer_callback_query(
|
self.bot.answer_callback_query(call.id, "Failed to cancel booking.")
|
||||||
call.id, "Failed to cancel booking."
|
|
||||||
)
|
|
||||||
self.bot.send_message(call.message.chat.id, f"Error: {str(e)}")
|
self.bot.send_message(call.message.chat.id, f"Error: {str(e)}")
|
||||||
else:
|
else:
|
||||||
self.bot.answer_callback_query(
|
self.bot.answer_callback_query(call.id, "Invalid booking selection.")
|
||||||
call.id, "Invalid booking selection."
|
|
||||||
)
|
|
||||||
except (IndexError, ValueError):
|
except (IndexError, ValueError):
|
||||||
self.bot.answer_callback_query(call.id, "Invalid data.")
|
self.bot.answer_callback_query(call.id, "Invalid data.")
|
||||||
|
|
||||||
@ -448,10 +434,6 @@ class TelegramBot:
|
|||||||
call.message.chat.id, call.message.message_id
|
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):
|
def manage_watchlist(self, message):
|
||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
|
|
||||||
@ -513,6 +495,8 @@ class TelegramBot:
|
|||||||
for chat_id, slots in list(self.watchlist.items()):
|
for chat_id, slots in list(self.watchlist.items()):
|
||||||
try:
|
try:
|
||||||
xclient = self.get_xclient(chat_id)
|
xclient = self.get_xclient(chat_id)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error polling watchlist: {str(e)}")
|
||||||
|
|
||||||
available_slots = []
|
available_slots = []
|
||||||
for slot in slots:
|
for slot in slots:
|
||||||
@ -550,18 +534,12 @@ class TelegramBot:
|
|||||||
chat_id,
|
chat_id,
|
||||||
f"Slot {slot.start_stamp} is now available and has been booked for you.",
|
f"Slot {slot.start_stamp} is now available and has been booked for you.",
|
||||||
)
|
)
|
||||||
available_slots.append(
|
available_slots.append(slot) # Mark it to remove from watchlist
|
||||||
slot
|
|
||||||
) # Mark it to remove from watchlist
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.bot.send_message(
|
self.bot.send_message(
|
||||||
chat_id,
|
chat_id, f"Error booking slot {slot.start_stamp}: {str(e)}"
|
||||||
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
|
# Remove the expired or booked slots from the watchlist
|
||||||
self.watchlist[chat_id] = [
|
self.watchlist[chat_id] = [
|
||||||
slot for slot in slots if slot not in available_slots
|
slot for slot in slots if slot not in available_slots
|
||||||
|
|||||||
38
xclient.py
38
xclient.py
@ -1,5 +1,4 @@
|
|||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
from selenium.webdriver.firefox.options import Options
|
|
||||||
from models import Booking
|
from models import Booking
|
||||||
import json
|
import json
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
@ -7,12 +6,12 @@ from selenium.webdriver.support.ui import WebDriverWait
|
|||||||
from selenium.webdriver.support import expected_conditions as EC
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
import time
|
import time
|
||||||
import requests
|
import requests
|
||||||
|
import config
|
||||||
from selenium.webdriver.chrome.service import Service
|
from selenium.webdriver.chrome.service import Service
|
||||||
|
from webdriver_manager.chrome import ChromeDriverManager
|
||||||
|
|
||||||
|
|
||||||
class LoginFailedException(Exception):
|
service = Service(ChromeDriverManager().install())
|
||||||
def __init__(self, *args: object) -> None:
|
|
||||||
super().__init__(*args)
|
|
||||||
|
|
||||||
|
|
||||||
class XClient:
|
class XClient:
|
||||||
@ -32,13 +31,20 @@ class XClient:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def fetch_access_token(self):
|
def fetch_access_token(self):
|
||||||
options = webdriver.FirefoxOptions()
|
# Set up the WebDriver (make sure to use the correct path for your WebDriver)
|
||||||
options.add_argument("--headless")
|
print("starting chromedriver")
|
||||||
|
options = webdriver.ChromeOptions()
|
||||||
|
options.add_argument("--headless=new")
|
||||||
|
options.add_argument("--no-sandbox")
|
||||||
|
|
||||||
driver = webdriver.Firefox(options=options)
|
print("started chromedriver")
|
||||||
|
|
||||||
|
driver = webdriver.Chrome(options=options, service=service)
|
||||||
|
|
||||||
driver.get("https://x.tudelft.nl")
|
driver.get("https://x.tudelft.nl")
|
||||||
|
|
||||||
|
print("Check1")
|
||||||
|
|
||||||
button = WebDriverWait(driver, 30).until(
|
button = WebDriverWait(driver, 30).until(
|
||||||
EC.element_to_be_clickable(
|
EC.element_to_be_clickable(
|
||||||
(By.XPATH, "//span[contains(text(), 'TUDelft')]")
|
(By.XPATH, "//span[contains(text(), 'TUDelft')]")
|
||||||
@ -55,6 +61,7 @@ class XClient:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
print("Check2")
|
||||||
button.click()
|
button.click()
|
||||||
|
|
||||||
# Input the username
|
# Input the username
|
||||||
@ -66,24 +73,13 @@ class XClient:
|
|||||||
|
|
||||||
password_input.submit()
|
password_input.submit()
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(1)
|
||||||
|
|
||||||
cookie = driver.execute_script(
|
delcom_auth = json.loads(
|
||||||
"return window.localStorage.getItem('delcom_auth');"
|
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()
|
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)
|
access_token = delcom_auth["tokenResponse"].get("accessToken", None)
|
||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user