Пример #1
0
    def setUp(self):
        os.environ.setdefault("URL_HOSTNAME", "example.com")

        app = Flask(__name__)
        app.config.from_pyfile("testconfig.py")
        self.app = app
        self.app_test = app.test_client()  # get a test client
        self.bot = Teleflask(API_KEY, return_python_objects=True)

        # replace the :class:`pytgbot.Bot` instance with something testable. (not using TG server)
        # All methods now return the stuff they would sent to the telegram servers as json instead.
        # This is not usable with the :class:`teleflask.message.Message` (sub)types.
        self.bot.bot = BotTestable(
            API_KEY, return_python_objects=self.bot._return_python_objects)

        # Init must be before replacing the ``bot.bot``,
        # because else the :meth:`Bot.getWebhook` won't work as expected in startup.
        self.bot.init_app(app)

        # Array to hold information about the called callbacks:
        self.callbacks_status = {}

        # Get the update_path to be able to test via emulating incoming updates
        self.update_path, self.update_url = self.bot.calculate_webhook_url(
            hostname=self.bot.hostname,
            hostpath=self.bot.hostpath,
            hookpath=self.bot.hookpath)
Пример #2
0
    def test_doubleblueprintability_and_execute(self):
        states_tbp = TBlueprint(__name__)
        states_tbp2 = TBlueprint(__name__ + "2")
        states_tbp.register_tblueprint(states_tbp2)
        states_drvr = SilentDriver()
        states = TeleStateMachine(__name__,
                                  database_driver=states_drvr,
                                  teleflask_or_tblueprint=states_tbp2)
        states.teleflask._bot = BotMock('FAKE_API_KEY',
                                        return_python_objects=True)

        called = [False]

        @states.DEFAULT.command('cancel')
        def func_1(update, text):
            called[0] = True

        # end def

        bot = Teleflask('FAKE_API_KEY',
                        app=None,
                        hostname="localhost",
                        debug_routes=False,
                        disable_setting_webhook_telegram=True,
                        disable_setting_webhook_route=True)
        bot._bot = BotMock('FAKE_API_KEY', return_python_objects=True)
        bot.init_bot()
        bot.register_tblueprint(states_tbp)
        bot.process_update(update1)
        self.assertTrue(called[0], 'func_1 should have been called')
Пример #3
0
 def setUp(self):
     self.b = Teleflask(api_key=None,
                        app=None,
                        hostname="localhost",
                        debug_routes=False,
                        disable_setting_webhook_telegram=True,
                        disable_setting_webhook_route=True)
     self.b._bot = BotMock('FAKE_API_KEY', return_python_objects=True)
     self.d = SilentDriver()
     self.m = TeleStateMachine(__name__, self.d, self.b)
     self.s = TeleState('LITTLEPIP')
     self.b.init_bot()
Пример #4
0
    def test_blueprintability_and_register(self):
        states_tbp = TBlueprint(__name__)
        states_drvr = SilentDriver()
        states: TeleStateMachine = TeleStateMachine(
            __name__,
            database_driver=states_drvr,
            teleflask_or_tblueprint=states_tbp)
        states.teleflask._bot = BotMock('FAKE_API_KEY',
                                        return_python_objects=True)
        states.teleflask.init_bot()

        @states.DEFAULT.command('cancel')
        def func_1(update):
            pass

        # end def

        bot = Teleflask('FAKE_API_KEY',
                        app=None,
                        hostname="localhost",
                        debug_routes=False,
                        disable_setting_webhook_telegram=True,
                        disable_setting_webhook_route=True)
        bot._bot = BotMock('FAKE_API_KEY', return_python_objects=True)
        bot.init_bot()
        bot.register_tblueprint(states_tbp)
        self.assertGreater(len(states.CURRENT.update_handler.commands), 0,
                           'should have added an command.')
Пример #5
0
    def __init__(self,
                 name: str,
                 database_driver: Union[Type[TeleStateDatabaseDriver],
                                        TeleStateDatabaseDriver],
                 teleflask_or_tblueprint: Teleflask = None):
        self.did_init = False
        self.listeners_registered = False
        self.states: Dict[str, TeleState] = {}  # NAME: telestate_instance
        assert_type_or_raise(database_driver,
                             TeleStateDatabaseDriver,
                             parameter_name='driver')
        self.database_driver = database_driver
        super(TeleStateMachine, self).__init__()
        if teleflask_or_tblueprint:
            self.blueprint = teleflask_or_tblueprint
            if isinstance(teleflask_or_tblueprint, Teleflask):
                # calls register_bot
                self.register_bot(teleflask_or_tblueprint)
                # now is registered
                self.is_registered = True
            elif isinstance(teleflask_or_tblueprint, TBlueprint):
                # calls register_bot
                teleflask_or_tblueprint.record(self.register_bot)
                # is registered as if that TBlueprint already is registered.
                self.is_registered = teleflask_or_tblueprint._got_registered_once and teleflask_or_tblueprint._teleflask
            # end if
        else:
            self.blueprint = TBlueprint(name)
            self.is_registered = False
        # end def

        # end if
        self.active_state = None

        self.DEFAULT = TeleState('DEFAULT', self)
        self.ALL = TeleState(
            'ALL', self
        )  # so you can register to states.ALL to be called on all the states.
        self.CURRENT = self.DEFAULT
        self.did_init = True
Пример #6
0
    def setUp(self):
        os.environ.setdefault("URL_HOSTNAME", "example.com")

        app = Flask(__name__)
        app.config.from_pyfile("testconfig.py")
        self.app = app
        self.app_test = app.test_client()  # get a test client
        self.bot = Teleflask(API_KEY, return_python_objects=True)

        # replace the :class:`pytgbot.Bot` instance with something testable. (not using TG server)
        # All methods now return the stuff they would sent to the telegram servers as json instead.
        # This is not usable with the :class:`teleflask.message.Message` (sub)types.
        self.bot.bot = BotTestable(API_KEY, return_python_objects=self.bot._return_python_objects)

        # Init must be before replacing the ``bot.bot``,
        # because else the :meth:`Bot.getWebhook` won't work as expected in startup.
        self.bot.init_app(app)

        # Array to hold information about the called callbacks:
        self.callbacks_status = {}

        # Get the update_path to be able to test via emulating incoming updates
        self.update_path, self.update_url = self.bot.calculate_webhook_url(hostname=self.bot.hostname, hostpath=self.bot.hostpath, hookpath=self.bot.hookpath)
from .utils import to_json_remove_api_key, msg_get_reply_params
from .secrets import API_KEY, EVENT_CHANNEL
from .commands import bot as commands_tbp
from .features import bot as features_tbp
from .gitinfo import bot as versions_tbp

__author__ = 'luckydonald'
logger = logging.getLogger(__name__)

logging.add_colored_handler(level=logging.DEBUG)


app = Flask(__name__)

bot = Teleflask(API_KEY, app)

bot.register_tblueprint(commands_tbp)
bot.register_tblueprint(features_tbp)
bot.register_tblueprint(versions_tbp)


@app.route("/info/<api_key>/<command>")
@to_json_remove_api_key
def info(api_key, command):

    """
    Issue commands. E.g. /info/getMe

    :param command:
    :return:
Пример #8
0
# -*- coding: utf-8 -*-
from flask import Flask
from teleflask import Teleflask
from teleflask.messages import TextMessage, PlainMessage, MarkdownMessage, HTMLMessage


__author__ = 'luckydonald'

from somewhere import API_KEY  # I import it from some file which is kept private, not in git.
# Just set API_KEY = "your-api-key".
app = Flask(__name__)
bot = Teleflask(API_KEY)
bot.init_app(app)


@app.route("/")
def index():
    return "This is a normal Flask page."
# end def


# Register the /start command
@bot.command("start")
def start(update, text):
    # update is the update object. It is of type pytgbot.api_types.receivable.updates.Update
    # text is the text after the command. Can be empty. Type is str.
    return HTMLMessage("<b>Hello!</b> Thanks for using @" + app.username + "!")
    # return TextMessage("<b>Hello!</b> Thanks for using @" + app.username + "!", parse_mode="html")
# end def

Пример #9
0
# -*- coding: utf-8 -*-

from teleflask import Teleflask

from somewhere import API_KEY

from luckydonaldUtils.logger import logging

logger = logging.getLogger(__name__)
__author__ = 'luckydonald'

bot = Teleflask(API_KEY)


@bot.command("test")
def test(update, text):
    return "You tested with {arg!r}".format(arg=text)


# end def
Пример #10
0
import os
from flask import Flask, jsonify, request
from teleflask import Teleflask
import datetime

###

print("oi")
print(os.environ["API_KEY"])

app = Flask(__name__)

bot = Teleflask(os.environ["API_KEY"])
print(bot)
bot.init_app(app)

###

print("ooi")

last_prediction_time = None
last_prediction_decision = False
last_predicition_leave_time = None


# Register the /start command
@bot.command("start")
def start(update, text):
    return TextMessage("<b>Oi, porra!</b>", parse_mode="html")

Пример #11
0
class SomeTestCase(unittest.TestCase):
    def setUp(self):
        os.environ.setdefault("URL_HOSTNAME", "example.com")

        app = Flask(__name__)
        app.config.from_pyfile("testconfig.py")
        self.app = app
        self.app_test = app.test_client()  # get a test client
        self.bot = Teleflask(API_KEY, return_python_objects=True)

        # replace the :class:`pytgbot.Bot` instance with something testable. (not using TG server)
        # All methods now return the stuff they would sent to the telegram servers as json instead.
        # This is not usable with the :class:`teleflask.message.Message` (sub)types.
        self.bot.bot = BotTestable(API_KEY, return_python_objects=self.bot._return_python_objects)

        # Init must be before replacing the ``bot.bot``,
        # because else the :meth:`Bot.getWebhook` won't work as expected in startup.
        self.bot.init_app(app)

        # Array to hold information about the called callbacks:
        self.callbacks_status = {}

        # Get the update_path to be able to test via emulating incoming updates
        self.update_path, self.update_url = self.bot.calculate_webhook_url(hostname=self.bot.hostname, hostpath=self.bot.hostpath, hookpath=self.bot.hookpath)

    def tearDown(self):
        pass
        # os.close(self.db_fd)
        # os.unlink(flaskr.app.config['DATABASE'])
    # end def

    data_cmd = {
        "update_id": 10000,
        "message": {
            "message_id": 4458,
            "from": {
                "id": 1234,
                "first_name": "Test User",
                "username": "******"
            },
            "chat": {
                "id": 1234,
                "first_name": "Test User",
                "username": "******",
                "type": "private"
            },
            "date": 1487612335,
            "text": "/test 123",
            "entities": [
                {
                    "type": "bot_command",
                    "offset": 0,
                    "length": 5
                }
            ]
        }
    }

    def test_webhook(self):
        self.assertEqual(self.update_url.replace(API_KEY, "{API_KEY}"), "https://example.com/income/{API_KEY}")
    # end def

    def test_command(self):
        @self.bot.command("test")
        def _callback_test_command(update, text):
            self.callbacks_status["_callback_test_command"] = text
        # end def

        self.app_test.post(self.update_path, data=json.dumps(self.data_cmd), content_type='application/json')

        self.assertIn("_callback_test_command", self.callbacks_status, "@command('test') func executed")
        self.assertEquals(self.callbacks_status["_callback_test_command"], "123")
    # end def

    def test_on_message(self):
        @self.bot.on_message
        def _callback_test_on_message(msg):
            self.callbacks_status["_callback_test_on_message"] = msg
        # end def

        self.app_test.post(self.update_path, data=json.dumps(self.data_cmd), content_type='application/json')

        self.assertIn("_callback_test_on_message", self.callbacks_status, "@on_message func executed")
        msg = self.callbacks_status["_callback_test_on_message"]
        from pytgbot.api_types.receivable.updates import Message
        self.assertIsInstance(msg, Message)
        self.assertEquals(msg.to_array(), self.data_cmd["message"])
    # end def

    def test_on_message2(self):
        @self.bot.on_message("text")
        def _callback_test_on_message2(msg):
            self.callbacks_status["_callback_test_on_message2"] = msg
        # end def

        self.app_test.post(self.update_path, data=json.dumps(self.data_cmd), content_type='application/json')

        self.assertIn("_callback_test_on_message2", self.callbacks_status, "@on_message('text') func executed")
        msg = self.callbacks_status["_callback_test_on_message2"]
        from pytgbot.api_types.receivable.updates import Message
        self.assertIsInstance(msg, Message)
        self.assertEquals(msg.to_array(), self.data_cmd["message"])
    # end def

    def test_on_message3(self):
        @self.bot.on_message("photo")
        def _callback_test_on_message3(msg):
            self.callbacks_status["_callback_test_on_message3"] = msg
        # end def

        self.app_test.post(self.update_path, data=json.dumps(self.data_cmd), content_type='application/json')

        self.assertNotIn("_callback_test_on_message3", self.callbacks_status, "@on_message('photo') func not executed")
Пример #12
0
    g
)
from teleflask import Teleflask
from teleflask.messages import MarkdownMessage
from hashlib import sha1
import requests
import dataset
import shlex
import random
import re
from distutils.version import StrictVersion

__version__  = '0.2.0'

app = Flask(__name__)
bot = Teleflask(os.environ.get('TG_TOKEN'), app)

DATABASE_URL = os.environ.get('DATABASE_URL', "sqlite:///data.db")

url_regex = re.compile(r"^(https?:\/\/[\w\-\.]+\.[a-z]{2,20}\/[\w\-]+\/[\w\-]+)$", re.I)

def get_db():
    db = getattr(g, '_database', None)
    if db is None:
        db = g._database = dataset.connect(DATABASE_URL)
    return db

def init_db():
    with app.app_context():
        db = get_db()
        fresh_db = False
Пример #13
0
class MyTestCase(unittest.TestCase):
    def setUp(self):
        self.b = Teleflask(api_key=None,
                           app=None,
                           hostname="localhost",
                           debug_routes=False,
                           disable_setting_webhook_telegram=True,
                           disable_setting_webhook_route=True)
        self.b._bot = BotMock('FAKE_API_KEY', return_python_objects=True)
        self.d = SilentDriver()
        self.m = TeleStateMachine(__name__, self.d, self.b)
        self.s = TeleState('LITTLEPIP')
        self.b.init_bot()

    # end def

    def test_invalid_name_lowercase(self):
        self.assertFalse(state.can_be_name('penis'))

    # end def

    def test_invalid_name_none(self):
        self.assertFalse(state.can_be_name(''))

    # end def

    def test_invalid_name_special_char_dash(self):
        self.assertFalse(state.can_be_name('FOO-BAR'))

    # end def

    def test_invalid_name_special_char_dot(self):
        self.assertFalse(state.can_be_name('FOO.BAR'))

    # end def

    def test_defaults(self):
        self.assertIsInstance(self.m.DEFAULT, TeleState)
        self.assertEqual(self.m.DEFAULT.name, 'DEFAULT')
        self.assertEqual(self.m.DEFAULT.machine, self.m)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)

    # end def

    def test_invalid_state_name(self):
        with self.assertRaises(ValueError) as context:
            s = TeleState('ponies')
        # end def

    # end def

    def test_add_state(self):
        self.assertEqual(self.s.name, 'LITTLEPIP')
        self.m.BEST_PONY = self.s
        self.assertEqual(self.m.BEST_PONY.name, 'BEST_PONY')

    # end def

    def test_switch_state(self):
        self.s = TeleState('LITTLEPIP')
        self.assertEqual(self.s.name, 'LITTLEPIP')
        self.m.BEST_PONY = self.s
        self.assertEqual(self.m.BEST_PONY.name, 'BEST_PONY')
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.CURRENT.name, 'DEFAULT')
        self.m.set(self.s)
        self.assertEqual(self.m.CURRENT, self.s)
        self.assertEqual(self.m.CURRENT.name, 'BEST_PONY')

    # end def

    def test_updates_parent_not_implemented(self):
        update = Update(1)
        m = TeleStateMachine('a', database_driver=TeleStateDatabaseDriver())
        with self.assertRaises(
                NotImplementedError,
                msg=
                "should require subclasses to implement load_state_for_chat_user"
        ):
            m.database_driver.load_state_for_chat_user(0, 0)
        # end with

        with self.assertRaises(
                NotImplementedError,
                msg=
                "should require subclasses to implement save_state_for_chat_user"
        ):
            m.database_driver.save_state_for_chat_user(0, 0, "", None)
        # end with

    # end def

    def test_updates(self):
        self.m.BEST_PONY = self.s
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.CURRENT.name, 'DEFAULT')
        update = Update(1)
        called = [False, False]

        def call_me(i):
            def call_me_inner(u):
                self.assertEqual(u, update)
                called[i] = True

            # end def
            return call_me_inner

        # end def

        self.m.DEFAULT.on_update()(call_me(0))
        self.m.BEST_PONY.on_update()(call_me(1))

        self.m.BEST_PONY.activate()
        self.assertEqual(self.m.CURRENT, self.s)
        self.assertEqual(self.m.CURRENT, self.m.BEST_PONY)
        self.assertEqual(self.m.CURRENT.name, 'BEST_PONY')

        self.m.process_update(update)
        self.assertEqual(
            self.m.CURRENT, self.m.DEFAULT,
            "load_state_for_chat_user should set DEFAULT (None) state again.")
        self.assertEqual(
            self.m.CURRENT.name, 'DEFAULT',
            "load_state_for_chat_user should set DEFAULT (None) state again.")
        self.assertTrue(
            called[0],
            'DEFAULT should have been called: load_state_for_chat_user set DEFAULT (None) state again.'
        )
        self.assertFalse(
            called[1],
            'BEST_PONY should not have been called: load_state_for_chat_user set DEFAULT (None) state again.'
        )

    # end def

    # end def

    def test_commands(self):
        self.m.BEST_PONY = self.s
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.CURRENT.name, 'DEFAULT')

        update = Update(1,
                        message=Message(2,
                                        date=int(time.time()),
                                        from_peer=User(3, False, "Günter"),
                                        chat=Chat(4, 'supergroup',
                                                  'FAKE CHAT'),
                                        text='/start'))
        called = [False, False]

        def call_me(i):
            def call_me_inner(u, text):
                logger.info('called {i}.'.format(i=i))
                self.assertEqual(u, update)
                called[i] = True

            # end def
            return call_me_inner

        # end def

        self.m.DEFAULT.command('start')(call_me(0))
        self.m.BEST_PONY.command('start')(call_me(1))

        self.m.BEST_PONY.activate()
        self.assertEqual(self.m.CURRENT, self.s)
        self.assertEqual(self.m.CURRENT, self.m.BEST_PONY)
        self.assertEqual(self.m.CURRENT.name, 'BEST_PONY')

        self.m.process_update(update)
        self.assertEqual(
            self.m.CURRENT, self.m.DEFAULT,
            "load_state_for_chat_user should set DEFAULT (None) state again.")
        self.assertEqual(
            self.m.CURRENT.name, 'DEFAULT',
            "load_state_for_chat_user should set DEFAULT (None) state again.")
        self.assertTrue(
            called[0],
            'DEFAULT should have been called: load_state_for_chat_user set DEFAULT (None) state again.'
        )
        self.assertFalse(
            called[1],
            'BEST_PONY should not have been called: load_state_for_chat_user set DEFAULT (None) state again.'
        )

    # end def

    def test_data_setter(self):
        test_data = ['something', 'json-ish']
        self.m.CURRENT.set_data(test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)
        self.assertEqual(self.m.DEFAULT.data, test_data)

    # end def

    def test_data_state_activate(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.m.BEST_PONY.activate(test_data)
        self.assertEqual(self.m.BEST_PONY.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

    # end def

    def test_data_statemachine_set(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.m.set('BEST_PONY', data=test_data)
        self.assertEqual(self.m.BEST_PONY.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

    # end def

    def test_data_statemachine_set_new_state(self):
        self.m.register_state('BEST_PONY', self.s)
        test_data = ['something', 'json-ish']
        self.m.set(self.s, data=test_data)
        self.assertEqual(self.m.BEST_PONY.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

    # end def

    def test_data_statemachine_set_new_state_data_in_state_ignored(self):
        self.m.register_state('BEST_PONY', self.s)
        test_data = ['something', 'json-ish']
        self.s = TeleState('LITTLEPIP')
        self.s.set_data(test_data)
        self.assertEqual(self.s.data, test_data, 'we manually set the data')
        self.m.register_state('LITTLEPIP', self.s)
        self.m.set(self.s)
        self.assertEqual(self.m.LITTLEPIP.data, None)
        self.assertEqual(self.m.CURRENT.data, None)

    # end def

    def test_data_statemachine_data_lost_after_switch_activate(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)

        self.m.DEFAULT.set_data(data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

        self.m.BEST_PONY.activate()
        self.assertEqual(self.m.CURRENT, self.m.BEST_PONY)
        self.assertEqual(self.m.BEST_PONY.data, None,
                         "never set data for this state")
        self.assertEqual(self.m.CURRENT.data, None,
                         "never set data for this state")

        self.m.DEFAULT.activate()
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, None,
                         "should have reset data with None")
        self.assertEqual(self.m.CURRENT.data, None,
                         "should have reset data with None")

    # end def

    def test_data_statemachine_data_lost_after_switch_set_reference(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)

        self.m.DEFAULT.set_data(data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

        self.m.set(self.m.BEST_PONY)
        self.assertEqual(self.m.CURRENT, self.m.BEST_PONY)
        self.assertEqual(
            self.m.BEST_PONY.data, test_data,
            "never set data for this state, should keep old state data")
        self.assertEqual(
            self.m.CURRENT.data, test_data,
            "never set data for this state, should keep old state data")

        self.m.set(self.m.DEFAULT)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(
            self.m.DEFAULT.data, test_data,
            "should have reset data with None, should keep old state data")
        self.assertEqual(
            self.m.CURRENT.data, test_data,
            "should have reset data with None, should keep old state data")

    # end def

    def test_data_statemachine_data_lost_after_switch_set_str(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)

        self.m.DEFAULT.set_data(data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

        self.m.set("BEST_PONY")
        self.assertEqual(self.m.CURRENT, self.m.BEST_PONY)
        self.assertEqual(
            self.m.BEST_PONY.data, test_data,
            "never set data for this state, should keep previous data")
        self.assertEqual(
            self.m.CURRENT.data, test_data,
            "never set data for this state, should keep previous data")

        self.m.set("DEFAULT")
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data,
                         "should keep data around")
        self.assertEqual(self.m.CURRENT.data, test_data,
                         "should keep data around")

    # end def

    def test_data_statemachine_data_lost_after_switch_activate_self(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)

        self.m.DEFAULT.set_data(data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

        self.m.DEFAULT.activate()
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, None,
                         "should have reset data with None")
        self.assertEqual(self.m.CURRENT.data, None,
                         "should have reset data with None")

        self.m.DEFAULT.activate(data=test_data)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

    # end def

    def test_data_statemachine_data_lost_after_switch_set_reference_self(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)

        self.m.DEFAULT.set_data(data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

        self.m.set(self.m.DEFAULT)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data,
                         "should not reset data with None")
        self.assertEqual(self.m.CURRENT.data, test_data,
                         "should not reset data with None")

        self.m.set(self.m.DEFAULT, data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

    # end def

    def test_data_statemachine_data_lost_after_switch_set_str_self(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)

        self.m.DEFAULT.set_data(data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

        self.m.set("DEFAULT")
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data,
                         "should have copied over data")
        self.assertEqual(self.m.CURRENT.data, test_data,
                         "should have copied over data")

        self.m.set("DEFAULT", data=None)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, None,
                         "should have reset data with None")
        self.assertEqual(self.m.CURRENT.data, None,
                         "should have reset data with None")

        self.m.set("DEFAULT", data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

    # end def

    def test_data_statemachine_data_lost_after_switch_set_self_None(self):
        self.m.BEST_PONY = self.s
        test_data = ['something', 'json-ish']
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)

        self.m.DEFAULT.set_data(data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

        self.m.set(None, None)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, None,
                         "should have reset data with None")
        self.assertEqual(self.m.CURRENT.data, None,
                         "should have reset data with None")

        self.m.set(None, data=test_data)
        self.assertEqual(self.m.CURRENT, self.m.DEFAULT)
        self.assertEqual(self.m.DEFAULT.data, test_data)
        self.assertEqual(self.m.CURRENT.data, test_data)

    # end def

    def test_AT_update(self):
        from unittest.mock import MagicMock
        self.d.load_state_for_chat_user: MagicMock = MagicMock(
            return_value=(None, None))
        self.d.save_state_for_chat_user: MagicMock = MagicMock(
            return_value=None)

        @self.m.DEFAULT.on_update('message')
        def asdf(update):
            return update

        # end def
        self.m.process_update(update1)
        self.d.load_state_for_chat_user.assert_called_with(
            update1.message.chat.id, update1.message.from_peer.id)
        self.d.save_state_for_chat_user.assert_called_with(
            update1.message.chat.id, update1.message.from_peer.id, 'DEFAULT',
            None)
Пример #14
0
# -*- coding: utf-8 -*-
from flask import Flask
from teleflask import Teleflask
from teleflask.messages import TextMessage, PlainMessage, MarkdownMessage, HTMLMessage

__author__ = 'luckydonald'

from somewhere import API_KEY  # I import it from some file which is kept private, not in git.
# Just set API_KEY = "your-api-key".
app = Flask(__name__)
bot = Teleflask(API_KEY)
bot.init_app(app)


@app.route("/")
def index():
    return "This is a normal Flask page."


# end def


# Register the /start command
@bot.command("start")
def start(update, text):
    # update is the update object. It is of type pytgbot.api_types.receivable.updates.Update
    # text is the text after the command. Can be empty. Type is str.
    return HTMLMessage("<b>Hello!</b> Thanks for using @" + app.username + "!")
    # return TextMessage("<b>Hello!</b> Thanks for using @" + app.username + "!", parse_mode="html")

Пример #15
0
class SomeTestCase(unittest.TestCase):
    def setUp(self):
        os.environ.setdefault("URL_HOSTNAME", "example.com")

        app = Flask(__name__)
        app.config.from_pyfile("testconfig.py")
        self.app = app
        self.app_test = app.test_client()  # get a test client
        self.bot = Teleflask(API_KEY, return_python_objects=True)

        # replace the :class:`pytgbot.Bot` instance with something testable. (not using TG server)
        # All methods now return the stuff they would sent to the telegram servers as json instead.
        # This is not usable with the :class:`teleflask.message.Message` (sub)types.
        self.bot.bot = BotTestable(
            API_KEY, return_python_objects=self.bot._return_python_objects)

        # Init must be before replacing the ``bot.bot``,
        # because else the :meth:`Bot.getWebhook` won't work as expected in startup.
        self.bot.init_app(app)

        # Array to hold information about the called callbacks:
        self.callbacks_status = {}

        # Get the update_path to be able to test via emulating incoming updates
        self.update_path, self.update_url = self.bot.calculate_webhook_url(
            hostname=self.bot.hostname,
            hostpath=self.bot.hostpath,
            hookpath=self.bot.hookpath)

    def tearDown(self):
        pass
        # os.close(self.db_fd)
        # os.unlink(flaskr.app.config['DATABASE'])

    # end def

    data_cmd = {
        "update_id": 10000,
        "message": {
            "message_id": 4458,
            "from": {
                "id": 1234,
                "first_name": "Test User",
                "username": "******"
            },
            "chat": {
                "id": 1234,
                "first_name": "Test User",
                "username": "******",
                "type": "private"
            },
            "date": 1487612335,
            "text": "/test 123",
            "entities": [{
                "type": "bot_command",
                "offset": 0,
                "length": 5
            }]
        }
    }

    def test_webhook(self):
        self.assertEqual(self.update_url.replace(API_KEY, "{API_KEY}"),
                         "https://example.com/income/{API_KEY}")

    # end def

    def test_command(self):
        @self.bot.command("test")
        def _callback_test_command(update, text):
            self.callbacks_status["_callback_test_command"] = text

        # end def

        self.app_test.post(self.update_path,
                           data=json.dumps(self.data_cmd),
                           content_type='application/json')

        self.assertIn("_callback_test_command", self.callbacks_status,
                      "@command('test') func executed")
        self.assertEquals(self.callbacks_status["_callback_test_command"],
                          "123")

    # end def

    def test_on_message(self):
        @self.bot.on_message
        def _callback_test_on_message(msg):
            self.callbacks_status["_callback_test_on_message"] = msg

        # end def

        self.app_test.post(self.update_path,
                           data=json.dumps(self.data_cmd),
                           content_type='application/json')

        self.assertIn("_callback_test_on_message", self.callbacks_status,
                      "@on_message func executed")
        msg = self.callbacks_status["_callback_test_on_message"]
        from pytgbot.api_types.receivable.updates import Message
        self.assertIsInstance(msg, Message)
        self.assertEquals(msg.to_array(), self.data_cmd["message"])

    # end def

    def test_on_message2(self):
        @self.bot.on_message("text")
        def _callback_test_on_message2(msg):
            self.callbacks_status["_callback_test_on_message2"] = msg

        # end def

        self.app_test.post(self.update_path,
                           data=json.dumps(self.data_cmd),
                           content_type='application/json')

        self.assertIn("_callback_test_on_message2", self.callbacks_status,
                      "@on_message('text') func executed")
        msg = self.callbacks_status["_callback_test_on_message2"]
        from pytgbot.api_types.receivable.updates import Message
        self.assertIsInstance(msg, Message)
        self.assertEquals(msg.to_array(), self.data_cmd["message"])

    # end def

    def test_on_message3(self):
        @self.bot.on_message("photo")
        def _callback_test_on_message3(msg):
            self.callbacks_status["_callback_test_on_message3"] = msg

        # end def

        self.app_test.post(self.update_path,
                           data=json.dumps(self.data_cmd),
                           content_type='application/json')

        self.assertNotIn("_callback_test_on_message3", self.callbacks_status,
                         "@on_message('photo') func not executed")
from .secrets import API_KEY, URL_HOSTNAME, URL_PATH

__author__ = 'luckydonald'

logger = logging.getLogger(__name__)
logging.add_colored_handler(level=logging.DEBUG)

POSSIBLE_CHAT_TYPES = ("supergroup", "group", "channel")
SEND_BACKOFF = 5

app = Flask(__name__)
app.register_blueprint(version_bp)
# sentry = add_error_reporting(app)

bot = Teleflask(API_KEY,
                hostname=URL_HOSTNAME,
                hostpath=URL_PATH,
                hookpath="/income/{API_KEY}")
bot.init_app(app)
bot.register_tblueprint(version_tbp)

assert_type_or_raise(bot.bot, Bot)
AT_ADMIN_REGEX = re.compile(".*([^\\w]|^)@(admins?)(\\W|$).*")


@app.errorhandler(404)
def url_404(error):
    return "Nope.", 404


# end def
Пример #17
0
API_KEY = os.getenv('TG_API_KEY', None)
assert (API_KEY is not None)  # TG_API_KEY environment variable

URL_HOSTNAME = os.getenv('URL_HOSTNAME', None)
# URL_HOSTNAME environment variable, can be None

URL_PATH = os.getenv('URL_PATH', None)
assert (URL_PATH is not None)  # URL_PATH environment variable

logger = logging.getLogger(__name__)
logging.add_colored_handler(level=logging.DEBUG)

app = Flask(__name__)

bot = Teleflask(API_KEY,
                hostname=URL_HOSTNAME,
                hostpath=URL_PATH,
                hookpath="/income/{API_KEY}")
bot.init_app(app)


@app.errorhandler(404)
def url_404(error):
    return "404.", 404


# end def


@app.route("/", methods=["GET", "POST"])
def url_root():
    return '<b>Hello world</b> from your <a href="https://github.com/luckydonald/docker-telegram-bot/">flask based telegram bot</b>.<br>' \
Пример #18
0
import os
from flask import Flask, Response
from teleflask import Teleflask
from teleflask.messages import TextMessage

app = Flask(__name__)

API_KEY = os.getenv("TELEGRAM_TOKEN")
bot = Teleflask(API_KEY, app)


@app.route("/api")
def index():
    return "This is awesome, isn't it?"


# end def


# Register the /start command
@bot.command("start")
def start(update, text):
    # update is the update object. It is of type pytgbot.api_types.receivable.updates.Update
    # text is the text after the command. Can be empty. Type is str.
    return TextMessage("<b>Hello!</b> Thanks for using @" + bot.username + "!",
                       parse_mode="html")


# end def