1
Fork 0
mirror of https://github.com/Steffo99/greed.git synced 2024-11-25 15:24:17 +00:00
greed/worker.py

68 lines
2.6 KiB
Python
Raw Normal View History

2017-12-14 07:53:16 +00:00
import threading
import telegram
2017-12-12 18:56:38 +00:00
import strings
2017-12-13 10:20:53 +00:00
import configloader
import sys
2017-12-14 07:53:16 +00:00
import queue as queuem
2017-12-13 10:20:53 +00:00
2017-12-12 18:56:38 +00:00
class StopSignal:
"""A data class that should be sent to the worker when the conversation has to be stopped abnormally."""
def __init__(self, reason: str=""):
self.reason = reason
2017-12-14 08:40:03 +00:00
class ChatWorker(threading.Thread):
"""A worker for a single conversation. A new one is created every time the /start command is sent."""
2017-12-14 08:40:03 +00:00
def __init__(self, bot: telegram.Bot, chat: telegram.Chat, *args, **kwargs):
# Initialize the thread
super().__init__(name=f"ChatThread {chat.first_name}", *args, **kwargs)
# Store the bot and chat info inside the class
self.bot = bot
self.chat = chat
# The sending pipe is stored in the ChatWorker class, allowing the forwarding of messages to the chat process
2017-12-14 07:53:16 +00:00
self.queue = queuem.Queue()
2017-12-14 08:40:03 +00:00
def run(self):
"""The conversation code."""
# TODO: catch all the possible exceptions
# Welcome the user to the bot
self.bot.send_message(self.chat.id, strings.conversation_after_start)
# TODO: Send a command list or something
while True:
# For now, echo the sent message
update = self._receive_next_update()
self.bot.send_message(self.chat.id, f"{threading.current_thread().name} {update.message.text}")
2017-12-12 18:56:38 +00:00
def stop(self, reason: str=""):
"""Gracefully stop the worker process"""
2017-12-14 07:53:16 +00:00
# Send a stop message to the thread
self.queue.put(StopSignal(reason))
# Wait for the thread to stop
2017-12-14 08:40:03 +00:00
self.join()
2017-12-14 08:40:03 +00:00
def _receive_next_update(self) -> telegram.Update:
"""Get the next update from the queue.
If no update is found, block the process until one is received.
If a stop signal is sent, try to gracefully stop the thread."""
# Pop data from the queue
try:
2017-12-17 15:49:46 +00:00
data = self.queue.get(timeout=int(configloader.config["Telegram"]["conversation_timeout"]))
2017-12-14 08:40:03 +00:00
except queuem.Empty:
# If the conversation times out, gracefully stop the thread
self._graceful_stop()
# Check if the data is a stop signal instance
if isinstance(data, StopSignal):
# Gracefully stop the process
self._graceful_stop()
# Return the received update
return data
2017-12-13 10:20:53 +00:00
2017-12-14 08:40:03 +00:00
def _graceful_stop(self):
"""Handle the graceful stop of the thread."""
# Notify the user that the session has expired
self.bot.send_message(self.chat.id, strings.conversation_expired)
# End the process
sys.exit(0)