Пример #1
0
class VBMLRule(MessageRule):
    """  """

    _patcher = vbml.Patcher()
    _patterns: List[vbml.Pattern]

    def __init__(self,
                 pattern: Union[str, List[str]],
                 patcher: Optional[vbml.Patcher] = None,
                 flags: Optional[re.RegexFlag] = None) -> None:

        if isinstance(pattern, str):
            _patterns = [pattern]
        elif isinstance(pattern, list):
            _patterns = pattern
        else:
            _patterns = list(pattern)

        self._patterns = [vbml.Pattern(i, flags=flags) for i in _patterns]

        if patcher is not None:
            self._patcher = patcher

    def check(self, msg: Message) -> Optional[RuleResult]:
        for i in self._patterns:
            result = self._patcher.check(i, msg.text)
            if result is True:
                return self.ok()
            if isinstance(result, dict):
                return self.ok(*result.values())
Пример #2
0
    def __init__(
        self,
        pattern: Union[str, "vbml.Pattern", Iterable[Union[str,
                                                           "vbml.Pattern"]]],
        patcher: Optional["vbml.Patcher"] = None,
        flags: Optional[re.RegexFlag] = None,
    ):
        flags = flags or self.config.get("vbml_flags") or (re.MULTILINE
                                                           | re.DOTALL)

        if isinstance(pattern, str):
            pattern = [
                vbml.Pattern(pattern,
                             flags=flags or self.config.get("vbml_flags"))
            ]
        elif isinstance(pattern, vbml.Pattern):
            pattern = [pattern]
        elif isinstance(pattern, Iterable):
            pattern = [
                p if isinstance(p, vbml.Pattern) else vbml.Pattern(p,
                                                                   flags=flags)
                for p in pattern
            ]

        self.patterns = pattern
        self.patcher = patcher or self.config.get(
            "vbml_patcher") or vbml.Patcher()
Пример #3
0
    def __init__(self, **kwargs):
        self.message_view = MessageView()
        self.raw_update_view = RawUpdateView()

        self.custom_rules = kwargs.get("custom_rules") or DEFAULT_CUSTOM_RULES
        self.auto_rules: List["ABCRule"] = []

        self.rule_config: Dict[str, Any] = {
            "vbml_flags": re.MULTILINE,  # Flags for VBMLRule
            "vbml_patcher": vbml.Patcher(),  # Patcher for VBMLRule
        }
Пример #4
0
    def __init__(self, pattern: typing.Union["vbml.Pattern", str], patcher: typing.Optional["vbml.Patcher"] = None):
        if vbml is None:
            raise RuntimeError("you have to install vbml - pip install vbml")

        if patcher is None:
            self.patcher = vbml.Patcher()

        if isinstance(pattern, str):
            self.pattern = vbml.Patcher.get_current(no_error=False).pattern(pattern)
        elif isinstance(pattern, vbml.Pattern):
            self.pattern = pattern

        self._patcher = vbml.Patcher.get_current(no_error=False)
Пример #5
0
    def __init__(
        self,
        pattern: typing.Union["vbml.Pattern", str],
        patcher: typing.Optional["vbml.Patcher"] = None,
    ):
        if vbml is None:
            raise RuntimeError("you have to install vbml - pip install vbml")

        self.patcher: vbml.Patcher = patcher or vbml.Patcher()

        if isinstance(pattern, str):
            self.pattern = vbml.Pattern(pattern)
        elif isinstance(pattern, vbml.Pattern):
            self.pattern = pattern
Пример #6
0
    def __init__(self, **kwargs):
        # Default views are fixed in BotLabeler,
        # if you need to create your own implement
        # custom labeler
        self.message_view = MessageView()
        self.raw_event_view = RawEventView()

        self.custom_rules = kwargs.get("custom_rules") or DEFAULT_CUSTOM_RULES
        self.auto_rules: List["ABCRule"] = []

        # Rule config is accessible from every single custom rule
        self.rule_config: Dict[str, Any] = {
            "vbml_flags": re.MULTILINE,  # Flags for VBMLRule
            "vbml_patcher": vbml.Patcher(),  # Patcher for VBMLRule
        }
Пример #7
0
    def __init__(
        self,
        message_view: "ABCMessageView",
        raw_event_view: "ABCRawEventView",
        custom_rules: Optional[Dict[str, Type["ABCRule"]]] = None,
        auto_rules: Optional[List["ABCRule"]] = None,
    ):
        self.message_view = message_view
        self.raw_event_view = raw_event_view

        self.custom_rules = custom_rules or DEFAULT_CUSTOM_RULES
        self.auto_rules = auto_rules or []

        # Rule config is accessible from every single custom rule
        self.rule_config: Dict[str, Any] = {
            "vbml_flags": re.MULTILINE | re.DOTALL,  # Flags for VBMLRule
            "vbml_patcher": vbml.Patcher(),  # Patcher for VBMLRule
        }
Пример #8
0
async def test_rules(api: API):
    assert await base.FromPeerRule(123).check(fake_message(api, peer_id=123))
    assert not await base.FromUserRule().check(fake_message(api, from_id=-1))
    assert await base.VBMLRule("i am in love with <whom>", vbml.Patcher()).check(
        fake_message(api, text="i am in love with you")
    ) == {"whom": "you"}
    assert await base.FuncRule(lambda m: m.text.endswith("!")).check(
        fake_message(api, text="yes!")
    )
    assert not await base.PeerRule().check(fake_message(api, peer_id=1, from_id=1))
    assert await base.PayloadMapRule([("a", int), ("b", str)]).check(
        fake_message(api, payload=json.dumps({"a": 1, "b": ""}))
    )
    assert await base.PayloadMapRule([("a", int), ("b", [("c", str), ("d", dict)])]).check(
        fake_message(api, payload=json.dumps({"a": 1, "b": {"c": "", "d": {}}}))
    )
    assert await base.PayloadMapRule({"a": int, "b": {"c": str, "d": dict}}).check(
        fake_message(api, payload=json.dumps({"a": 1, "b": {"c": "", "d": {}}}))
    )
    assert await base.StickerRule(sticker_ids=[1, 2]).check(
        fake_message(api, attachments=[{"type": "sticker", "sticker": {"sticker_id": 2}}])
    )

    assert (
        await AndRule(base.FromPeerRule(123), base.FromPeerRule([1, 123])).check(
            fake_message(api, peer_id=123)
        )
        is not False
    )
    assert (
        await OrRule(base.FromPeerRule(123), base.FromPeerRule([1, 123])).check(
            fake_message(api, peer_id=1)
        )
        is not False
    )
    assert await NotRule(base.FromPeerRule(123)).check(fake_message(api, peer_id=1)) is not False
    assert await base.RegexRule(r"Hi .*?").check(fake_message(api, text="Hi bro")) == {"match": ()}
    assert await base.RegexRule("Hi (.*?)$").check(fake_message(api, text="Hi bro")) == {
        "match": ("bro",)
    }
    assert await base.RegexRule(r"Hi .*?").check(fake_message(api, text="Hi")) != {"match": ()}

    assert base.PayloadMapRule.transform_to_map({"a": int, "b": {"c": str, "d": dict}}) == [
        ("a", int),
        ("b", [("c", str), ("d", dict)]),
    ]
    assert await base.CommandRule("cmd", ["!", "."], 2).check(
        fake_message(api, text="!cmd test bar")
    ) == {"args": ("test", "bar")}
    assert (
        await base.CommandRule("cmd", ["!", "."], 2).check(fake_message(api, text="cmd test bar"))
        is False
    )

    # todo: if args are more than args_count do join excess args with last
    assert (
        await base.CommandRule("cmd", ["!", "."], 1).check(fake_message(api, text="cmd test bar"))
        is False
    )

    assert (
        await base.CommandRule("cmd", ["!", "."], 3).check(fake_message(api, text="cmd test bar"))
        is False
    )

    labeler = BotLabeler()
    labeler.vbml_ignore_case = True
    assert (
        await labeler.get_custom_rules({"text": "privet"})[0].check(
            fake_message(api, text="Privet")
        )
        == {}
    )
    labeler.vbml_ignore_case = False
    assert not await labeler.get_custom_rules({"text": "privet"})[0].check(
        fake_message(api, text="Private")
    )
    assert await base.PayloadRule({"cmd": "text"}).check(
        fake_message(api, payload='{"cmd":"text"}')
    )
    assert await base.PayloadRule([{"cmd": "text"}, {"cmd": "ne text"}]).check(
        fake_message(api, payload='{"cmd":"text"}')
    )
    s_mock_message = fake_message(api)
    s_mock_message.state_peer = StatePeer(peer_id=1, state=FirstMockState.MOCK)
    assert await base.StateRule(state=FirstMockState.MOCK).check(s_mock_message)
    assert not await base.StateRule(state=SecondMockState.MOCK).check(s_mock_message)
    assert await base.StateRule(state=None).check(fake_message(api))
    assert await base.StateGroupRule(state_group=None).check(fake_message(api))
    sg_mock_message = fake_message(api)
    sg_mock_message.state_peer = StatePeer(peer_id=1, state=FirstMockState.MOCK, payload={})
    assert await base.StateGroupRule(state_group=FirstMockState).check(sg_mock_message)
    assert not await base.StateGroupRule(state_group=SecondMockState).check(sg_mock_message)
Пример #9
0
    def __init__(
        self,
        tokens: Token = None,
        *,
        login: str = None,
        password: str = None,
        user_id: int = None,
        debug: typing.Union[str, bool] = True,
        loop: asyncio.AbstractEventLoop = None,
        expand_models: bool = True,
        mobile: bool = False,
        log_to_path: typing.Union[str, bool] = None,
        vbml_patcher: vbml.Patcher = None,
        mode: int = 234,
        only_asyncio_loop: bool = False,
        **context,
    ):
        self.__tokens = [tokens] if isinstance(tokens, str) else tokens

        self.context: dict = context

        if uvloop is not None:
            if not only_asyncio_loop:
                asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

        if login and password:
            self.__tokens = self.get_tokens(login, password)

        self.loop = loop or asyncio.get_event_loop()
        self.__debug: bool = debug
        self._api: UserApi = UserApi(self.__tokens)
        self.mode = mode

        self._expand_models: bool = expand_models
        self._patcher: vbml.Patcher = vbml_patcher or vbml.Patcher(
            pattern="^{}$")

        self.user_id: typing.Optional[int] = user_id or self.get_id_by_token(
            self.__tokens[0])

        self._api.user_id = user_id
        self.error_handler: VKErrorHandler = DefaultErrorHandler()
        UserApi.set_current(self._api)
        VKErrorHandler.set_current(self.error_handler)

        self.on: UserHandler = UserHandler()
        self.branch: ABCBranchGenerator = DictBranch()
        self.middleware: MiddlewareExecutor = MiddlewareExecutor()
        self.error_handler: VKErrorHandler = DefaultErrorHandler()
        self.deconstructed_handle: UserProcessor = UserProcessor(
            self.user_id, expand_models=expand_models)

        self._stop: bool = False
        self.status = UserStatus()

        if isinstance(debug, bool):
            debug = "INFO" if debug else "ERROR"

        self.logger = LoggerLevel(debug)
        logger.remove()
        logger.add(
            sys.stderr,
            colorize=True,
            format="<level>[<blue>VKBottle</blue>] {message}</level>",
            filter=self.logger,
            level=0,
            enqueue=mobile is False,
        )
        if log_to_path:
            logger.add(
                "log_user_{time}.log" if log_to_path is True else log_to_path,
                rotation="20 MB",
            )

        logger.info("Using JSON_MODULE - {}".format(USAGE))
        logger.info("Using asyncio loop - {}".format(
            asyncio.get_event_loop_policy().__class__.__module__))
Пример #10
0
async def test_rules(api: API):
    assert await rules.FromPeerRule(123).check(fake_message(api, peer_id=123))
    assert not await rules.FromUserRule().check(fake_message(api, from_id=-1))
    assert await rules.VBMLRule(
        "i am in love with <whom>",
        vbml.Patcher()).check(fake_message(api,
                                           text="i am in love with you")) == {
                                               "whom": "you"
                                           }
    assert await rules.FuncRule(lambda m: m.text.endswith("!")).check(
        fake_message(api, text="yes!"))
    assert not await rules.PeerRule(from_chat=True).check(
        fake_message(api, peer_id=1, from_id=1))
    assert await rules.PayloadMapRule([
        ("a", int), ("b", str)
    ]).check(fake_message(api, payload=json.dumps({
        "a": 1,
        "b": ""
    })))
    assert await rules.PayloadMapRule([("a", int),
                                       ("b", [("c", str), ("d", dict)])]
                                      ).check(
                                          fake_message(api,
                                                       payload=json.dumps({
                                                           "a": 1,
                                                           "b": {
                                                               "c": "",
                                                               "d": {}
                                                           }
                                                       })))
    assert await rules.PayloadMapRule({
        "a": int,
        "b": {
            "c": str,
            "d": dict
        }
    }).check(
        fake_message(api,
                     payload=json.dumps({
                         "a": 1,
                         "b": {
                             "c": "",
                             "d": {}
                         }
                     })))
    assert await rules.StickerRule(sticker_ids=[1, 2]).check(
        fake_message(api,
                     attachments=[{
                         "type": "sticker",
                         "sticker": {
                             "sticker_id": 2
                         }
                     }]))

    assert (await AndFilter(rules.FromPeerRule(123),
                            rules.FromPeerRule([1, 123])).check(
                                fake_message(api, peer_id=123)) is not False)
    assert (await
            OrFilter(rules.FromPeerRule(123),
                     rules.FromPeerRule([1, 123
                                         ])).check(fake_message(api,
                                                                peer_id=1))
            is not False)
    assert await rules.RegexRule(r"Hi .*?").check(
        fake_message(api, text="Hi bro")) == {
            "match": ()
        }
    assert await rules.RegexRule("Hi (.*?)$").check(
        fake_message(api, text="Hi bro")) == {
            "match": ("bro", )
        }
    assert not await rules.RegexRule(r"Hi .*?").check(
        fake_message(api, text="Hi")) == {
            "match": ()
        }
    assert rules.PayloadMapRule.transform_to_map({
        "a": int,
        "b": {
            "c": str,
            "d": dict
        }
    }) == [
        ("a", int),
        ("b", [("c", str), ("d", dict)]),
    ]

    labeler = BotLabeler()
    labeler.vbml_ignore_case = True
    assert (await labeler.get_custom_rules({"text": "privet"})
            [0].check(fake_message(api, text="Privet")) == {})
    labeler.vbml_ignore_case = False
    assert not await labeler.get_custom_rules({"text": "privet"})[0].check(
        fake_message(api, text="Private"))
    assert await rules.PayloadRule({
        "cmd": "text"
    }).check(fake_message(api, payload='{"cmd":"text"}'))
    assert await rules.PayloadRule([{
        "cmd": "text"
    }, {
        "cmd": "ne text"
    }]).check(fake_message(api, payload='{"cmd":"text"}'))
    assert await rules.StateRule(state=None).check(fake_message(api))
    assert not await rules.StateRule(state=MockIntEnum.MOCK).check(
        fake_message(api))
    assert await rules.StateGroupRule(state_group=None).check(fake_message(api)
                                                              )
    sg_mock_message = fake_message(api)
    sg_mock_message.state_peer = StatePeer(peer_id=1,
                                           state=MockIntEnum.MOCK,
                                           payload={})
    assert await rules.StateGroupRule(state_group=MockIntEnum
                                      ).check(sg_mock_message)
Пример #11
0
import re
from abc import abstractmethod
from typing import Union, List

import vbml

from tottle.types.mini import MessageMini
from tottle.dispatch.rules import ABCRule
from tottle.utils.enums import ChatType

VBML_PATCHER = vbml.Patcher()


class ABCMessageRule(ABCRule):
    @abstractmethod
    async def check(self, message: MessageMini) -> bool:
        pass


class FromChatRule(ABCMessageRule):
    async def check(self, message: MessageMini) -> bool:
        return message.chat.type in (ChatType.GROUP, ChatType.SUPERGROUP)


class PrivateMessageRule(ABCMessageRule):
    async def check(self, message: MessageMini) -> bool:
        return message.chat.type == ChatType.PRIVATE


class TextRule(ABCMessageRule):
    def __init__(