diff --git a/tbr.py b/tbr.py index c17edc4..50d8b8f 100644 --- a/tbr.py +++ b/tbr.py @@ -23,11 +23,13 @@ # import json -import pprint +import logging from pprint import pformat +from multiprocessing import Process from telegram.ext import Updater, CommandHandler, MessageHandler, Filters -import logging +from telegram.error import (TelegramError, Unauthorized, BadRequest, + TimedOut, ChatMigrated, NetworkError) # Enable logging logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', @@ -36,6 +38,7 @@ logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s logger = logging.getLogger(__name__) + # Define a few command handlers. These usually take the two arguments bot and # update. Error handlers also receive the raised TelegramError object in error. def start(bot, update): @@ -54,8 +57,27 @@ def echo(bot, update): update.message.reply_text(update.message.text) -def error(bot, update, error): - logger.warn('Update "%s" caused error "%s"' % (update, error)) +def error_callback(bot, update, error): + try: + raise error + except Unauthorized: + # remove update.message.chat_id from conversation list + logger.warning(error.msg) + except BadRequest: + # handle malformed requests - read more below! + logger.warning(error.msg) + except TimedOut: + # handle slow connection problems + logger.warning('TimedOut occurred') + except NetworkError: + # handle other connection problems + logger.warning(error.msg) + except ChatMigrated as e: + # the chat_id of a group has changed, use e.new_chat_id instead + logger.warning(error.msg) + except TelegramError: + # handle all other telegram related errors + logger.warning(error.msg) routingdict = dict() @@ -72,6 +94,22 @@ def print_routes(bot, update): update.message.reply_text(pformat(routingdict)) +def input_handler(fd): + stream = open(fd) + for line in stream: # CTRL+D, eli EOF, lopettaa + print('Line: {}'.format(line), end='') + parsed = json.loads(line) + source_id = parsed.get('source_id', '') + for chat_id in routingdict.get(source_id, {}): + if source_id == 'pandacraft': + if parsed['verb'] == 'joined': + updater.bot.send_message(chat_id=chat_id, text='Pandacraft: {} liittyi peliin'.format(parsed['player'])) + else: + updater.bot.send_message(chat_id=chat_id, text='Pandacraft: {} poistui'.format(parsed['player'])) + else: + updater.bot.send_message(chat_id=chat_id, text=line) + + def main(token_file): TG_TOKEN = open(token_file).read() @@ -94,29 +132,23 @@ def main(token_file): dp.add_handler(MessageHandler(Filters.text, echo)) # log all errors - dp.add_error_handler(error) + dp.add_error_handler(error_callback) # Start the Bot updater.start_polling() - # PA-PA - for line in sys.stdin: # CTRL+D, eli EOF, lopettaa - print('Line: {}'.format(line)) - parsed = json.loads(line) - source_id = parsed.get('source_id', '') - for chat_id in routingdict.get(source_id, {}): - if source_id == 'pandacraft': - if parsed['verb'] == 'joined': - updater.bot.send_message(chat_id=chat_id, text='Pandacraft: {} liittyi peliin'.format(parsed['player'])) - else: - updater.bot.send_message(chat_id=chat_id, text='Pandacraft: {} poistui'.format(parsed['player'])) - else: - updater.bot.send_message(chat_id=chat_id, text=line) + # Start input handler + fd = sys.stdin.fileno() # = 0 + ih = Process(target=input_handler, args=(fd,)) + ih.start() + + print('Input handler started.') + ih.join() # Run the bot until you press Ctrl-C or the process receives SIGINT, # SIGTERM or SIGABRT. This should be used most of the time, since # start_polling() is non-blocking and will stop the bot gracefully. - print('Entering idle...') + print('Entering idle.') updater.idle() return 0