# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['ayaka']

package_data = \
{'': ['*']}

install_requires = \
['nonebot-adapter-onebot>=2.1.3,<3.0.0',
 'nonebot2>=2.0.0b5,<3.0.0',
 'playwright>=1.27.1,<2.0.0']

setup_kwargs = {
    'name': 'nonebot-plugin-ayaka',
    'version': '0.3.6',
    'description': 'a useful plugin providing convinient tools for the development of textual game on QQ',
    'long_description': '# Ayaka 0.3.6\n针对Nonebot2框架 Onebot_v11协议的文字游戏开发辅助插件\n\n<img src="https://img.shields.io/badge/python-3.8%2B-blue">\n\n<b>注意：由于更新pypi的readme.md需要占用版本号，因此其readme.md可能不是最新的，强烈建议读者前往[github仓库](https://github.com/bridgeL/nonebot-plugin-ayaka)以获取最新版本的帮助</b>\n\n\n# 更新记录\n\n<details>\n<summary>更新记录</summary>\n\n## 0.3.0 \n借助contextvar内置模块，全部重写了之间的代码，现在它们被合并为一个单文件，并能实现ayaka插件先前提供的所有功能，但不幸的是，其无法兼容0.2.x的ayaka插件，需要代码迁移 \n## 0.3.1 \n规定了应用启动后的默认初始状态为 init \n## 0.3.2 \n增加了较为完善的注释 \n## 0.3.3 \n在本文档中更新了部分帮助\n## 0.3.5\n将ayaka_master集成进本插件中\n## 0.3.6\n**不兼容** \n\n修改了AyakaStorage和AyakaApp的两处方法：\n- plugin_storage\n- group_storage\n\n修改内容：\n\n取消了suffix参数，现在，你需要在最后一个name中指定suffix，否则，AyakaStorage中的path属性将指向一个文件夹\n\n迁移方式：\n\n`app.plugin_storage("name")` -> `app.plugin_storage("name.json")`\n\n`app.plugin_storage("test", "name", suffix=".txt") `-> `app.plugin_storage("test", "name.txt")`\n\n</details>\n\n# 安装\n\n1. `poetry add nonebot-plugin-ayaka` \n2. `poetry run playwright install chromium`\n3. `bot.py`无需修改，只要在ayaka衍生插件里正常导入就行：`from ayaka import AyakaApp`\n\n**ayaka衍生插件需要nonebot来加载**\n\n如果没有用到无头浏览器截图的功能，可忽略第二步\n\n\n## 配置\n\n推荐配置（非强制要求）\n```\nCOMMAND_START=["#"]\nCOMMAND_SEP=[" "]\n```\n\n# 快速了解\n\n通过ayaka插件，二次封装nonebot2提供的api，提供专用api，便于其他文字游戏插件的编写\n\n基于ayaka的衍生插件库 https://github.com/bridgeL/ayaka_plugins\n\n基于ayaka的小游戏合集 https://github.com/bridgeL/nonebot-plugin-ayaka-games\n\n基于ayaka的谁是卧底小游戏 https://github.com/bridgeL/nonebot-plugin-ayaka-who-is-suspect\n\n## 基本特性\n- 状态机\n- 命令隔离\n- 数据隔离\n\n## ayaka 内置插件\n\nayaka内部已安装一份特殊的综合管理插件，它基于ayaka插件而实现\n\n命令一览：\n- 启用/permit\n- 禁用/forbid\n- 插件/plugin\n- 状态/state\n- 帮助/help\n  \n所有ayaka衍生插件只需要编写app.help，就可以在用户输入 `#help <插件名>` 后获取该插件的帮助\n\n## 代码速看\n\n```python\n\n\'\'\'\n    hello world\n    \n    ayaka可以帮助你实现命令隔离\n\'\'\'\nfrom ayaka import AyakaApp\n\napp = AyakaApp("hello-world")\n\n# 你可以不写帮助\n# app.help\n\n\n# 桌面状态下\n@app.on_command("hw")\nasync def app_entrance():\n    await app.start()\n    # app运行后，进入指定状态(state = "world")\n    app.set_state("world")\n\n\n# 只有world状态可以退出，其他状态运行该指令均为返回world状态\n@app.on_state_command(["exit", "退出"], "*")\nasync def app_exit():\n    if app.state == "world":\n        await app.close()\n    else:\n        app.set_state("world")\n        await app.send("跳转到 world")\n\n\n# 对世界、月亮和太阳打个招呼\n@app.on_state_command("hi", ["world", "moon", "sun"])\nasync def hello():\n    await app.send(f"hello,{app.state}!")\n\n\n# 对世界、月亮和太阳来个大比兜\n@app.on_state_command("hit", "world")\nasync def hit():\n    await app.send("earthquake")\n\n\n@app.on_state_command("hit", "moon")\nasync def hit():\n    await app.send("moon fall")\n\n\n@app.on_state_command("hit", "sun")\nasync def hit():\n    await app.send("big bang!")\n\n\n# 跳转状态\n@app.on_state_command("jump", "*")\nasync def jump_to_somewhere():\n    if not app.arg:\n        await app.send("没有参数！")\n    else:\n        next_state = str(app.arg)\n        app.set_state(next_state)\n        await app.send(f"跳转到 [{next_state}]")\n```\n\n<img src="1.png" width="400">\n\n# 术语解释\n\n## 无状态应用\n\n例如，简单复读我说的话的应用\n\n那么对于该应用而言，我之前说了啥都是无所谓的，它只需要复读我当前正在说的这句就行了。也就是说，无论我曾经下达过什么指令，都不会影响到该应用的状态，它是永恒不变的，即无状态应用\n\n无状态应用在注册回调时，使用`app.on_command`和`app.on_text`即可\n\n## 有状态应用 \n\n例如，代码速看中的hello-world应用\n\n我发送hi指令时，应用需要根据自身的状态（earth/moon/sun）给出不同的响应，因此它是有状态应用\n\n有状态应用在注册回调时，需要使用`app.on_state_command`和`app.on_state_text`\n\n## 应用启用/禁用\n\n该应用（不管是`无状态应用`还是`有状态应用`）的指令是否可以响应\n\n比如禁用了hello-world应用后，当你发送`hw`时，bot将不会触发回调\n\n## 应用运行/关闭 \n\n是指`有状态应用`是否正在运行\n\n比如当前群聊并没有运行应用时，你发送`hw`，bot将运行hello-world应用\n\n## 单一应用原则\n\n一个群聊同一时间只能运行一个`有状态应用`，避免过于混乱的情形，如果想要运行另一个应用，请先关闭当前的应用\n\n`无状态应用`没有运行和关闭的概念，你发完指令，它立刻就会回应你\n\n# API\n\n## app属性一览表\n| 名称      | 类型                   | 功能                                           |\n| --------- | ---------------------- | ---------------------------------------------- |\n| intro     | `str`                  | 应用介绍（帮助dict中key为init所对应的value）   |\n| help      | `str`                  | 当前应用在当前状态下的帮助                     |\n| all_help  | `str`                  | 当前应用的所有帮助                             |\n| state     | `bool`                 | 当前应用的状态                                 |\n| valid     | `bool`                 | 应用在当前设备 是否被启用                      |\n| bot       | `Bot`                  | 当前机器人                                     |\n| group     | `AyakaGroup`           | 当前群组                                       |\n| event     | `MessageEvent`         | 当前消息事件                                   |\n| message   | `Message`              | 当前消息                                       |\n| arg       | `Message`              | 删除了命令后剩下的消息部分                     |\n| args      | `List[MessageSegment]` | 删除命令后，依照分隔符分割，并移除空数据       |\n| cmd       | `str`                  | 本次响应是针对哪个命令                         |\n| bot_id    | `int`                  | 当前机器人的qq号                               |\n| group_id  | `int`                  | 当前群聊的群号                                 |\n| user_id   | `int`                  | 当前消息的发送者的qq号                         |\n| user_name | `str`                  | 当前消息的发送者的群名片或昵称（优先为群名片） |\n| cache     | `AyakaCache`           | 为当前群组当前应用提供的独立缓存数据空间       |\n\n## app方法一览表\n| 名称             | 功能                                      | 是否异步 |\n| ---------------- | ----------------------------------------- | -------- |\n| start            | 运行应用                                  | 是       |\n| close            | 关闭应用                                  | 是       |\n| send             | 发送消息                                  | 是       |\n| send_many        | 发送合并转发消息                          | 是       |\n| t_send           | 定时器触发回调时所使用的专用发送消息方法  | 是       |\n| set_state        | 设置应用状态（在应用运行时可以设置）      | \\        |\n| on_command       | 注册桌面模式下的命令回调                  | \\        |\n| on_state_command | 注册应用运行时在不同状态下的命令回调      | \\        |\n| on_text          | 注册桌面模式下的消息回调                  | \\        |\n| on_state_text    | 注册应用运行时在不同状态下的消息回调      | \\        |\n| on_everyday      | 每日定时触发回调（东8区）                 | \\        |\n| on_interval      | 在指定的时间点后开始循环触发（东8区）     | \\        |\n| add_listener     | 为该群组添加对 指定私聊 的监听            | \\        |\n| remove_listener  | 移除该群组对 指定私聊/所有其他私聊 的监听 | \\        |\n\n# 如何编写ayaka衍生插件\n\n给出几份例程代码以帮助读者理解使用\n\n## 如何使用例程代码？\n以下两种方式皆可\n\n### 手动复制本文档中的代码\n你可以在nonebot工作目录的src/plugins中新建一个代码文件，手动复制代码进去，nonebot会在读到`bot.py`文件中的`nonebot.load_from_toml(...)`语句后导入该插件\n\n### 从仓库下载\n你也可以前往[ayaka衍生插件库](https://github.com/bridgeL/ayaka_plugins)，下载其中的example文件夹，放到nonebot工作目录下，然后在`bot.py`中添加`nonebot.load_plugin("example")`\n\n## 插件编写范例 echo\n\n```python\n\'\'\'\n    具有状态机的复读模块\n\'\'\'\nfrom ayaka import AyakaApp\n\napp = AyakaApp("echo")\n\n# 得益于ayaka内置插件 ayaka_master\n# 用户可通过#help命令展示插件帮助，只需编写app.help即可\napp.help = \'\'\'复读只因\n特殊命令一览：\n- reverse 开始说反话\n- back 停止说反话\n- exit 退出\n\'\'\'\n\n# 另一种写法\napp.help = {\n    "init": "复读只因\\n特殊命令一览：\\n- reverse 开始说反话\\n- exit 退出",\n    "reverse": "说反话模式\\n- back 停止说反话"\n}\n\n\n# 桌面状态下\n@app.on_command("echo")\nasync def app_entrance():\n    # 输入参数则复读参数（无状态响应\n    # > #echo hihi\n    # < hihi\n    if app.arg:\n        await app.send(app.arg)\n        return\n\n    # 没有输入参数则运行该应用\n    await app.start()\n\n\n# app运行后，进入初始状态(state = "init")\n\n# 正常复读\n@app.on_state_text()\nasync def repeat():\n    await app.send(app.message)\n\n\n# 任意状态均可直接退出\n@app.on_state_command(["exit", "退出"], "*")\nasync def app_exit():\n    await app.close()\n\n\n# 通过命令，跳转到reverse状态\n@app.on_state_command(["rev", "reverse", "话反说", "反", "说反话"])\nasync def start_rev():\n    app.set_state("reverse")\n    await app.send("开始说反话")\n\n\n# 反向复读\n@app.on_state_text("reverse")\nasync def reverse_echo():\n    msg = str(app.message)\n    msg = "".join(s for s in reversed(msg))\n    await app.send(msg)\n\n\n# 通过命令，跳转回初始状态\n@app.on_state_command("back", "reverse")\nasync def back():\n    app.set_state()\n    await app.send("话反说止停")\n```\n\n## 插件编写范例 a plus b\n\n```python\n\'\'\'\n    a + b \n    \n    各群聊间、各插件间，数据独立，互不影响；不需要自己再专门建个字典了\n\'\'\'\nfrom ayaka import AyakaApp\n\napp = AyakaApp("a-plus-b")\n\n\n@app.on_command("set_a")\nasync def set_a():\n    app.cache.a = int(str(app.arg)) if app.arg else 0\n    await app.send(app.cache.a)\n\n\n@app.on_command("set_b")\nasync def set_b():\n    app.cache.b = int(str(app.arg)) if app.arg else 0\n    await app.send(app.cache.b)\n\n\n@app.on_command("calc")\nasync def calc():\n    a = app.cache.a or 0\n    b = app.cache.b or 0\n    await app.send(str(a+b))\n```\n\n## 定时器 Timer\n\n注意，定时器触发回调时，由于缺乏消息激励源，app的大部分属性(bot、group、event、valid、cache、user_name等)将无法正确访问到，并且无法使用app.send方法，需要使用专用的t_send方法\n\n```python\n\'\'\'\n    整点报时\n\'\'\'\nfrom ayaka import AyakaApp\n\napp = AyakaApp("整点报时")\n\n\n@app.on_interval(60, s=0)\nasync def every_minute():\n    await app.t_send(bot_id=2317709898, group_id=666214666, message="小乐")\n\n\n@app.on_interval(3600, m=0, s=0)\nasync def every_hour():\n    await app.t_send(bot_id=2317709898, group_id=666214666, message="大乐")\n\n\n@app.on_everyday(h=23, m=59, s=59)\nasync def every_day():\n    await app.t_send(bot_id=2317709898, group_id=666214666, message="呃呃呃一天要结束了")\n\n```\n\n## 截图 playwright\n\n注意，win平台使用playwright时需要关闭fastapi的reload功能\n\n```python\n\n\'\'\'\n    can can baidu\n\'\'\'\n\nfrom pathlib import Path\nfrom ayaka import get_new_page, AyakaApp, MessageSegment\n\napp = AyakaApp("看看baidu")\n\n\n@app.on_command("ccb")\nasync def _():\n    async with get_new_page() as p:\n        await p.goto("http://www.baidu.com", wait_until="networkidle")\n        path = Path("test.png").absolute()\n        await p.screenshot(path=path)\n    image = MessageSegment.image(path)\n    await app.send(image)\n\n```\n\n## 自动分割消息\n\nayaka插件将会自动根据配置项中的分割符来分割消息，例如\n\n```\n#test a   b c\n```\n\n会在ayaka插件处理后变为\n\n```python\n@app.on_command("test")\nasync def _():\n    # 此时app身上的如下属性的值应该是：...\n    assert app.cmd == "test"\n    assert str(app.arg) == "a   b c"\n    assert str(app.args[0]) == "a"\n    assert str(app.args[1]) == "b"\n    assert str(app.args[2]) == "c"\n```\n\n# 未来计划\n提供aiosqlite数据库支持\n',
    'author': 'Su',
    'author_email': 'wxlxy316@163.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'https://github.com/bridgeL/nonebot-plugin-ayaka',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
