├── .github
└── workflows
│ └── pypi-publish.yml
├── .gitignore
├── LICENSE
├── README.md
├── nonebot_plugin_fishing
├── __init__.py
├── config.py
├── data_source.py
├── migrations
│ ├── 1be1c9b715a9_add_achievements.py
│ ├── 68463f3e5f33_.py
│ ├── 7609e6d106dd_init_db.py
│ ├── c5ab992c9af3_add_achievements.py
│ ├── e9015df43907_add_special_fishes_field.py
│ └── f70bdeaec7a4_add_specialfishes_table.py
└── model.py
├── pdm.lock
└── pyproject.toml
/.github/workflows/pypi-publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | push:
5 | tags:
6 | - '*'
7 | workflow_dispatch:
8 |
9 | jobs:
10 | pypi-publish:
11 | name: Upload release to PyPI
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@master
15 | - name: Set up Python
16 | uses: actions/setup-python@v1
17 | with:
18 | python-version: "3.x"
19 | - name: Install pypa/build
20 | run: >-
21 | python -m
22 | pip install
23 | build
24 | --user
25 | - name: Build a binary wheel and a source tarball
26 | run: >-
27 | python -m
28 | build
29 | --sdist
30 | --wheel
31 | --outdir dist/
32 | .
33 | - name: Publish distribution to PyPI
34 | uses: pypa/gh-action-pypi-publish@release/v1
35 | with:
36 | password: ${{ secrets.PYPI_API_TOKEN }}
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | share/python-wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | MANIFEST
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .nox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | *.py,cover
50 | .hypothesis/
51 | .pytest_cache/
52 | cover/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | .pybuilder/
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | # For a library or package, you might want to ignore these files since the code is
87 | # intended to run in multiple environments; otherwise, check them in:
88 | # .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # poetry
98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99 | # This is especially recommended for binary packages to ensure reproducibility, and is more
100 | # commonly ignored for libraries.
101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102 | #poetry.lock
103 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
104 | poetry.toml
105 |
106 | # pdm
107 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
108 | #pdm.lock
109 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
110 | # in version control.
111 | # https://pdm.fming.dev/#use-with-ide
112 | .pdm-python
113 |
114 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115 | __pypackages__/
116 |
117 | # Celery stuff
118 | celerybeat-schedule
119 | celerybeat.pid
120 |
121 | # SageMath parsed files
122 | *.sage.py
123 |
124 | # Environments
125 | .env
126 | .venv
127 | env/
128 | venv/
129 | ENV/
130 | env.bak/
131 | venv.bak/
132 |
133 | # Spyder project settings
134 | .spyderproject
135 | .spyproject
136 |
137 | # Rope project settings
138 | .ropeproject
139 |
140 | # mkdocs documentation
141 | /site
142 |
143 | # mypy
144 | .mypy_cache/
145 | .dmypy.json
146 | dmypy.json
147 |
148 | # Pyre type checker
149 | .pyre/
150 |
151 | # pytype static type analyzer
152 | .pytype/
153 |
154 | # Cython debug symbols
155 | cython_debug/
156 |
157 | # ruff
158 | .ruff_cache/
159 |
160 | # LSP config files
161 | pyrightconfig.json
162 |
163 | # PyCharm
164 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166 | # and can be added to the global gitignore or merged into this file. For a more nuclear
167 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168 | .idea/
169 |
170 | # VisualStudioCode
171 | .vscode/*
172 | !.vscode/settings.json
173 | !.vscode/tasks.json
174 | !.vscode/launch.json
175 | !.vscode/extensions.json
176 | !.vscode/*.code-snippets
177 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 C14H22O
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 |

5 |
6 |
7 |
8 |
9 | # nonebot-plugin-fishing
10 |
11 | _✨ 你甚至可以电子钓鱼 ✨_
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |

20 |
21 |
22 |
23 | ## 💿 安装
24 |
25 |
26 | 使用 nb-cli 安装
27 | 在 nonebot2 项目的根目录下打开命令行, 输入以下指令即可安装
28 |
29 | nb plugin install nonebot-plugin-fishing
30 |
31 |
32 |
33 |
34 | 使用包管理器安装
35 | 在 nonebot2 项目的插件目录下, 打开命令行, 根据你使用的包管理器, 输入相应的安装命令
36 |
37 |
38 | pip
39 |
40 | pip install nonebot-plugin-fishing
41 |
42 |
43 | pdm
44 |
45 | pdm add nonebot-plugin-fishing
46 |
47 |
48 | poetry
49 |
50 | poetry add nonebot-plugin-fishing
51 |
52 |
53 | conda
54 |
55 | conda install nonebot-plugin-fishing
56 |
57 |
58 | 打开 nonebot2 项目根目录下的 `pyproject.toml` 文件, 在 `[tool.nonebot]` 部分追加写入
59 |
60 | plugins = ["nonebot_plugin_fishing"]
61 |
62 |
63 |
64 | 注意:安装过后,需在控制台输入 `nb orm upgrade` 指令以初始化数据库。
65 |
66 | ## ⚙️ 配置
67 |
68 | 在 nonebot2 项目的`.env`文件中添加下表中的必填配置
69 |
70 | | 配置项 | 必填 | 说明 |
71 | |:-----:|:----:|:----:|
72 | | fishes | 否 | 配置鱼塘内鱼们的名称、权重、等待时间和价格 |
73 | | fishing_limit | 否 | 填入每次钓鱼后,限制钓鱼的秒数 |
74 | | fishing_coin_name | 否 | 填入卖鱼获取的货币名称 |
75 | | special_fish_enabled | 否 | 是否启用赛博放生功能(默认为否) |
76 | | special_fish_price | 否 | 每放生一次所需的货币数量 |
77 | | special_fish_probability | 否 | 钓鱼时钓到用户放生的鱼的概率 |
78 |
79 | 其中 `fishes` 配置项说明如下:
80 |
81 | ```dotenv
82 | FISHES='
83 | [
84 | {
85 | "name": "小鱼", # 鱼的名称
86 | "frequency": 2, # 鱼上钩的时间
87 | "weight": 100, # 权重
88 | "price": 2 # 价格
89 | }
90 | ]
91 | '
92 | ```
93 |
94 | ## 🔨 更新
95 |
96 | 每一次更新后,需执行 `nb orm upgrade`。
97 |
98 | 由于此前版本数据库迁移存在问题,故插件无法对 [v0.2.1](https://pypi.org/project/nonebot-plugin-fishing/0.2.1/) 版本及以前的数据进行迁移。
99 |
100 | ## 🎉 使用
101 |
102 | ### 指令表
103 | | 指令 | 范围 | 说明 |
104 | |:-----:|:----:|:----:|
105 | | 钓鱼 | 所有 | 放下鱼竿 |
106 | | 统计信息 | 所有 | 查看钓鱼次数 |
107 | | 背包 | 所有 | 查看背包 |
108 | | 卖鱼 | 所有 | 卖鱼 |
109 | | 余额 | 所有 | 查看当前余额 |
110 | | 放生 | 所有 | 赛博放生 |
111 |
112 | ### 赛博放生
113 |
114 | 当用户使用货币放生由自己取名的一条鱼后,每个用户在钓鱼时都有机会钓到那一条鱼。但此功能开关 `special_fish_enabled` 默认关闭,原因是用户生成内容如果不符合规范,可能导致出现不可预料的情况,请谨慎开启。
115 |
116 | ## 🔨 更新
117 |
118 | 每一次升级后,都需执行 `nb orm upgrade`。
119 |
120 | ## 📝 Todo
121 |
122 | - [x] 重写数据库逻辑(改为使用 [nonebot/plugin-orm](https://github.com/nonebot/plugin-orm))
123 | - [x] 增加系统商店,卖出钓到的鱼们
124 | - [ ] 赛博放生 [#4](https://github.com/C14H22O/nonebot-plugin-fishing/issues/4) (已基本完成)
125 | - [ ] 使用 [nonebot_plugin_chikari_economy](https://github.com/mrqx0195/nonebot_plugin_chikari_economy) 经济系统
126 | - [ ] 为鱼竿增加耐久度,耐久度为0时需重新购买鱼竿
127 | - [ ] 为钓鱼背包添加排序
128 | - [ ] 添加成就系统
129 |
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/__init__.py:
--------------------------------------------------------------------------------
1 | from nonebot import on_command, require
2 |
3 | require("nonebot_plugin_orm") # noqa
4 |
5 | from nonebot.plugin import PluginMetadata
6 | from nonebot.adapters import Event, Message
7 | from nonebot.params import CommandArg
8 | from nonebot.permission import SUPERUSER
9 |
10 | import asyncio
11 |
12 | from .config import Config, config
13 | from .data_source import (
14 | choice,
15 | can_fishing,
16 | can_catch_special_fish,
17 | can_free_fish,
18 | get_stats,
19 | save_fish,
20 | save_special_fish,
21 | get_backpack,
22 | sell_fish,
23 | get_balance,
24 | free_fish,
25 | random_get_a_special_fish,
26 | lottery,
27 | give,
28 | check_achievement,
29 | get_achievements
30 | )
31 |
32 | __plugin_meta__ = PluginMetadata(
33 | name="赛博钓鱼",
34 | description="你甚至可以电子钓鱼",
35 | usage="发送“钓鱼”,放下鱼竿。",
36 | type="application",
37 | homepage="https://github.com/ALittleBot/nonebot-plugin-fishing",
38 | config=Config,
39 | supported_adapters=None
40 | )
41 |
42 | fishing = on_command("fishing", aliases={"钓鱼"}, priority=5)
43 | stats = on_command("stats", aliases={"统计信息", "钓鱼统计信息"}, priority=5)
44 | backpack = on_command("backpack", aliases={"背包", "钓鱼背包"}, priority=5)
45 | sell = on_command("sell", aliases={"卖鱼"}, priority=5)
46 | balance = on_command("balance", aliases={"余额", "钓鱼余额"}, priority=5)
47 | free_fish_cmd = on_command("free_fish", aliases={"放生", "钓鱼放生"}, priority=5)
48 | lottery_cmd = on_command("lottery", aliases={"祈愿"}, priority=5)
49 | achievement_cmd = on_command("achievement", aliases={"成就", "钓鱼成就"}, priority=5)
50 | give_cmd = on_command("give", permission=SUPERUSER, priority=5)
51 |
52 |
53 | @fishing.handle()
54 | async def _(event: Event):
55 | user_id = event.get_user_id()
56 | if not await can_fishing(user_id):
57 | await fishing.finish("河累了, 休息一下吧")
58 | await fishing.send("正在钓鱼…")
59 | if await can_catch_special_fish():
60 | special_fish_name = await random_get_a_special_fish()
61 | result = f"你钓到了别人放生的 {special_fish_name}"
62 | await save_special_fish(user_id, special_fish_name)
63 | await fishing.finish(result)
64 | choice_result = choice()
65 | fish = choice_result[0]
66 | sleep_time = choice_result[1]
67 | result = f"钓到了一条{fish}, 你把它收进了背包里"
68 | await save_fish(user_id, fish)
69 | await asyncio.sleep(sleep_time)
70 | achievements = await check_achievement(user_id)
71 | if achievements is not None:
72 | for achievement in achievements:
73 | await fishing.send(achievement)
74 | await fishing.finish(result)
75 |
76 |
77 | @stats.handle()
78 | async def _(event: Event):
79 | user_id = event.get_user_id()
80 | await stats.finish(await get_stats(user_id))
81 |
82 |
83 | @backpack.handle()
84 | async def _(event: Event):
85 | user_id = event.get_user_id()
86 | await backpack.finish(await get_backpack(user_id))
87 |
88 |
89 | @sell.handle()
90 | async def _(event: Event, arg: Message = CommandArg()):
91 | fish_info = arg.extract_plain_text()
92 | if fish_info == "":
93 | await sell.finish("请输入要卖出的鱼的名字和数量 (数量为1时可省略), 如 /卖鱼 小鱼 1")
94 | user_id = event.get_user_id()
95 | if len(fish_info.split()) == 1:
96 | await sell.finish(await sell_fish(user_id, fish_info))
97 | else:
98 | fish_name, fish_quantity = fish_info.split()
99 | await sell.finish(await sell_fish(user_id, fish_name, int(fish_quantity)))
100 |
101 |
102 | @balance.handle()
103 | async def _(event: Event):
104 | user_id = event.get_user_id()
105 | await balance.finish(await get_balance(user_id))
106 |
107 |
108 | @free_fish_cmd.handle()
109 | async def _(event: Event, arg: Message = CommandArg()):
110 | if not can_free_fish():
111 | await free_fish_cmd.finish("未开启此功能, 请联系机器人管理员")
112 | fish_name = arg.extract_plain_text()
113 | if fish_name == "":
114 | await free_fish_cmd.finish("请输入要放生的鱼的名字, 如 /放生 测试鱼")
115 | user_id = event.get_user_id()
116 | await free_fish_cmd.finish(await free_fish(user_id, fish_name))
117 |
118 |
119 | @lottery_cmd.handle()
120 | async def _(event: Event):
121 | user_id = event.get_user_id()
122 | await lottery_cmd.finish(await lottery(user_id))
123 |
124 |
125 | @give_cmd.handle()
126 | async def _(arg: Message = CommandArg()):
127 | info = arg.extract_plain_text().split()
128 | if len(info) < 2 or len(info) > 3:
129 | await give_cmd.finish("请输入用户的 id 和鱼的名字和数量 (数量为1时可省略), 如 /give 114514 开发鱼 1")
130 | else:
131 | quantity = int(info[2]) if len(info) == 3 else 1
132 | await give_cmd.finish(await give(info[0], info[1], quantity))
133 |
134 |
135 | @achievement_cmd.handle()
136 | async def _(event: Event):
137 | user_id = event.get_user_id()
138 | await achievement_cmd.finish(await get_achievements(user_id))
139 |
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/config.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import List, Dict
3 | from nonebot import get_plugin_config
4 |
5 |
6 | class Config(BaseModel):
7 | fishes: List[Dict] = [
8 | {
9 | "name": "小鱼",
10 | "frequency": 2,
11 | "weight": 100,
12 | "price": 2
13 | },
14 | {
15 | "name": "尚方宝剑",
16 | "frequency": 2,
17 | "weight": 100,
18 | "price": 1
19 | },
20 | {
21 | "name": "小杂鱼~♡",
22 | "frequency": 3,
23 | "weight": 5,
24 | "price": 100
25 | },
26 | {
27 | "name": "烤激光鱼",
28 | "frequency": 10,
29 | "weight": 1,
30 | "price": 1000
31 | }
32 | ]
33 |
34 | fishing_limit: int = 30
35 |
36 | fishing_coin_name: str = "FC" # It means Fishing Coin.
37 |
38 | special_fish_enabled: bool = False
39 |
40 | special_fish_price: int = 50
41 |
42 | special_fish_probability: float = 0.01
43 |
44 | fishing_achievement: List[Dict] = [
45 | {
46 | "type": "fishing_frequency",
47 | "name": "腥味十足的生意",
48 | "data": 1,
49 | "description": "钓到一条鱼。"
50 | },
51 | {
52 | "type": "fishing_frequency",
53 | "name": "还是钓鱼大佬",
54 | "data": 100,
55 | "description": "累计钓鱼一百次。"
56 | },
57 | {
58 | "type": "fish_type",
59 | "name": "那是鱼吗?",
60 | "data": "小杂鱼~♡",
61 | "description": "获得#####。[原文如此]"
62 | },
63 | {
64 | "type": "fish_type",
65 | "name": "那一晚, 激光鱼和便携式烤炉都喝醉了",
66 | "data": "烤激光鱼",
67 | "description": "获得烤激光鱼。"
68 | }
69 | ]
70 |
71 |
72 | config = get_plugin_config(Config)
73 |
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/data_source.py:
--------------------------------------------------------------------------------
1 | import random
2 | import time
3 | import json
4 |
5 | from sqlalchemy import select, update, delete
6 | from sqlalchemy.sql.expression import func
7 | from nonebot_plugin_orm import get_session
8 |
9 | from .config import config
10 | from .model import FishingRecord, SpecialFishes
11 |
12 | fishing_coin_name = config.fishing_coin_name
13 |
14 |
15 | def choice() -> tuple:
16 | config_fishes = config.fishes
17 | weights = [weight["weight"] for weight in config_fishes]
18 | choices = random.choices(
19 | config_fishes,
20 | weights=weights,
21 | )
22 | return choices[0]["name"], choices[0]["frequency"]
23 |
24 |
25 | def get_price(fish_name: str) -> int:
26 | """获取鱼的价格"""
27 | config_fishes = config.fishes
28 | return next(
29 | (
30 | fish["price"]
31 | for fish in config_fishes
32 | if fish["name"] == fish_name
33 | ),
34 | 0
35 | )
36 |
37 |
38 | async def random_get_a_special_fish() -> str:
39 | """随机返回一条别人放生的鱼"""
40 | session = get_session()
41 | async with session.begin():
42 | random_select = select(SpecialFishes).order_by(func.random())
43 | data = await session.scalar(random_select)
44 | return data.fish
45 |
46 |
47 | async def can_fishing(user_id: str) -> bool:
48 | """判断是否可以钓鱼"""
49 | time_now = int(time.time())
50 | session = get_session()
51 | async with session.begin():
52 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
53 | record = await session.scalar(select_user)
54 | return True if not record else record.time < time_now
55 |
56 |
57 | def can_free_fish() -> bool:
58 | return config.special_fish_enabled
59 |
60 |
61 | async def check_achievement(user_id: str) -> str | None:
62 | session = get_session()
63 | async with session.begin():
64 | record = await session.scalar(select(FishingRecord).where(FishingRecord.user_id == user_id))
65 | if not record:
66 | return None
67 | fishing_frequency = record.frequency
68 | user_fishes = json.loads(record.fishes)
69 | achievements = config.fishing_achievement
70 | result_list = []
71 | for achievement in achievements:
72 | achievement_name = achievement["name"]
73 | if await is_exists_achievement(user_id, achievement_name):
74 | continue
75 | if (achievement["type"] == "fishing_frequency" and achievement["data"] <= fishing_frequency) or \
76 | (achievement["type"] == "fish_type" and achievement["data"] in user_fishes):
77 | await save_achievement(user_id, achievement_name)
78 | result_list.append(f"""达成成就: {achievement_name}\n{achievement["description"]}""")
79 | return result_list if result_list != [] else None
80 |
81 |
82 | async def is_exists_achievement(user_id: str, achievement_name: str) -> bool:
83 | session = get_session()
84 | async with session.begin():
85 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
86 | record = await session.scalar(select_user)
87 | if record:
88 | loads_achievements = json.loads(record.achievements)
89 | return achievement_name in loads_achievements
90 | return False
91 |
92 |
93 | async def save_achievement(user_id: str, achievement_name: str):
94 | time_now = int(time.time())
95 | session = get_session()
96 | async with session.begin():
97 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
98 | record = await session.scalar(select_user)
99 | if record:
100 | loads_achievements = json.loads(record.achievements)
101 | loads_achievements.append(achievement_name)
102 | dump_achievements = json.dumps(loads_achievements)
103 | user_update = update(FishingRecord).where(
104 | FishingRecord.user_id == user_id
105 | ).values(
106 | achievements=dump_achievements
107 | )
108 | await session.execute(user_update)
109 | await session.commit()
110 | return
111 | data = []
112 | dump_achievements = json.dumps(data)
113 | new_record = FishingRecord(
114 | user_id=user_id,
115 | time=time_now,
116 | frequency=0,
117 | fishes="{}",
118 | special_fishes="{}",
119 | coin=0,
120 | achievements=dump_achievements
121 | )
122 | session.add(new_record)
123 | await session.commit()
124 |
125 |
126 | async def save_fish(user_id: str, fish_name: str) -> None:
127 | """向数据库写入鱼以持久化保存"""
128 | time_now = int(time.time())
129 | fishing_limit = config.fishing_limit
130 | session = get_session()
131 | async with session.begin():
132 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
133 | record = await session.scalar(select_user)
134 | if record:
135 | loads_fishes = json.loads(record.fishes)
136 | try:
137 | loads_fishes[fish_name] += 1
138 | except KeyError:
139 | loads_fishes[fish_name] = 1
140 | dump_fishes = json.dumps(loads_fishes)
141 | new_frequency = record.frequency + 1
142 | user_update = update(FishingRecord).where(
143 | FishingRecord.user_id == user_id
144 | ).values(
145 | time=time_now + fishing_limit,
146 | frequency=new_frequency,
147 | fishes=dump_fishes
148 | )
149 | await session.execute(user_update)
150 | await session.commit()
151 | return
152 | data = {
153 | fish_name: 1
154 | }
155 | dump_fishes = json.dumps(data)
156 | new_record = FishingRecord(
157 | user_id=user_id,
158 | time=time_now + fishing_limit,
159 | frequency=1,
160 | fishes=dump_fishes,
161 | special_fishes="{}",
162 | coin=0,
163 | achievements="[]"
164 | )
165 | session.add(new_record)
166 | await session.commit()
167 |
168 |
169 | async def can_catch_special_fish():
170 | session = get_session()
171 | async with session.begin():
172 | records = await session.execute(select(SpecialFishes))
173 | return len(records.all()) != 0 and random.random() <= config.special_fish_probability
174 |
175 |
176 | async def save_special_fish(user_id: str, fish_name: str) -> None:
177 | time_now = int(time.time())
178 | fishing_limit = config.fishing_limit
179 | session = get_session()
180 | async with session.begin():
181 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
182 | record = await session.scalar(select_user)
183 | if record:
184 | loads_fishes = json.loads(record.special_fishes)
185 | try:
186 | loads_fishes[fish_name] += 1
187 | except KeyError:
188 | loads_fishes[fish_name] = 1
189 | dump_fishes = json.dumps(loads_fishes)
190 | user_update = update(FishingRecord).where(
191 | FishingRecord.user_id == user_id
192 | ).values(
193 | time=time_now + fishing_limit,
194 | frequency=record.frequency + 1,
195 | special_fishes=dump_fishes
196 | )
197 | await session.execute(user_update)
198 | else:
199 | data = {
200 | fish_name: 1
201 | }
202 | dump_fishes = json.dumps(data)
203 | new_record = FishingRecord(
204 | user_id=user_id,
205 | time=time_now + fishing_limit,
206 | frequency=1,
207 | fishes="{}",
208 | special_fishes=dump_fishes,
209 | coin=0,
210 | achievements=[]
211 | )
212 | session.add(new_record)
213 | select_fish = select(SpecialFishes).where(
214 | SpecialFishes.fish == fish_name
215 | ).order_by(SpecialFishes.id).limit(1)
216 | record = await session.scalar(select_fish)
217 | fish_id = record.id
218 | delete_fishes = delete(SpecialFishes).where(SpecialFishes.id == fish_id)
219 | await session.execute(delete_fishes)
220 | await session.commit()
221 |
222 |
223 | async def get_stats(user_id: str) -> str:
224 | """获取钓鱼统计信息"""
225 | session = get_session()
226 | async with session.begin():
227 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
228 | fishing_record = await session.scalar(select_user)
229 | if fishing_record:
230 | return f"你钓鱼了 {fishing_record.frequency} 次"
231 | return "你还没有钓过鱼,快去钓鱼吧"
232 |
233 |
234 | def print_backpack(backpack: dict, special_backpack=None) -> str:
235 | """输出背包内容"""
236 | result = [
237 | f"{fish_name}×{str(quantity)}"
238 | for fish_name, quantity in backpack.items()
239 | ]
240 | if special_backpack:
241 | special_result = [
242 | f"{fish_name}×{str(quantity)}"
243 | for fish_name, quantity in special_backpack.items()
244 | ]
245 | return "背包:\n" + "\n".join(result) + "\n\n特殊鱼:\n" + "\n".join(special_result)
246 | return "背包:\n" + "\n".join(result)
247 |
248 |
249 | async def get_backpack(user_id: str) -> str:
250 | """从数据库查询背包内容"""
251 | session = get_session()
252 | async with session.begin():
253 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
254 | fishes_record = await session.scalar(select_user)
255 | if fishes_record:
256 | load_fishes = json.loads(fishes_record.fishes)
257 | load_special_fishes = json.loads(fishes_record.special_fishes)
258 | if load_special_fishes:
259 | return print_backpack(load_fishes, load_special_fishes)
260 | return "你的背包里空无一物" if load_fishes == {} else print_backpack(load_fishes)
261 | return "你的背包里空无一物"
262 |
263 |
264 | async def sell_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
265 | """
266 | 卖鱼
267 |
268 | 参数:
269 | - user_id: 用户标识符
270 | - fish_name: 将要卖鱼的鱼名称
271 | - quantity: 卖出鱼的数量
272 |
273 | 返回:
274 | - (str): 回复的文本
275 | """
276 | if quantity <= 0:
277 | return "你在卖什么 w(゚Д゚)w"
278 | session = get_session()
279 | async with session.begin():
280 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
281 | fishes_record = await session.scalar(select_user)
282 | if fishes_record := fishes_record:
283 | loads_fishes = json.loads(fishes_record.fishes)
284 | if fish_name in loads_fishes and loads_fishes[fish_name] > 0:
285 | fish_price = get_price(fish_name)
286 | if loads_fishes[fish_name] < quantity:
287 | return f"{fish_name} 太少了!"
288 | loads_fishes[fish_name] -= quantity
289 | if loads_fishes[fish_name] == 0:
290 | del loads_fishes[fish_name]
291 | dump_fishes = json.dumps(loads_fishes)
292 | user_update = update(FishingRecord).where(
293 | FishingRecord.user_id == user_id
294 | ).values(
295 | coin=fishes_record.coin + fish_price * quantity,
296 | fishes=dump_fishes
297 | )
298 | await session.execute(user_update)
299 | await session.commit()
300 | return (f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} 条 {fish_name}, "
301 | f"你获得了 {fish_price * quantity} {fishing_coin_name}")
302 | return "查无此鱼"
303 | else:
304 | return "还没钓鱼就想卖鱼?"
305 |
306 |
307 | async def get_balance(user_id: str) -> str:
308 | """获取余额"""
309 | session = get_session()
310 | async with session.begin():
311 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
312 | fishes_record = await session.scalar(select_user)
313 | if fishes_record:
314 | return f"你有 {fishes_record.coin} {fishing_coin_name}"
315 | return "你什么也没有 :)"
316 |
317 |
318 | async def free_fish(user_id: str, fish_name: str) -> str:
319 | session = get_session()
320 | async with session.begin():
321 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
322 | fishes_record = await session.scalar(select_user)
323 | if fishes_record:
324 | user_coin = fishes_record.coin
325 | if user_coin < config.special_fish_price:
326 | special_fish_coin_less = str(config.special_fish_price - fishes_record.coin)
327 | return f"你没有足够的 {fishing_coin_name}, 还需 {special_fish_coin_less} {fishing_coin_name}"
328 | user_coin -= config.special_fish_price
329 | new_record = SpecialFishes(
330 | user_id=user_id,
331 | fish=fish_name
332 | )
333 | session.add(new_record)
334 | user_update = update(FishingRecord).where(
335 | FishingRecord.user_id == user_id
336 | ).values(
337 | coin=user_coin
338 | )
339 | await session.execute(user_update)
340 | await session.commit()
341 | return f"你花费 {config.special_fish_price} {fishing_coin_name} 放生了 {fish_name}, 未来或许会被有缘人钓到呢"
342 | return "你甚至还没钓过鱼"
343 |
344 |
345 | async def lottery(user_id: str) -> str:
346 | """算法来自于 https://github.com/fossifer/minesweeperbot/blob/master/cards.py"""
347 | session = get_session()
348 | async with session.begin():
349 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
350 | fishes_record = await session.scalar(select_user)
351 | if fishes_record:
352 | user_coin = fishes_record.coin
353 | if user_coin <= 0:
354 | return f"你只有 {user_coin} {fishing_coin_name}, 不足以祈愿"
355 | new_coin = abs(user_coin) / 3
356 | new_coin = random.randrange(5000, 15000) / 10000 * new_coin
357 | new_coin = int(new_coin) if new_coin > 1 else 1
358 | new_coin *= random.randrange(-1, 2, 2)
359 | user_update = update(FishingRecord).where(
360 | FishingRecord.user_id == user_id
361 | ).values(
362 | coin=fishes_record.coin + new_coin,
363 | )
364 | await session.execute(user_update)
365 | await session.commit()
366 | return f'你{"获得" if new_coin >= 0 else "血亏"}了 {abs(new_coin)} {fishing_coin_name}'
367 |
368 |
369 | async def give(user_id: str, fish_name: str, quantity: int = 1) -> str:
370 | session = get_session()
371 | async with session.begin():
372 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
373 | record = await session.scalar(select_user)
374 | if record:
375 | loads_fishes = json.loads(record.fishes)
376 | try:
377 | loads_fishes[fish_name] += quantity
378 | except KeyError:
379 | loads_fishes[fish_name] = quantity
380 | dump_fishes = json.dumps(loads_fishes)
381 | user_update = update(FishingRecord).where(
382 | FishingRecord.user_id == user_id
383 | ).values(
384 | fishes=dump_fishes
385 | )
386 | await session.execute(user_update)
387 | await session.commit()
388 | return f"使用滥权之力成功使 {fish_name} 添加到 {user_id} 的背包之中 ヾ(≧▽≦*)o"
389 | return "未查找到用户信息, 无法执行滥权操作 w(゚Д゚)w"
390 |
391 |
392 | async def get_achievements(user_id: str) -> str:
393 | session = get_session()
394 | async with session.begin():
395 | select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
396 | record = await session.scalar(select_user)
397 | if record:
398 | achievements = json.loads(record.achievements)
399 | return "已完成成就:\n" + "\n".join(achievements)
400 | return "你甚至还没钓过鱼 (╬▔皿▔)╯"
401 |
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/migrations/1be1c9b715a9_add_achievements.py:
--------------------------------------------------------------------------------
1 | """add achievements
2 |
3 | 迁移 ID: 1be1c9b715a9
4 | 父迁移: e9015df43907
5 | 创建时间: 2024-09-22 17:12:51.193361
6 |
7 | """
8 | from __future__ import annotations
9 |
10 | from collections.abc import Sequence
11 |
12 | from alembic import op
13 | import sqlalchemy as sa
14 |
15 |
16 | revision: str = '1be1c9b715a9'
17 | down_revision: str | Sequence[str] | None = 'e9015df43907'
18 | branch_labels: str | Sequence[str] | None = None
19 | depends_on: str | Sequence[str] | None = None
20 |
21 |
22 | def upgrade(name: str = "") -> None:
23 | if name:
24 | return
25 | # ### commands auto generated by Alembic - please adjust! ###
26 | with op.batch_alter_table('nonebot_plugin_fishing_fishingrecord', schema=None) as batch_op:
27 | batch_op.add_column(sa.Column('achievements', sa.TEXT(), nullable=False))
28 |
29 | # ### end Alembic commands ###
30 |
31 |
32 | def downgrade(name: str = "") -> None:
33 | if name:
34 | return
35 | # ### commands auto generated by Alembic - please adjust! ###
36 | with op.batch_alter_table('nonebot_plugin_fishing_fishingrecord', schema=None) as batch_op:
37 | batch_op.drop_column('achievements')
38 |
39 | # ### end Alembic commands ###
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/migrations/68463f3e5f33_.py:
--------------------------------------------------------------------------------
1 | """Update version
2 |
3 | 迁移 ID: 68463f3e5f33
4 | 父迁移: 7609e6d106dd
5 | 创建时间: 2024-04-13 01:21:12.144452
6 |
7 | """
8 | from __future__ import annotations
9 |
10 | from collections.abc import Sequence
11 |
12 | from alembic import op
13 | import sqlalchemy as sa
14 |
15 |
16 | revision: str = '68463f3e5f33'
17 | down_revision: str | Sequence[str] | None = '7609e6d106dd'
18 | branch_labels: str | Sequence[str] | None = None
19 | depends_on: str | Sequence[str] | None = None
20 |
21 |
22 | def upgrade(name: str = "") -> None:
23 | if name:
24 | return
25 | # ### commands auto generated by Alembic - please adjust! ###
26 | pass
27 | # ### end Alembic commands ###
28 |
29 |
30 | def downgrade(name: str = "") -> None:
31 | if name:
32 | return
33 | # ### commands auto generated by Alembic - please adjust! ###
34 | pass
35 | # ### end Alembic commands ###
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/migrations/7609e6d106dd_init_db.py:
--------------------------------------------------------------------------------
1 | """init db
2 |
3 | 迁移 ID: 7609e6d106dd
4 | 父迁移:
5 | 创建时间: 2024-04-05 19:08:58.835014
6 |
7 | """
8 | from __future__ import annotations
9 |
10 | from collections.abc import Sequence
11 |
12 | from alembic import op
13 | import sqlalchemy as sa
14 |
15 |
16 | revision: str = '7609e6d106dd'
17 | down_revision: str | Sequence[str] | None = None
18 | branch_labels: str | Sequence[str] | None = ('nonebot_plugin_fishing',)
19 | depends_on: str | Sequence[str] | None = None
20 |
21 |
22 | def upgrade(name: str = "") -> None:
23 | if name:
24 | return
25 | # ### commands auto generated by Alembic - please adjust! ###
26 | op.create_table('nonebot_plugin_fishing_fishingrecord',
27 | sa.Column('id', sa.Integer(), nullable=False),
28 | sa.Column('user_id', sa.String(length=32), nullable=False),
29 | sa.Column('time', sa.Integer(), nullable=False),
30 | sa.Column('frequency', sa.Integer(), nullable=False),
31 | sa.Column('fishes', sa.TEXT(), nullable=False),
32 | sa.Column('coin', sa.Integer(), nullable=False),
33 | sa.PrimaryKeyConstraint('id', name=op.f('pk_nonebot_plugin_fishing_fishingrecord')),
34 | info={'bind_key': 'nonebot_plugin_fishing'}
35 | )
36 | # ### end Alembic commands ###
37 |
38 |
39 | def downgrade(name: str = "") -> None:
40 | if name:
41 | return
42 | # ### commands auto generated by Alembic - please adjust! ###
43 | op.drop_table('nonebot_plugin_fishing_fishingrecord')
44 | # ### end Alembic commands ###
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/migrations/c5ab992c9af3_add_achievements.py:
--------------------------------------------------------------------------------
1 | """add achievements
2 |
3 | 迁移 ID: c5ab992c9af3
4 | 父迁移: e9015df43907
5 | 创建时间: 2024-09-22 16:44:24.934270
6 |
7 | """
8 | from __future__ import annotations
9 |
10 | from collections.abc import Sequence
11 |
12 | from alembic import op
13 | import sqlalchemy as sa
14 |
15 |
16 | revision: str = 'c5ab992c9af3'
17 | down_revision: str | Sequence[str] | None = 'e9015df43907'
18 | branch_labels: str | Sequence[str] | None = None
19 | depends_on: str | Sequence[str] | None = None
20 |
21 |
22 | def upgrade(name: str = "") -> None:
23 | if name:
24 | return
25 | # ### commands auto generated by Alembic - please adjust! ###
26 | with op.batch_alter_table('nonebot_plugin_fishing_fishingrecord', schema=None) as batch_op:
27 | batch_op.add_column(sa.Column('achievements', sa.TEXT(), nullable=False))
28 |
29 | # ### end Alembic commands ###
30 |
31 |
32 | def downgrade(name: str = "") -> None:
33 | if name:
34 | return
35 | # ### commands auto generated by Alembic - please adjust! ###
36 | with op.batch_alter_table('nonebot_plugin_fishing_fishingrecord', schema=None) as batch_op:
37 | batch_op.drop_column('achievements')
38 |
39 | # ### end Alembic commands ###
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/migrations/e9015df43907_add_special_fishes_field.py:
--------------------------------------------------------------------------------
1 | """add special_fishes field
2 |
3 | 迁移 ID: e9015df43907
4 | 父迁移: f70bdeaec7a4
5 | 创建时间: 2024-04-20 12:43:35.168261
6 |
7 | """
8 | from __future__ import annotations
9 |
10 | from collections.abc import Sequence
11 |
12 | from alembic import op
13 | import sqlalchemy as sa
14 |
15 |
16 | revision: str = 'e9015df43907'
17 | down_revision: str | Sequence[str] | None = 'f70bdeaec7a4'
18 | branch_labels: str | Sequence[str] | None = None
19 | depends_on: str | Sequence[str] | None = None
20 |
21 |
22 | def upgrade(name: str = "") -> None:
23 | if name:
24 | return
25 | # ### commands auto generated by Alembic - please adjust! ###
26 | with op.batch_alter_table('nonebot_plugin_fishing_fishingrecord', schema=None) as batch_op:
27 | batch_op.add_column(sa.Column('special_fishes', sa.TEXT(), nullable=False))
28 |
29 | # ### end Alembic commands ###
30 |
31 |
32 | def downgrade(name: str = "") -> None:
33 | if name:
34 | return
35 | # ### commands auto generated by Alembic - please adjust! ###
36 | with op.batch_alter_table('nonebot_plugin_fishing_fishingrecord', schema=None) as batch_op:
37 | batch_op.drop_column('special_fishes')
38 |
39 | # ### end Alembic commands ###
40 |
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/migrations/f70bdeaec7a4_add_specialfishes_table.py:
--------------------------------------------------------------------------------
1 | """add SpecialFishes table
2 |
3 | 迁移 ID: f70bdeaec7a4
4 | 父迁移: 68463f3e5f33
5 | 创建时间: 2024-04-11 12:59:25.138990
6 |
7 | """
8 | from __future__ import annotations
9 |
10 | from collections.abc import Sequence
11 |
12 | from alembic import op
13 | import sqlalchemy as sa
14 |
15 |
16 | revision: str = 'f70bdeaec7a4'
17 | down_revision: str | Sequence[str] | None = '68463f3e5f33'
18 | branch_labels: str | Sequence[str] | None = None
19 | depends_on: str | Sequence[str] | None = None
20 |
21 |
22 | def upgrade(name: str = "") -> None:
23 | if name:
24 | return
25 | # ### commands auto generated by Alembic - please adjust! ###
26 | op.create_table('nonebot_plugin_fishing_specialfishes',
27 | sa.Column('id', sa.Integer(), nullable=False),
28 | sa.Column('user_id', sa.String(length=32), nullable=False),
29 | sa.Column('fish', sa.TEXT(), nullable=False),
30 | sa.PrimaryKeyConstraint('id', name=op.f('pk_nonebot_plugin_fishing_specialfishes')),
31 | info={'bind_key': 'nonebot_plugin_fishing'}
32 | )
33 | # ### end Alembic commands ###
34 |
35 |
36 | def downgrade(name: str = "") -> None:
37 | if name:
38 | return
39 | # ### commands auto generated by Alembic - please adjust! ###
40 | op.drop_table('nonebot_plugin_fishing_specialfishes')
41 | # ### end Alembic commands ###
42 |
--------------------------------------------------------------------------------
/nonebot_plugin_fishing/model.py:
--------------------------------------------------------------------------------
1 | from nonebot_plugin_orm import Model
2 | from sqlalchemy import String, TEXT
3 | from sqlalchemy.orm import Mapped, mapped_column
4 |
5 |
6 | class FishingRecord(Model):
7 | id: Mapped[int] = mapped_column(primary_key=True)
8 | user_id: Mapped[str] = mapped_column(String(32))
9 | time: Mapped[int]
10 | frequency: Mapped[int]
11 | fishes: Mapped[str] = mapped_column(TEXT)
12 | special_fishes: Mapped[str] = mapped_column(TEXT, default="{}")
13 | coin: Mapped[int] = mapped_column(default=0)
14 | achievements: Mapped[str] = mapped_column(TEXT, default="[]")
15 |
16 |
17 | class SpecialFishes(Model):
18 | id: Mapped[int] = mapped_column(primary_key=True)
19 | user_id: Mapped[str] = mapped_column(String(32))
20 | fish: Mapped[str] = mapped_column(TEXT, default="{}")
21 |
--------------------------------------------------------------------------------
/pdm.lock:
--------------------------------------------------------------------------------
1 | # This file is @generated by PDM.
2 | # It is not intended for manual editing.
3 |
4 | [metadata]
5 | groups = ["default"]
6 | strategy = ["cross_platform", "inherit_metadata"]
7 | lock_version = "4.4.1"
8 | content_hash = "sha256:ab940abf33ccfcf918d9946cc634d334aab185d1ad43a2ecaae17ef8efd4066a"
9 |
10 | [[package]]
11 | name = "aiosqlite"
12 | version = "0.20.0"
13 | requires_python = ">=3.8"
14 | summary = "asyncio bridge to the standard sqlite3 module"
15 | groups = ["default"]
16 | dependencies = [
17 | "typing-extensions>=4.0",
18 | ]
19 | files = [
20 | {file = "aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6"},
21 | {file = "aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7"},
22 | ]
23 |
24 | [[package]]
25 | name = "alembic"
26 | version = "1.13.1"
27 | requires_python = ">=3.8"
28 | summary = "A database migration tool for SQLAlchemy."
29 | groups = ["default"]
30 | dependencies = [
31 | "Mako",
32 | "SQLAlchemy>=1.3.0",
33 | "importlib-metadata; python_version < \"3.9\"",
34 | "importlib-resources; python_version < \"3.9\"",
35 | "typing-extensions>=4",
36 | ]
37 | files = [
38 | {file = "alembic-1.13.1-py3-none-any.whl", hash = "sha256:2edcc97bed0bd3272611ce3a98d98279e9c209e7186e43e75bbb1b2bdfdbcc43"},
39 | {file = "alembic-1.13.1.tar.gz", hash = "sha256:4932c8558bf68f2ee92b9bbcb8218671c627064d5b08939437af6d77dc05e595"},
40 | ]
41 |
42 | [[package]]
43 | name = "annotated-types"
44 | version = "0.6.0"
45 | requires_python = ">=3.8"
46 | summary = "Reusable constraint types to use with typing.Annotated"
47 | groups = ["default"]
48 | dependencies = [
49 | "typing-extensions>=4.0.0; python_version < \"3.9\"",
50 | ]
51 | files = [
52 | {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"},
53 | {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"},
54 | ]
55 |
56 | [[package]]
57 | name = "click"
58 | version = "8.1.7"
59 | requires_python = ">=3.7"
60 | summary = "Composable command line interface toolkit"
61 | groups = ["default"]
62 | dependencies = [
63 | "colorama; platform_system == \"Windows\"",
64 | ]
65 | files = [
66 | {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
67 | {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
68 | ]
69 |
70 | [[package]]
71 | name = "colorama"
72 | version = "0.4.6"
73 | requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
74 | summary = "Cross-platform colored terminal text."
75 | groups = ["default"]
76 | marker = "sys_platform == \"win32\" or platform_system == \"Windows\""
77 | files = [
78 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
79 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
80 | ]
81 |
82 | [[package]]
83 | name = "greenlet"
84 | version = "3.0.3"
85 | requires_python = ">=3.7"
86 | summary = "Lightweight in-process concurrent programming"
87 | groups = ["default"]
88 | marker = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""
89 | files = [
90 | {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"},
91 | {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"},
92 | {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"},
93 | {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"},
94 | {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"},
95 | {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"},
96 | {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"},
97 | {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"},
98 | {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"},
99 | {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"},
100 | ]
101 |
102 | [[package]]
103 | name = "idna"
104 | version = "3.6"
105 | requires_python = ">=3.5"
106 | summary = "Internationalized Domain Names in Applications (IDNA)"
107 | groups = ["default"]
108 | files = [
109 | {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
110 | {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
111 | ]
112 |
113 | [[package]]
114 | name = "importlib-metadata"
115 | version = "7.0.2"
116 | requires_python = ">=3.8"
117 | summary = "Read metadata from Python packages"
118 | groups = ["default"]
119 | marker = "python_version < \"3.10\""
120 | dependencies = [
121 | "zipp>=0.5",
122 | ]
123 | files = [
124 | {file = "importlib_metadata-7.0.2-py3-none-any.whl", hash = "sha256:f4bc4c0c070c490abf4ce96d715f68e95923320370efb66143df00199bb6c100"},
125 | {file = "importlib_metadata-7.0.2.tar.gz", hash = "sha256:198f568f3230878cb1b44fbd7975f87906c22336dba2e4a7f05278c281fbd792"},
126 | ]
127 |
128 | [[package]]
129 | name = "importlib-resources"
130 | version = "6.1.3"
131 | requires_python = ">=3.8"
132 | summary = "Read resources from Python packages"
133 | groups = ["default"]
134 | marker = "python_version < \"3.12\""
135 | dependencies = [
136 | "zipp>=3.1.0; python_version < \"3.10\"",
137 | ]
138 | files = [
139 | {file = "importlib_resources-6.1.3-py3-none-any.whl", hash = "sha256:4c0269e3580fe2634d364b39b38b961540a7738c02cb984e98add8b4221d793d"},
140 | {file = "importlib_resources-6.1.3.tar.gz", hash = "sha256:56fb4525197b78544a3354ea27793952ab93f935bb4bf746b846bb1015020f2b"},
141 | ]
142 |
143 | [[package]]
144 | name = "loguru"
145 | version = "0.7.2"
146 | requires_python = ">=3.5"
147 | summary = "Python logging made (stupidly) simple"
148 | groups = ["default"]
149 | dependencies = [
150 | "colorama>=0.3.4; sys_platform == \"win32\"",
151 | "win32-setctime>=1.0.0; sys_platform == \"win32\"",
152 | ]
153 | files = [
154 | {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"},
155 | {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"},
156 | ]
157 |
158 | [[package]]
159 | name = "mako"
160 | version = "1.3.2"
161 | requires_python = ">=3.8"
162 | summary = "A super-fast templating language that borrows the best ideas from the existing templating languages."
163 | groups = ["default"]
164 | dependencies = [
165 | "MarkupSafe>=0.9.2",
166 | ]
167 | files = [
168 | {file = "Mako-1.3.2-py3-none-any.whl", hash = "sha256:32a99d70754dfce237019d17ffe4a282d2d3351b9c476e90d8a60e63f133b80c"},
169 | {file = "Mako-1.3.2.tar.gz", hash = "sha256:2a0c8ad7f6274271b3bb7467dd37cf9cc6dab4bc19cb69a4ef10669402de698e"},
170 | ]
171 |
172 | [[package]]
173 | name = "markupsafe"
174 | version = "2.1.5"
175 | requires_python = ">=3.7"
176 | summary = "Safely add untrusted strings to HTML/XML markup."
177 | groups = ["default"]
178 | files = [
179 | {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
180 | {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
181 | {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
182 | {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
183 | {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
184 | {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
185 | {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
186 | {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
187 | {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
188 | {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
189 | {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
190 | {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
191 | {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
192 | {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
193 | {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
194 | {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
195 | {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
196 | {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
197 | {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
198 | {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
199 | {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
200 | {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
201 | {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
202 | {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
203 | {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
204 | {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
205 | {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
206 | {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
207 | {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
208 | {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
209 | {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
210 | {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
211 | {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
212 | {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
213 | {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
214 | {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
215 | {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
216 | {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
217 | {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
218 | {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
219 | {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
220 | {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
221 | {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
222 | {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
223 | {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
224 | {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
225 | {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
226 | {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
227 | {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
228 | {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
229 | {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
230 | ]
231 |
232 | [[package]]
233 | name = "multidict"
234 | version = "6.0.5"
235 | requires_python = ">=3.7"
236 | summary = "multidict implementation"
237 | groups = ["default"]
238 | files = [
239 | {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"},
240 | {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"},
241 | {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"},
242 | {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"},
243 | {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"},
244 | {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"},
245 | {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"},
246 | {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"},
247 | {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"},
248 | {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"},
249 | {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"},
250 | {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"},
251 | {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"},
252 | {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"},
253 | {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"},
254 | {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"},
255 | {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"},
256 | ]
257 |
258 | [[package]]
259 | name = "nonebot-plugin-localstore"
260 | version = "0.6.0"
261 | requires_python = ">=3.8,<4.0"
262 | summary = "Local Storage Support for NoneBot2"
263 | groups = ["default"]
264 | dependencies = [
265 | "nonebot2<3.0.0,>=2.2.0",
266 | "pydantic!=2.5.0,!=2.5.1,<3.0.0,>=1.10.0",
267 | "typing-extensions>=4.0.0",
268 | ]
269 | files = [
270 | {file = "nonebot_plugin_localstore-0.6.0-py3-none-any.whl", hash = "sha256:59f0126d85680601166a9a62cca886a33e1b0a8fef7cd67fff52747bd47f42d3"},
271 | {file = "nonebot_plugin_localstore-0.6.0.tar.gz", hash = "sha256:7eb4039cb2e76c54b860b2b98f2b90cd25284919603e81dedec367f215662fcd"},
272 | ]
273 |
274 | [[package]]
275 | name = "nonebot-plugin-orm"
276 | version = "0.7.1"
277 | requires_python = "<4.0,>=3.8"
278 | summary = "SQLAlchemy ORM support for nonebot"
279 | groups = ["default"]
280 | dependencies = [
281 | "alembic~=1.13",
282 | "click~=8.1",
283 | "importlib-metadata~=7.0; python_version < \"3.10\"",
284 | "importlib-resources~=6.1; python_version < \"3.12\"",
285 | "nonebot-plugin-localstore~=0.6",
286 | "nonebot2~=2.2",
287 | "sqlalchemy~=2.0",
288 | "typing-extensions~=4.9; python_version < \"3.11\"",
289 | ]
290 | files = [
291 | {file = "nonebot_plugin_orm-0.7.1-py3-none-any.whl", hash = "sha256:8e663094b0521a4838a4f7e65d53b603bfc5da77bafe9a89c912385918efb569"},
292 | {file = "nonebot_plugin_orm-0.7.1.tar.gz", hash = "sha256:e6ae8f93e7e2a0f3de40a4f3dbfd48684654468aea1ea3ca31009fa5aaff42d8"},
293 | ]
294 |
295 | [[package]]
296 | name = "nonebot2"
297 | version = "2.2.1"
298 | requires_python = ">=3.8,<4.0"
299 | summary = "An asynchronous python bot framework."
300 | groups = ["default"]
301 | dependencies = [
302 | "loguru<1.0.0,>=0.6.0",
303 | "pydantic!=2.5.0,!=2.5.1,<3.0.0,>=1.10.0",
304 | "pygtrie<3.0.0,>=2.4.1",
305 | "python-dotenv<2.0.0,>=0.21.0",
306 | "tomli<3.0.0,>=2.0.1; python_version < \"3.11\"",
307 | "typing-extensions<5.0.0,>=4.4.0",
308 | "yarl<2.0.0,>=1.7.2",
309 | ]
310 | files = [
311 | {file = "nonebot2-2.2.1-py3-none-any.whl", hash = "sha256:88f2bb456bf90922925bbe489a9effe3b09300f3aa50bfa75ee50d8a83d7330f"},
312 | {file = "nonebot2-2.2.1.tar.gz", hash = "sha256:fe57692300571b00724999238545d8d894523460e6835a11b326a2e1cdf98fc4"},
313 | ]
314 |
315 | [[package]]
316 | name = "pydantic"
317 | version = "2.6.3"
318 | requires_python = ">=3.8"
319 | summary = "Data validation using Python type hints"
320 | groups = ["default"]
321 | dependencies = [
322 | "annotated-types>=0.4.0",
323 | "pydantic-core==2.16.3",
324 | "typing-extensions>=4.6.1",
325 | ]
326 | files = [
327 | {file = "pydantic-2.6.3-py3-none-any.whl", hash = "sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a"},
328 | {file = "pydantic-2.6.3.tar.gz", hash = "sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f"},
329 | ]
330 |
331 | [[package]]
332 | name = "pydantic-core"
333 | version = "2.16.3"
334 | requires_python = ">=3.8"
335 | summary = ""
336 | groups = ["default"]
337 | dependencies = [
338 | "typing-extensions!=4.7.0,>=4.6.0",
339 | ]
340 | files = [
341 | {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"},
342 | {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"},
343 | {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"},
344 | {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"},
345 | {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"},
346 | {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"},
347 | {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"},
348 | {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"},
349 | {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"},
350 | {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"},
351 | {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"},
352 | {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"},
353 | {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"},
354 | {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"},
355 | {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"},
356 | {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"},
357 | {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"},
358 | {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"},
359 | {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"},
360 | {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"},
361 | {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"},
362 | {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"},
363 | {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"},
364 | {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"},
365 | {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"},
366 | {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"},
367 | {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"},
368 | {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"},
369 | {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"},
370 | {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"},
371 | ]
372 |
373 | [[package]]
374 | name = "pygtrie"
375 | version = "2.5.0"
376 | summary = "A pure Python trie data structure implementation."
377 | groups = ["default"]
378 | files = [
379 | {file = "pygtrie-2.5.0-py3-none-any.whl", hash = "sha256:8795cda8105493d5ae159a5bef313ff13156c5d4d72feddefacaad59f8c8ce16"},
380 | {file = "pygtrie-2.5.0.tar.gz", hash = "sha256:203514ad826eb403dab1d2e2ddd034e0d1534bbe4dbe0213bb0593f66beba4e2"},
381 | ]
382 |
383 | [[package]]
384 | name = "python-dotenv"
385 | version = "1.0.1"
386 | requires_python = ">=3.8"
387 | summary = "Read key-value pairs from a .env file and set them as environment variables"
388 | groups = ["default"]
389 | files = [
390 | {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
391 | {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
392 | ]
393 |
394 | [[package]]
395 | name = "sqlalchemy"
396 | version = "2.0.27"
397 | requires_python = ">=3.7"
398 | summary = "Database Abstraction Library"
399 | groups = ["default"]
400 | dependencies = [
401 | "greenlet!=0.4.17; platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\"",
402 | "typing-extensions>=4.6.0",
403 | ]
404 | files = [
405 | {file = "SQLAlchemy-2.0.27-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d04e579e911562f1055d26dab1868d3e0bb905db3bccf664ee8ad109f035618a"},
406 | {file = "SQLAlchemy-2.0.27-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fa67d821c1fd268a5a87922ef4940442513b4e6c377553506b9db3b83beebbd8"},
407 | {file = "SQLAlchemy-2.0.27-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c7a596d0be71b7baa037f4ac10d5e057d276f65a9a611c46970f012752ebf2d"},
408 | {file = "SQLAlchemy-2.0.27-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:954d9735ee9c3fa74874c830d089a815b7b48df6f6b6e357a74130e478dbd951"},
409 | {file = "SQLAlchemy-2.0.27-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5cd20f58c29bbf2680039ff9f569fa6d21453fbd2fa84dbdb4092f006424c2e6"},
410 | {file = "SQLAlchemy-2.0.27-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:03f448ffb731b48323bda68bcc93152f751436ad6037f18a42b7e16af9e91c07"},
411 | {file = "SQLAlchemy-2.0.27-cp310-cp310-win32.whl", hash = "sha256:d997c5938a08b5e172c30583ba6b8aad657ed9901fc24caf3a7152eeccb2f1b4"},
412 | {file = "SQLAlchemy-2.0.27-cp310-cp310-win_amd64.whl", hash = "sha256:eb15ef40b833f5b2f19eeae65d65e191f039e71790dd565c2af2a3783f72262f"},
413 | {file = "SQLAlchemy-2.0.27-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c5bad7c60a392850d2f0fee8f355953abaec878c483dd7c3836e0089f046bf6"},
414 | {file = "SQLAlchemy-2.0.27-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3012ab65ea42de1be81fff5fb28d6db893ef978950afc8130ba707179b4284a"},
415 | {file = "SQLAlchemy-2.0.27-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbcd77c4d94b23e0753c5ed8deba8c69f331d4fd83f68bfc9db58bc8983f49cd"},
416 | {file = "SQLAlchemy-2.0.27-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d177b7e82f6dd5e1aebd24d9c3297c70ce09cd1d5d37b43e53f39514379c029c"},
417 | {file = "SQLAlchemy-2.0.27-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:680b9a36029b30cf063698755d277885d4a0eab70a2c7c6e71aab601323cba45"},
418 | {file = "SQLAlchemy-2.0.27-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1306102f6d9e625cebaca3d4c9c8f10588735ef877f0360b5cdb4fdfd3fd7131"},
419 | {file = "SQLAlchemy-2.0.27-cp311-cp311-win32.whl", hash = "sha256:5b78aa9f4f68212248aaf8943d84c0ff0f74efc65a661c2fc68b82d498311fd5"},
420 | {file = "SQLAlchemy-2.0.27-cp311-cp311-win_amd64.whl", hash = "sha256:15e19a84b84528f52a68143439d0c7a3a69befcd4f50b8ef9b7b69d2628ae7c4"},
421 | {file = "SQLAlchemy-2.0.27-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0de1263aac858f288a80b2071990f02082c51d88335a1db0d589237a3435fe71"},
422 | {file = "SQLAlchemy-2.0.27-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce850db091bf7d2a1f2fdb615220b968aeff3849007b1204bf6e3e50a57b3d32"},
423 | {file = "SQLAlchemy-2.0.27-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dfc936870507da96aebb43e664ae3a71a7b96278382bcfe84d277b88e379b18"},
424 | {file = "SQLAlchemy-2.0.27-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4fbe6a766301f2e8a4519f4500fe74ef0a8509a59e07a4085458f26228cd7cc"},
425 | {file = "SQLAlchemy-2.0.27-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4535c49d961fe9a77392e3a630a626af5baa967172d42732b7a43496c8b28876"},
426 | {file = "SQLAlchemy-2.0.27-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0fb3bffc0ced37e5aa4ac2416f56d6d858f46d4da70c09bb731a246e70bff4d5"},
427 | {file = "SQLAlchemy-2.0.27-cp312-cp312-win32.whl", hash = "sha256:7f470327d06400a0aa7926b375b8e8c3c31d335e0884f509fe272b3c700a7254"},
428 | {file = "SQLAlchemy-2.0.27-cp312-cp312-win_amd64.whl", hash = "sha256:f9374e270e2553653d710ece397df67db9d19c60d2647bcd35bfc616f1622dcd"},
429 | {file = "SQLAlchemy-2.0.27-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec1f5a328464daf7a1e4e385e4f5652dd9b1d12405075ccba1df842f7774b4fc"},
430 | {file = "SQLAlchemy-2.0.27-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ad862295ad3f644e3c2c0d8b10a988e1600d3123ecb48702d2c0f26771f1c396"},
431 | {file = "SQLAlchemy-2.0.27-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48217be1de7d29a5600b5c513f3f7664b21d32e596d69582be0a94e36b8309cb"},
432 | {file = "SQLAlchemy-2.0.27-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e56afce6431450442f3ab5973156289bd5ec33dd618941283847c9fd5ff06bf"},
433 | {file = "SQLAlchemy-2.0.27-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:611068511b5531304137bcd7fe8117c985d1b828eb86043bd944cebb7fae3910"},
434 | {file = "SQLAlchemy-2.0.27-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b86abba762ecfeea359112b2bb4490802b340850bbee1948f785141a5e020de8"},
435 | {file = "SQLAlchemy-2.0.27-cp38-cp38-win32.whl", hash = "sha256:30d81cc1192dc693d49d5671cd40cdec596b885b0ce3b72f323888ab1c3863d5"},
436 | {file = "SQLAlchemy-2.0.27-cp38-cp38-win_amd64.whl", hash = "sha256:120af1e49d614d2525ac247f6123841589b029c318b9afbfc9e2b70e22e1827d"},
437 | {file = "SQLAlchemy-2.0.27-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d07ee7793f2aeb9b80ec8ceb96bc8cc08a2aec8a1b152da1955d64e4825fcbac"},
438 | {file = "SQLAlchemy-2.0.27-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb0845e934647232b6ff5150df37ceffd0b67b754b9fdbb095233deebcddbd4a"},
439 | {file = "SQLAlchemy-2.0.27-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fc19ae2e07a067663dd24fca55f8ed06a288384f0e6e3910420bf4b1270cc51"},
440 | {file = "SQLAlchemy-2.0.27-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b90053be91973a6fb6020a6e44382c97739736a5a9d74e08cc29b196639eb979"},
441 | {file = "SQLAlchemy-2.0.27-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2f5c9dfb0b9ab5e3a8a00249534bdd838d943ec4cfb9abe176a6c33408430230"},
442 | {file = "SQLAlchemy-2.0.27-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33e8bde8fff203de50399b9039c4e14e42d4d227759155c21f8da4a47fc8053c"},
443 | {file = "SQLAlchemy-2.0.27-cp39-cp39-win32.whl", hash = "sha256:d873c21b356bfaf1589b89090a4011e6532582b3a8ea568a00e0c3aab09399dd"},
444 | {file = "SQLAlchemy-2.0.27-cp39-cp39-win_amd64.whl", hash = "sha256:ff2f1b7c963961d41403b650842dc2039175b906ab2093635d8319bef0b7d620"},
445 | {file = "SQLAlchemy-2.0.27-py3-none-any.whl", hash = "sha256:1ab4e0448018d01b142c916cc7119ca573803a4745cfe341b8f95657812700ac"},
446 | {file = "SQLAlchemy-2.0.27.tar.gz", hash = "sha256:86a6ed69a71fe6b88bf9331594fa390a2adda4a49b5c06f98e47bf0d392534f8"},
447 | ]
448 |
449 | [[package]]
450 | name = "tomli"
451 | version = "2.0.1"
452 | requires_python = ">=3.7"
453 | summary = "A lil' TOML parser"
454 | groups = ["default"]
455 | marker = "python_version < \"3.11\""
456 | files = [
457 | {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
458 | {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
459 | ]
460 |
461 | [[package]]
462 | name = "typing-extensions"
463 | version = "4.10.0"
464 | requires_python = ">=3.8"
465 | summary = "Backported and Experimental Type Hints for Python 3.8+"
466 | groups = ["default"]
467 | files = [
468 | {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
469 | {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
470 | ]
471 |
472 | [[package]]
473 | name = "win32-setctime"
474 | version = "1.1.0"
475 | requires_python = ">=3.5"
476 | summary = "A small Python utility to set file creation time on Windows"
477 | groups = ["default"]
478 | marker = "sys_platform == \"win32\""
479 | files = [
480 | {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
481 | {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
482 | ]
483 |
484 | [[package]]
485 | name = "yarl"
486 | version = "1.9.4"
487 | requires_python = ">=3.7"
488 | summary = "Yet another URL library"
489 | groups = ["default"]
490 | dependencies = [
491 | "idna>=2.0",
492 | "multidict>=4.0",
493 | ]
494 | files = [
495 | {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"},
496 | {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"},
497 | {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"},
498 | {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"},
499 | {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"},
500 | {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"},
501 | {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"},
502 | {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"},
503 | {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"},
504 | {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"},
505 | {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"},
506 | {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"},
507 | {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"},
508 | {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"},
509 | {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"},
510 | {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"},
511 | {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"},
512 | ]
513 |
514 | [[package]]
515 | name = "zipp"
516 | version = "3.17.0"
517 | requires_python = ">=3.8"
518 | summary = "Backport of pathlib-compatible object wrapper for zip files"
519 | groups = ["default"]
520 | marker = "python_version < \"3.10\""
521 | files = [
522 | {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
523 | {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
524 | ]
525 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "nonebot-plugin-fishing"
3 | version = "0.2.4_alpha5"
4 | description = "你甚至可以电子钓鱼"
5 | authors = [
6 | {name = "ALittleBot", email = "160833462+C14H22O@users.noreply.github.com"},
7 | ]
8 | dependencies = [
9 | "nonebot2>=2.2.1",
10 | "pydantic>=1.10",
11 | "nonebot-plugin-localstore>=0.6.0",
12 | "sqlalchemy>=2.0.27",
13 | "aiosqlite>=0.20.0",
14 | "nonebot-plugin-orm>=0.7.1",
15 | ]
16 | readme = "README.md"
17 | license = {text = "MIT"}
18 | requires-python = ">=3.8"
19 |
--------------------------------------------------------------------------------