Ejemplo n.º 1
0
def main():
    setup_logging()

    updater = Updater(TOKEN, workers=int(os.environ.get('PTB_WORKERS', 2)))

    dp = updater.dispatcher

    dp.addTelegramCommandHandler('start', start)
    addTelegramCommandHandler(dp, 'help', help, 'display help message')
    mensa_help = '\[<date>] get what offerings are waiting for you at the specified date ' \
                 'formatted like \'YYYY-MM-DD\'.'
    addTelegramCommandHandler(dp, 'mensa', mensa_plan_all, mensa_help)
        # alias for autocorrected command
    dp.addTelegramCommandHandler('Mensa', mensa_plan_all)
    addTelegramCommandHandler(dp, 'm', m_plan_keyboard, 'show quick-access menu')

    # shortcuts to direct offers
    for cmd, f, h in SHORTCUTS:
        addTelegramCommandHandler(dp, cmd, f, h)
        dp.addTelegramCommandHandler(cmd.capitalize(), f)

    dp.addTelegramCommandHandler('week', week_plan)

    dp.addErrorHandler(error)
    dp.addUnknownTelegramCommandHandler(unknown)

    if USE_POLLING:
        logging.info('Bot running with polling enabled.')
        update_queue = updater.start_polling(poll_interval=1, timeout=5)
        updater.idle()
    else:
        logging.info('Bot running with webhook.')
        # You can also set the webhook yourself (via cURL) or delete it sending an empty url.
        # Note that for self-signed certificates, you also have to send the .pem certificate file
        # to the Telegram API.
        updater.bot.setWebhook(webhook_url=os.environ.get('PTB_WEBHOOK_URL'))
        update_queue = updater.start_webhook(os.environ.get('PTB_WEBHOOK_LISTEN_IP'),
                                             os.environ.get('PTB_WEBHOOK_LISTEN_PORT'))
Ejemplo n.º 2
0
class UpdaterTest(BaseTest, unittest.TestCase):
    """
    This object represents Tests for Updater, Dispatcher, WebhookServer and
    WebhookHandler
    """

    def setUp(self):
        self.updater = Updater('', workers=2)

        self.received_message = None
        self.message_count = 0
        self.lock = Lock()

    def tearDown(self):
        self.updater.stop()

    def reset(self):
        self.message_count = 0
        self.received_message = None

    def telegramHandlerTest(self, bot, update):
        self.received_message = update.message.text
        self.message_count += 1

    @run_async
    def asyncHandlerTest(self, bot, update):
        sleep(1)
        with self.lock:
            self.received_message = update.message.text
            self.message_count += 1

    def stringHandlerTest(self, bot, update):
        self.received_message = update
        self.message_count += 1

    def additionalArgsTest(self, bot, update, update_queue, args):
        self.received_message = update
        self.message_count += 1
        if args[0] == 'resend':
            update_queue.put('/test5 noresend')
        elif args[0] == 'noresend':
            pass

    def errorRaisingHandlerTest(self, bot, update):
        raise TelegramError(update)

    def errorHandlerTest(self, bot, update, error):
        self.received_message = error.message
        self.message_count += 1

    def test_addRemoveTelegramMessageHandler(self):
        print('Testing add/removeTelegramMessageHandler')
        bot = MockBot('Test')
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test')

        # Remove handler
        d.removeTelegramMessageHandler(self.telegramHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addTelegramMessageHandlerMultipleMessages(self):
        print('Testing addTelegramMessageHandler and send 100 messages...')
        self.updater.bot = MockBot('Multiple', 100)
        self.updater.dispatcher.addTelegramMessageHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.0)
        sleep(.5)
        self.assertEqual(self.received_message, 'Multiple')
        self.assertEqual(self.message_count, 100)

    def test_addRemoveTelegramRegexHandler(self):
        print('Testing add/removeStringRegexHandler')
        bot = MockBot('Test2')
        self.updater.bot = bot
        d = self.updater.dispatcher
        regobj = re.compile('Te.*')
        self.updater.dispatcher.addTelegramRegexHandler(regobj,
                                                        self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test2')

        # Remove handler
        d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveTelegramCommandHandler(self):
        print('Testing add/removeTelegramCommandHandler')
        bot = MockBot('/test')
        self.updater.bot = bot
        d = self.updater.dispatcher
        self.updater.dispatcher.addTelegramCommandHandler(
            'test', self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test')

        # Remove handler
        d.removeTelegramCommandHandler('test', self.telegramHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownTelegramCommandHandler(self):
        print('Testing add/removeUnknownTelegramCommandHandler')
        bot = MockBot('/test2')
        self.updater.bot = bot
        d = self.updater.dispatcher
        self.updater.dispatcher.addUnknownTelegramCommandHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test2')

        # Remove handler
        d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringRegexHandler(self):
        print('Testing add/removeStringRegexHandler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addStringRegexHandler('Te.*', self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('Test3')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test3')

        # Remove handler
        d.removeStringRegexHandler('Te.*', self.stringHandlerTest)
        self.reset()

        queue.put('Test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringCommandHandler(self):
        print('Testing add/removeStringCommandHandler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addStringCommandHandler(
            'test3', self.stringHandlerTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test3')
        sleep(.1)
        self.assertEqual(self.received_message, '/test3')

        # Remove handler
        d.removeStringCommandHandler('test3', self.stringHandlerTest)
        self.reset()

        queue.put('/test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownStringCommandHandler(self):
        print('Testing add/removeUnknownStringCommandHandler')
        bot = MockBot('/test')
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addUnknownStringCommandHandler(
            self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('/test4')
        sleep(.1)
        self.assertEqual(self.received_message, '/test4')

        # Remove handler
        d.removeUnknownStringCommandHandler(self.stringHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveErrorHandler(self):
        print('Testing add/removeErrorHandler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)
        error = TelegramError("Unauthorized.")
        queue.put(error)
        sleep(.1)
        self.assertEqual(self.received_message, "Unauthorized.")

        # Remove handler
        d.removeErrorHandler(self.errorHandlerTest)
        self.reset()

        queue.put(error)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_errorInHandler(self):
        print('Testing error in Handler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addStringRegexHandler('.*',
                                                self.errorRaisingHandlerTest)
        self.updater.dispatcher.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)

        queue.put('Test Error 1')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test Error 1')

    def test_errorOnGetUpdates(self):
        print('Testing error on getUpdates')
        bot = MockBot('', raise_error=True)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, "Test Error 2")

    def test_addRemoveTypeHandler(self):
        print('Testing add/removeTypeHandler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTypeHandler(dict, self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        payload = {"Test": 42}
        queue.put(payload)
        sleep(.1)
        self.assertEqual(self.received_message, payload)

        # Remove handler
        d.removeTypeHandler(dict, self.stringHandlerTest)
        self.reset()

        queue.put(payload)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_runAsync(self):
        print('Testing @run_async')
        bot = MockBot('Test5', messages=2)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(
            self.asyncHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, 'Test5')
        self.assertEqual(self.message_count, 2)

    def test_additionalArgs(self):
        print('Testing additional arguments for handlers')
        self.updater.bot = MockBot('', messages=0)
        self.updater.dispatcher.addStringCommandHandler(
            'test5', self.additionalArgsTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test5 resend')
        sleep(.1)
        self.assertEqual(self.received_message, '/test5 noresend')
        self.assertEqual(self.message_count, 2)

    def test_webhook(self):
        print('Testing Webhook')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(
            self.telegramHandlerTest)

        # Select random port for travis
        port = randrange(1024, 49152)
        self.updater.start_webhook('127.0.0.1', port,
                                   './tests/test_updater.py',
                                   './tests/test_updater.py',
                                   listen='127.0.0.1')
        sleep(0.5)
        # SSL-Wrapping will fail, so we start the server without SSL
        Thread(target=self.updater.httpd.serve_forever).start()

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester"), datetime.now(),
                          GroupChat(1, "Test Group"))

        message.text = "Webhook Test"
        update = Update(1)
        update.message = message

        try:
            payload = bytes(update.to_json(), encoding='utf-8')
        except TypeError:
            payload = bytes(update.to_json())

        header = {
            'content-type': 'application/json',
            'content-length': str(len(payload))
        }

        r = Request('http://127.0.0.1:%d/TOKEN' % port,
                    data=payload,
                    headers=header)

        urlopen(r)

        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test')

        print("Test other webhook server functionalites...")
        request = Request('http://localhost:%d/webookhandler.py' % port)
        response = urlopen(request)
        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        request.get_method = lambda: 'HEAD'

        response = urlopen(request)
        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        # Test multiple shutdown() calls
        self.updater.httpd.shutdown()
        self.updater.httpd.shutdown()
        self.assertTrue(True)

    def signalsender(self):
        sleep(0.5)
        os.kill(os.getpid(), signal.SIGTERM)

    def test_idle(self):
        print('Testing idle')
        self.updater.bot = MockBot('Test6', messages=0)
        self.updater.start_polling(poll_interval=0.01)
        Thread(target=self.signalsender).start()
        self.updater.idle()
        # If we get this far, idle() ran through
        sleep(1)
        self.updater.running = False
Ejemplo n.º 3
0
class UpdaterTest(BaseTest, unittest.TestCase):
    """
    This object represents Tests for Updater, Dispatcher, WebhookServer and
    WebhookHandler
    """
    def setUp(self):
        self.updater = None
        self.received_message = None
        self.message_count = 0
        self.lock = Lock()

    def _setup_updater(self, *args, **kwargs):
        bot = MockBot(*args, **kwargs)
        self.updater = Updater(workers=2, bot=bot)

    def tearDown(self):
        if self.updater is not None:
            self.updater.stop()

    def reset(self):
        self.message_count = 0
        self.received_message = None

    def telegramHandlerTest(self, bot, update):
        self.received_message = update.message.text
        self.message_count += 1

    def telegramInlineHandlerTest(self, bot, update):
        self.received_message = (update.inline_query,
                                 update.chosen_inline_result)
        self.message_count += 1

    @run_async
    def asyncHandlerTest(self, bot, update, **kwargs):
        sleep(1)
        with self.lock:
            self.received_message = update.message.text
            self.message_count += 1

    def stringHandlerTest(self, bot, update):
        self.received_message = update
        self.message_count += 1

    def regexGroupHandlerTest(self, bot, update, groups=None, groupdict=None):
        self.received_message = (groups, groupdict)
        self.message_count += 1

    def additionalArgsTest(self, bot, update, update_queue, args):
        self.received_message = update
        self.message_count += 1
        if args[0] == 'resend':
            update_queue.put('/test5 noresend')
        elif args[0] == 'noresend':
            pass

    def contextTest(self, bot, update, context):
        self.received_message = update
        self.message_count += 1
        self.context = context

    @run_async
    def asyncAdditionalHandlerTest(self,
                                   bot,
                                   update,
                                   update_queue=None,
                                   **kwargs):
        sleep(1)
        with self.lock:
            if update_queue is not None:
                self.received_message = update.message.text
                self.message_count += 1

    def errorRaisingHandlerTest(self, bot, update):
        raise TelegramError(update)

    def errorHandlerTest(self, bot, update, error):
        self.received_message = error.message
        self.message_count += 1

    def test_addRemoveTelegramMessageHandler(self):
        self._setup_updater('Test')
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test')

        # Remove handler
        d.removeTelegramMessageHandler(self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addTelegramMessageHandlerMultipleMessages(self):
        self._setup_updater('Multiple', 100)
        self.updater.dispatcher.addTelegramMessageHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.0)
        sleep(2)
        self.assertEqual(self.received_message, 'Multiple')
        self.assertEqual(self.message_count, 100)

    def test_addRemoveTelegramRegexHandler(self):
        self._setup_updater('Test2')
        d = self.updater.dispatcher
        regobj = re.compile('Te.*')
        self.updater.dispatcher.addTelegramRegexHandler(
            regobj, self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test2')

        # Remove handler
        d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveTelegramCommandHandler(self):
        self._setup_updater('/test')
        d = self.updater.dispatcher
        self.updater.dispatcher.addTelegramCommandHandler(
            'test', self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test')

        # Remove handler
        d.removeTelegramCommandHandler('test', self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownTelegramCommandHandler(self):
        self._setup_updater('/test2')
        d = self.updater.dispatcher
        self.updater.dispatcher.addUnknownTelegramCommandHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test2')

        # Remove handler
        d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringRegexHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('Te.*', self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('Test3')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test3')

        # Remove handler
        d.removeStringRegexHandler('Te.*', self.stringHandlerTest)
        self.reset()

        queue.put('Test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringCommandHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringCommandHandler('test3', self.stringHandlerTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test3')
        sleep(.1)
        self.assertEqual(self.received_message, '/test3')

        # Remove handler
        d.removeStringCommandHandler('test3', self.stringHandlerTest)
        self.reset()

        queue.put('/test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownStringCommandHandler(self):
        self._setup_updater('/test')
        d = self.updater.dispatcher
        d.addUnknownStringCommandHandler(self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('/test4')
        sleep(.1)
        self.assertEqual(self.received_message, '/test4')

        # Remove handler
        d.removeUnknownStringCommandHandler(self.stringHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveErrorHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)
        error = TelegramError("Unauthorized.")
        queue.put(error)
        sleep(.1)
        self.assertEqual(self.received_message, "Unauthorized.")

        # Remove handler
        d.removeErrorHandler(self.errorHandlerTest)
        self.reset()

        queue.put(error)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_errorInHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('.*', self.errorRaisingHandlerTest)
        self.updater.dispatcher.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)

        queue.put('Test Error 1')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test Error 1')

    def test_cleanBeforeStart(self):
        self._setup_updater('')
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)
        self.updater.start_polling(0.01, clean=True)
        sleep(.1)
        self.assertEqual(self.message_count, 0)
        self.assertIsNone(self.received_message)

    def test_errorOnGetUpdates(self):
        self._setup_updater('', raise_error=True)
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, "Test Error 2")

    def test_addRemoveTypeHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTypeHandler(dict, self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        payload = {"Test": 42}
        queue.put(payload)
        sleep(.1)
        self.assertEqual(self.received_message, payload)

        # Remove handler
        d.removeTypeHandler(dict, self.stringHandlerTest)
        self.reset()

        queue.put(payload)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveInlineHandlerQuery(self):
        print('Testing add/removeInlineHandler')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramInlineHandler(self.telegramInlineHandlerTest)
        queue = self.updater.start_polling(0.01)
        update = Update(update_id=0, inline_query="testquery")
        update2 = Update(update_id=0, chosen_inline_result="testresult")
        queue.put(update)
        sleep(.1)
        self.assertEqual(self.received_message[0], "testquery")

        queue.put(update2)
        sleep(.1)
        self.assertEqual(self.received_message[1], "testresult")

        # Remove handler
        d.removeTelegramInlineHandler(self.telegramInlineHandlerTest)
        self.reset()

        queue.put(update)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_runAsync(self):
        self._setup_updater('Test5', messages=2)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.asyncHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, 'Test5')
        self.assertEqual(self.message_count, 2)

    def test_additionalArgs(self):
        self._setup_updater('', messages=0)
        self.updater.dispatcher.addStringCommandHandler(
            'test5', self.additionalArgsTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test5 resend')
        sleep(.1)
        self.assertEqual(self.received_message, '/test5 noresend')
        self.assertEqual(self.message_count, 2)

    def test_context(self):
        context = "context_data"
        self._setup_updater('', messages=0)
        self.updater.dispatcher.addStringCommandHandler(
            'test_context', self.contextTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test_context', context=context)
        sleep(.5)
        self.assertEqual(self.received_message, '/test_context')
        self.assertEqual(self.message_count, 1)
        self.assertEqual(self.context, context)

    def test_regexGroupHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('^(This).*?(?P<testgroup>regex group).*',
                                self.regexGroupHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('This is a test message for regex group matching.')
        sleep(.1)
        self.assertEqual(self.received_message, (('This', 'regex group'), {
            'testgroup': 'regex group'
        }))

    def test_runAsyncWithAdditionalArgs(self):
        self._setup_updater('Test6', messages=2)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.asyncAdditionalHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, 'Test6')
        self.assertEqual(self.message_count, 2)

    def test_webhook(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port for travis
        self.updater.start_webhook(ip,
                                   port,
                                   url_path='TOKEN',
                                   cert='./tests/test_updater.py',
                                   key='./tests/test_updater.py')
        sleep(0.5)
        # SSL-Wrapping will fail, so we start the server without SSL
        Thread(target=self.updater.httpd.serve_forever).start()

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester"), datetime.now(),
                          Chat(1, "group", title="Test Group"))

        message.text = "Webhook Test"
        update = Update(1)
        update.message = message

        self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN')

        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test')

        print("Test other webhook server functionalities...")
        response = self._send_webhook_msg(ip, port, None, 'webookhandler.py')
        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        response = self._send_webhook_msg(ip,
                                          port,
                                          None,
                                          'webookhandler.py',
                                          get_method=lambda: 'HEAD')

        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        # Test multiple shutdown() calls
        self.updater.httpd.shutdown()
        self.updater.httpd.shutdown()
        self.assertTrue(True)

    def test_webhook_no_ssl(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port for travis
        self.updater.start_webhook(ip, port)
        sleep(0.5)

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester 2"), datetime.now(),
                          Chat(1, 'group', title="Test Group 2"))

        message.text = "Webhook Test 2"
        update = Update(1)
        update.message = message

        self._send_webhook_msg(ip, port, update.to_json())
        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test 2')

    def test_webhook_invalid_posts(self):
        self._setup_updater('', messages=0)

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # select random port for travis
        thr = Thread(target=self.updater._start_webhook,
                     args=(ip, port, '', None, None))
        thr.start()

        sleep(0.5)

        try:
            with self.assertRaises(HTTPError) as ctx:
                self._send_webhook_msg(ip,
                                       port,
                                       '<root><bla>data</bla></root>',
                                       content_type='application/xml')
            self.assertEqual(ctx.exception.code, 403)

            with self.assertRaises(HTTPError) as ctx:
                self._send_webhook_msg(ip,
                                       port,
                                       'dummy-payload',
                                       content_len=-2)
            self.assertEqual(ctx.exception.code, 403)

            # TODO: prevent urllib or the underlying from adding content-length
            # with self.assertRaises(HTTPError) as ctx:
            #     self._send_webhook_msg(ip, port, 'dummy-payload',
            #                            content_len=None)
            # self.assertEqual(ctx.exception.code, 411)

            with self.assertRaises(HTTPError) as ctx:
                self._send_webhook_msg(ip,
                                       port,
                                       'dummy-payload',
                                       content_len='not-a-number')
            self.assertEqual(ctx.exception.code, 403)

        finally:
            self.updater._stop_httpd()
            thr.join()

    def _send_webhook_msg(self,
                          ip,
                          port,
                          payload_str,
                          url_path='',
                          content_len=-1,
                          content_type='application/json',
                          get_method=None):
        headers = {
            'content-type': content_type,
        }

        if not payload_str:
            content_len = None
            payload = None
        else:
            payload = bytes(payload_str, encoding='utf-8')

        if content_len == -1:
            content_len = len(payload)

        if content_len is not None:
            headers['content-length'] = str(content_len)

        url = 'http://{ip}:{port}/{path}'.format(ip=ip,
                                                 port=port,
                                                 path=url_path)

        req = Request(url, data=payload, headers=headers)

        if get_method is not None:
            req.get_method = get_method

        return urlopen(req)

    def signalsender(self):
        sleep(0.5)
        os.kill(os.getpid(), signal.SIGTERM)

    def test_idle(self):
        self._setup_updater('Test6', messages=0)
        self.updater.start_polling(poll_interval=0.01)
        Thread(target=self.signalsender).start()
        self.updater.idle()
        # If we get this far, idle() ran through
        sleep(1)
        self.assertFalse(self.updater.running)

    def test_createBot(self):
        updater = Updater('123:abcd')
        self.assertIsNotNone(updater.bot)

    def test_mutualExclusiveTokenBot(self):
        bot = Bot('123:zyxw')
        self.assertRaises(ValueError, Updater, token='123:abcd', bot=bot)

    def test_noTokenOrBot(self):
        self.assertRaises(ValueError, Updater)
Ejemplo n.º 4
0
class UpdaterTest(BaseTest, unittest.TestCase):
    """
    This object represents Tests for Updater, Dispatcher, WebhookServer and
    WebhookHandler
    """

    def setUp(self):
        self.updater = None
        self.received_message = None
        self.message_count = 0
        self.lock = Lock()

    def _setup_updater(self, *args, **kwargs):
        bot = MockBot(*args, **kwargs)
        self.updater = Updater(workers=2, bot=bot)

    def tearDown(self):
        if self.updater is not None:
            self.updater.stop()

    def reset(self):
        self.message_count = 0
        self.received_message = None

    def telegramHandlerTest(self, bot, update):
        self.received_message = update.message.text
        self.message_count += 1

    def telegramInlineHandlerTest(self, bot, update):
        self.received_message = (update.inline_query,
                                 update.chosen_inline_result)
        self.message_count += 1

    @run_async
    def asyncHandlerTest(self, bot, update, **kwargs):
        sleep(1)
        with self.lock:
            self.received_message = update.message.text
            self.message_count += 1

    def stringHandlerTest(self, bot, update):
        self.received_message = update
        self.message_count += 1

    def regexGroupHandlerTest(self, bot, update, groups=None, groupdict=None):
        self.received_message = (groups, groupdict)
        self.message_count += 1

    def additionalArgsTest(self, bot, update, update_queue, args):
        self.received_message = update
        self.message_count += 1
        if args[0] == 'resend':
            update_queue.put('/test5 noresend')
        elif args[0] == 'noresend':
            pass
        
    def contextTest(self, bot, update, context):
        self.received_message = update
        self.message_count += 1
        self.context = context

    @run_async
    def asyncAdditionalHandlerTest(self, bot, update, update_queue=None,
                                   **kwargs):
        sleep(1)
        with self.lock:
            if update_queue is not None:
                self.received_message = update.message.text
                self.message_count += 1

    def errorRaisingHandlerTest(self, bot, update):
        raise TelegramError(update)

    def errorHandlerTest(self, bot, update, error):
        self.received_message = error.message
        self.message_count += 1

    def test_addRemoveTelegramMessageHandler(self):
        self._setup_updater('Test')
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test')

        # Remove handler
        d.removeTelegramMessageHandler(self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addTelegramMessageHandlerMultipleMessages(self):
        self._setup_updater('Multiple', 100)
        self.updater.dispatcher.addTelegramMessageHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.0)
        sleep(2)
        self.assertEqual(self.received_message, 'Multiple')
        self.assertEqual(self.message_count, 100)

    def test_addRemoveTelegramRegexHandler(self):
        self._setup_updater('Test2')
        d = self.updater.dispatcher
        regobj = re.compile('Te.*')
        self.updater.dispatcher.addTelegramRegexHandler(regobj,
                                                        self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test2')

        # Remove handler
        d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveTelegramCommandHandler(self):
        self._setup_updater('/test')
        d = self.updater.dispatcher
        self.updater.dispatcher.addTelegramCommandHandler(
            'test', self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test')

        # Remove handler
        d.removeTelegramCommandHandler('test', self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownTelegramCommandHandler(self):
        self._setup_updater('/test2')
        d = self.updater.dispatcher
        self.updater.dispatcher.addUnknownTelegramCommandHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test2')

        # Remove handler
        d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringRegexHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('Te.*', self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('Test3')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test3')

        # Remove handler
        d.removeStringRegexHandler('Te.*', self.stringHandlerTest)
        self.reset()

        queue.put('Test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringCommandHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringCommandHandler(
            'test3', self.stringHandlerTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test3')
        sleep(.1)
        self.assertEqual(self.received_message, '/test3')

        # Remove handler
        d.removeStringCommandHandler('test3', self.stringHandlerTest)
        self.reset()

        queue.put('/test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownStringCommandHandler(self):
        self._setup_updater('/test')
        d = self.updater.dispatcher
        d.addUnknownStringCommandHandler(
            self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('/test4')
        sleep(.1)
        self.assertEqual(self.received_message, '/test4')

        # Remove handler
        d.removeUnknownStringCommandHandler(self.stringHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveErrorHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)
        error = TelegramError("Unauthorized.")
        queue.put(error)
        sleep(.1)
        self.assertEqual(self.received_message, "Unauthorized.")

        # Remove handler
        d.removeErrorHandler(self.errorHandlerTest)
        self.reset()

        queue.put(error)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_errorInHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('.*', self.errorRaisingHandlerTest)
        self.updater.dispatcher.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)

        queue.put('Test Error 1')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test Error 1')

    def test_cleanBeforeStart(self):
        self._setup_updater('')
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)
        self.updater.start_polling(0.01, clean=True)
        sleep(.1)
        self.assertEqual(self.message_count, 0)
        self.assertIsNone(self.received_message)

    def test_errorOnGetUpdates(self):
        self._setup_updater('', raise_error=True)
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, "Test Error 2")

    def test_addRemoveTypeHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTypeHandler(dict, self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        payload = {"Test": 42}
        queue.put(payload)
        sleep(.1)
        self.assertEqual(self.received_message, payload)

        # Remove handler
        d.removeTypeHandler(dict, self.stringHandlerTest)
        self.reset()

        queue.put(payload)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveInlineHandlerQuery(self):
        print('Testing add/removeInlineHandler')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramInlineHandler(self.telegramInlineHandlerTest)
        queue = self.updater.start_polling(0.01)
        update = Update(update_id=0, inline_query="testquery")
        update2 = Update(update_id=0, chosen_inline_result="testresult")
        queue.put(update)
        sleep(.1)
        self.assertEqual(self.received_message[0], "testquery")

        queue.put(update2)
        sleep(.1)
        self.assertEqual(self.received_message[1], "testresult")

        # Remove handler
        d.removeTelegramInlineHandler(self.telegramInlineHandlerTest)
        self.reset()

        queue.put(update)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_runAsync(self):
        self._setup_updater('Test5', messages=2)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(
            self.asyncHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, 'Test5')
        self.assertEqual(self.message_count, 2)

    def test_additionalArgs(self):
        self._setup_updater('', messages=0)
        self.updater.dispatcher.addStringCommandHandler(
            'test5', self.additionalArgsTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test5 resend')
        sleep(.1)
        self.assertEqual(self.received_message, '/test5 noresend')
        self.assertEqual(self.message_count, 2)
        
    def test_context(self):
        context = "context_data"
        self._setup_updater('', messages=0)
        self.updater.dispatcher.addStringCommandHandler(
            'test_context', self.contextTest)
        
        queue = self.updater.start_polling(0.01)
        queue.put('/test_context', context=context)
        sleep(.5)
        self.assertEqual(self.received_message, '/test_context')
        self.assertEqual(self.message_count, 1)
        self.assertEqual(self.context, context)

    def test_regexGroupHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('^(This).*?(?P<testgroup>regex group).*',
                                self.regexGroupHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('This is a test message for regex group matching.')
        sleep(.1)
        self.assertEqual(self.received_message, (('This', 'regex group'),
                                                 {'testgroup': 'regex group'}))

    def test_runAsyncWithAdditionalArgs(self):
        self._setup_updater('Test6', messages=2)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(
            self.asyncAdditionalHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, 'Test6')
        self.assertEqual(self.message_count, 2)

    def test_webhook(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(
            self.telegramHandlerTest)

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port for travis
        self.updater.start_webhook(ip, port,
                                   url_path='TOKEN',
                                   cert='./tests/test_updater.py',
                                   key='./tests/test_updater.py')
        sleep(0.5)
        # SSL-Wrapping will fail, so we start the server without SSL
        Thread(target=self.updater.httpd.serve_forever).start()

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester"), datetime.now(),
                          Chat(1, "group", title="Test Group"))

        message.text = "Webhook Test"
        update = Update(1)
        update.message = message

        self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN')

        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test')

        print("Test other webhook server functionalities...")
        response = self._send_webhook_msg(ip, port, None, 'webookhandler.py')
        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        response = self._send_webhook_msg(ip, port, None, 'webookhandler.py',
                                          get_method=lambda: 'HEAD')

        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        # Test multiple shutdown() calls
        self.updater.httpd.shutdown()
        self.updater.httpd.shutdown()
        self.assertTrue(True)

    def test_webhook_no_ssl(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(
            self.telegramHandlerTest)

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port for travis
        self.updater.start_webhook(ip, port)
        sleep(0.5)

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester 2"), datetime.now(),
                          Chat(1, 'group', title="Test Group 2"))

        message.text = "Webhook Test 2"
        update = Update(1)
        update.message = message

        self._send_webhook_msg(ip, port, update.to_json())
        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test 2')

    def test_webhook_invalid_posts(self):
        self._setup_updater('', messages=0)

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # select random port for travis
        thr = Thread(target=self.updater._start_webhook,
                     args=(ip, port, '', None, None))
        thr.start()

        sleep(0.5)

        try:
            with self.assertRaises(HTTPError) as ctx:
                self._send_webhook_msg(ip, port,
                                       '<root><bla>data</bla></root>',
                                       content_type='application/xml')
            self.assertEqual(ctx.exception.code, 403)

            with self.assertRaises(HTTPError) as ctx:
                self._send_webhook_msg(ip, port, 'dummy-payload',
                                       content_len=-2)
            self.assertEqual(ctx.exception.code, 403)

            # TODO: prevent urllib or the underlying from adding content-length
            # with self.assertRaises(HTTPError) as ctx:
            #     self._send_webhook_msg(ip, port, 'dummy-payload',
            #                            content_len=None)
            # self.assertEqual(ctx.exception.code, 411)

            with self.assertRaises(HTTPError) as ctx:
                self._send_webhook_msg(ip, port, 'dummy-payload',
                                       content_len='not-a-number')
            self.assertEqual(ctx.exception.code, 403)

        finally:
            self.updater._stop_httpd()
            thr.join()

    def _send_webhook_msg(self, ip, port, payload_str, url_path='',
                          content_len=-1, content_type='application/json',
                          get_method=None):
        headers = {
            'content-type': content_type,
        }

        if not payload_str:
            content_len = None
            payload = None
        else:
            payload = bytes(payload_str, encoding='utf-8')

        if content_len == -1:
            content_len = len(payload)

        if content_len is not None:
            headers['content-length'] = str(content_len)

        url = 'http://{ip}:{port}/{path}'.format(ip=ip, port=port,
                                                 path=url_path)

        req = Request(url, data=payload, headers=headers)


        if get_method is not None:
            req.get_method = get_method

        return urlopen(req)

    def signalsender(self):
        sleep(0.5)
        os.kill(os.getpid(), signal.SIGTERM)

    def test_idle(self):
        self._setup_updater('Test6', messages=0)
        self.updater.start_polling(poll_interval=0.01)
        Thread(target=self.signalsender).start()
        self.updater.idle()
        # If we get this far, idle() ran through
        sleep(1)
        self.assertFalse(self.updater.running)

    def test_createBot(self):
        updater = Updater('123:abcd')
        self.assertIsNotNone(updater.bot)

    def test_mutualExclusiveTokenBot(self):
        bot = Bot('123:zyxw')
        self.assertRaises(ValueError, Updater, token='123:abcd', bot=bot)

    def test_noTokenOrBot(self):
        self.assertRaises(ValueError, Updater)
Ejemplo n.º 5
0
class Bot(object):
    translations = {}
    bot = None

    def __init__(self):
        self.playing_state = dict()

        self.updater = Updater(token=dungeon.get_bot_conf("TOKEN"))
        self.dispatcher = self.updater.dispatcher
        self.add_handlers()

        try:
            self.tzinfo = timezone(dungeon.get_bot_conf("TIMEZONE"))
        except:
            self.tzinfo = pytz.utc

        # i18n BLOCK (see dungeon world commit 66 / haibot commits)

    def start_polling_loop(self):
        self.disable_webhook()
        self.update_queue = self.updater.start_polling()
        self.updater.idle()
        self.cleaning()

    def start_webhook_server(self):
        self.set_webhook()
        self.update_queue = self.updater.start_webhook(dungeon.get_env_conf("IP","127.0.0.1"),
                                                       int(dungeon.get_env_conf("PORT","8080")),
                                                       dungeon.get_bot_conf("TOKEN"))
        self.updater.idle()
        self.cleaning()

    def cleaning(self):
        dungeon.logger.info("Finished program.")

    def set_webhook(self):
        s = self.updater.bot.setWebhook(dungeon.get_bot_conf("WEBHOOK_URL") + "/" + dungeon.get_bot_conf("TOKEN"))
        if s:
            dungeon.logger.info("webhook setup worked")
        else:
            dungeon.logger.warning("webhook setup failed")
        return s

    def disable_webhook(self):
        s = self.updater.bot.setWebhook("")
        if s:
            dungeon.logger.info("webhook was disabled")
        else:
            dungeon.logger.warning("webhook couldn't be disabled")
        return s

    def add_handlers(self):
        self.dispatcher.addTelegramCommandHandler("start", self.command_start)
        self.dispatcher.addTelegramCommandHandler("help", self.command_help)
        self.dispatcher.addTelegramCommandHandler("exit", self.command_exit)
        self.dispatcher.addTelegramCommandHandler("pj", self.command_pj)
        self.dispatcher.addTelegramCommandHandler("master", self.command_master)
        self.dispatcher.addTelegramCommandHandler("play", self.command_play)

    def get_chat_info(self, update):
        self.last_chat = update.message.chat
        chad_id = update.message.chat.id

        sender = update.message.from_user
        text = update.message.text
        chat_data = db.chats.find_one({"_id" : chad_id})
        if not chat_data:
            chat_data = {"_id" : chad_id, "state" : const.STOPPED, "context": None}

        return chat_data, sender, text

    def command_start(self, bot, update):
        chat, sender, text = self.get_chat_info(update)
        if chat["state"] == const.STOPPED:
            chat["state"] = const.STOPPED
            self.send_message(messages.welcome)
            self.send_message(messages.help[chat["state"]])
        else:
            self.send_message(messages.already_started[chat["state"]])

    def command_help(self, bot, update):
        chat, sender, text = self.get_chat_info(update)
        self.send_message(messages.help[chat["state"]])

    def command_exit(self, bot, update):
        chat, sender, text = self.get_chat_info(update)
        if chat["state"] != const.STOPPED:
            self.send_message(messages.exit[chat["state"]])
            chat["state"] = const.STOPPED
            db.chats.replace_one({"_id":chat["_id"]}, chat, upsert=True )
            chat["context"] = None
        else:
            self.send_message(messages.no_exit)

    def command_pj(self, bot, update):
        chat, sender, text = self.get_chat_info(update)
        if chat["state"] == const.STOPPED:
            chat["state"] = const.NEWPJ
            db.chats.replace_one({"_id":chat["_id"]}, chat, upsert=True )
            self.send_message("guay")
        else:
            self.send_message("ya")

    def command_master(self, bot, update):
        pass

    def command_play(self, bot, update):
        pass

    def send_message(self, text):
        try:
            self.updater.bot.sendMessage(chat_id=self.last_chat.id, text=text)
            return True
        except TelegramError as e:
            if self.last_chat.type == "private":
                dungeon.logger.warning("Message sending error to %s [%d] [%s] (TelegramError: %s)" % (self.last_chat.first_name, self.last_chat.id, self.last_chat.type, e))
            else:
                dungeon.logger.warning("Message sending error to %s [%d] [%s] (TelegramError: %s)" % (self.last_chat.title, self.last_chat.id, self.last_chat.type, e))
            return False
        except:
            if self.last_chat.type == "private":
                dungeon.logger.warning("Message sending error to %s [%d] [%s]" % (self.last_chat.first_name, self.last_chat.id, self.last_chat.type))
            else:
                dungeon.logger.warning("Message sending error to %s [%d] [%s]" % (self.last_chat.title, self.last_chat.id, self.last_chat.type))
            return False
Ejemplo n.º 6
0
class UpdaterTest(BaseTest, unittest.TestCase):
    """
    This object represents Tests for Updater, Dispatcher, WebhookServer and
    WebhookHandler
    """
    def setUp(self):
        self.updater = Updater('', workers=2)

        self.received_message = None
        self.message_count = 0
        self.lock = Lock()

    def tearDown(self):
        self.updater.stop()

    def reset(self):
        self.message_count = 0
        self.received_message = None

    def telegramHandlerTest(self, bot, update):
        self.received_message = update.message.text
        self.message_count += 1

    @run_async
    def asyncHandlerTest(self, bot, update):
        sleep(1)
        with self.lock:
            self.received_message = update.message.text
            self.message_count += 1

    def stringHandlerTest(self, bot, update):
        self.received_message = update
        self.message_count += 1

    def additionalArgsTest(self, bot, update, update_queue, args):
        self.received_message = update
        self.message_count += 1
        if args[0] == 'resend':
            update_queue.put('/test5 noresend')
        elif args[0] == 'noresend':
            pass

    def errorRaisingHandlerTest(self, bot, update):
        raise TelegramError(update)

    def errorHandlerTest(self, bot, update, error):
        self.received_message = error.message
        self.message_count += 1

    def test_addRemoveTelegramMessageHandler(self):
        print('Testing add/removeTelegramMessageHandler')
        bot = MockBot('Test')
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test')

        # Remove handler
        d.removeTelegramMessageHandler(self.telegramHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addTelegramMessageHandlerMultipleMessages(self):
        print('Testing addTelegramMessageHandler and send 100 messages...')
        self.updater.bot = MockBot('Multiple', 100)
        self.updater.dispatcher.addTelegramMessageHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.0)
        sleep(.5)
        self.assertEqual(self.received_message, 'Multiple')
        self.assertEqual(self.message_count, 100)

    def test_addRemoveTelegramRegexHandler(self):
        print('Testing add/removeStringRegexHandler')
        bot = MockBot('Test2')
        self.updater.bot = bot
        d = self.updater.dispatcher
        regobj = re.compile('Te.*')
        self.updater.dispatcher.addTelegramRegexHandler(
            regobj, self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test2')

        # Remove handler
        d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveTelegramCommandHandler(self):
        print('Testing add/removeTelegramCommandHandler')
        bot = MockBot('/test')
        self.updater.bot = bot
        d = self.updater.dispatcher
        self.updater.dispatcher.addTelegramCommandHandler(
            'test', self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test')

        # Remove handler
        d.removeTelegramCommandHandler('test', self.telegramHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownTelegramCommandHandler(self):
        print('Testing add/removeUnknownTelegramCommandHandler')
        bot = MockBot('/test2')
        self.updater.bot = bot
        d = self.updater.dispatcher
        self.updater.dispatcher.addUnknownTelegramCommandHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test2')

        # Remove handler
        d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringRegexHandler(self):
        print('Testing add/removeStringRegexHandler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addStringRegexHandler('Te.*', self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('Test3')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test3')

        # Remove handler
        d.removeStringRegexHandler('Te.*', self.stringHandlerTest)
        self.reset()

        queue.put('Test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringCommandHandler(self):
        print('Testing add/removeStringCommandHandler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addStringCommandHandler('test3', self.stringHandlerTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test3')
        sleep(.1)
        self.assertEqual(self.received_message, '/test3')

        # Remove handler
        d.removeStringCommandHandler('test3', self.stringHandlerTest)
        self.reset()

        queue.put('/test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownStringCommandHandler(self):
        print('Testing add/removeUnknownStringCommandHandler')
        bot = MockBot('/test')
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addUnknownStringCommandHandler(self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('/test4')
        sleep(.1)
        self.assertEqual(self.received_message, '/test4')

        # Remove handler
        d.removeUnknownStringCommandHandler(self.stringHandlerTest)
        self.reset()

        bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveErrorHandler(self):
        print('Testing add/removeErrorHandler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)
        error = TelegramError("Unauthorized.")
        queue.put(error)
        sleep(.1)
        self.assertEqual(self.received_message, "Unauthorized.")

        # Remove handler
        d.removeErrorHandler(self.errorHandlerTest)
        self.reset()

        queue.put(error)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_errorInHandler(self):
        print('Testing error in Handler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addStringRegexHandler('.*', self.errorRaisingHandlerTest)
        self.updater.dispatcher.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)

        queue.put('Test Error 1')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test Error 1')

    def test_errorOnGetUpdates(self):
        print('Testing error on getUpdates')
        bot = MockBot('', raise_error=True)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, "Test Error 2")

    def test_addRemoveTypeHandler(self):
        print('Testing add/removeTypeHandler')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTypeHandler(dict, self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        payload = {"Test": 42}
        queue.put(payload)
        sleep(.1)
        self.assertEqual(self.received_message, payload)

        # Remove handler
        d.removeTypeHandler(dict, self.stringHandlerTest)
        self.reset()

        queue.put(payload)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_runAsync(self):
        print('Testing @run_async')
        bot = MockBot('Test5', messages=2)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.asyncHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, 'Test5')
        self.assertEqual(self.message_count, 2)

    def test_additionalArgs(self):
        print('Testing additional arguments for handlers')
        self.updater.bot = MockBot('', messages=0)
        self.updater.dispatcher.addStringCommandHandler(
            'test5', self.additionalArgsTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test5 resend')
        sleep(.1)
        self.assertEqual(self.received_message, '/test5 noresend')
        self.assertEqual(self.message_count, 2)

    def test_webhook(self):
        print('Testing Webhook')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        # Select random port for travis
        port = randrange(1024, 49152)
        self.updater.start_webhook('127.0.0.1',
                                   port,
                                   './tests/test_updater.py',
                                   './tests/test_updater.py',
                                   listen='127.0.0.1')
        sleep(0.5)
        # SSL-Wrapping will fail, so we start the server without SSL
        Thread(target=self.updater.httpd.serve_forever).start()

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester"), datetime.now(),
                          GroupChat(1, "Test Group"))

        message.text = "Webhook Test"
        update = Update(1)
        update.message = message

        try:
            payload = bytes(update.to_json(), encoding='utf-8')
        except TypeError:
            payload = bytes(update.to_json())

        header = {
            'content-type': 'application/json',
            'content-length': str(len(payload))
        }

        r = Request('http://127.0.0.1:%d/TOKEN' % port,
                    data=payload,
                    headers=header)

        urlopen(r)

        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test')

        print("Test other webhook server functionalites...")
        request = Request('http://localhost:%d/webookhandler.py' % port)
        response = urlopen(request)
        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        request.get_method = lambda: 'HEAD'

        response = urlopen(request)
        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        # Test multiple shutdown() calls
        self.updater.httpd.shutdown()
        self.updater.httpd.shutdown()
        self.assertTrue(True)

    def signalsender(self):
        sleep(0.5)
        os.kill(os.getpid(), signal.SIGTERM)

    def test_idle(self):
        print('Testing idle')
        self.updater.bot = MockBot('Test6', messages=0)
        self.updater.start_polling(poll_interval=0.01)
        Thread(target=self.signalsender).start()
        self.updater.idle()
        # If we get this far, idle() ran through
        sleep(1)
        self.updater.running = False
Ejemplo n.º 7
0
class UpdaterTest(BaseTest, unittest.TestCase):
    """
    This object represents Tests for Updater, Dispatcher, WebhookServer and
    WebhookHandler
    """

    def setUp(self):
        self.updater = None
        self.received_message = None
        self.message_count = 0
        self.lock = Lock()

    def _setup_updater(self, *args, **kwargs):
        bot = MockBot(*args, **kwargs)
        self.updater = Updater(workers=2, bot=bot)

    def tearDown(self):
        if self.updater is not None:
            self.updater.stop()

    def reset(self):
        self.message_count = 0
        self.received_message = None

    def telegramHandlerTest(self, bot, update):
        self.received_message = update.message.text
        self.message_count += 1

    @run_async
    def asyncHandlerTest(self, bot, update, **kwargs):
        sleep(1)
        with self.lock:
            self.received_message = update.message.text
            self.message_count += 1

    def stringHandlerTest(self, bot, update):
        self.received_message = update
        self.message_count += 1

    def regexGroupHandlerTest(self, bot, update, groups=None, groupdict=None):
        self.received_message = (groups, groupdict)
        self.message_count += 1

    def additionalArgsTest(self, bot, update, update_queue, args):
        self.received_message = update
        self.message_count += 1
        if args[0] == "resend":
            update_queue.put("/test5 noresend")
        elif args[0] == "noresend":
            pass

    def contextTest(self, bot, update, context):
        self.received_message = update
        self.message_count += 1
        self.context = context

    @run_async
    def asyncAdditionalHandlerTest(self, bot, update, update_queue=None, **kwargs):
        sleep(1)
        with self.lock:
            if update_queue is not None:
                self.received_message = update.message.text
                self.message_count += 1

    def errorRaisingHandlerTest(self, bot, update):
        raise TelegramError(update)

    def errorHandlerTest(self, bot, update, error):
        self.received_message = error.message
        self.message_count += 1

    def test_addRemoveTelegramMessageHandler(self):
        print("Testing add/removeTelegramMessageHandler")
        self._setup_updater("Test")
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(0.1)
        self.assertEqual(self.received_message, "Test")

        # Remove handler
        d.removeTelegramMessageHandler(self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_addTelegramMessageHandlerMultipleMessages(self):
        print("Testing addTelegramMessageHandler and send 100 messages...")
        self._setup_updater("Multiple", 100)
        self.updater.dispatcher.addTelegramMessageHandler(self.telegramHandlerTest)
        self.updater.start_polling(0.0)
        sleep(2)
        self.assertEqual(self.received_message, "Multiple")
        self.assertEqual(self.message_count, 100)

    def test_addRemoveTelegramRegexHandler(self):
        print("Testing add/removeStringRegexHandler")
        self._setup_updater("Test2")
        d = self.updater.dispatcher
        regobj = re.compile("Te.*")
        self.updater.dispatcher.addTelegramRegexHandler(regobj, self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(0.1)
        self.assertEqual(self.received_message, "Test2")

        # Remove handler
        d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveTelegramCommandHandler(self):
        print("Testing add/removeTelegramCommandHandler")
        self._setup_updater("/test")
        d = self.updater.dispatcher
        self.updater.dispatcher.addTelegramCommandHandler("test", self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(0.1)
        self.assertEqual(self.received_message, "/test")

        # Remove handler
        d.removeTelegramCommandHandler("test", self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownTelegramCommandHandler(self):
        print("Testing add/removeUnknownTelegramCommandHandler")
        self._setup_updater("/test2")
        d = self.updater.dispatcher
        self.updater.dispatcher.addUnknownTelegramCommandHandler(self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(0.1)
        self.assertEqual(self.received_message, "/test2")

        # Remove handler
        d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringRegexHandler(self):
        print("Testing add/removeStringRegexHandler")
        self._setup_updater("", messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler("Te.*", self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put("Test3")
        sleep(0.1)
        self.assertEqual(self.received_message, "Test3")

        # Remove handler
        d.removeStringRegexHandler("Te.*", self.stringHandlerTest)
        self.reset()

        queue.put("Test3")
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringCommandHandler(self):
        print("Testing add/removeStringCommandHandler")
        self._setup_updater("", messages=0)
        d = self.updater.dispatcher
        d.addStringCommandHandler("test3", self.stringHandlerTest)

        queue = self.updater.start_polling(0.01)
        queue.put("/test3")
        sleep(0.1)
        self.assertEqual(self.received_message, "/test3")

        # Remove handler
        d.removeStringCommandHandler("test3", self.stringHandlerTest)
        self.reset()

        queue.put("/test3")
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownStringCommandHandler(self):
        print("Testing add/removeUnknownStringCommandHandler")
        self._setup_updater("/test")
        d = self.updater.dispatcher
        d.addUnknownStringCommandHandler(self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put("/test4")
        sleep(0.1)
        self.assertEqual(self.received_message, "/test4")

        # Remove handler
        d.removeUnknownStringCommandHandler(self.stringHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveErrorHandler(self):
        print("Testing add/removeErrorHandler")
        self._setup_updater("", messages=0)
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)
        error = TelegramError("Unauthorized.")
        queue.put(error)
        sleep(0.1)
        self.assertEqual(self.received_message, "Unauthorized.")

        # Remove handler
        d.removeErrorHandler(self.errorHandlerTest)
        self.reset()

        queue.put(error)
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_errorInHandler(self):
        print("Testing error in Handler")
        self._setup_updater("", messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler(".*", self.errorRaisingHandlerTest)
        self.updater.dispatcher.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)

        queue.put("Test Error 1")
        sleep(0.1)
        self.assertEqual(self.received_message, "Test Error 1")

    def test_errorOnGetUpdates(self):
        print("Testing error on getUpdates")
        self._setup_updater("", raise_error=True)
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        self.updater.start_polling(0.01)
        sleep(0.1)
        self.assertEqual(self.received_message, "Test Error 2")

    def test_addRemoveTypeHandler(self):
        print("Testing add/removeTypeHandler")
        self._setup_updater("", messages=0)
        d = self.updater.dispatcher
        d.addTypeHandler(dict, self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        payload = {"Test": 42}
        queue.put(payload)
        sleep(0.1)
        self.assertEqual(self.received_message, payload)

        # Remove handler
        d.removeTypeHandler(dict, self.stringHandlerTest)
        self.reset()

        queue.put(payload)
        sleep(0.1)
        self.assertTrue(None is self.received_message)

    def test_runAsync(self):
        print("Testing @run_async")
        self._setup_updater("Test5", messages=2)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.asyncHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, "Test5")
        self.assertEqual(self.message_count, 2)

    def test_additionalArgs(self):
        print("Testing additional arguments for handlers")
        self._setup_updater("", messages=0)
        self.updater.dispatcher.addStringCommandHandler("test5", self.additionalArgsTest)

        queue = self.updater.start_polling(0.01)
        queue.put("/test5 resend")
        sleep(0.1)
        self.assertEqual(self.received_message, "/test5 noresend")
        self.assertEqual(self.message_count, 2)

    def test_context(self):
        print("Testing context for handlers")
        context = "context_data"
        self._setup_updater("", messages=0)
        self.updater.dispatcher.addStringCommandHandler("test_context", self.contextTest)

        queue = self.updater.start_polling(0.01)
        queue.put("/test_context", context=context)
        sleep(0.5)
        self.assertEqual(self.received_message, "/test_context")
        self.assertEqual(self.message_count, 1)
        self.assertEqual(self.context, context)

    def test_regexGroupHandler(self):
        print("Testing optional groups and groupdict parameters")
        self._setup_updater("", messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler("^(This).*?(?P<testgroup>regex group).*", self.regexGroupHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put("This is a test message for regex group matching.")
        sleep(0.1)
        self.assertEqual(self.received_message, (("This", "regex group"), {"testgroup": "regex group"}))

    def test_runAsyncWithAdditionalArgs(self):
        print("Testing @run_async with additional parameters")
        self._setup_updater("Test6", messages=2)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.asyncAdditionalHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, "Test6")
        self.assertEqual(self.message_count, 2)

    def test_webhook(self):
        print("Testing Webhook")
        self._setup_updater("", messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        # Select random port for travis
        port = randrange(1024, 49152)
        self.updater.start_webhook(
            "127.0.0.1", port, url_path="TOKEN", cert="./tests/test_updater.py", key="./tests/test_updater.py"
        )
        sleep(0.5)
        # SSL-Wrapping will fail, so we start the server without SSL
        Thread(target=self.updater.httpd.serve_forever).start()

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester"), datetime.now(), Chat(1, "group", title="Test Group"))

        message.text = "Webhook Test"
        update = Update(1)
        update.message = message

        try:
            payload = bytes(update.to_json(), encoding="utf-8")
        except TypeError:
            payload = bytes(update.to_json())

        header = {"content-type": "application/json", "content-length": str(len(payload))}

        r = Request("http://127.0.0.1:%d/TOKEN" % port, data=payload, headers=header)

        urlopen(r)

        sleep(1)
        self.assertEqual(self.received_message, "Webhook Test")

        print("Test other webhook server functionalities...")
        request = Request("http://localhost:%d/webookhandler.py" % port)
        response = urlopen(request)
        self.assertEqual(b"", response.read())
        self.assertEqual(200, response.code)

        request.get_method = lambda: "HEAD"

        response = urlopen(request)
        self.assertEqual(b"", response.read())
        self.assertEqual(200, response.code)

        # Test multiple shutdown() calls
        self.updater.httpd.shutdown()
        self.updater.httpd.shutdown()
        self.assertTrue(True)

    def test_webhook_no_ssl(self):
        print("Testing Webhook without SSL")
        self._setup_updater("", messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        # Select random port for travis
        port = randrange(1024, 49152)
        self.updater.start_webhook("127.0.0.1", port)
        sleep(0.5)

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester 2"), datetime.now(), Chat(1, "group", title="Test Group 2"))

        message.text = "Webhook Test 2"
        update = Update(1)
        update.message = message

        try:
            payload = bytes(update.to_json(), encoding="utf-8")
        except TypeError:
            payload = bytes(update.to_json())

        header = {"content-type": "application/json", "content-length": str(len(payload))}

        r = Request("http://127.0.0.1:%d/" % port, data=payload, headers=header)

        urlopen(r)
        sleep(1)
        self.assertEqual(self.received_message, "Webhook Test 2")

    def signalsender(self):
        sleep(0.5)
        os.kill(os.getpid(), signal.SIGTERM)

    def test_idle(self):
        print("Testing idle")
        self._setup_updater("Test6", messages=0)
        self.updater.start_polling(poll_interval=0.01)
        Thread(target=self.signalsender).start()
        self.updater.idle()
        # If we get this far, idle() ran through
        sleep(1)
        self.updater.running = False

    def test_createBot(self):
        updater = Updater("123:abcd")
        self.assertIsNotNone(updater.bot)

    def test_mutualExclusiveTokenBot(self):
        bot = Bot("123:zyxw")
        self.assertRaises(ValueError, Updater, token="123:abcd", bot=bot)

    def test_noTokenOrBot(self):
        self.assertRaises(ValueError, Updater)
Ejemplo n.º 8
0
class UpdaterTest(BaseTest, unittest.TestCase):
    """
    This object represents Tests for Updater, Dispatcher, WebhookServer and
    WebhookHandler
    """
    def setUp(self):
        self.updater = None
        self.received_message = None
        self.message_count = 0
        self.lock = Lock()

    def _setup_updater(self, *args, **kwargs):
        bot = MockBot(*args, **kwargs)
        self.updater = Updater(workers=2, bot=bot)

    def tearDown(self):
        if self.updater is not None:
            self.updater.stop()

    def reset(self):
        self.message_count = 0
        self.received_message = None

    def telegramHandlerTest(self, bot, update):
        self.received_message = update.message.text
        self.message_count += 1

    @run_async
    def asyncHandlerTest(self, bot, update, **kwargs):
        sleep(1)
        with self.lock:
            self.received_message = update.message.text
            self.message_count += 1

    def stringHandlerTest(self, bot, update):
        self.received_message = update
        self.message_count += 1

    def regexGroupHandlerTest(self, bot, update, groups=None, groupdict=None):
        self.received_message = (groups, groupdict)
        self.message_count += 1

    def additionalArgsTest(self, bot, update, update_queue, args):
        self.received_message = update
        self.message_count += 1
        if args[0] == 'resend':
            update_queue.put('/test5 noresend')
        elif args[0] == 'noresend':
            pass

    def contextTest(self, bot, update, context):
        self.received_message = update
        self.message_count += 1
        self.context = context

    @run_async
    def asyncAdditionalHandlerTest(self,
                                   bot,
                                   update,
                                   update_queue=None,
                                   **kwargs):
        sleep(1)
        with self.lock:
            if update_queue is not None:
                self.received_message = update.message.text
                self.message_count += 1

    def errorRaisingHandlerTest(self, bot, update):
        raise TelegramError(update)

    def errorHandlerTest(self, bot, update, error):
        self.received_message = error.message
        self.message_count += 1

    def test_addRemoveTelegramMessageHandler(self):
        print('Testing add/removeTelegramMessageHandler')
        self._setup_updater('Test')
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test')

        # Remove handler
        d.removeTelegramMessageHandler(self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addTelegramMessageHandlerMultipleMessages(self):
        print('Testing addTelegramMessageHandler and send 100 messages...')
        self._setup_updater('Multiple', 100)
        self.updater.dispatcher.addTelegramMessageHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.0)
        sleep(2)
        self.assertEqual(self.received_message, 'Multiple')
        self.assertEqual(self.message_count, 100)

    def test_addRemoveTelegramRegexHandler(self):
        print('Testing add/removeStringRegexHandler')
        self._setup_updater('Test2')
        d = self.updater.dispatcher
        regobj = re.compile('Te.*')
        self.updater.dispatcher.addTelegramRegexHandler(
            regobj, self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, 'Test2')

        # Remove handler
        d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveTelegramCommandHandler(self):
        print('Testing add/removeTelegramCommandHandler')
        self._setup_updater('/test')
        d = self.updater.dispatcher
        self.updater.dispatcher.addTelegramCommandHandler(
            'test', self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test')

        # Remove handler
        d.removeTelegramCommandHandler('test', self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownTelegramCommandHandler(self):
        print('Testing add/removeUnknownTelegramCommandHandler')
        self._setup_updater('/test2')
        d = self.updater.dispatcher
        self.updater.dispatcher.addUnknownTelegramCommandHandler(
            self.telegramHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, '/test2')

        # Remove handler
        d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringRegexHandler(self):
        print('Testing add/removeStringRegexHandler')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('Te.*', self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('Test3')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test3')

        # Remove handler
        d.removeStringRegexHandler('Te.*', self.stringHandlerTest)
        self.reset()

        queue.put('Test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveStringCommandHandler(self):
        print('Testing add/removeStringCommandHandler')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringCommandHandler('test3', self.stringHandlerTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test3')
        sleep(.1)
        self.assertEqual(self.received_message, '/test3')

        # Remove handler
        d.removeStringCommandHandler('test3', self.stringHandlerTest)
        self.reset()

        queue.put('/test3')
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveUnknownStringCommandHandler(self):
        print('Testing add/removeUnknownStringCommandHandler')
        self._setup_updater('/test')
        d = self.updater.dispatcher
        d.addUnknownStringCommandHandler(self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('/test4')
        sleep(.1)
        self.assertEqual(self.received_message, '/test4')

        # Remove handler
        d.removeUnknownStringCommandHandler(self.stringHandlerTest)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_addRemoveErrorHandler(self):
        print('Testing add/removeErrorHandler')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)
        error = TelegramError("Unauthorized.")
        queue.put(error)
        sleep(.1)
        self.assertEqual(self.received_message, "Unauthorized.")

        # Remove handler
        d.removeErrorHandler(self.errorHandlerTest)
        self.reset()

        queue.put(error)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_errorInHandler(self):
        print('Testing error in Handler')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('.*', self.errorRaisingHandlerTest)
        self.updater.dispatcher.addErrorHandler(self.errorHandlerTest)
        queue = self.updater.start_polling(0.01)

        queue.put('Test Error 1')
        sleep(.1)
        self.assertEqual(self.received_message, 'Test Error 1')

    def test_errorOnGetUpdates(self):
        print('Testing error on getUpdates')
        self._setup_updater('', raise_error=True)
        d = self.updater.dispatcher
        d.addErrorHandler(self.errorHandlerTest)
        self.updater.start_polling(0.01)
        sleep(.1)
        self.assertEqual(self.received_message, "Test Error 2")

    def test_addRemoveTypeHandler(self):
        print('Testing add/removeTypeHandler')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTypeHandler(dict, self.stringHandlerTest)
        queue = self.updater.start_polling(0.01)
        payload = {"Test": 42}
        queue.put(payload)
        sleep(.1)
        self.assertEqual(self.received_message, payload)

        # Remove handler
        d.removeTypeHandler(dict, self.stringHandlerTest)
        self.reset()

        queue.put(payload)
        sleep(.1)
        self.assertTrue(None is self.received_message)

    def test_runAsync(self):
        print('Testing @run_async')
        self._setup_updater('Test5', messages=2)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.asyncHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, 'Test5')
        self.assertEqual(self.message_count, 2)

    def test_additionalArgs(self):
        print('Testing additional arguments for handlers')
        self._setup_updater('', messages=0)
        self.updater.dispatcher.addStringCommandHandler(
            'test5', self.additionalArgsTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test5 resend')
        sleep(.1)
        self.assertEqual(self.received_message, '/test5 noresend')
        self.assertEqual(self.message_count, 2)

    def test_context(self):
        print('Testing context for handlers')
        context = "context_data"
        self._setup_updater('', messages=0)
        self.updater.dispatcher.addStringCommandHandler(
            'test_context', self.contextTest)

        queue = self.updater.start_polling(0.01)
        queue.put('/test_context', context=context)
        sleep(.5)
        self.assertEqual(self.received_message, '/test_context')
        self.assertEqual(self.message_count, 1)
        self.assertEqual(self.context, context)

    def test_regexGroupHandler(self):
        print('Testing optional groups and groupdict parameters')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addStringRegexHandler('^(This).*?(?P<testgroup>regex group).*',
                                self.regexGroupHandlerTest)
        queue = self.updater.start_polling(0.01)
        queue.put('This is a test message for regex group matching.')
        sleep(.1)
        self.assertEqual(self.received_message, (('This', 'regex group'), {
            'testgroup': 'regex group'
        }))

    def test_runAsyncWithAdditionalArgs(self):
        print('Testing @run_async with additional parameters')
        self._setup_updater('Test6', messages=2)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.asyncAdditionalHandlerTest)
        self.updater.start_polling(0.01)
        sleep(1.2)
        self.assertEqual(self.received_message, 'Test6')
        self.assertEqual(self.message_count, 2)

    def test_webhook(self):
        print('Testing Webhook')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        # Select random port for travis
        port = randrange(1024, 49152)
        self.updater.start_webhook('127.0.0.1',
                                   port,
                                   url_path='TOKEN',
                                   cert='./tests/test_updater.py',
                                   key='./tests/test_updater.py')
        sleep(0.5)
        # SSL-Wrapping will fail, so we start the server without SSL
        Thread(target=self.updater.httpd.serve_forever).start()

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester"), datetime.now(),
                          Chat(1, "group", title="Test Group"))

        message.text = "Webhook Test"
        update = Update(1)
        update.message = message

        try:
            payload = bytes(update.to_json(), encoding='utf-8')
        except TypeError:
            payload = bytes(update.to_json())

        header = {
            'content-type': 'application/json',
            'content-length': str(len(payload))
        }

        r = Request('http://127.0.0.1:%d/TOKEN' % port,
                    data=payload,
                    headers=header)

        urlopen(r)

        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test')

        print("Test other webhook server functionalities...")
        request = Request('http://localhost:%d/webookhandler.py' % port)
        response = urlopen(request)
        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        request.get_method = lambda: 'HEAD'

        response = urlopen(request)
        self.assertEqual(b'', response.read())
        self.assertEqual(200, response.code)

        # Test multiple shutdown() calls
        self.updater.httpd.shutdown()
        self.updater.httpd.shutdown()
        self.assertTrue(True)

    def test_webhook_no_ssl(self):
        print('Testing Webhook without SSL')
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        # Select random port for travis
        port = randrange(1024, 49152)
        self.updater.start_webhook('127.0.0.1', port)
        sleep(0.5)

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester 2"), datetime.now(),
                          Chat(1, 'group', title="Test Group 2"))

        message.text = "Webhook Test 2"
        update = Update(1)
        update.message = message

        try:
            payload = bytes(update.to_json(), encoding='utf-8')
        except TypeError:
            payload = bytes(update.to_json())

        header = {
            'content-type': 'application/json',
            'content-length': str(len(payload))
        }

        r = Request('http://127.0.0.1:%d/' % port,
                    data=payload,
                    headers=header)

        urlopen(r)
        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test 2')

    def signalsender(self):
        sleep(0.5)
        os.kill(os.getpid(), signal.SIGTERM)

    def test_idle(self):
        print('Testing idle')
        self._setup_updater('Test6', messages=0)
        self.updater.start_polling(poll_interval=0.01)
        Thread(target=self.signalsender).start()
        self.updater.idle()
        # If we get this far, idle() ran through
        sleep(1)
        self.updater.running = False

    def test_createBot(self):
        updater = Updater('123:abcd')
        self.assertIsNotNone(updater.bot)

    def test_mutualExclusiveTokenBot(self):
        bot = Bot('123:zyxw')
        self.assertRaises(ValueError, Updater, token='123:abcd', bot=bot)

    def test_noTokenOrBot(self):
        self.assertRaises(ValueError, Updater)
Ejemplo n.º 9
0
import os

from datetime import datetime

from bot_token import Token
from calendar_utils import greg2flawless as g2f, flawless_months

updater = Updater(token=Token)
dispatcher = updater.dispatcher


def now_handler(bot, update):
    fl_today = g2f(datetime.now().date())
    text = "It's the %dth day of %s(%d) %d." % (fl_today[2], flawless_months[fl_today[1]], fl_today[1], fl_today[0])
    bot.sendMessage(chat_id=update.message.chat_id, text=text)


def help_handler(bot, update):
    text = "This bot converts a gregorian date into a flawless date(a particular calendar based on regular months and years)"
    bot.sendMessage(chat_id=update.message.chat_id, text=text)


if __name__ == "__main__":
    dispatcher.addTelegramCommandHandler("now", now_handler)
    dispatcher.addTelegramCommandHandler("help", help_handler)

    # Get the port to bind to
    port = int(os.environ.get("PORT", 5000))
    # Start the updater listening on all public IPs
    updater.start_webhook("0.0.0.0", port)
Ejemplo n.º 10
0
class Bot(object):
    translations = {}
    bot = None

    def __init__(self):
        self.config = configparser.ConfigParser()
        self.config.read( CONFIGFILE_PATH )

        self.updater = Updater(token=self.get_bot_conf("TOKEN"))
        self.dispatcher = self.updater.dispatcher
        self.add_handlers()

        try:
            self.tzinfo = timezone(self.get_bot_conf("TIMEZONE"))
        except:
            self.tzinfo = pytz.utc

    def get_bot_conf(self, value):
        return self.config["bot"][value]

    def get_env_conf(self, value, default_value=None):
        if default_value:
            return os.environ.get(self.config["env"][value], default_value)
        else:
            return os.environ.get(self.config["env"][value])

    def start_polling_loop(self):
        self.disable_webhook()
        self.update_queue = self.updater.start_polling()
        self.updater.idle()
        self.cleaning()

    def start_webhook_server(self):
        self.set_webhook()
        self.update_queue = self.updater.start_webhook(self.get_env_conf("IP","127.0.0.1"),
                                                       int(self.get_env_conf("PORT","8080")),
                                                       self.get_bot_conf("TOKEN"))
        self.updater.idle()
        self.cleaning()

    def cleaning(self):
        logger.info("Finished program.")

    def set_webhook(self):
        s = self.updater.bot.setWebhook(self.get_bot_conf("WEBHOOK_URL") + "/" + self.get_bot_conf("TOKEN"))
        if s:
            logger.info("webhook setup worked")
        else:
            logger.warning("webhook setup failed")
        return s

    def disable_webhook(self):
        s = self.updater.bot.setWebhook("")
        if s:
            logger.info("webhook was disabled")
        else:
            logger.warning("webhook couldn't be disabled")
        return s

    def add_handlers(self):
        self.dispatcher.addTelegramCommandHandler("start", self.command_start)
        self.dispatcher.addTelegramCommandHandler("help", self.command_help)
        self.dispatcher.addTelegramCommandHandler("time", self.command_time)
        self.dispatcher.addTelegramMessageHandler(self.command_echo)
        #self.dispatcher.addUnknownTelegramCommandHandler(self.command_unknown)
        #self.dispatcher.addErrorHandler(self.error_handle)

    def command_start(self, bot, update):
        self.send_message(bot, update.message.chat, _("Welcome to Dungeon World Bot."))

    def command_help(self, bot, update):
        self.send_message(bot, update.message.chat, _(
            """Available Commands:
            /start - Iniciciate or Restart the bot
            /help - Show the command list.
            /time - Bot local time check"""))

    def command_time(self, bot , update):
        utc_date = datetime.utcnow()
        local_date = pytz.utc.localize(utc_date).astimezone(self.tzinfo)
        formated_string = local_date.strftime("%d/%m/%y %H:%M")
        self.send_message(bot, update.message.chat, formated_string)

    def command_echo(self, bot , update):
        self.send_message(bot, update.message.chat, update.message.text)

    def send_message(self, bot, chat, text):
        try:
            bot.sendMessage(chat_id=chat.id, text=text)
            return True
        except TelegramError as e:
            logger.warning("Message sending error to %s [%d] [%s] (TelegramError: %s)" % (chat.name, chat.id, chat.type, e))
            return False
        except:
            logger.warning("Message sending error to %s [%d] [%s]" % (chat.name, chat.id, chat.type))
            return False
Ejemplo n.º 11
0
class HaiBot(object):
    translations = {}
    bot = None

    def __init__(self):
        self.terraria = Terraria()
        self.play_status = None
        self.play_user = None

        #LANGUAGE STUFF
        self.language_list = os.listdir(haibot.config.get("haibot","LOCALE_DIR"))
        for l in self.language_list:
            self.translations[l] = gettext.translation("telegrambot", haibot.config.get("haibot","LOCALE_DIR"), languages=[l], fallback=True)
        try:
            if haibot.config.get("haibot","LANGUAGE") in self.language_list:
                translation_install(self.translations[haibot.config.get("haibot","LANGUAGE")])
            else:
                translation_install(self.translations[DEFAULT_LANGUAGE])
        except:
            translation_install(self.translations[DEFAULT_LANGUAGE])

        # bot INICIALIZATION
        self.updater = Updater(token=haibot.config.get("haibot","TOKEN"))
        self.play_job_queue = self.updater.job_queue
        self.dispatcher = self.updater.dispatcher
        self.add_handlers()

        # Timezone Stuff
        try:
            self.tzinfo = pytz.timezone(haibot.config.get("haibot","TIMEZONE"))
        except:
            self.tzinfo = pytz.utc

    def start_polling_loop(self):
        self.disable_webhook()
        self.update_queue = self.updater.start_polling()
        self.updater.idle()
        self.cleaning()

    def start_webhook_server(self):
        # url/token/server_on |  url/token/server_off | url/token/server_on?hostname |  url/token/server_off?hostname
        from telegram.utils.webhookhandler import WebhookHandler
        from .terraria_server_urls import do_GET
        WebhookHandler.do_GET = do_GET

        self.set_webhook()
        self.update_queue = self.updater.start_webhook(haibot.config.get("haibot","IP"),
                                                       haibot.config.getint("haibot","PORT"),
                                                       haibot.config.get("haibot","TOKEN"))
        self.updater.idle()
        self.cleaning()

    def cleaning(self):
        with open(haibot.CONFIGFILE_PATH, "w") as configfile:
            haibot.config.write(configfile)
            haibot.logger.info("Saving config file...")
        haibot.logger.info("Finished program.")

    def set_webhook(self):
        s = self.updater.bot.setWebhook(haibot.config.get("haibot","WEBHOOK_URL") + "/" + haibot.config.get("haibot","TOKEN"))
        if s:
            haibot.logger.info("webhook setup worked")
        else:
            haibot.logger.warning("webhook setup failed")
        return s

    def disable_webhook(self):
        s = self.updater.bot.setWebhook("")
        if s:
            haibot.logger.info("webhook was disabled")
        else:
            haibot.logger.warning("webhook couldn't be disabled")
        return s

    def add_handlers(self):
        self.dispatcher.addTelegramCommandHandler("start", self.command_start)
        self.dispatcher.addTelegramCommandHandler("help", self.command_help)
        self.dispatcher.addTelegramCommandHandler("terraria", self.command_terraria)
        self.dispatcher.addTelegramCommandHandler("list", self.command_list)
        self.dispatcher.addTelegramCommandHandler("quote", self.command_quote)
        self.dispatcher.addTelegramCommandHandler("search", self.command_search)
        self.dispatcher.addTelegramCommandHandler("autonot", self.command_autonot)
        self.dispatcher.addTelegramCommandHandler("play", self.command_play)
        self.dispatcher.addTelegramCommandHandler("settings",self.command_settings)
        self.dispatcher.addTelegramCommandHandler("profile",self.command_profile)
        self.dispatcher.addUnknownTelegramCommandHandler(self.command_unknown)
        #self.dispatcher.addErrorHandler(self.error_handle)
        self.dispatcher.addStringCommandHandler("terraria_on", self.stringcommand_terraria_on)
        self.dispatcher.addStringCommandHandler("terraria_off", self.stringcommand_terraria_off)
        self.dispatcher.addStringCommandHandler("notify", self.stringcommand_notify)

    @save_user
    def command_start(self, bot, update, args):
        self.send_message(bot, update.message.chat_id, _("Bot was initiated. Use /help for commands."))

    @save_user
    def command_help(self, bot, update, args):
        self.send_message(bot, update.message.chat_id, _(
            """Available Commands:
            /start - Iniciciate or Restart the bot
            /help - Show the command list.
            /terraria status/log/ip/milestone/on/off - Terraria options
            /list - Manage your lists (Use /list help)
            /quote - Save your group chat quotes (Use /quote help)
            /autonot on/off - Enable or disable autonotifications
            /play - Set \"want to play to X\" for a amount of hours [Autonot]
            /search engine word - Search using a engine.
            /settings - Change bot options (language, etc.)
            /profile - Show your user profile """))

    @save_user
    def command_terraria(self, bot, update, args):
        chat = update.message.chat_id
        sender = update.message.from_user
        help_text = _(
            """Use one of the following commands:
            /terraria status - Server status (s)
            /terraria log <number> - Show Server history (l)
            /terraria ip - Display server IP (i)
            /terraria milestone - Add a milestone to server (m)[Autonot]
            /terraria on/off manually change server status [Autonot]""")
        if len(args) < 1:
            self.send_message(bot,chat, help_text)
        else:
            if args[0] == "status" or args[0] == "s":
                self.send_message(bot, chat, self.terraria.get_status())

            elif args[0] == "log" or args[0] == "l":
                if len(args) > 1:
                    try:
                        log_text = self.terraria.get_log(int(args[1]), tzinfo=self.tzinfo)
                    except:
                        if args[1] == "m":
                            log_text = self.terraria.get_log(5, only_milestone=True, tzinfo=self.tzinfo)
                        else:
                            log_text = _("/terraria log <number> - Number of log entries to show\n"
                                         "/terraria log m - Show only milestones")
                else:
                    log_text = self.terraria.get_log(5, tzinfo=self.tzinfo)
                if log_text:
                    self.send_message(bot, chat, log_text)
                else:
                    self.send_message(bot, chat, _("There is no Log History"))

            elif args[0] == "autonot" or args[0] == "a":
                self.send_message(bot, chat, _("This is a legacy (v0.1) command.\n Use the new command: /autonot <on/off> "))

            elif args[0] == "ip" or args[0] == "i":
                self.send_message(bot, chat, self.terraria.get_ip())

            elif args[0] == "milestone" or args[0] == "m":
                if len(args) > 1:
                    milestone_text = self.terraria.add_milestone(sender.name, " ".join(args[1:]))
                    is_confirmated = self.send_message(bot, chat, milestone_text)
                    self.autonotify(milestone_text, check_double=is_confirmated, previous_chat_id=chat)

                else:
                    self.send_message(bot, chat,_("Use /terraria milestone <TEXT>"))

            elif args[0] == "on":
                if len(args) > 1:
                    text = self.terraria.change_status(True, sender.name, args[1])
                else:
                    text = self.terraria.change_status(True, sender.name)
                    self.send_message(bot, chat,_("Note: You can set a IP with:\n/terraria on <your ip>" ))
                is_confirmated = self.send_message(bot, chat, text)
                self.autonotify(text, check_double=is_confirmated, previous_chat_id=chat)

            elif args[0] == "off":
                text = self.terraria.change_status(False, sender.name)
                is_confirmated = self.send_message(bot, chat, text)
                self.autonotify(text, check_double=is_confirmated, previous_chat_id=chat)

            else:
                self.send_message(bot, chat, help_text)

    @save_user
    def command_list(self, bot, update, args):
        chat = update.message.chat_id
        sender = update.message.from_user
        current_list = profile.get_user_value(sender.id,"current_list")
        sender_is_writer = profile.get_user_value(sender.id, "is_writer")
        no_writer_text = _("You have no writting rights")
        no_reader_text = _("You have no reading rights")
        non_existent_list_text = _("List \"%s\" does not exist. Select another list with /list use") % (current_list)

        if not profile.get_user_value(sender.id,"is_reader"):
            self.send_message(bot, chat, no_reader_text)
        else:
            help_text = _(
                """Use one of the following commands:
                /list show <all:done:notdone> - show entries in the current list (s)
                /list <number> - Show only one entry using his index
                /list add - add a new entry to the current list (a)
                /list delete - delete an entry from the current list (d)
                /list lists <show:add:delete:clone> - manage lists (l)
                /list use - select a list (makes the list the current list) (u)
                /list writers <show:add:delete> - manage admins for the list (w)
                /list readers <show:add:delete> - manage readers for the list (if apply) (r)
                /list done - mark an entry as <done> (do)
                /list random - pick a random entry and show it (ra)
                /list search - show all entries matching a text (se)""")
            if len(args) < 1:
                self.send_message(bot, chat, help_text)
            else:
                if args[0] == "show" or args[0] == "s":
                    show_help = False
                    if len(args) <2:
                        entry_list = lists.get_entries(current_list,mode="notdone")
                    else:
                        if args[1] == "done" or args[1] == "d":
                            entry_list = lists.get_entries(current_list, mode="done")
                        elif args[1] == "notdone" or args[1] == "n":
                            entry_list = lists.get_entries(current_list, mode="notdone")
                        elif args[1] == "all" or args[1] == "a":
                            entry_list = lists.get_entries(current_list, mode="all")
                        else:
                            show_help = True

                    if show_help:
                        self.send_message(bot, chat, _("Use /list show <all:done:notdone>"))
                    else:
                        if lists.has_list(current_list):
                            if entry_list:
                                entry_text= "%s: \n" % (current_list)
                                for entry in entry_list:
                                    if entry["done"]:
                                        entry_text += _("[%d][done] %s\n") % (entry["index"], entry["entry"] )
                                    else:
                                        entry_text += "[%d] %s\n" % (entry["index"], entry["entry"] )
                                self.send_message(bot, chat, entry_text)
                            else:
                                self.send_message(bot, chat, _("Your list is empty"))
                        else:
                            self.send_message(bot, chat, non_existent_list_text )

                elif args[0] == "add" or args[0] == "a":
                    if len(args) <2:
                        self.send_message(bot, chat, _("/list add <name>"))
                    else:
                        if sender_is_writer:
                            new_entry = " ".join(args[1:])
                            if lists.has_list(current_list):
                                new_index = lists.add_entry(new_entry,current_list, sender.name)
                                self.send_message(bot, chat, _("Entry #%d was added to list \"%s\"") % (new_index, current_list))
                            else:
                                self.send_message(bot, chat, non_existent_list_text )
                        else:
                            self.send_message(bot, chat, no_writer_text)

                elif args[0] == "delete" or args[0] == "d":
                    if len(args) <2:
                        self.send_message(bot, chat, _("/list delete <entry index>"))
                    else:
                        if sender_is_writer:
                            if lists.has_list(current_list):
                                try:
                                    if lists.has_entry_index(int(args[1]), current_list):
                                        deleted_entry = lists.delete_entry(int(args[1]),current_list)
                                        self.send_message(bot, chat, _("Entry #%d was deleted from list \"%s\".")%(deleted_entry["index"], current_list))
                                    else:
                                        self.send_message(bot, chat, _("The entry number does not exist. Use /list show"))
                                except:
                                    self.send_message(bot, chat, _("Use /list delete <entry number>"))
                            else:
                                self.send_message(bot, chat, non_existent_list_text )
                        else:
                            self.send_message(bot, chat, no_writer_text)

                elif args[0] == "lists" or args[0] == "l":
                    if len(args) <2:
                        self.send_message(bot, chat, "/list lists <show:add:delete:clone>")
                    else:
                        if args[1] == "show" or args[1] == "s":
                            show_text = ""
                            for list in lists.get_lists(enumerated=True):
                                show_text += "%s: %s\n" % (str(list[0]), list[1])
                            if show_text:
                                self.send_message(bot, chat, show_text)
                            else:
                                self.send_message(bot, chat, _("There is no lists. Create one."))
                        elif args[1] == "add" or args[1] == "a":
                            if len(args) <3:
                                self.send_message(bot, chat, _("/list lists add <something>"))
                            else:
                                if sender_is_writer:
                                    new_list = " ".join(args[2:])
                                    if lists.has_list(new_list):
                                        self.send_message(bot, chat, _("\"%s\" already exists!") % (new_list))
                                    else:
                                        list_index = lists.add_list(new_list, sender.name)
                                        self.send_message(bot, chat, _("\"%s\" list was created. Switch with /list use %d") % (new_list, list_index))
                                else:
                                    self.send_message(bot, chat, no_writer_text)

                        elif args[1] == "delete" or args[1] == "d":
                            if len(args) <3:
                                self.send_message(bot, chat, _("/list lists delete <list index>"))
                            else:
                                if sender_is_writer:
                                    list_array =  lists.get_lists(enumerated=True)
                                    was_deleted = False
                                    for list in list_array:
                                        try:
                                            if list[0] == int(args[2]):
                                                lists.delete_list(list[1])
                                                was_deleted = True
                                                self.send_message(bot, chat,
                                                    _("\"%s\" list was deleted. Use \"show\" for the new order. ")%(list[1]))
                                        except:
                                            was_deleted = False
                                    if not was_deleted:
                                        self.send_message(bot, chat, _("The list could not be deleted. Use:\n"
                                                                                         "/list lists delete <list index>"))
                                else:
                                    self.send_message(bot, chat, no_writer_text)

                        elif args[1] == "clone" or args[1] == "c":
                            if len(args) <4:
                                self.send_message(bot, chat, _("Use: /list clone <list_index> new name"))
                            else:
                                if sender_is_writer:
                                    list_array =  lists.get_lists(enumerated=True)
                                    was_cloned = False
                                    new_list = " ".join(args[3:])
                                    if lists.has_list(new_list):
                                        self.send_message(bot, chat, _("Cannot be cloned. \"%s\" already exists!") % (new_list))
                                    else:
                                        for list in list_array:
                                            try:
                                                if list[0] == int(args[2]):
                                                    was_cloned = lists.clone_list(list[1], new_list, sender.name)
                                                    if was_cloned:
                                                        self.send_message(bot, chat, _("\"%s\" list was cloned to \"%s\" and"
                                                                                " entries were ordered.")%(list[1], new_list))
                                            except:
                                               was_cloned = False
                                        if not was_cloned:
                                            self.send_message(bot, chat, _("The list could not be cloned. Use:\n"
                                                                                "Use: /list clone <list_index> new name"))
                                else:
                                    self.send_message(bot, chat, no_writer_text)

                        else:
                            self.send_message(bot, chat, "/list lists <show:add:delete:clone>")


                elif args[0] == "use" or args[0] == "u":
                    if len(args) <2:
                        self.send_message(bot, chat, _("/list use <list ID>\nUse /list lists show for IDs"))
                    else:
                        enumerated_list = lists.get_lists(enumerated=True)
                        is_changed = False
                        for list in enumerated_list:
                            try:
                                if list[0] == int(args[1]):
                                    profile.set_user_value(sender.id, "current_list", list[1])
                                    self.send_message(bot, chat, _("%s selected list: \"%s\"") % (sender.name, list[1]) )
                                    is_changed = True
                            except:
                                is_changed = False
                        if is_changed == False:
                            self.send_message(bot, chat, _("/Invalid ID. Use /list lists show") )

                elif args[0] == "writers" or args[0] == "w":
                    if len(args) <2:
                        self.send_message(bot, chat, "/list writers <show:add:delete:clone>")
                    else:
                        if args[1] == "show" or args[1] == "s":
                            show_text = ""
                            for list in profile.get_users("is_writer",with_name=True):
                                show_text += "%s: %s\n" % (list["user_id"], list["user_name"])
                            if show_text:
                                self.send_message(bot, chat, show_text)
                            else:
                                self.send_message(bot, chat, _("There is no writers."))
                                haibot.logger.warning("No writers. There should be one. Add bot owner to config file")

                        elif args[1] == "add" or args[1] == "a":
                            add_writers_help = _("/list writer add ID.\n Use \"/profile list\" for a list of known IDs")
                            if len(args) <3:
                                self.send_message(bot, chat, add_writers_help)
                            else:
                                if sender_is_writer:
                                    try:
                                        new_writer = int(args[2])
                                        if profile.has_user(new_writer):
                                            profile.set_user_value(new_writer, "is_writer", True)
                                            self.send_message(bot, chat, _("writer rights for (ID:%d) were added") % (new_writer))
                                        else:
                                            self.send_message(bot, chat, add_writers_help)
                                    except:
                                        self.send_message(bot, chat, add_writers_help)
                                else:
                                    self.send_message(bot, chat, no_writer_text)

                        elif args[1] == "delete" or args[1] == "d":
                            delete_writers_help = _("/list writer delete ID.\n Use \"/list writers show\" for a list of writers IDs")
                            if len(args) <3:
                                self.send_message(bot, chat, delete_writers_help)
                            else:
                                if sender_is_writer:
                                    try:
                                        del_writer = int(args[2])
                                        if profile.has_user(del_writer):
                                            if del_writer != sender.id:
                                                profile.set_user_value(del_writer, "is_writer", False)
                                                self.send_message(bot, chat, _("writer rights for (ID:%d) were deleted") % (del_writer))
                                            else:
                                                self.send_message(bot, chat, _("You can't delete your own rights"))
                                        else:
                                            self.send_message(bot, chat, delete_writers_help)
                                    except:
                                        self.send_message(bot, chat, delete_writers_help)
                                else:
                                    self.send_message(bot, chat, no_writer_text)
                        else:
                            self.send_message(bot, chat, "/list writers <show:add:delete>")

                elif args[0] == "readers" or args[0] == "r":
                    if len(args) <2:
                        self.send_message(bot, chat, "/list readers <show:add:delete:clone>")
                    else:
                        if args[1] == "show" or args[1] == "s":
                            show_text = ""
                            for list in profile.get_users("is_reader",with_name=True):
                                show_text += "%s: %s\n" % (list["user_id"], list["user_name"])
                            if show_text:
                                self.send_message(bot, chat, show_text)
                            else:
                                self.send_message(bot, chat, _("There is no readers."))
                                haibot.logger.warning("No readers. There should be one. Add bot owner to config file")

                        elif args[1] == "add" or args[1] == "a":
                            add_readers_help = _("/list reader add ID.\n Use \"/profile list\" for a list of known IDs")
                            if len(args) <3:
                                self.send_message(bot, chat, add_readers_help)
                            else:
                                if sender_is_writer:
                                    try:
                                        new_reader = int(args[2])
                                        if profile.has_user(new_reader):
                                            profile.set_user_value(new_reader, "is_reader", True)
                                            self.send_message(bot, chat, _("reader rights for (ID:%d) were added") % (new_reader))
                                        else:
                                            self.send_message(bot, chat, add_readers_help)
                                    except:
                                        self.send_message(bot, chat, add_readers_help)
                                else:
                                    self.send_message(bot, chat, no_writer_text)

                        elif args[1] == "delete" or args[1] == "d":
                            delete_readers_help = _("/list reader delete ID.\n Use \"/list readers show\" for a list of readers IDs")
                            if len(args) <3:
                                self.send_message(bot, chat, delete_readers_help)
                            else:
                                if sender_is_writer:
                                    try:
                                        del_reader = int(args[2])
                                        if profile.has_user(del_reader):
                                            if del_reader != sender.id:
                                                profile.set_user_value(del_reader, "is_reader", False)
                                                self.send_message(bot, chat, _("reader rights for (ID:%d) were deleted") % (del_reader))
                                            else:
                                                self.send_message(bot, chat, _("You can't delete your own rights"))
                                        else:
                                            self.send_message(bot, chat, delete_readers_help)
                                    except:
                                        self.send_message(bot, chat, delete_readers_help)
                                else:
                                    self.send_message(bot, chat, no_writer_text)
                        else:
                            self.send_message(bot, chat, "/list readers <show:add:delete>")

                elif args[0] == "done" or args[0] == "do":
                    if len(args) <2:
                        self.send_message(bot, chat, _("/list done <entry index>"))
                    else:
                        if sender_is_writer:
                            if lists.has_list(current_list):
                                try:
                                    if lists.has_entry_index(int(args[1]), current_list):
                                        entry, done_status = lists.toogle_done_entry(int(args[1]),current_list)
                                        if done_status:
                                            self.send_message(bot, chat,_("#%d: done (list:%s)")%(entry["index"],current_list))
                                            self.send_message(bot, chat,_("See: \list show <all:done:notdone>"))
                                        else:
                                            self.send_message(bot, chat,_("#%d: notdone (list:%s)")%(entry["index"],current_list))
                                    else:
                                        self.send_message(bot, chat, _("The entry number does not exist. Use /list show all"))
                                except:
                                    self.send_message(bot, chat, _("Use /list done <entry number>"))
                            else:
                                self.send_message(bot, chat, non_existent_list_text )
                        else:
                            self.send_message(bot, chat, no_writer_text)

                elif args[0] == "random" or args[0] == "ra":
                    if lists.has_list(current_list):
                        entry = lists.get_random_entry(current_list)
                        if entry:
                            if entry["done"] == True:
                                self.send_message(bot, chat, _("[%d][done] %s\n") % (entry["index"], entry["entry"]))
                            else:
                                self.send_message(bot, chat, "[%d] %s\n" % (entry["index"], entry["entry"]))
                        else:
                            self.send_message(bot, chat, _("Your list is empty"))
                    else:
                        self.send_message(bot, chat, non_existent_list_text )

                elif args[0] == "search" or args[0] == "se":
                    if len(args) <2:
                        self.send_message(bot, chat, _("/list search <words>"))
                    else:
                        if lists.has_list(current_list):
                            result = lists.search_entries(" ".join(args[1:]), current_list)
                            if result:
                                self.send_message(bot, chat, result)
                            else:
                                self.send_message(bot, chat, _("No entries were found"))
                        else:
                            self.send_message(bot, chat, non_existent_list_text )

                else:
                    try:
                        if lists.has_entry_index(int(args[0]), current_list ) :
                            if lists.has_list(current_list):
                                entry = lists.get_entry( int(args[0]), current_list)
                                if entry["done"] == True:
                                    self.send_message(bot, chat, _("[%d][done] %s\n") % (entry["index"], entry["entry"]))
                                else:
                                    self.send_message(bot, chat, "[%d] %s\n" % (entry["index"], entry["entry"]))
                            else:
                                self.send_message(bot, chat, non_existent_list_text )
                        else:
                            self.send_message(bot, chat, _("Invalid number. Use /list show o /list search <word>"))
                    except:
                        self.send_message(bot, chat, help_text)

    @save_user
    def command_quote(self, bot, update, args):
        chat = update.message.chat_id
        sender = update.message.from_user
        no_write = _("You have no writting rights. See /list writers")

        help_text = _(
            "You can add a quote, selecting a message and clicking on \"reply\" and then writting /quote\n\n"
            "/quote search - show all quote matching a text (s/se)\n"
            "/quote <number> show the quote associated to a index\n"
            "/quote delete - delete a quote (d)\n"
            "/quote random - pick a random quote and show it (r/ra)\n"
            "/quote islist - Show the quotes as a list in the command /list (i/is)")
        if len(args) < 1:
            if update.message.reply_to_message:
                username = update.message.reply_to_message.from_user.name
                new_quote = update.message.reply_to_message.text
                new_index = lists.add_entry(new_quote, "quote", username)
                if not new_index:
                    self.send_message(bot, chat, _("Error: There is not Quote List in database. Use: /list lists add quote"))
                    haibot.logger.warning("There is not Quote List in database.")
                else:
                    self.send_message(bot, chat, _("Quote #%d was recorded") % (new_index))
            else:
                self.send_message(bot, chat, help_text)
        else:
            if args[0] == "delete" or args[0] == "d":
                if len(args) <2:
                    self.send_message(bot, chat, _("/quote delete <entry index>"))
                else:
                    if profile.get_user_value(sender.id, "is_writer"):
                        try:
                            if lists.has_entry_index(int(args[1]), "quote"):
                                deleted_entry = lists.delete_entry(int(args[1]), "quote")
                                self.send_message(bot, chat, _("Quote #%d was deleted.")%(deleted_entry["index"]))
                            else:
                                self.send_message(bot, chat, _("The quote number does not exist. Use /quote search <word>"))
                        except:
                            self.send_message(bot, chat, _("Use /quote delete <entry number>"))
                    else:
                        self.send_message(bot, chat, no_write)

            elif args[0] == "random" or args[0] == "r" or args[0] == "ra" :
                entry = lists.get_random_entry("quote")
                if entry:
                    self.send_message(bot, chat, "*%s*\n`[%d] %s`\n"
                                          % (entry["owner"], entry["index"], entry["entry"]), with_markdown=True)
                else:
                    self.send_message(bot, chat, _("There is no quotes"))

            elif args[0] == "search" or args[0] == "s" or args[0] == "se":
                if len(args) <2:
                    self.send_message(bot, chat, _("/quote search <words>"))
                else:
                    result = lists.search_entries(" ".join(args[1:]), "quote")
                    if result:
                        self.send_message(bot, chat, result)
                    else:
                        self.send_message(bot, chat, _("No quotes were found"))
            elif args[0] == "islist" or args[0] == "i" or args[0] == "is":
                if profile.get_user_value(sender.id, "is_writer"):
                    hidden = lists.toogle_hidden_list("quote")
                    if not hidden:
                        self.send_message(bot, chat, _("The quotes are now a list.\nBe careful: all the quotes can now be deleted, cloned or full showed"))
                    else:
                        self.send_message(bot, chat, _("The quotes are now hidden in list command."))
                else:
                    self.send_message(bot, chat, no_write)
            else:
                try:
                    if lists.has_entry_index(int(args[0]), "quote" ) :
                        entry = lists.get_entry( int(args[0]), "quote")
                        self.send_message(bot, chat, "*%s*\n`[%d] %s`\n"
                                          % (entry["owner"], entry["index"], entry["entry"]), with_markdown=True)
                    else:
                        self.send_message(bot, chat, _("Invalid number. Use /quote search <word>"))
                except:
                    self.send_message(bot, chat, help_text)

    @save_user
    def command_autonot(self, bot, update, args):
        sender = update.message.from_user
        chat = update.message.chat_id
        if len(args) > 0:
            if args[0] == "on":
                profile.set_user_value(sender.id,"in_autonot", True)
                self.send_message(bot, chat, sender.name+_(" was added to auto notifications."))
            elif args[0] == "off":
                profile.set_user_value(sender.id,"in_autonot", False)
                self.send_message(bot, chat, sender.name+_(" was removed from auto notifications."))
            else:
                self.send_message(bot, chat, "/terraria autonot\n/terraria autonot on/off")
        else:
            if profile.get_user_value(sender.id, "in_autonot"):
                profile.set_user_value(sender.id,"in_autonot", False)
                self.send_message(bot, chat, sender.name+_(" was removed from auto notifications."))
            else:
                profile.set_user_value(sender.id,"in_autonot", True)
                self.send_message(bot, chat, sender.name+_(" was added to auto notifications."))

    @save_user
    def command_play(self, bot, update, args):
        sender = update.message.from_user
        chat = update.message.chat_id
        help_text = _("/play <hours> <game>  - Display that you are playing a game for X hours. "
                      "(Example: play 2.5 dota2 ). The message will be sent to users with autonot enabled. "
                      "Another notification will be sent automatically when the time indicated elapses. \n\n"
                      "/play status - Display the play message if there is one active \n"
                      "/play stop - Manually stops the play, instead of waiting that the time elapses ")
        if len(args) < 1:
            self.send_message(bot, chat, help_text )
        if len(args) < 2:
            if args[0] == "status" or args[0] == "s":
                if self.play_job_queue.running:
                    self.send_message(bot, chat, self.play_status)
                else:
                    self.send_message(bot, chat, _("There is not \"play\" ongoing"))
            elif args[0] == "stop" or args[0] == "st":
                if self.play_user == sender.name:
                    if self.play_job_queue.running:
                        self.stop_play(bot)
                        self.send_message(bot, chat, _("Done."))
                    else:
                        self.send_message(bot, chat, _("You can only stop your own \"play\""))
                else:
                    self.send_message(bot, chat, _("There is not \"play\" to stop."))
            else:
                self.send_message(bot, chat, help_text )
        else:
            try:
                total_hours = float(args[0])
                if total_hours > MAX_PLAY_HOURS:
                    self.send_message(bot, chat, _("The max number of hours allowed is %d") % (MAX_PLAY_HOURS))
                elif total_hours < 0.02:
                    self.send_message(bot, chat, _("You tried to set up less than 1 minute of play"))
                else:
                    if not self.play_job_queue.running:
                        game =  " ".join(args[1:])
                        hour = datetime.now(self.tzinfo)
                        hour_until = (hour + timedelta(hours=total_hours)).strftime("%H:%M")
                        self.play_user = sender.name
                        self.play_status = _("%s is ready to play: %s (until %s)") % (sender.name, game, hour_until )
                        self.send_message(bot, chat, _("A notification was sent to all subscribed users. Use /autonot for subscribing"))
                        self.autonotify(self.play_status)
                        self.play_job_queue.put(self.stop_play, total_hours*60*60, repeat=False)
                    else:
                        self.send_message(bot, chat, _("There is already a play. See /play status for info."))
            except:
                self.send_message(bot, update.message.chat_id, help_text )

    @save_user
    def command_search(self, bot, update, args):
        self.send_message(bot, update.message.chat_id, _("NOT IMPLEMENTED"))

    @save_user
    def command_settings(self, bot,update, args):
        chat = update.message.chat_id
        languages_codes_text = _("Language codes:\n")
        for lang in self.language_list:
            languages_codes_text+= "<"+lang+"> "

        help_text = _("Use /settings language language_code\n\n" + languages_codes_text)

        if len(args) < 2:
            self.send_message(bot, chat, help_text)
        else:
            if args[0] == "language" or args[0] == "l":
                if args[1] in self.language_list:
                    try:
                        haibot.config.set("haibot","LANGUAGE", args[1] )
                        translation_install(self.translations[haibot.config.get("haibot","LANGUAGE")])
                        self.send_message(bot, chat, _("Language changed to %s") % (args[1]))
                        haibot.logger.info("Language was changed to %s" % (args[1]))
                    except:
                        haibot.logger.info("A error happened changing language to %s" % (args[1]))

                else:
                    self.send_message(bot, chat, _("Unknown language code\n\n" + languages_codes_text))
            else:
                self.send_message(bot, chat, help_text)

    @save_user
    def command_profile(self, bot, update,args):
        if len(args) < 1:
            user = profile.get_user(update.message.from_user.id)
            profile_text = ""
            if user:
                for i in user:
                    profile_text += "%s = %s\n" % (str(i), str(user[i]))
            else:
                profile_text = _("Could not get user profile")
        else:
            if args[0] == "list" or args[0] == "l":
                users = profile.get_allusers(projection={"user_id":True, "user_name":True })
                profile_text = ""
                if users:
                    for u in users:
                        profile_text += "%s : %s\n" % (str(u["user_id"]), u["user_name"])
                else:
                    profile_text = _("Could not get profile list")
            else:
                try:
                    profile_id = int(args[0])
                    user = profile.get_user(profile_id)
                    profile_text = ""
                    if user:
                        for i in user:
                            profile_text += "%s = %s\n" % (str(i), str(user[i]))
                    else:
                        profile_text = _("Could not get profile from user <%s>") % (profile_id)
                except:
                        profile_text = _("Use a profile ID with only numbers")

        self.send_message(bot, update.message.chat_id, profile_text)

    @save_user
    def command_unknown(self, bot, update,args):
        self.send_message(bot, update.message.chat_id, _("%s is a unknown command. Use /help for available commands.") % (update.message.text))

    # /terraria_on IP user
    def stringcommand_terraria_on(self, bot, update, args):
        if len(args) > 1:
            text = self.terraria.change_status(True, " ".join(args[1:]), args[0])
        else:
            text = self.terraria.change_status(True)
        self.autonotify(text)

    # /terraria_off user
    def stringcommand_terraria_off(self, bot, update, args):
        if len(args) > 0:
            text = self.terraria.change_status(False, " ".join(args[0:]))
        else:
            text = self.terraria.change_status(False)
        self.autonotify(text)

    # /notify ID text
    def stringcommand_notify(self, bot, update, args):
        self.send_message(bot, int(args[0]), " ".join(args[1:]))


    def autonotify(self, text, check_double=False, previous_chat_id=None ):
        autonot_list = profile.get_users("in_autonot")
        for user in autonot_list:
            if check_double and user["user_id"] == previous_chat_id:
                break
            else:
                text_to_queue = str("/notify %s %s" % (user["user_id"], text))
                self.update_queue.put(text_to_queue)

    def stop_play(self,bot):
        self.autonotify( self.play_user + _(" stopped playing."))
        self.play_job_queue.stop()
        self.play_status = None
        self.play_user = None

    def send_message(self, bot, chat_id, text, with_markdown=False):
        try:
            if with_markdown:
                bot.sendMessage(chat_id=chat_id, text=text, disable_web_page_preview=True, parse_mode="Markdown")
            else:
                bot.sendMessage(chat_id=chat_id, text=text, disable_web_page_preview=True)
            return True
        except TelegramError as e:
            try:
                user_name = profile.get_user_value(chat_id, "user_name")
            except:
                user_name = "unknown"
            haibot.logger.warning("A Message could not be sent to User: %s [%d] (TelegramError: %s)" % (user_name, chat_id , e))
            return False
        except:
            haibot.logger.warning("A Message could not be sent:\n%s " % (text))
            return False
Ejemplo n.º 12
0
class Bot(object):
    translations = {}
    bot = None

    def __init__(self):
        self.config = configparser.ConfigParser()
        self.config.read(CONFIGFILE_PATH)

        self.updater = Updater(token=self.get_bot_conf("TOKEN"))
        self.dispatcher = self.updater.dispatcher
        self.add_handlers()

        try:
            self.tzinfo = timezone(self.get_bot_conf("TIMEZONE"))
        except:
            self.tzinfo = pytz.utc

    def get_bot_conf(self, value):
        return self.config["bot"][value]

    def get_env_conf(self, value, default_value=None):
        if default_value:
            return os.environ.get(self.config["env"][value], default_value)
        else:
            return os.environ.get(self.config["env"][value])

    def start_polling_loop(self):
        self.disable_webhook()
        self.update_queue = self.updater.start_polling()
        self.updater.idle()
        self.cleaning()

    def start_webhook_server(self):
        self.set_webhook()
        self.update_queue = self.updater.start_webhook(
            self.get_env_conf("IP", "127.0.0.1"),
            int(self.get_env_conf("PORT", "8080")), self.get_bot_conf("TOKEN"))
        self.updater.idle()
        self.cleaning()

    def cleaning(self):
        logger.info("Finished program.")

    def set_webhook(self):
        s = self.updater.bot.setWebhook(
            self.get_bot_conf("WEBHOOK_URL") + "/" +
            self.get_bot_conf("TOKEN"))
        if s:
            logger.info("webhook setup worked")
        else:
            logger.warning("webhook setup failed")
        return s

    def disable_webhook(self):
        s = self.updater.bot.setWebhook("")
        if s:
            logger.info("webhook was disabled")
        else:
            logger.warning("webhook couldn't be disabled")
        return s

    def add_handlers(self):
        self.dispatcher.addTelegramCommandHandler("start", self.command_start)
        self.dispatcher.addTelegramCommandHandler("help", self.command_help)
        self.dispatcher.addTelegramCommandHandler("time", self.command_time)
        self.dispatcher.addTelegramMessageHandler(self.command_echo)
        #self.dispatcher.addUnknownTelegramCommandHandler(self.command_unknown)
        #self.dispatcher.addErrorHandler(self.error_handle)

    def command_start(self, bot, update):
        self.send_message(bot, update.message.chat,
                          _("Welcome to Dungeon World Bot."))

    def command_help(self, bot, update):
        self.send_message(
            bot, update.message.chat,
            _("""Available Commands:
            /start - Iniciciate or Restart the bot
            /help - Show the command list.
            /time - Bot local time check"""))

    def command_time(self, bot, update):
        utc_date = datetime.utcnow()
        local_date = pytz.utc.localize(utc_date).astimezone(self.tzinfo)
        formated_string = local_date.strftime("%d/%m/%y %H:%M")
        self.send_message(bot, update.message.chat, formated_string)

    def command_echo(self, bot, update):
        self.send_message(bot, update.message.chat, update.message.text)

    def send_message(self, bot, chat, text):
        try:
            bot.sendMessage(chat_id=chat.id, text=text)
            return True
        except TelegramError as e:
            logger.warning(
                "Message sending error to %s [%d] [%s] (TelegramError: %s)" %
                (chat.name, chat.id, chat.type, e))
            return False
        except:
            logger.warning("Message sending error to %s [%d] [%s]" %
                           (chat.name, chat.id, chat.type))
            return False