diff --git a/.gitignore b/.gitignore index 849d3ca..0740544 100644 --- a/.gitignore +++ b/.gitignore @@ -117,3 +117,5 @@ GitHub.sublime-settings !.vscode/launch.json !.vscode/extensions.json .history + +local_platform.json diff --git a/Dockerfile b/Dockerfile index 90f9ad2..5375a3d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,4 +4,5 @@ WORKDIR /usr/src/app COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . -ENTRYPOINT ["python", "entrypoint.py"] +ENV PYTHONUNBUFFERED 1 +ENTRYPOINT ["python", "main.py"] diff --git a/daemons/base.py b/daemons/base.py index 7201992..bd6fd00 100644 --- a/daemons/base.py +++ b/daemons/base.py @@ -1,3 +1,3 @@ -class Base: +class Daemon: def execute(self): raise NotImplemented diff --git a/daemons/mailbox.py b/daemons/mailbox.py index 9d531a4..d3a041c 100644 --- a/daemons/mailbox.py +++ b/daemons/mailbox.py @@ -20,6 +20,8 @@ class Daemon(base.Daemon, queues.TasksHandlerMixin): if bot['type'] == 'telegram': token = bot['secrets']['telegram_token'] self.process_telegram(token, payload['body']) + else: + print('Unknown bot type:', bot['type']) def process_telegram(self, token, payload): try: diff --git a/daemons/poll.py b/daemons/poll.py index 362ec52..412c4bd 100644 --- a/daemons/poll.py +++ b/daemons/poll.py @@ -1,5 +1,5 @@ import telebot -import multiprocessing +import threading import time from daemons import base @@ -9,34 +9,39 @@ from utils import queues class Daemon(base.Daemon): def __init__(self): - self.telegram_pollers: dict[str, dict[str, multiprocessing.Process|None]] = {} + self.telegram_bots: dict[str, dict[str, telebot.TeleBot|None]] = {} def execute(self): - bots = platform.platform_client.get_config('bots') - for project_name, project in bots.items(): - if project_name not in self.telegram_pollers: - self.telegram_pollers[project_name] = {} - for bot_name, bot_info in project.items(): - if bot_name not in self.telegram_pollers[project_name]: - self.telegram_pollers[project_name][bot_name] = None - process = self.telegram_pollers[project_name][bot_name] - if bot_info.get('poll_enabled'): - if process is not None and process.is_alive: - continue - new_process = multiprocessing.Process(target=self.start_polling, args=[bot_info['secrets']['telegram_token'], bot_info['queue']]) - new_process.start() - self.telegram_pollers[project_name][bot_name] = new_process - else: - if process is None: - continue - if process.is_alive: - process.terminate() - self.telegram_pollers[project_name][bot_name] = None - time.sleep(10) + while True: + bots = platform.platform_client.get_config('bots') + for project_name, project in bots.items(): + if project_name not in self.telegram_bots: + self.telegram_bots[project_name] = {} + for bot_name, bot_info in project.items(): + if bot_name not in self.telegram_bots[project_name]: + self.telegram_bots[project_name][bot_name] = None + bot = self.telegram_bots[project_name][bot_name] + if bot_info.get('poll_enabled'): + if bot is not None: + print(f'process for {project_name} {bot_name} is alive') + continue + print(f'starting process for {project_name} {bot_name}') + bot = telebot.TeleBot(bot_info['secrets']['telegram_token']) + self.start_polling(bot, bot_info['queue']) + self.telegram_bots[project_name][bot_name] = bot + print(f'started process for {project_name} {bot_name}') + else: + if bot is None: + print(f'process for {project_name} {bot_name} is not alive') + continue + print(f'terminating process for {project_name} {bot_name}') + bot.stop_bot() + self.telegram_bots[project_name][bot_name] = None + print(f'terminated process for {project_name} {bot_name}') + time.sleep(10) - def start_polling(telegram_token, queue): - bot = telebot.TeleBot(telegram_token) + def start_polling(self, bot: telebot.TeleBot, queue: str): @bot.message_handler() - def do_action(message): + def do_action(message: telebot.types.Message): queues.set_task(queue, message.json, 1) - bot.polling() + threading.Thread(target=bot.polling).start() diff --git a/main.py b/main.py index 49ce915..b1f1648 100644 --- a/main.py +++ b/main.py @@ -2,14 +2,16 @@ import sys arg = sys.argv[-1] +# arg = 'poll' -if arg == "poll": - print("poll is starting") - from daemons.poll import Daemon -elif arg == 'mailbox': - print("mailbox is starting") - from daemons.mailbox import Daemon -else: - raise ValueError(f"Unknown param {arg}") +if __name__ == '__main__': + if arg == "poll": + print("poll is starting") + from daemons.poll import Daemon + elif arg == 'mailbox': + print("mailbox is starting") + from daemons.mailbox import Daemon + else: + raise ValueError(f"Unknown param {arg}") -Daemon().execute() + Daemon().execute() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b20b21f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +certifi==2024.8.30 +charset-normalizer==3.4.0 +idna==3.10 +pyTelegramBotAPI==4.1.1 +requests==2.32.3 +urllib3==2.2.3 diff --git a/utils/platform.py b/utils/platform.py index 9b4e864..4b5068d 100644 --- a/utils/platform.py +++ b/utils/platform.py @@ -88,6 +88,6 @@ class PlatformClient: platform_client = PlatformClient( 'Botalka', - os.getenv('STAGE'), + os.getenv('STAGE', 'local'), need_poll=True, )