From 9d94a01b631676b54f680c2571ae4dbba9ccd037 Mon Sep 17 00:00:00 2001 From: jantuomi Date: Tue, 19 Jul 2016 14:50:22 +0300 Subject: Restructure project --- basecommunicator.py | 10 --- botmanager.py | 133 ------------------------------------ jsonfactory.py | 27 -------- mockshoutbox.py | 79 ---------------------- project/__init__.py | 0 project/basecommunicator.py | 10 +++ project/botmanager.py | 135 +++++++++++++++++++++++++++++++++++++ project/jsonfactory.py | 27 ++++++++ project/mockshoutbox.py | 79 ++++++++++++++++++++++ project/shoutboxapicommunicator.py | 41 +++++++++++ project/telegramapicommunicator.py | 47 +++++++++++++ radiodiodibot | 97 ++++++++++++++++++++++++++ radiodiodibot.py | 96 -------------------------- shoutboxapicommunicator.py | 39 ----------- telegramapicommunicator.py | 47 ------------- 15 files changed, 436 insertions(+), 431 deletions(-) delete mode 100644 basecommunicator.py delete mode 100644 botmanager.py delete mode 100644 jsonfactory.py delete mode 100644 mockshoutbox.py create mode 100644 project/__init__.py create mode 100644 project/basecommunicator.py create mode 100644 project/botmanager.py create mode 100644 project/jsonfactory.py create mode 100644 project/mockshoutbox.py create mode 100644 project/shoutboxapicommunicator.py create mode 100644 project/telegramapicommunicator.py create mode 100755 radiodiodibot delete mode 100755 radiodiodibot.py delete mode 100644 shoutboxapicommunicator.py delete mode 100644 telegramapicommunicator.py diff --git a/basecommunicator.py b/basecommunicator.py deleted file mode 100644 index f4f8337..0000000 --- a/basecommunicator.py +++ /dev/null @@ -1,10 +0,0 @@ -class BaseCommunicator: - """Parent class for Telegram and shoutbox API communicators""" - - @staticmethod - def fetch(): - ... - - @staticmethod - def send(data): - ... diff --git a/botmanager.py b/botmanager.py deleted file mode 100644 index 8cfe949..0000000 --- a/botmanager.py +++ /dev/null @@ -1,133 +0,0 @@ -# -*- coding: utf-8 -*- - -import random -import sys -import telepot -import traceback -import time -import logging - -from jsonfactory import JSONFactory -from shoutboxapicommunicator import ShoutboxCommunicator -from 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. radiodiodibot 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) diff --git a/jsonfactory.py b/jsonfactory.py deleted file mode 100644 index c57b430..0000000 --- a/jsonfactory.py +++ /dev/null @@ -1,27 +0,0 @@ -import json - - -class JSONFactory(object): - """Factory class to create JSON messages to be sent to the shoutbox API""" - running_id = 1 - - @staticmethod - def make_object(text, user, timestamp, ip): - """ - Create a JSON object from the passed parameters and - add a running id - """ - message = json.dumps({ - "id": JSONFactory.running_id, - "text": text, - "user": user, - "timestamp": timestamp, - "ip": ip - }) - JSONFactory.running_id += 1 - return message - - @staticmethod - def make_array(object_list): - """Create a JSON array from a list of JSON objects""" - return "[\n" + ",\n".join(object_list) + "\n]" diff --git a/mockshoutbox.py b/mockshoutbox.py deleted file mode 100644 index 4a64406..0000000 --- a/mockshoutbox.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python - -import sys -import http.server -import traceback -from http.server import SimpleHTTPRequestHandler -import json - -import time - - -class MyHandler(SimpleHTTPRequestHandler): - """ - Mock shoutbox HTTP server to test - shoutbox API requests. - """ - def do_HEAD(self): - self.send_response(200) - self.send_header("Content-type", "application/json") - self.end_headers() - - def do_GET(self): - """ - Respond to a GET with a JSON array containing one object - that contains the following: - - test user: test message - """ - - self.send_response(200) - self.send_header("Content-type", "application/json") - self.end_headers() - - timestamp = str(round(time.time())) - body = json.dumps([{ - "user": "test user", - "text": "test message", - "timestamp": timestamp, - "id": timestamp, - "ip": "1.2.3.4" - }]) - self.wfile.write(body.encode()) - - def do_POST(self): - """ - Respond to a POST by printing the message contents to console - """ - content_len = int(self.headers.get('Content-Length')) - post_data = self.rfile.read(content_len) - - try: - message = json.loads(post_data.decode('utf-8')) - print("{}: {}".format(message["user"], message["text"])) - self.send_response(200) - - except: - traceback.print_exc() - self.send_response(400) - - self.end_headers() - - return - -HandlerClass = MyHandler -ServerClass = http.server.HTTPServer -Protocol = "HTTP/1.0" - -if sys.argv[1:]: - port = int(sys.argv[1]) -else: - port = 8000 -server_address = ('127.0.0.1', port) - -HandlerClass.protocol_version = Protocol -httpd = ServerClass(server_address, HandlerClass) - -sa = httpd.socket.getsockname() -print("Serving HTTP on", sa[0], "port", sa[1], "...") -httpd.serve_forever() diff --git a/project/__init__.py b/project/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/project/basecommunicator.py b/project/basecommunicator.py new file mode 100644 index 0000000..f4f8337 --- /dev/null +++ b/project/basecommunicator.py @@ -0,0 +1,10 @@ +class BaseCommunicator: + """Parent class for Telegram and shoutbox API communicators""" + + @staticmethod + def fetch(): + ... + + @staticmethod + def send(data): + ... 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) diff --git a/project/jsonfactory.py b/project/jsonfactory.py new file mode 100644 index 0000000..c57b430 --- /dev/null +++ b/project/jsonfactory.py @@ -0,0 +1,27 @@ +import json + + +class JSONFactory(object): + """Factory class to create JSON messages to be sent to the shoutbox API""" + running_id = 1 + + @staticmethod + def make_object(text, user, timestamp, ip): + """ + Create a JSON object from the passed parameters and + add a running id + """ + message = json.dumps({ + "id": JSONFactory.running_id, + "text": text, + "user": user, + "timestamp": timestamp, + "ip": ip + }) + JSONFactory.running_id += 1 + return message + + @staticmethod + def make_array(object_list): + """Create a JSON array from a list of JSON objects""" + return "[\n" + ",\n".join(object_list) + "\n]" diff --git a/project/mockshoutbox.py b/project/mockshoutbox.py new file mode 100644 index 0000000..4a64406 --- /dev/null +++ b/project/mockshoutbox.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +import sys +import http.server +import traceback +from http.server import SimpleHTTPRequestHandler +import json + +import time + + +class MyHandler(SimpleHTTPRequestHandler): + """ + Mock shoutbox HTTP server to test + shoutbox API requests. + """ + def do_HEAD(self): + self.send_response(200) + self.send_header("Content-type", "application/json") + self.end_headers() + + def do_GET(self): + """ + Respond to a GET with a JSON array containing one object + that contains the following: + + test user: test message + """ + + self.send_response(200) + self.send_header("Content-type", "application/json") + self.end_headers() + + timestamp = str(round(time.time())) + body = json.dumps([{ + "user": "test user", + "text": "test message", + "timestamp": timestamp, + "id": timestamp, + "ip": "1.2.3.4" + }]) + self.wfile.write(body.encode()) + + def do_POST(self): + """ + Respond to a POST by printing the message contents to console + """ + content_len = int(self.headers.get('Content-Length')) + post_data = self.rfile.read(content_len) + + try: + message = json.loads(post_data.decode('utf-8')) + print("{}: {}".format(message["user"], message["text"])) + self.send_response(200) + + except: + traceback.print_exc() + self.send_response(400) + + self.end_headers() + + return + +HandlerClass = MyHandler +ServerClass = http.server.HTTPServer +Protocol = "HTTP/1.0" + +if sys.argv[1:]: + port = int(sys.argv[1]) +else: + port = 8000 +server_address = ('127.0.0.1', port) + +HandlerClass.protocol_version = Protocol +httpd = ServerClass(server_address, HandlerClass) + +sa = httpd.socket.getsockname() +print("Serving HTTP on", sa[0], "port", sa[1], "...") +httpd.serve_forever() diff --git a/project/shoutboxapicommunicator.py b/project/shoutboxapicommunicator.py new file mode 100644 index 0000000..7194c8f --- /dev/null +++ b/project/shoutboxapicommunicator.py @@ -0,0 +1,41 @@ +import json +import logging + +import requests + +from project.basecommunicator import BaseCommunicator + + +class ShoutboxCommunicator(BaseCommunicator): + """Class for communication with the shoutbox API""" + + url = "http://localhost:8000" + interval = 10 + + @staticmethod + def fetch(): + """Get and return a list of new messages from the API""" + try: + r = requests.get(ShoutboxCommunicator.url) + logging.info("Response from API OK.") + + except: + logging.warning("Failed to get response from API!") + return + + content = json.loads(r.text) + logging.info("Messages:") + for msg in content: + logging.info("{}: {}".format(msg["user"], msg["text"])) + + return content + + @staticmethod + def send(data): + """Send a JSON message to the API""" + try: + requests.post(ShoutboxCommunicator.url, data) + user = json.loads(data)["user"] + logging.info("Sent message from {} to shoutbox.".format(user)) + except: + logging.warning("Failed to send message to shoutbox API!") diff --git a/project/telegramapicommunicator.py b/project/telegramapicommunicator.py new file mode 100644 index 0000000..7fdb29c --- /dev/null +++ b/project/telegramapicommunicator.py @@ -0,0 +1,47 @@ +import logging +import sys + +import telepot + +from project.basecommunicator import BaseCommunicator + + +class TelegramCommunicator(BaseCommunicator): + """Class for communicating with the Telegram API""" + + chat_id = "default_id" + bot = None + token = "DEFAULT_TOKEN_123" + + @staticmethod + def spawn_bot(token): + TelegramCommunicator.bot = telepot.Bot(token) + + @staticmethod + def fetch(): + raise Exception("""Attempted to fetch messages from Telegram manually. + Please use telepot bot functionality for listening to messages.""") + + @staticmethod + def send(data): + TelegramCommunicator.send_raw("{}: {}".format(data["user"], data["text"])) + + @staticmethod + def send_raw(message): + try: + TelegramCommunicator.bot.sendMessage(TelegramCommunicator.chat_id, + message) + except: + logging.warning("Could not send message to Telegram chat id {}!".format(TelegramCommunicator.chat_id)) + + @staticmethod + def start_listening(handle): + try: + logging.info("Bot info: {}".format(TelegramCommunicator.bot.getMe())) + except: + logging.error("Could not fetch bot info. Check your token and connectivity to Telegram!") + sys.exit(1) + + TelegramCommunicator.bot.message_loop(handle) + + logging.info("Listening for messages...") diff --git a/radiodiodibot b/radiodiodibot new file mode 100755 index 0000000..4bd53e0 --- /dev/null +++ b/radiodiodibot @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +import argparse +import configparser +import logging +import signal +import sys + +from project import botmanager + + +def sigint_handler(signal, frame): + """Exit gracefully when receiving an interrupt signal""" + print("Exiting src...") + sys.exit(0) + +signal.signal(signal.SIGINT, sigint_handler) + +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +logging.getLogger(__name__).addHandler(NullHandler()) + +# Read configs, unsuccessful reads are +# silently ignored +CONFIG_FILE = "bot.config" +config = configparser.ConfigParser() +config.read(CONFIG_FILE) + +# Get the bot token as an argument from the user +parser = argparse.ArgumentParser(description="Telegram bot for the Radiodiodi Student Radio broadcast.") +parser.add_argument("-t", "--token", help="Telegram Bot API token") +parser.add_argument("-U", "--shoutbox-api-url", help="Shoutbox API URL") +parser.add_argument("-C", "--telegram-chat-id", help="Telegram Chat ID") +parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true") +parser.add_argument("-i", "--interval", help="Delay between API update calls in seconds", type=int, default=10) +args = parser.parse_args() + +# Show verbose output with the -v option +if args.verbose: + logging_level = logging.INFO +else: + logging_level = logging.WARNING + +logging.basicConfig(level=logging_level, format="%(asctime)s %(levelname)s %(message)s") + +# Try to import telepot +# If not installed, inform user and fail gracefully +try: + import telepot +except: + print("src needs the telepot module to communicate with Telegram.") + print("Please install telepot before using src.") + sys.exit(1) + + +# Entry point +def main(): + print("=== Radiodiodibot ===") + print("Press CTRL-C to exit.") + # Get default parameter values from the config file + telegram_bot_token = config["GENERAL"]["TelegramBotToken"] + shoutbox_api_url = config["GENERAL"]["ShoutboxApiUrl"] + telegram_chat_id = config["GENERAL"]["TelegramChatID"] + api_call_interval = config["GENERAL"]["ApiCallInterval"] + + # If the user has specified the parameters as command line + # arguments, use them to override the config values + if args.token is not None: + telegram_bot_token = args.token + + if args.shoutbox_api_url is not None: + shoutbox_api_url = args.shoutbox_api_url + + if args.telegram_chat_id is not None: + telegram_chat_id = args.telegram_chat_id + + if args.interval is not None: + api_call_interval = args.interval + + # Store the final values in a manager instance + manager = botmanager.BotManager(telegram_bot_token) + manager.set_parameters(shoutbox_api_url, telegram_chat_id, api_call_interval) + + logging.info("Using Shoutbox API URL: {}".format(shoutbox_api_url)) + logging.info("Using Telegram Chat ID: {}".format(telegram_chat_id)) + logging.info("Using API call interval of {} seconds.".format(api_call_interval)) + + # Start listening + manager.start() + + +if __name__ == "__main__": + main() diff --git a/radiodiodibot.py b/radiodiodibot.py deleted file mode 100755 index 8499e90..0000000 --- a/radiodiodibot.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python -import configparser -import sys -import argparse -import botmanager -import logging -import signal - - -def sigint_handler(signal, frame): - """Exit gracefully when receiving an interrupt signal""" - print("Exiting radiodiodibot...") - sys.exit(0) - -signal.signal(signal.SIGINT, sigint_handler) - -try: # Python 2.7+ - from logging import NullHandler -except ImportError: - class NullHandler(logging.Handler): - def emit(self, record): - pass - -logging.getLogger(__name__).addHandler(NullHandler()) - -# Read configs, unsuccessful reads are silently -# ignored -CONFIG_FILE = "bot.config" -config = configparser.ConfigParser() -config.read(CONFIG_FILE) - -# Get the bot token as an argument from the user -parser = argparse.ArgumentParser(description="Telegram bot for the Radiodiodi Student Radio broadcast.") -parser.add_argument("-t", "--token", help="Telegram Bot API token") -parser.add_argument("-U", "--shoutbox-api-url", help="Shoutbox API URL") -parser.add_argument("-C", "--telegram-chat-id", help="Telegram Chat ID") -parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true") -parser.add_argument("-i", "--interval", help="Delay between API update calls in seconds", type=int, default=10) -args = parser.parse_args() - -# Show verbose output with the -v option -if args.verbose: - logging_level = logging.INFO -else: - logging_level = logging.WARNING - -logging.basicConfig(level=logging_level, format="%(asctime)s %(levelname)s %(message)s") - -# Try to import telepot -# If not installed, inform user and fail gracefully -try: - import telepot -except: - print("radiodiodibot needs the telepot module to communicate with Telegram.") - print("Please install telepot before using radiodiodibot.") - sys.exit(1) - - -# Entry point -def main(): - print("=== Radiodiodibot ===") - print("Press CTRL-C to exit.") - # Get default parameter values from the config file - telegram_bot_token = config["GENERAL"]["TelegramBotToken"] - shoutbox_api_url = config["GENERAL"]["ShoutboxApiUrl"] - telegram_chat_id = config["GENERAL"]["TelegramChatID"] - api_call_interval = config["GENERAL"]["ApiCallInterval"] - - # If the user has specified the parameters as command line - # arguments, use them to override the config values - if args.token is not None: - telegram_bot_token = args.token - - if args.shoutbox_api_url is not None: - shoutbox_api_url = args.shoutbox_api_url - - if args.telegram_chat_id is not None: - telegram_chat_id = args.telegram_chat_id - - if args.interval is not None: - api_call_interval = args.interval - - # Store the final values in a manager instance - manager = botmanager.BotManager(telegram_bot_token) - manager.set_parameters(shoutbox_api_url, telegram_chat_id, api_call_interval) - - logging.info("Using Shoutbox API URL: {}".format(shoutbox_api_url)) - logging.info("Using Telegram Chat ID: {}".format(telegram_chat_id)) - logging.info("Using API call interval of {} seconds.".format(api_call_interval)) - - # Start listening - manager.start() - - -if __name__ == "__main__": - main() diff --git a/shoutboxapicommunicator.py b/shoutboxapicommunicator.py deleted file mode 100644 index 7138aa9..0000000 --- a/shoutboxapicommunicator.py +++ /dev/null @@ -1,39 +0,0 @@ -import json -import requests -import logging -from basecommunicator import BaseCommunicator - - -class ShoutboxCommunicator(BaseCommunicator): - """Class for communication with the shoutbox API""" - - url = "http://localhost:8000" - interval = 10 - - @staticmethod - def fetch(): - """Get and return a list of new messages from the API""" - try: - r = requests.get(ShoutboxCommunicator.url) - logging.info("Response from API OK.") - - except: - logging.warning("Failed to get response from API!") - return - - content = json.loads(r.text) - logging.info("Messages:") - for msg in content: - logging.info("{}: {}".format(msg["user"], msg["text"])) - - return content - - @staticmethod - def send(data): - """Send a JSON message to the API""" - try: - requests.post(ShoutboxCommunicator.url, data) - user = json.loads(data)["user"] - logging.info("Sent message from {} to shoutbox.".format(user)) - except: - logging.warning("Failed to send message to shoutbox API!") diff --git a/telegramapicommunicator.py b/telegramapicommunicator.py deleted file mode 100644 index 169a1ce..0000000 --- a/telegramapicommunicator.py +++ /dev/null @@ -1,47 +0,0 @@ -import logging - -import sys -import telepot - -from basecommunicator import BaseCommunicator - - -class TelegramCommunicator(BaseCommunicator): - """Class for communicating with the Telegram API""" - - chat_id = "default_id" - bot = None - token = "DEFAULT_TOKEN_123" - - @staticmethod - def spawn_bot(token): - TelegramCommunicator.bot = telepot.Bot(token) - - @staticmethod - def fetch(): - raise Exception("""Attempted to fetch messages from Telegram manually. - Please use telepot bot functionality for listening to messages.""") - - @staticmethod - def send(data): - TelegramCommunicator.send_raw("{}: {}".format(data["user"], data["text"])) - - @staticmethod - def send_raw(message): - try: - TelegramCommunicator.bot.sendMessage(TelegramCommunicator.chat_id, - message) - except: - logging.warning("Could not send message to Telegram chat id {}!".format(TelegramCommunicator.chat_id)) - - @staticmethod - def start_listening(handle): - try: - logging.info("Bot info: {}".format(TelegramCommunicator.bot.getMe())) - except: - logging.error("Could not fetch bot info. Check your token and connectivity to Telegram!") - sys.exit(1) - - TelegramCommunicator.bot.message_loop(handle) - - logging.info("Listening for messages...") -- cgit v1.3