#!/usr/bin/env python3 import argparse import configparser import logging import signal import sys import threading import os from project import botmanager from project import uptimeservice from project import shoutboxapicommunicator class BotLauncher(object): CONFIG_FILE = "bot.config" @staticmethod def sigint_handler(signal, frame): """Exit gracefully when receiving an interrupt signal""" logging.info("Stopping uptime services (if any)...") uptimeservice.UptimeService.stop_services() shoutboxapicommunicator.ShoutboxCommunicator.save_largest_id() print("Exiting radiodiodibot...") sys.exit(0) def __init__(self): signal.signal(signal.SIGINT, BotLauncher.sigint_handler) try: # Python 2.7+ from logging import NullHandler except ImportError: class NullHandler(logging.Handler): def emit(self, record): pass # Read configs, unsuccessful reads are # silently ignored self.config = configparser.ConfigParser() self.config.read(BotLauncher.CONFIG_FILE) # Get the bot token as an argument from the user parser = argparse.ArgumentParser( description="""Telegram bot for the Radiodiodi Student Radio broadcast. Please configure the bot with 'bot.config' before launching.""") parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true") self.args = parser.parse_args() # Show verbose output with the -v option if self.args.verbose: logging_level = logging.INFO else: logging_level = logging.WARNING formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s") logging.getLogger().addHandler(NullHandler()) fileLogger = logging.FileHandler("output.log") fileLogger.setFormatter(formatter) consoleLogger = logging.StreamHandler() consoleLogger.setFormatter(formatter) logging.getLogger().addHandler(fileLogger) logging.getLogger().addHandler(consoleLogger) logging.getLogger().setLevel(logging_level) # 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) def run_uptime(self, port): logging.info("Setting up uptime service...") self.uptime_server = uptimeservice.UptimeService(int(port)) self.uptime_server.start() # Entry point def main(self): print("=== Radiodiodibot ===") print("Press CTRL-C to exit.") # Get default parameter values from the config file try: telegram_bot_token = self.config["GENERAL"]["TelegramBotToken"] shoutbox_api_url = self.config["GENERAL"]["ShoutboxApiUrl"] telegram_chat_id = self.config["GENERAL"]["TelegramChatID"] api_call_interval = int(self.config["GENERAL"]["ApiCallInterval"]) api_auth_token = self.config["GENERAL"]["ApiAuthToken"] uptime_port = self.config["UPTIME"]["Port"] except: logging.fatal("Config file '{}' is malformed. Please reconfigure radiodiodibot.".format( BotLauncher.CONFIG_FILE )) sys.exit(1) # 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, api_auth_token) 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 uptime server if user has provided a port to bind if uptime_port is not None: self.run_uptime(uptime_port) # Start listening manager.start() sys.exit(0) def launch(self): self.main() def main(): l = BotLauncher() l.launch() if __name__ == "__main__": main()