diff --git a/src/main.py b/src/main.py index f40a6cf..592d073 100644 --- a/src/main.py +++ b/src/main.py @@ -6,7 +6,7 @@ from telegram.ext import Application, CommandHandler, CallbackQueryHandler from src.jobspy import Site from src.jobspy.scrapers.utils import create_logger from src.telegram_handler import TelegramIndeedHandler, TelegramDefaultHandler -from src.telegram_handler.telegram_callback_handler import TelegramCallHandler +from src.telegram_handler.button_callback.telegram_callback_handler import TelegramCallHandler logger = create_logger("Main") title_filters: list[str] = ["test", "qa", "Lead", "Full-Stack", "Full Stack", "Fullstack", "Frontend", "Front-end", diff --git a/src/telegram_bot.py b/src/telegram_bot.py index 77d433e..2875eb8 100644 --- a/src/telegram_bot.py +++ b/src/telegram_bot.py @@ -44,7 +44,6 @@ class TelegramBot: logger.error(f"Failed to send job to Telegram: {job.id}") logger.error(f"Error: {e}") - async def send_test_message(self): """ Send Test Message to Telegram chat. @@ -65,15 +64,14 @@ class TelegramBot: logger.error("Failed o send test message to Telegram") logger.error(f"Error: {e}") - - async def set_message_reaction(self, message_id: int, emoji_reaction: str): + async def set_message_reaction(self, message_id: int, emoji_reaction: ReactionEmoji): """ Send Test Message to Telegram chat. """ try: await self.bot.set_message_reaction(chat_id=self.chatId, message_id=message_id, - reaction=ReactionEmoji[emoji_reaction]) - logger.info("Sent test message to Telegram") + reaction=emoji_reaction) + logger.info(f"Reaction set to message: {message_id}") except Exception as e: - logger.error("Failed to send test message to Telegram") + logger.error(f"Failed to set Reaction to message: {message_id}") logger.error(f"Error: {e}") diff --git a/src/telegram_handler/button_callback/__init__.py b/src/telegram_handler/button_callback/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/telegram_handler/button_callback/button_callback_context.py b/src/telegram_handler/button_callback/button_callback_context.py new file mode 100644 index 0000000..51b6f6b --- /dev/null +++ b/src/telegram_handler/button_callback/button_callback_context.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +from src.telegram_bot import TelegramBot +from src.telegram_handler.button_callback.button_strategy import ButtonStrategy + + +class ButtonCallBackContext(): + """ + The Context defines the interface + """ + + def __init__(self, strategy: ButtonStrategy = None) -> None: + self.telegram_bot = TelegramBot() + self._strategy = strategy + + @property + def strategy(self) -> ButtonStrategy: + """ + The Context maintains a reference to one of the Strategy objects. The + Context does not know the concrete class of a strategy. It should work + with all strategies via the Strategy interface. + """ + + return self._strategy + + @strategy.setter + def strategy(self, strategy: ButtonStrategy) -> None: + """ + Usually, the Context allows replacing a Strategy object at runtime. + """ + + self._strategy = strategy + + async def run(self) -> None: + # extract job id from message + # find the position in DB + # set applied to True + # save + # set reaction to message + + print("Context: Starting") + await self._strategy.execute() + print("Context: Finished") + + # ... diff --git a/src/telegram_handler/button_callback/button_fire_strategy.py b/src/telegram_handler/button_callback/button_fire_strategy.py new file mode 100644 index 0000000..5c1e4cd --- /dev/null +++ b/src/telegram_handler/button_callback/button_fire_strategy.py @@ -0,0 +1,24 @@ +from telegram import MaybeInaccessibleMessage +from telegram.constants import ReactionEmoji + +from src.telegram_bot import TelegramBot +from src.telegram_handler.button_callback.button_strategy import ButtonStrategy + + +class FireStrategy(ButtonStrategy): + def __init__(self, data: MaybeInaccessibleMessage) -> None: + """ + Usually, the Context accepts a strategy through the constructor, but + also provides a setter to change it at runtime. + """ + self.data = data + self._emoji = ReactionEmoji.FIRE + + async def execute(self): + telegram_bot = TelegramBot() + await telegram_bot.set_message_reaction(self.data.message_id, self._emoji) + # find the position in DB + # set applied to True + # save + # set reaction to message + pass diff --git a/src/telegram_handler/button_callback/button_poo_strategy.py b/src/telegram_handler/button_callback/button_poo_strategy.py new file mode 100644 index 0000000..e21c679 --- /dev/null +++ b/src/telegram_handler/button_callback/button_poo_strategy.py @@ -0,0 +1,17 @@ +from telegram import MaybeInaccessibleMessage +from telegram.constants import ReactionEmoji + +from src.telegram_handler.button_callback.button_strategy import ButtonStrategy + + +class PooStrategy(ButtonStrategy): + def __init__(self, data: MaybeInaccessibleMessage) -> None: + """ + Usually, the Context accepts a strategy through the constructor, but + also provides a setter to change it at runtime. + """ + self.data = data + self._emoji = ReactionEmoji.PILE_OF_POO + + async def execute(self): + pass \ No newline at end of file diff --git a/src/telegram_handler/button_callback/button_strategy.py b/src/telegram_handler/button_callback/button_strategy.py new file mode 100644 index 0000000..5163b0b --- /dev/null +++ b/src/telegram_handler/button_callback/button_strategy.py @@ -0,0 +1,15 @@ +from abc import ABC, abstractmethod + + +class ButtonStrategy(ABC): + """ + The Strategy interface declares operations common to all supported versions + of some algorithm. + + The Context uses this interface to call the algorithm defined by Concrete + Strategies. + """ + + @abstractmethod + async def execute(self): + pass \ No newline at end of file diff --git a/src/telegram_handler/button_callback/telegram_callback_handler.py b/src/telegram_handler/button_callback/telegram_callback_handler.py new file mode 100644 index 0000000..b6e9915 --- /dev/null +++ b/src/telegram_handler/button_callback/telegram_callback_handler.py @@ -0,0 +1,37 @@ +from telegram import Update +from telegram.constants import ReactionEmoji +from telegram.ext import ( + ContextTypes, +) + +from src.telegram_bot import TelegramBot +from src.telegram_handler.button_callback.button_callback_context import ButtonCallBackContext +from src.telegram_handler.button_callback.button_fire_strategy import FireStrategy +from src.telegram_handler.button_callback.button_poo_strategy import PooStrategy + + +class TelegramCallHandler: + def __init__(self): + self.telegram_bot = TelegramBot() + + async def button_callback(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Parses the CallbackQuery and updates the message text.""" + query = update.callback_query + + # CallbackQueries need to be answered, even if no notification to the user is needed + # Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery + await query.answer() + button_context = ButtonCallBackContext() + if ReactionEmoji.FIRE.name == query.data: + strategy = FireStrategy(query.message) + # elif ReactionEmoji.PILE_OF_POO.name == query.data: + # strategy = PooStrategy(query.message) + else: + raise ValueError("Invalid enum value") + + if not strategy: + return + + button_context.strategy = strategy + await button_context.run() + diff --git a/src/telegram_handler/telegram_callback_handler.py b/src/telegram_handler/telegram_callback_handler.py deleted file mode 100644 index b28df7b..0000000 --- a/src/telegram_handler/telegram_callback_handler.py +++ /dev/null @@ -1,21 +0,0 @@ -from telegram import Update -from telegram.ext import ( - ContextTypes, -) - -from src.telegram_bot import TelegramBot - - -class TelegramCallHandler: - def __init__(self): - self.telegram_bot = TelegramBot() - - async def button_callback(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: - """Parses the CallbackQuery and updates the message text.""" - query = update.callback_query - - # CallbackQueries need to be answered, even if no notification to the user is needed - # Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery - await query.answer() - await self.telegram_bot.set_message_reaction(query.message.message_id, query.data) -