diff options
| author | jantuomi <jans.tuomi@gmail.com> | 2016-07-19 14:50:22 +0300 |
|---|---|---|
| committer | jantuomi <jans.tuomi@gmail.com> | 2016-07-19 14:50:22 +0300 |
| commit | 9d94a01b631676b54f680c2571ae4dbba9ccd037 (patch) | |
| tree | 2cac58eba2cd5d29ae0c2192efc5ca365dde7f74 /project/botmanager.py | |
| parent | 080cfd6cfe946e243239af201dea8466abaee020 (diff) | |
Restructure project
Diffstat (limited to 'project/botmanager.py')
| -rw-r--r-- | project/botmanager.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/project/botmanager.py b/project/botmanager.py new file mode 100644 index 0000000..805f20c --- /dev/null +++ b/project/botmanager.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- + +import logging +import random +import sys +import time +import traceback + +import telepot + +from project.jsonfactory import JSONFactory +from project.shoutboxapicommunicator import ShoutboxCommunicator +from project.telegramapicommunicator import TelegramCommunicator + + +class BotManager(object): + """Manager class for the process""" + + # Make a dict of ( message id : timestamp ) pairs to + # keep track of sent messages. + # Messages older than 2 * update interval will be forgotten. + last_message_timestamps = {} + + def __init__(self, token): + """ + Attempt to create a bot with telepot + + If not possible, crash gracefully + """ + TelegramCommunicator.token = token + try: + logging.info("Creating bot listener with token {}...".format(token)) + TelegramCommunicator.spawn_bot(token) + logging.info("Bot succesfully created.") + except: + traceback.print_exc() + logging.error("Error creating bot listener. src will now exit...") + sys.exit(1) + + def set_parameters(self, shoutbox_api_url, telegram_chat_id, api_call_interval): + """Store parameters in the manager instance""" + ShoutboxCommunicator.url = shoutbox_api_url + TelegramCommunicator.chat_id = telegram_chat_id + ShoutboxCommunicator.interval = api_call_interval + + def start(self): + """Try fetching bot information from Telegram to check connection""" + TelegramCommunicator.start_listening(self.handle) + + while True: + # Forward all new messages to the Telegram chat + # and add them to the message dict + self.forward_to_telegram(ShoutboxCommunicator.fetch()) + + # Wait for the update interval + time.sleep(ShoutboxCommunicator.interval) + + # Remove obsolete messages from the dict to prevent it + # from bloating + self.clean_up_message_dict() + + def clean_up_message_dict(self): + """Purge all obsolete messages from the message dict""" + new_message_dict = {} + for msg_id in self.last_message_timestamps: + + # if the message is older than 2 * call interval, + # pop it from the buffer because there is no way + # it can be a duplicate anymore + timestamp = round(float(self.last_message_timestamps[msg_id])) + if not round(time.time()) - timestamp < 2 * ShoutboxCommunicator.interval: + new_message_dict[msg_id] = self.last_message_timestamps[msg_id] + else: + logging.info("Popped message from buffer.") + self.last_message_timestamps = new_message_dict + + def forward_to_telegram(self, messages): + """Send all messages in the messages list to the Telegram chat""" + try: + for message in messages: + # Do not send messages that have already been sent + # This check is in place because of possible artifacts in API calls + if message["id"] not in self.last_message_timestamps: + TelegramCommunicator.send(message) + self.last_message_timestamps[message["id"]] = message["timestamp"] + + except: + logging.warning("Failed to send message to Telegram!") + + songs = ["Ace of Spades", "Mökkitie", "Alpha Russian XXL Night Mixtape", "teekkarihymni"] + + def action_now_playing(self, msg): + """Placeholder action for testing commands""" + TelegramCommunicator.send_raw("Radiossa soi {}!".format(random.choice(BotManager.songs))) + + def action_not_supported(self, msg): + """Notify the user that the given command is not supported""" + TelegramCommunicator.send_raw("Tätä toimintoa ei ole tuettu.") + + def parse_message(self, msg): + """Determine which action to take for an incoming Telegram text message""" + t = msg["text"] + content_type, chat_type, chat_id = telepot.glance(msg) + if "/nowplaying" in t: + self.action_now_playing(msg) + elif "/start" in t: + self.action_not_supported(msg) + elif "/stop" in t: + self.action_not_supported(msg) + elif str(chat_id) == TelegramCommunicator.chat_id.strip(): + self.action_send_to_shoutbox(msg) + else: + logging.info("Got non-forwarded message from chat_id: {}".format(chat_id)) + + def action_send_to_shoutbox(self, msg): + """Forward a Telegram message to shoutbox""" + try: + user_name = msg["from"]["first_name"] + text = msg["text"] + date = msg["date"] + except KeyError: + logging.warning("Malformed message from Telegram! Details:\n{}".format(msg)) + logging.warning("Skipped sending message to shoutbox.") + return + + data = JSONFactory.make_object(text, user_name, date, "null") + logging.info("Created JSON packet:\n{}".format(data)) + ShoutboxCommunicator.send(data) + + def handle(self, msg): + """Start parsing the incoming message if it is a text message""" + content_type, chat_type, chat_id = telepot.glance(msg) + + if content_type == 'text': + self.parse_message(msg) |
