Beispiel #1
0
    async def run(
        self,
        bot: Bot,
        event: Event,
        state: T_State,
        stack: Optional[AsyncExitStack] = None,
        dependency_cache: Optional[T_DependencyCache] = None,
    ):
        try:
            await self.simple_run(bot, event, state, stack, dependency_cache)

        except RejectedException:
            await self.resolve_reject()
            type_ = await self.update_type(bot, event)
            permission = await self.update_permission(bot, event)

            Matcher.new(
                type_,
                Rule(),
                permission,
                self.handlers,
                temp=True,
                priority=0,
                block=True,
                plugin=self.plugin,
                module=self.module,
                expire_time=datetime.now() + bot.config.session_expire_timeout,
                default_state=self.state,
                default_parser=self.__class__._default_parser,
                default_type_updater=self.__class__._default_type_updater,
                default_permission_updater=self.__class__._default_permission_updater,
            )
        except PausedException:
            type_ = await self.update_type(bot, event)
            permission = await self.update_permission(bot, event)

            Matcher.new(
                type_,
                Rule(),
                permission,
                self.handlers,
                temp=True,
                priority=0,
                block=True,
                plugin=self.plugin,
                module=self.module,
                expire_time=datetime.now() + bot.config.session_expire_timeout,
                default_state=self.state,
                default_parser=self.__class__._default_parser,
                default_type_updater=self.__class__._default_type_updater,
                default_permission_updater=self.__class__._default_permission_updater,
            )
        except FinishedException:
            pass
Beispiel #2
0
    async def run(self, bot: "Bot", event: "Event", state: T_State):
        b_t = current_bot.set(bot)
        e_t = current_event.set(event)
        try:
            # Refresh preprocess state
            state_ = await self._default_state_factory(
                bot, event) if self._default_state_factory else self.state
            state_.update(state)

            for _ in range(len(self.handlers)):
                handler = self.handlers.pop(0)
                await self.run_handler(handler, bot, event, state_)

        except RejectedException:
            self.handlers.insert(0, handler)  # type: ignore
            Matcher.new(
                "message",
                Rule(),
                USER(event.get_session_id(),
                     perm=self.permission),  # type:ignore
                self.handlers,
                temp=True,
                priority=0,
                block=True,
                module=self.module,
                default_state=self.state,
                expire_time=datetime.now() + bot.config.session_expire_timeout)
        except PausedException:
            Matcher.new(
                "message",
                Rule(),
                USER(event.get_session_id(),
                     perm=self.permission),  # type:ignore
                self.handlers,
                temp=True,
                priority=0,
                block=True,
                module=self.module,
                default_state=self.state,
                expire_time=datetime.now() + bot.config.session_expire_timeout)
        except FinishedException:
            pass
        except StopPropagation:
            self.block = True
        finally:
            logger.info(f"Matcher {self} running complete")
            current_bot.reset(b_t)
            current_event.reset(e_t)
Beispiel #3
0
def sv_sw(name: str,
          usage: Union[str, Message, MessageSegment] = "",
          hierarchy: str = "top") -> Rule:
    """
    :Summary:
        
        使用此规则可以控制在不同群内的功能开关
    
    :Args:
        ``name``: 功能名字,使用相同name的功能以相同的开关控制
        ``usage``: 功能说明,可传入Message来添加图片信息
        ``hierarchy``: 层级,查看帮助时top以外的功能不会显示在总菜单中,而是在指定层级的功能中显示
    """

    if name not in func_ls:
        func_ls[name] = [usage, hierarchy]

    async def _checker(bot: Bot, event: GroupMessageEvent, state: T_State):
        if hasattr(event, 'group_id') and str(event.group_id) in group_func_off\
            and name in group_func_off[str(event.group_id)]:
            return False
        else:
            return True

    return Rule(_checker)
Beispiel #4
0
def check(command_name: str, event_type: Event = GroupMessageEvent) -> Rule:
    """Check the policy of each command by name."""
    _name = command_name

    async def _check(bot: Bot, event: Event, state: dict) -> bool:
        """Rule wrapper for "check" item in the policy control."""
        logger.debug('Checking command: [%s].' % _name)
        if not isinstance(event, event_type):
            return False

        bid = f'{event.self_id}'
        gid = f'{event.group_id}'
        sid = event.user_id
        try:
            # Check the whitelist policy by name.
            in_whitelist = ('+' not in policy_config[bid][gid][_name]
                            or sid in policy_config[bid][gid][_name]['+'])

            # Check the blacklist policy by name.
            not_in_blacklist = ('-' not in policy_config[bid][gid][_name] or
                                sid not in policy_config[bid][gid][_name]['-'])

            # Combine the whitelist and blacklist together
            return in_whitelist and not_in_blacklist
        except Exception:
            return True

    return Rule(_check)
Beispiel #5
0
def on_metaevent(
    rule: Optional[Union[Rule, T_RuleChecker]] = None,
    *,
    handlers: Optional[List[Union[T_Handler, Dependent]]] = None,
    temp: bool = False,
    priority: int = 1,
    block: bool = False,
    state: Optional[T_State] = None,
    _depth: int = 0,
) -> Type[Matcher]:
    """
    注册一个元事件响应器。

    参数:
        rule: 事件响应规则
        handlers: 事件处理函数列表
        temp: 是否为临时事件响应器(仅执行一次)
        priority: 事件响应器优先级
        block: 是否阻止事件向更低优先级传递
        state: 默认 state
    """
    matcher = Matcher.new(
        "meta_event",
        Rule() & rule,
        Permission(),
        temp=temp,
        priority=priority,
        block=block,
        handlers=handlers,
        plugin=_current_plugin.get(),
        module=_get_matcher_module(_depth + 1),
        default_state=state,
    )
    _store_matcher(matcher)
    return matcher
Beispiel #6
0
    def new(cls,
            type_: str = "",
            rule: Rule = Rule(),
            permission: Permission = Permission(),
            handlers: Optional[list] = None,
            temp: bool = False,
            priority: int = 1,
            block: bool = False,
            *,
            module: Optional[str] = None,
            default_state: Optional[dict] = None,
            expire_time: Optional[datetime] = None) -> Type["Matcher"]:
        """创建新的 Matcher

        Returns:
            Type["Matcher"]: 新的 Matcher 类
        """

        NewMatcher = type(
            "Matcher", (Matcher, ), {
                "module": module,
                "type": type_,
                "rule": rule,
                "permission": permission,
                "handlers": handlers or [],
                "temp": temp,
                "expire_time": expire_time,
                "priority": priority,
                "block": block,
                "_default_state": default_state or {}
            })

        matchers[priority].append(NewMatcher)

        return NewMatcher
Beispiel #7
0
    def raw_keyword(keyword: str) -> Rule:
        """Ensure the raw message contains the target keyword."""
        async def _raw_keyword(bot: Bot, event: Event, state: dict) -> bool:
            """Rule wrapper for raw_keyword."""
            return keyword in str(event.message)

        return Rule(_raw_keyword)
Beispiel #8
0
def to_me():
    if plugin_config.haruka_to_me:
        from nonebot.rule import to_me
        return to_me()
    async def _to_me(bot: Bot, event: Event, state: dict):
        return True
    return Rule(_to_me)
Beispiel #9
0
def check_banlist() -> Rule:
    '''
    检查目标是否存在于封禁名单

    :return: bool
    '''
    async def _chech_banlist(bot: Bot, event: Event, state: dict) -> bool:
        # 获取目标信息
        user = str(event.user_id)

        # 名单目录
        BAN_LIST_USER_PATH = Path(
            '.') / 'ATRI' / 'utils' / 'utils_rule' / 'ban_list_user.json'

        # 检查文件是否存在,如不存在,自动创建并写入默认值
        if not BAN_LIST_USER_PATH.is_file():
            with open(BAN_LIST_USER_PATH, 'w') as f:
                f.write(json.dumps({}))

        # 读取文件
        with open(BAN_LIST_USER_PATH, 'r') as f:
            data_user = json.load(f)

        return user not in data_user

    return Rule(_chech_banlist)
Beispiel #10
0
def check_white_list_all() -> Rule:
    """
    :说明:

        私聊消息全都上,群聊消息则判断是否为指定群聊

    :参数:

        无
    """
    async def _check(bot: Bot, event: Event, state: T_State) -> bool:
        if isinstance(event, GroupMessageEvent):
            if event.group_id in bot.config.GroupList.values():
                return True
            else:
                return False
        elif isinstance(event, PrivateMessageEvent):
            if event.message_type == 'private':
                return True
            else:
                return False
        else:
            return False

    return Rule(_check)  # type:ignore
Beispiel #11
0
def to_me():
    if config.haruka_to_me:
        from nonebot.rule import to_me
        return to_me()
    async def _to_me(bot: Bot, event: Event, state: T_State) -> bool:
        return True
    return Rule(_to_me)
Beispiel #12
0
def on(type: str = "",
       rule: Optional[Union[Rule, RuleChecker]] = None,
       permission: Optional[Permission] = None,
       *,
       handlers: Optional[List[Handler]] = None,
       temp: bool = False,
       priority: int = 1,
       block: bool = False,
       state: Optional[dict] = None) -> Type[Matcher]:
    """
    :说明:
      注册一个基础事件响应器,可自定义类型。
    :参数:
      * ``type: str``: 事件响应器类型
      * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
      * ``permission: Optional[Permission]``: 事件响应权限
      * ``handlers: Optional[List[Handler]]``: 事件处理函数列表
      * ``temp: bool``: 是否为临时事件响应器(仅执行一次)
      * ``priority: int``: 事件响应器优先级
      * ``block: bool``: 是否阻止事件向更低优先级传递
      * ``state: Optional[dict]``: 默认的 state
    :返回:
      - ``Type[Matcher]``
    """
    matcher = Matcher.new(type,
                          Rule() & rule,
                          permission or Permission(),
                          temp=temp,
                          priority=priority,
                          block=block,
                          handlers=handlers,
                          default_state=state)
    _tmp_matchers.add(matcher)
    return matcher
Beispiel #13
0
def on_metaevent(rule: Optional[Union[Rule, RuleChecker]] = None,
                 *,
                 handlers: Optional[List[Handler]] = None,
                 temp: bool = False,
                 priority: int = 1,
                 block: bool = False,
                 state: Optional[dict] = None) -> Type[Matcher]:
    """
    :说明:
      注册一个元事件响应器。
    :参数:
      * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则
      * ``handlers: Optional[List[Handler]]``: 事件处理函数列表
      * ``temp: bool``: 是否为临时事件响应器(仅执行一次)
      * ``priority: int``: 事件响应器优先级
      * ``block: bool``: 是否阻止事件向更低优先级传递
      * ``state: Optional[dict]``: 默认的 state
    :返回:
      - ``Type[Matcher]``
    """
    matcher = Matcher.new("meta_event",
                          Rule() & rule,
                          Permission(),
                          temp=temp,
                          priority=priority,
                          block=block,
                          handlers=handlers,
                          default_state=state)
    _tmp_matchers.add(matcher)
    return matcher
Beispiel #14
0
    def __init__(self,
                 type_: str = "",
                 rule: Optional[Rule] = None,
                 permission: Optional[Permission] = None,
                 handlers: Optional[list] = None,
                 temp: bool = False,
                 priority: int = 1,
                 block: bool = False,
                 *,
                 module: Optional[str] = None,
                 default_state: Optional[dict] = None,
                 expire_time: Optional[datetime] = None):
        """
        :说明:
          创建一个事件响应器组合,参数为默认值,与 ``Matcher.new`` 一致
        """
        self.matchers: List[Type[Matcher]] = []
        """
        :类型: ``List[Type[Matcher]]``
        :说明: 组内事件响应器列表
        """

        self.type = type_
        self.rule = rule or Rule()
        self.permission = permission or Permission()
        self.handlers = handlers
        self.temp = temp
        self.priority = priority
        self.block = block
        self.module = module
        self.expire_time = expire_time

        self._default_state = default_state

        self._default_parser: Optional[ArgsParser] = None
Beispiel #15
0
def chat_me() -> Rule:
    """
    :说明:

      通过 ``event.is_tome()`` 判断事件是否与机器人有关

    :参数:

      * 无
    """
    async def _chat_me(bot: "Bot", event: "Event", state: T_State) -> bool:
        if event.is_tome():
            try:
                if event.group_id:
                    group_id = event.group_id
            except:
                group_id = None
            try:
                if group_id in nonebot.get_driver().config.dict()['bangroup']:
                    logger.info('{} 处在黑名单,拒绝回复'.format(group_id))
                    return False
                if event.user_id in nonebot.get_driver().config.dict(
                )['bangroup']:
                    logger.info('{} 处在黑名单,拒绝回复'.format(event.user_id))
                    return False
            except:
                return True
            return True
        else:
            return False

    return Rule(_chat_me)
Beispiel #16
0
    def on_request(self, docs: str, block: bool = True) -> Type[Matcher]:
        a = 0
        cmd_list = self._load_cmds()
        while True:
            _type = "request" + str(a)
            if _type not in cmd_list:
                break
            else:
                a += 1

        cmd_list[_type] = CommandInfo(type=_type, docs=docs,
                                      aliases=list()).dict()
        self._save_cmds(cmd_list)

        matcher = Matcher.new(
            "request",
            Rule() & self.rule,
            Permission(),
            temp=self.temp,
            priority=self.priority,
            block=block,
            handlers=self.handlers,
            default_state=self.state,
        )
        return matcher
Beispiel #17
0
    async def run(self, bot: Bot, event: Event, state: dict):
        b_t = current_bot.set(bot)
        e_t = current_event.set(event)
        try:
            # Refresh preprocess state
            self.state.update(state)

            for _ in range(len(self.handlers)):
                handler = self.handlers.pop(0)
                annotation = typing.get_type_hints(handler)
                BotType = annotation.get("bot")
                if BotType and inspect.isclass(BotType) and not isinstance(
                        bot, BotType):
                    continue
                await handler(bot, event, self.state)

        except RejectedException:
            self.handlers.insert(0, handler)  # type: ignore
            Matcher.new(
                self.type,
                Rule(),
                USER(event.user_id, perm=self.permission),  # type:ignore
                self.handlers,
                temp=True,
                priority=0,
                block=True,
                module=self.module,
                default_state=self.state,
                expire_time=datetime.now() + bot.config.session_expire_timeout)
        except PausedException:
            Matcher.new(
                self.type,
                Rule(),
                USER(event.user_id, perm=self.permission),  # type:ignore
                self.handlers,
                temp=True,
                priority=0,
                block=True,
                module=self.module,
                default_state=self.state,
                expire_time=datetime.now() + bot.config.session_expire_timeout)
        except FinishedException:
            pass
        finally:
            logger.info(f"Matcher {self} running complete")
            current_bot.reset(b_t)
            current_event.reset(e_t)
Beispiel #18
0
def on_metaevent(rule: Union[Rule, RuleChecker] = Rule(),
                 *,
                 handlers: Optional[List[Handler]] = None,
                 temp: bool = False,
                 priority: int = 1,
                 block: bool = False,
                 state: Optional[dict] = None) -> Type[Matcher]:
    matcher = Matcher.new("meta_event",
                          Rule() & rule,
                          Permission(),
                          temp=temp,
                          priority=priority,
                          block=block,
                          handlers=handlers,
                          default_state=state)
    _tmp_matchers.add(matcher)
    return matcher
Beispiel #19
0
def check_switch(func_name: str, notice: bool) -> Rule:
    async def _check_switch(bot: Bot, event: GroupMessageEvent,
                            state: dict) -> bool:
        # 获取目标信息
        group = event.group_id
        return check_control_function(func_name, group)

    return Rule(_check_switch)
Beispiel #20
0
def ckimg(file: str) -> Rule:
    async def _ckimg(bot: Bot, event: Event, state: dict) -> bool:
        for seg in event.message:
            if seg.type == "image" and seg.data["file"] == file:
                return True
        return False

    return Rule(_ckimg)
Beispiel #21
0
def on_notice(rule: Union[Rule, RuleChecker] = Rule(),
              *,
              handlers=[],
              temp=False,
              priority: int = 1,
              block: bool = False,
              state={}) -> Type[Matcher]:
    matcher = Matcher.new("notice",
                          Rule() & rule,
                          Permission(),
                          temp=temp,
                          priority=priority,
                          block=block,
                          handlers=handlers,
                          default_state=state)
    _tmp_matchers.add(matcher)
    return matcher
Beispiel #22
0
def on_message(rule: Union[Rule, RuleChecker] = Rule(),
               permission: Permission = Permission(),
               *,
               handlers: Optional[list] = None,
               temp: bool = False,
               priority: int = 1,
               block: bool = True,
               state: Optional[dict] = None) -> Type[Matcher]:
    matcher = Matcher.new("message",
                          Rule() & rule,
                          permission,
                          temp=temp,
                          priority=priority,
                          block=block,
                          handlers=handlers,
                          default_state=state)
    _tmp_matchers.add(matcher)
    return matcher
Beispiel #23
0
def is_in_service(service: str) -> Rule:
    async def _is_in_service(bot, event, state) -> bool:
        user = str(event.user_id)
        if isinstance(event, GroupMessageEvent):
            return sv.auth_service(service, user, str(event.group_id))
        else:
            return sv.auth_service(service, user, None)

    return Rule(_is_in_service)
Beispiel #24
0
def keyword(*keywords: str, normal: bool = True) -> Rule:
    async def _keyword(bot: Bot, event: CQEvent, state: T_State) -> bool:
        if event.get_type() != "message":
            return False
        text = event.get_plaintext()
        if normal:
            text = normalize_str(text)
        return bool(text and any(kw in text for kw in keywords))
    return Rule(_keyword)
Beispiel #25
0
    def simple_command(cmd: str, aliases: set = None) -> Rule:
        """Recognize a command that does not contain any parameters."""
        commands = set([cmd]) | (aliases or set())  # generate the commands

        async def _simple_command(bot: Bot, event: Event, state: dict) -> bool:
            """Rule wrapper for simple_command."""
            return str(event.message).strip() in commands

        return Rule(_simple_command)
Beispiel #26
0
def check_sepi() -> Rule:
    """检查目标是否是涩批"""
    async def _check_sepi(bot: Bot, event: Event, state: dict) -> bool:
        if event.user_id in SP_list:
            await bot.send(event, "你可少冲点吧!涩批!哼唧")
            return False
        else:
            return True

    return Rule(_check_sepi)
Beispiel #27
0
def isPixivURL() -> Rule:
    async def isPixivURL_(bot: "Bot", event: "Event", state: T_State) -> bool:
        if event.get_type() != "message":
            return False
        msg = str(event.get_message())
        if re.findall("https://www.pixiv.net/artworks/(\d+)|illust_id=(\d+)",
                      msg):
            return True
        return False

    return Rule(isPixivURL_)
Beispiel #28
0
 def check_service(self, only_to_me: bool = False, only_group: bool = True) -> Rule:
     async def _cs(bot: Bot, event: CQEvent, state: T_State) -> bool:
         if not 'group_id' in event.__dict__:
             return not only_group
         else:
             group_id = event.group_id
             return self.check_enabled(group_id) and not priv.check_block_group(group_id) and priv.check_priv(event, self.use_priv)
     rule = Rule(_cs)
     if only_to_me:
         rule = rule & (to_me())
     return rule
Beispiel #29
0
        def decorator(func: Callable):
            matcher = on_message(rule=Rule(fullmatch_checker), **kwargs)

            @wraps(func)
            @self._pre_check(only_to_me=only_to_me)
            async def wrapper(bot: Bot, event: Event, state: T_State):
                await func(bot, event)
                logger.info(
                    f'消息{event.get_session_id()}已被on_fullmatch处理器{func.__name__}处理。'
                )

            matcher.handle()(wrapper)
Beispiel #30
0
    def new(cls,
            type_: str = "",
            rule: Optional[Rule] = None,
            permission: Optional[Permission] = None,
            handlers: Optional[List[Handler]] = None,
            temp: bool = False,
            priority: int = 1,
            block: bool = False,
            *,
            module: Optional[str] = None,
            default_state: Optional[dict] = None,
            expire_time: Optional[datetime] = None) -> Type["Matcher"]:
        """
        :说明:

          创建一个新的事件响应器,并存储至 `matchers <#matchers>`_

        :参数:

          * ``type_: str``: 事件响应器类型,与 ``event.type`` 一致时触发,空字符串表示任意
          * ``rule: Optional[Rule]``: 匹配规则
          * ``permission: Optional[Permission]``: 权限
          * ``handlers: Optional[List[Handler]]``: 事件处理函数列表
          * ``temp: bool``: 是否为临时事件响应器,即触发一次后删除
          * ``priority: int``: 响应优先级
          * ``block: bool``: 是否阻止事件向更低优先级的响应器传播
          * ``module: Optional[str]``: 事件响应器所在模块名称
          * ``default_state: Optional[dict]``: 默认状态 ``state``
          * ``expire_time: Optional[datetime]``: 事件响应器最终有效时间点,过时即被删除

        :返回:

          - ``Type[Matcher]``: 新的事件响应器类
        """

        NewMatcher = type(
            "Matcher", (Matcher, ), {
                "module": module,
                "type": type_,
                "rule": rule or Rule(),
                "permission": permission or Permission(),
                "handlers": handlers or [],
                "temp": temp,
                "expire_time": expire_time,
                "priority": priority,
                "block": block,
                "_default_state": default_state or {}
            })

        matchers[priority].append(NewMatcher)

        return NewMatcher