Exemplo n.º 1
0
    def require(self, module: str) -> Union[Channel, Any]:
        logger.debug(f"require {module}")

        if module in self.alive_channel_name_mapping:
            return self.alive_channel_name_mapping[module]

        channel = Channel(module)
        channel_token = channel_instance.set(channel)

        try:
            imported_module = importlib.import_module(module, module)
            channel._py_module = imported_module
            with self.behaviour_interface.require_context(module) as interface:
                for cube in channel.content:
                    try:
                        interface.allocate_cube(cube)
                    except:
                        logger.exception(f"an error occurred while loading the module's cube: {module}::{cube}")
                        raise
        finally:
            channel_instance.reset(channel_token)

        self.channels.append(channel)

        if self.broadcast:
            token = saya_instance.set(self)
            self.broadcast.postEvent(SayaModuleInstalled(
                module=module,
                channel=channel,
            ))
            saya_instance.reset(token)

        return channel
Exemplo n.º 2
0
    def require_resolve(self, module: str) -> Channel:
        """导入模块, 并注入 Channel, 模块完成内容注册后返回该 Channel

        Args:
            module (str): 需为可被当前运行时访问的 Python Module 的引入路径

        Returns:
            Channel: 已注册了内容的 Channel.
        """
        channel = Channel(module)
        channel_token = channel_instance.set(channel)

        try:
            imported_module = importlib.import_module(module, module)
            channel._py_module = imported_module
            with self.behaviour_interface.require_context(module) as interface:
                for cube in channel.content:
                    try:
                        interface.allocate_cube(cube)
                    except:
                        logger.exception(
                            f"an error occurred while loading the module's cube: {module}::{cube}"
                        )
                        raise
        finally:
            channel_instance.reset(channel_token)

        return channel
Exemplo n.º 3
0
    def create_main_channel(self) -> Channel:
        """创建不可被卸载的 `__main__` 主程序模块

        Returns:
            Channel: 属性 `name` 值为 `__main__`, 且无法被 `uninstall_channel` 卸载的模块.
        """
        may_current = self.channels.get("__main__")
        if may_current:
            return may_current

        main_channel = Channel("__main__")
        self.channels["__main__"] = main_channel

        if self.broadcast:
            from .event import SayaModuleInstalled

            token = saya_instance.set(self)
            self.broadcast.postEvent(
                SayaModuleInstalled(
                    module="__main__",
                    channel=main_channel,
                ))
            saya_instance.reset(token)

        return main_channel
Exemplo n.º 4
0
    def uninstall_channel(self, channel: Channel):
        """卸载指定的 Channel

        Args:
            channel (Channel): 需要卸载的 Channel

        Raises:
            TypeError: 提供的 Channel 不在本 Saya 实例内
            ValueError: 尝试卸载 __main__, 即主程序所属的模块
        """
        if channel not in self.channels.values():
            raise TypeError("assert an existed channel")

        if channel.module == "__main__":
            raise ValueError("main channel cannot uninstall")

        # TODO: builtin signal(async or sync)
        if self.broadcast:
            from .event import SayaModuleUninstall

            token = saya_instance.set(self)
            self.broadcast.postEvent(
                SayaModuleUninstall(
                    module=channel.module,
                    channel=channel,
                ))
            saya_instance.reset(token)

        with self.behaviour_interface.require_context(
                channel.module) as interface:
            for cube in channel.content:
                try:
                    interface.release_cube(cube)
                except:
                    logger.exception(
                        f"an error occurred while loading the module's cube: {channel.module}::{cube}"
                    )
                    raise

        del self.channels[channel.module]
        channel._py_module = None

        if sys.modules.get(channel.module):
            del sys.modules[channel.module]

        if self.broadcast:
            from .event import SayaModuleUninstalled

            token = saya_instance.set(self)
            self.broadcast.postEvent(
                SayaModuleUninstalled(module=channel.module, ))
            saya_instance.reset(token)
Exemplo n.º 5
0
 def create_main_channel(self) -> Channel:
     may_current = self.alive_channel_name_mapping.get("__main__")
     if may_current:
         return may_current
     main_channel = Channel("__main__")
     self.channels.append(main_channel)
     
     if self.broadcast:
         token = saya_instance.set(self)
         self.broadcast.postEvent(SayaModuleInstalled(
             module="__main__",
             channel=main_channel,
         ))
         saya_instance.reset(token)
     
     return main_channel
Exemplo n.º 6
0
    def reload_channel(self, channel: Channel) -> None:
        """重载指定的模块

        Args:
            channel (Channel): 指定需要重载的模块, 请使用 channels.get 方法获取

        Raises:
            TypeError: 没有给定需要被重载的模块(`channel` 与 `module` 都不给定)
            ValueError: 没有通过 `module` 找到对应的 Channel
        """
        self.uninstall_channel(channel)
        new_channel: Channel = self.require_resolve(channel.module)

        channel._name = new_channel._name
        channel._author = new_channel._author
        channel._description = new_channel._description
        channel._export = new_channel._export
        channel._py_module = new_channel._py_module
        channel.content = new_channel.content

        self.channels[channel.module] = channel
Exemplo n.º 7
0
from .api import query
from graia.application import GraiaMiraiApplication
from graia.application.entry import GroupMessage
from graia.application.group import Group, Member
from graia.application.message.chain import MessageChain
from graia.application.message.elements.internal import At, Plain
from graia.saya import Saya
from graia.saya.builtins.broadcast.behaviour import ListenerSchema
from graia.saya.channel import Channel

saya = Saya.current()
channel = Channel.current()

config = saya.current_env()["genshin"]


@channel.use(ListenerSchema(listening_events=[GroupMessage]))
async def genshin(
    app: GraiaMiraiApplication, group: Group, message: MessageChain, member: Member
):
    if message.asDisplay().startswith("!genshin "):
        uid = message.asDisplay().split(" ")[1]
        if len(uid) != 9:
            await app.sendGroupMessage(
                group, MessageChain.create([At(member.id), Plain(" Invalid uid!")])
            )
            return
        _s = await query(config["cookie"], uid)
        await app.sendGroupMessage(
            group, MessageChain.create([At(member.id), Plain(f" {_s}")])
        )