Ejemplo n.º 1
0
def test_not_active_backend():
    app = Kutana()
    app.add_backend(Debug([], name="backend1", active=False))

    async def test():
        with patch('asyncio.ensure_future') as ensure_future:
            await app._on_start(None)
            ensure_future.assert_not_called

    asyncio.get_event_loop().run_until_complete(test())
Ejemplo n.º 2
0
def make_kutana(messages):
    app = Kutana()

    debug = Debug(
        messages=messages,
        on_complete=app.stop,
    )

    app.add_backend(debug)

    return app, debug
Ejemplo n.º 3
0
def test_happy_path():
    app = Kutana()

    # Simple echo plugin
    pl = Plugin("")

    @pl.on_messages()
    async def __(message, ctx):
        await ctx.reply(message.text)

    app.add_plugin(pl)

    # Simple debug backend
    debug = Debug(
        messages=[("message 1", 1), ("message 2", 2)],
        on_complete=app.stop,
    )

    app.add_backend(debug)

    # Run application
    app.run()

    # Check replies
    assert debug.answers[1] == [("message 1", (), {})]
    assert debug.answers[2] == [("message 2", (), {})]
Ejemplo n.º 4
0
def main():
    app = Kutana()
    # set_logger_level(logging.DEBUG)

    backend = Vkontakte(SHUF_SETTINGS['TOKEN'])
    app.add_backend(backend)
    app.config['settings'] = SHUF_SETTINGS
    app.config['prefixes'] = ('еш ', 'есб ', 'esb ', 'ешаф ', 'eshuf '
                              )  # ('шаф ', 'sb ', 'шб ', 'shuf ', 'shufbot ')
    app.config['inform_time'] = time(20, 50)  # 12:00
    app.config['votekick_time'] = 5 * 60
    init_db(app)

    app.add_plugins(load_plugins(os.path.join(os.curdir, 'bot', 'plugins')))

    return app
Ejemplo n.º 5
0
def test_incorrect_values():
    app = Kutana()

    with pytest.raises(ValueError):
        app.add_backend(None)

    with pytest.raises(ValueError):
        app.set_storage('permanent', None)

    with pytest.raises(ValueError):
        app.add_plugin(None)
Ejemplo n.º 6
0
def test_storages():
    app = Kutana()

    app.set_storage('permanent', MemoryStorage())

    assert app.get_storage('default')
    assert app.get_storage('permanent')
    assert not app.get_storage('temporary')
Ejemplo n.º 7
0
    def debug_controller(self, queue):
        if self.kutana is None:
            self.kutana = Kutana()

        self.controller = DebugController(*queue)

        self.kutana.add_controller(self.controller)

        self.plugin = Plugin()

        self.plugins = [self.plugin]

        try:
            yield self.plugin
        finally:
            for plugin in self.plugins:
                self.kutana.executor.register_plugins(plugin)

            self.kutana.run()

        self.assertEqual(self.target, self.controller.replies)
Ejemplo n.º 8
0
    def debug_manager(self, queue):
        if self.app is None:
            self.app = Kutana()

        self.manager = DebugManager(*queue)

        self.app.add_manager(self.manager)

        self.plugin = Plugin()

        self.plugins = [self.plugin]

        try:
            yield self.plugin
        finally:
            for plugin in self.plugins:
                self.app.register_plugins([plugin])

            self.app.run()

        self.assertEqual(self.target, self.manager.replies)
Ejemplo n.º 9
0
    def setUpClass(cls):
        try:
            with open("configuration_test.json") as o:
                cls.conf = json.load(o)

        except FileNotFoundError:
            cls.conf = {}

        if "vk_token" not in cls.conf:
            cls.conf["vk_token"] = os.environ.get("TEST_TOKEN", "")

        if "vk_utoken" not in cls.conf:
            cls.conf["vk_utoken"] = os.environ.get("TEST_UTOKEN", "")

        cls.messages_to_delete = set()

        if not cls.conf["vk_token"] or not cls.conf["vk_utoken"]:
            raise unittest.SkipTest("No authorization found for this tests.")

        async def get_receiver_coroutine_function(self):
            actual_reci = await self.original_get_receiver_coroutine_function()

            empty_if_done = [1]

            async def reci():
                if not empty_if_done:
                    raise ExitException

                empty_if_done.pop(0)

                cls.ureq("messages.setActivity",
                         type="typing",
                         peer_id=-self.group_id)

                cls.messages_to_delete.add(
                    str(
                        cls.ureq("messages.send",
                                 message="echo message",
                                 peer_id=-self.group_id,
                                 attachment="photo-164328508_456239017," * 2)))

                return await actual_reci()

            return reci

        VKController.original_get_receiver_coroutine_function = VKController.get_receiver_coroutine_function
        VKController.get_receiver_coroutine_function = get_receiver_coroutine_function

        cls.kutana = Kutana()

        cls.kutana.add_controller(
            VKController(token=cls.conf["vk_token"],
                         longpoll_settings={"message_typing_state": 1}))
Ejemplo n.º 10
0
    async def test():
        vk = VkontakteCallback("token")

        vk.start_server = noop
        vk._execute_loop = noop
        vk._update_group_data = noop
        vk.request = _request

        await vk.on_start(Kutana())

        assert vk.updates_queue
        assert len(calls) == 0
Ejemplo n.º 11
0
class KutanaTest(unittest.TestCase):
    def setUp(self):
        self.app = None
        self.target = []

    @contextmanager
    def debug_manager(self, queue):
        if self.app is None:
            self.app = Kutana()

        self.manager = DebugManager(*queue)

        self.app.add_manager(self.manager)

        self.plugin = Plugin()

        self.plugins = [self.plugin]

        try:
            yield self.plugin
        finally:
            for plugin in self.plugins:
                self.app.register_plugins([plugin])

            self.app.run()

        self.assertEqual(self.target, self.manager.replies)
Ejemplo n.º 12
0
def test_get_backend():
    app = Kutana()
    app.add_backend(Debug([], name="backend1"))
    app.add_backend(Debug([], name="backend2"))

    assert app.get_backend("backend1").name == "backend1"
    assert app.get_backend("backend2").name == "backend2"
    assert app.get_backend("backend3") is None
Ejemplo n.º 13
0
def make_kutana_no_run(backend_source=None):
    app = Kutana()
    app.storage = NaiveMemory()

    debug = Debug(messages=[])

    if backend_source:
        debug.get_identity = lambda: backend_source

    app.add_backend(debug)

    async def _handle_update(update):
        ctx = await Context.create(app=app,
                                   config={"prefixes": (".", )},
                                   update=update,
                                   backend=debug)

        return await app._handle_update(update, ctx)

    def handle_update(update):
        return app.get_loop().run_until_complete(_handle_update(update))

    return app, debug, handle_update
Ejemplo n.º 14
0
def test_add_plugins():
    added = []

    app = Kutana()
    assert app.get_plugins() == []

    app.add_plugin = lambda pl: added.append(pl)
    app.add_plugins(["a", "b", "c"])
    assert added == ["a", "b", "c"]
Ejemplo n.º 15
0
def test_kutana_shutdown():
    for exception in [Exception, KeyboardInterrupt]:
        app = Kutana()

        _shutdown = app._shutdown

        async def checker():
            checker._called += 1
            await _shutdown()

        checker._called = 0

        app._main_loop = MagicMock(side_effect=exception)
        app._shutdown = checker
        app.run()

        assert checker._called == 1
Ejemplo n.º 16
0
def test_kutana_shutdown():
    app = Kutana()

    async def trigger():
        raise KeyboardInterrupt

    _shutdown = app._shutdown
    async def checker():
        checker._called = True
        await _shutdown()
    checker._called = False

    app._main_loop = trigger
    app._shutdown = checker
    app.run()

    assert checker._called == True
Ejemplo n.º 17
0
Archivo: cli.py Proyecto: ekonda/kutana
def run():
    """
    This function runs kutana application using provided
    configuration and CLI options.

    Refer to its source to create more specific starter for
    your application.
    """

    # Parse provided arguments
    args = parser.parse_args()

    # Setup logger
    if args.debug:
        logger.set_logger_level(logging.DEBUG)

    # Import configuration
    if not os.path.isfile(args.config):
        logger.logger.error(f"Couldn't open confiuration file: {args.config}")
        exit(1)

    with open(args.config) as fh:
        config = yaml.safe_load(fh)

    # Create application
    app = Kutana()

    # Update configuration
    app.config.update(config)

    # Setup i18n
    set_default_language(config.get("language", "en"))
    load_translations(args.translations)

    # Add each backend from config
    add_backends(app, config.get("backends"))

    # Add each storage from config
    add_storages(app, config.get("storages"))

    # Load and register plugins from provided path
    app.add_plugins(load_plugins(args.plugins))

    # Run application
    app.run()
Ejemplo n.º 18
0
    def test_load_plugins(self):
        loaded_plugins = load_plugins("test/test_plugins/")
        loaded_plugins.sort(key=lambda plugin: plugin.name)

        self.assertEqual(len(loaded_plugins), 3)

        self.assertEqual(loaded_plugins[0].name, "Memory")
        self.assertEqual(loaded_plugins[1].name, "My file")
        self.assertEqual(loaded_plugins[2].name, "My file twice")

        app = Kutana()
        app.register_plugins(loaded_plugins)

        loop = asyncio.get_event_loop()

        loop.run_until_complete(app.startup())

        loop.run_until_complete(app.process(DebugManager(), "message"))

        self.assertEqual(loaded_plugins[0].memory, "message")
        self.assertEqual(loaded_plugins[1].my_file, ":)")
        self.assertEqual(loaded_plugins[2].my_file, ":):)")
Ejemplo n.º 19
0
from kutana import Kutana, VKController, load_plugins, load_configuration


# Create engine
kutana = Kutana()

# Create VKController
kutana.add_controller(
    VKController(token = "d6842a32a19fefc24f1ac19b17cba1c9243f4bf1ecdf426215d193d96135a111d0d537f6e2df8f1452482")
)

# Load and register plugins
kutana.executor.register_plugins(*load_plugins("/root/bot/example/"))

# Run engine
kutana.run()
Ejemplo n.º 20
0
def test_happy_path(mock_post):
    group_change_settings_update = {
        "type": "group_change_settings",
        "object": {
            "changes": {
                "screen_name": {"old_value": "", "new_value": "sdffff23f23"},
                "title": {"old_value": "Спасибо", "new_value": "Спасибо 2"}
            }
        }
    }

    raw_updates = [
        {},
        {"type": "present"},
        group_change_settings_update,
        MESSAGES["not_message"],
        MESSAGES["message"],
        MESSAGES[".echo"],
        MESSAGES[".echo chat"],
        MESSAGES[".echo wa"],
    ]

    answers = []
    updated_longpoll = []

    def acquire_updates(content_type=None):
        if not raw_updates:
            return {"updates": [], "ts": "100"}
        if updated_longpoll == [1]:
            return {"failed": 3}
        return {"updates": [raw_updates.pop(0)], "ts": "0"}

    mock_post.return_value.__aenter__.return_value.json = CoroutineMock(
        side_effect=acquire_updates
    )

    class _VkontakteLongpoll(VkontakteLongpoll):
        async def _get_response(self, method, kwargs={}):
            if method == "groups.setLongPollSettings":
                return {"response": 1}

            if method == "groups.getById":
                return {
                    "response": [
                        {"id": 1, "name": "group", "screen_name": "grp"},
                    ],
                }

            if method == "groups.getLongPollServer":
                updated_longpoll.append(1)
                return {
                    "response": {
                        "server": "s",
                        "key": "k",
                        "ts": "1",
                    },
                }

            if method == "execute":
                answers.extend(kwargs["code"].split("API.")[1:])
                return {
                    "response": [1] * kwargs["code"].count("API."),
                }

            print(method, kwargs)

    app = Kutana()

    vkontakte = _VkontakteLongpoll(token="token")

    app.add_backend(vkontakte)

    echo_plugin = Plugin("echo")

    @echo_plugin.on_commands(["echo", "ec"])
    async def __(message, ctx):
        assert ctx.resolve_screen_name
        assert ctx.reply

        await ctx.reply(message.text, attachments=message.attachments)

    app.add_plugin(echo_plugin)

    app.get_loop().call_later(
        delay=vkontakte.api_request_pause * 4,
        callback=app.stop,
    )

    app.run()

    assert vkontakte.group_name == "Спасибо 2"
    assert vkontakte.group_screen_name == "sdffff23f23"

    assert len(updated_longpoll) == 2

    answers.sort()
    assert len(answers) == 3
    assert '{"message": ".echo chat [michaelkrukov|Михаил]",' in answers[0]
    assert '{"message": ".echo wa",' in answers[1]
    assert 'attachment": ""' not in answers[1]
    assert '{"message": ".echo",' in answers[2]
Ejemplo n.º 21
0
import os
from pathlib import Path

from kutana import Kutana, load_plugins
from kutana.backends import Telegram
import dotenv

env = dotenv.dotenv_values() if Path(".env").exists() else os.environ

# Create application
app = Kutana()

# Add manager to application
app.add_backend(Telegram(env.get("TELEGRAM_TOKEN"), proxy=env.get("PROXY")))

# Load and register plugins
app.add_plugins(load_plugins("plugins/"))

if __name__ == "__main__":
    # Run application
    app.run()
Ejemplo n.º 22
0
import json

from kutana import Kutana, VKManager, load_plugins, TGManager

# Load configuration
with open("configuration.json") as fh:
    config = json.load(fh)

# Create application
app = Kutana()

# Add manager to application
app.add_manager(VKManager(config["vk_token"]))

app.add_manager(TGManager(config["tg_token"]))

# Load and register plugins
app.register_plugins(load_plugins("plugins/"))

if __name__ == "__main__":
    # Run application
    app.run()
Ejemplo n.º 23
0
def test_callback_setup():
    calls = []

    class _VkontakteCallback(VkontakteCallback):
        async def _execute_loop(self, loop):
            pass

        async def start_server(self):
            pass

        async def request(self, method, _timeout=None, **kwargs):
            return await self.raw_request(method, kwargs)

        async def _get_response(self, method, kwargs={}):
            calls.append([method, kwargs])

            if method == "groups.getById":
                return {
                    "response": [
                        {
                            "id": 1,
                            "name": "group",
                            "screen_name": "grp"
                        },
                    ],
                }

            if method == "groups.getCallbackServers":
                return {
                    "response": {
                        "items": [
                            {
                                "url": self._address,
                                "id": 1
                            },
                            {
                                "url": "123",
                                "title": "kutana@2"
                            },
                            {
                                "url": "abc",
                                "title": "kutana@3"
                            },
                        ]
                    }
                }

            if method == "groups.deleteCallbackServer":
                return {"response": "ok"}

            if method == "groups.addCallbackServer":
                return {"response": {"server_id": "10"}}

            if method == "groups.setCallbackSettings":
                assert kwargs["server_id"] == "10"
                return {"response": "ok"}

            print(method, kwargs)

    app = Kutana()

    async def test():
        vk = _VkontakteCallback("token", address="127.0.0.1:8080")

        await vk.on_start(app)

        assert vk.updates_queue
        assert len(calls) == 5

        await vk.on_shutdown(app)

    app.get_loop().run_until_complete(test())
Ejemplo n.º 24
0
from ai_dungeon import config
from ai_dungeon.storage.redis import RedisStorage
from kutana import Kutana, load_plugins
from kutana.backends import Vkontakte, Telegram

import logging

logging.basicConfig(level=logging.DEBUG)

# Create application
if config.REDIS_URL is not None:
    app = Kutana(storage=RedisStorage(config.REDIS_URL))
else:
    app = Kutana()

# Add manager to application
if config.TELEGRAM_TOKEN:
    app.add_backend(Telegram(token=config.TELEGRAM_TOKEN))
if config.VK_TOKEN:
    app.add_backend(Vkontakte(token=config.VK_TOKEN))

# Load and register plugins
app.add_plugins(load_plugins("plugins/"))

if __name__ == "__main__":
    # Run application
    app.run()
Ejemplo n.º 25
0
import json
from kutana import Kutana, load_plugins
from kutana.backends import Vkontakte

# Import configuration
with open("config.json") as fh:
    config = json.load(fh)

# Create application
app = Kutana()

# Add manager to application
app.add_backend(Vkontakte(token=config["vk_token"]))

# Load and register plugins
app.add_plugins(load_plugins("plugins/"))

if __name__ == "__main__":
    # Run application
    app.run()
Ejemplo n.º 26
0
def test_same_plugins_and_backends():
    app = Kutana()

    plugin = Plugin("")
    backend = Debug([])

    app.add_plugin(plugin)
    with pytest.raises(RuntimeError):
        app.add_plugin(plugin)

    app.add_backend(backend)
    with pytest.raises(RuntimeError):
        app.add_backend(backend)

    assert app.get_backends() == [backend]
Ejemplo n.º 27
0
def test_get_loop():
    app = Kutana()
    assert app._loop == app.get_loop()
Ejemplo n.º 28
0
import json

from kutana import (Kutana, TGManager, VKManager, load_plugins)

# Create engine
app = Kutana()

# Load configuration and available plugins
with open("config.json", "r") as fh:
    config = json.load(fh)

app.config["names"] = config["info"]["names"]

# Register plugins
app.register_plugins(load_plugins("plugins/"))

# Add managers from configuration
for manager_conf in config["managers"]:
    manager = None

    if manager_conf["type"] == "vkontakte":
        manager = VKManager

    elif manager_conf["type"] == "telegram":
        manager = TGManager

    if manager is None:
        raise ValueError("Unknown manager type: {}".format(
            manager_conf["type"]))

    kwargs = manager_conf
Ejemplo n.º 29
0
def test_add_backend():
    app = Kutana()

    with pytest.raises(ValueError):
        app.add_backend(None)
Ejemplo n.º 30
0
def test_happy_path():
    updates = [
        MESSAGES["not_message"],
        MESSAGES["message"],
        MESSAGES[".echo"],
        MESSAGES[".echo chat"],
        MESSAGES["/echo@bot chat"],
        MESSAGES["/echo chat"],
        MESSAGES[".echo@bot chat"],
        MESSAGES["_image"],
    ]

    answers = []

    class _Telegram(Telegram):
        async def _request(self, method, kwargs={}):
            if method == "getMe":
                return {
                    "first_name": "te",
                    "last_name": "st",
                    "username": "******"
                }

            if method == "getUpdates":
                if not updates:
                    return []
                return [updates.pop(0)]

            if method == "sendMessage":
                answers.append(("msg", kwargs["text"]))
                return 1

            if method == "sendPhoto":
                answers.append(("image", kwargs["photo"]))
                return 1

            print(method, kwargs)

    app = Kutana()

    telegram = _Telegram(token="token")

    app.add_backend(telegram)

    echo_plugin = Plugin("echo")

    @echo_plugin.on_commands(["echo", "ec"])
    async def _(message, ctx):
        await ctx.reply(message.text)

    @echo_plugin.on_attachments(["image"])
    async def _(message, ctx):
        await ctx.reply(message.text, attachments=message.attachments[0])

    app.add_plugin(echo_plugin)

    app.get_loop().call_later(
        delay=0.5,
        callback=app.stop,
    )

    app.run()

    answers.sort()
    assert len(answers) == 5
    assert answers[0][0] == "image"
    assert answers[1] == ("msg", ".echo")
    assert answers[2] == ("msg", ".echo chat")
    assert answers[3] == ("msg", "/echo chat")
    assert answers[4] == ("msg", "/echo chat")