初次提交请多关照

This commit is contained in:
2025-09-28 00:15:16 +08:00
commit 3d0c77d1e6
14 changed files with 3183 additions and 0 deletions

4
.dockerignore Normal file
View File

@ -0,0 +1,4 @@
/.env
/.git
__pycache__

1
.env.dev Normal file
View File

@ -0,0 +1 @@
DRIVER=~fastapi+~httpx+~websockets

4
.env.example Normal file
View File

@ -0,0 +1,4 @@
ENVIRONMENT=dev
PORT=21333
ENABLE_CONSOLE=true

1
.env.prod Normal file
View File

@ -0,0 +1 @@
DRIVER=~fastapi+~httpx+~websockets

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/.env
__pycache__

29
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,29 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Poetry: Export requirements.txt (Production)",
"type": "shell",
"command": "poetry export -f requirements.txt --output requirements.txt --without-hashes",
"group": "build",
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": [],
"detail": "导出生产环境依赖到 requirements.txt不包含开发依赖和哈希值。"
},
{
"label": "Poetry: Export requirements.txt (Full)",
"type": "shell",
"command": "poetry export -f requirements.txt --output requirements.txt",
"group": "build",
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": [],
"detail": "导出所有依赖(包括生产和开发依赖)到 requirements.txt包含哈希值以确保完全一致。"
}
]
}

8
Dockerfile Normal file
View File

@ -0,0 +1,8 @@
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt --no-deps
COPY . .
CMD [ "python", "bot.py" ]

37
bot.py Normal file
View File

@ -0,0 +1,37 @@
import os
import dotenv
import nonebot
from nonebot.adapters.console import Adapter as ConsoleAdapter
from nonebot.adapters.discord import Adapter as DiscordAdapter
from nonebot.adapters.minecraft import Adapter as MinecraftAdapter
from nonebot.adapters.onebot.v11 import Adapter as OnebotAdapter
dotenv.load_dotenv()
env = os.environ.get("ENVIRONMENT", "prod")
env_enable_console = os.environ.get("ENABLE_CONSOLE", "none")
env_enable_qq = os.environ.get("ENABLE_QQ", "none")
env_enable_discord = os.environ.get("ENABLE_DISCORD", "none")
env_enable_minecraft = os.environ.get("ENABLE_MINECRAFT", "none")
if __name__ == "__main__":
nonebot.init()
driver = nonebot.get_driver()
if (env != "prod" and env != "test" and env_enable_console.upper() != "FALSE") or (env_enable_console.upper() == "TRUE"):
driver.register_adapter(ConsoleAdapter)
if env_enable_qq.upper() == "TRUE":
driver.register_adapter(OnebotAdapter)
if env_enable_discord.upper() == "TRUE":
driver.register_adapter(DiscordAdapter)
if env_enable_minecraft.upper() == "TRUE":
driver.register_adapter(MinecraftAdapter)
# nonebot.load_builtin_plugin("echo")
nonebot.load_plugins("konabot/plugins")
nonebot.run()

View File

@ -0,0 +1,9 @@
from nonebot import on_message
from nonebot_plugin_alconna import UniMessage, UniMsg
evt = on_message()
@evt.handle()
async def _(msg: UniMsg):
if msg.extract_plain_text() == "":
await evt.send(await UniMessage().text("").export())

View File

@ -0,0 +1,16 @@
from nonebot_plugin_alconna import Alconna, Args, Field, UniMessage, on_alconna
from konabot.plugins.weather.fetcher import fetch_radar
evt = on_alconna(Alconna(
"!雷达回波",
Args["region", str, Field(missing_tips=lambda: "请输入需要获取的地区,例如 !雷达回波 华南")],
), use_cmd_start=False, use_cmd_sep=False, skip_for_unmatch=False)
@evt.handle()
async def _(region: str):
img, err = await fetch_radar(region)
if err != None:
await evt.send(await UniMessage().text(err).export())
return
await evt.send(await UniMessage.image(raw=img).export())

View File

@ -0,0 +1,37 @@
import functools
import httpx
from bs4 import BeautifulSoup
STATION_LINKS = {
"全国": "https://www.nmc.cn/publish/radar/chinaall.html",
"华北": "https://www.nmc.cn/publish/radar/huabei.html",
"东北": "https://www.nmc.cn/publish/radar/dongbei.html",
"华东": "https://www.nmc.cn/publish/radar/huadong.html",
"华中": "https://www.nmc.cn/publish/radar/huazhong.html",
"华南": "https://www.nmc.cn/publish/radar/huanan.html",
"西南": "https://www.nmc.cn/publish/radar/xinan.html",
"西北": "https://www.nmc.cn/publish/radar/xibei.html",
}
async def fetch_radar(station: str) -> tuple[bytes, None] | tuple[None, str]:
if station not in STATION_LINKS.keys():
return None, f"获取失败:站点不存在。可用的站点:{','.join(STATION_LINKS.keys())}"
async with httpx.AsyncClient() as client:
response = await client.get(STATION_LINKS[station])
if response.status_code != 200:
return None, "获取失败:可能存在网络错误"
soup = BeautifulSoup(response.text, "lxml")
links = functools.reduce(lambda x, y: x + y, [
img.get_attribute_list("src") for img in soup.select("div.imgblock>img#imgpath")
])
if len(links) != 1:
return None, "获取失败:链接获取失败"
response2 = await client.get(links[0])
if response2.status_code != 200:
return None, "获取失败:图片下载失败"
return response2.content, None

2929
poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

26
pyproject.toml Normal file
View File

@ -0,0 +1,26 @@
[project]
name = "konabot"
version = "0.1.0"
description = "在 MTTU 内部使用的 bot"
authors = [
{name = "passthem",email = "Passthem183@gmail.com"}
]
readme = "README.md"
requires-python = ">=3.12,<4.0"
dependencies = [
"nonebot2[all] (>=2.4.3,<3.0.0)",
"nonebot-adapter-onebot (>=2.4.6,<3.0.0)",
"nonebot-adapter-console (>=0.9.0,<0.10.0)",
"nonebot-adapter-discord (>=0.1.8,<0.2.0)",
"nonebot-adapter-minecraft (>=1.5.2,<2.0.0)",
"nonebot-plugin-alconna (>=0.59.4,<0.60.0)",
"nonebot-plugin-apscheduler (>=0.5.0,<0.6.0)",
"requests (>=2.32.5,<3.0.0)",
"beautifulsoup4 (>=4.13.5,<5.0.0)",
"lxml (>=6.0.2,<7.0.0)",
]
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

79
requirements.txt Normal file
View File

@ -0,0 +1,79 @@
aio-mc-rcon==3.4.1 ; python_version >= "3.12" and python_version < "4.0"
aiodns==3.5.0 ; python_version >= "3.12" and python_version < "4.0"
aiohappyeyeballs==2.6.1 ; python_version >= "3.12" and python_version < "4.0"
aiohttp==3.12.15 ; python_version >= "3.12" and python_version < "4.0"
aiosignal==1.4.0 ; python_version >= "3.12" and python_version < "4.0"
annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "4.0"
anyio==4.11.0 ; python_version >= "3.12" and python_version < "4.0"
apscheduler==3.11.0 ; python_version >= "3.12" and python_version < "4.0"
arclet-alconna-tools==0.7.11 ; python_version >= "3.12" and python_version < "4.0"
arclet-alconna==1.8.40 ; python_version >= "3.12" and python_version < "4.0"
attrs==25.3.0 ; python_version >= "3.12" and python_version < "4.0"
beautifulsoup4==4.13.5 ; python_version >= "3.12" and python_version < "4.0"
brotli==1.1.0 ; python_version >= "3.12" and python_version < "4.0" and platform_python_implementation == "CPython"
brotlicffi==1.1.0.0 ; python_version >= "3.12" and python_version < "4.0" and platform_python_implementation != "CPython"
certifi==2025.8.3 ; python_version >= "3.12" and python_version < "4.0"
cffi==2.0.0 ; python_version >= "3.12" and python_version < "4.0"
charset-normalizer==3.4.3 ; python_version >= "3.12" and python_version < "4.0"
click==8.3.0 ; python_version >= "3.12" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows")
exceptiongroup==1.3.0 ; python_version >= "3.12" and python_version < "4.0"
fastapi==0.117.1 ; python_version >= "3.12" and python_version < "4.0"
frozenlist==1.7.0 ; python_version >= "3.12" and python_version < "4.0"
h11==0.16.0 ; python_version >= "3.12" and python_version < "4.0"
h2==4.3.0 ; python_version >= "3.12" and python_version < "4.0"
hpack==4.1.0 ; python_version >= "3.12" and python_version < "4.0"
httpcore==1.0.9 ; python_version >= "3.12" and python_version < "4.0"
httptools==0.6.4 ; python_version >= "3.12" and python_version < "4.0"
httpx==0.28.1 ; python_version >= "3.12" and python_version < "4.0"
hyperframe==6.1.0 ; python_version >= "3.12" and python_version < "4.0"
idna==3.10 ; python_version >= "3.12" and python_version < "4.0"
importlib-metadata==8.7.0 ; python_version >= "3.12" and python_version < "4.0"
linkify-it-py==2.0.3 ; python_version >= "3.12" and python_version < "4.0"
loguru==0.7.3 ; python_version >= "3.12" and python_version < "4.0"
lxml==6.0.2 ; python_version >= "3.12" and python_version < "4.0"
markdown-it-py==4.0.0 ; python_version >= "3.12" and python_version < "4.0"
mdit-py-plugins==0.5.0 ; python_version >= "3.12" and python_version < "4.0"
mdurl==0.1.2 ; python_version >= "3.12" and python_version < "4.0"
msgpack==1.1.1 ; python_version >= "3.12" and python_version < "4.0"
multidict==6.6.4 ; python_version >= "3.12" and python_version < "4.0"
nepattern==0.7.7 ; python_version >= "3.12" and python_version < "4.0"
nonebot-adapter-console==0.9.0 ; python_version >= "3.12" and python_version < "4.0"
nonebot-adapter-discord==0.1.8 ; python_version >= "3.12" and python_version < "4.0"
nonebot-adapter-minecraft==1.5.2 ; python_version >= "3.12" and python_version < "4.0"
nonebot-adapter-onebot==2.4.6 ; python_version >= "3.12" and python_version < "4.0"
nonebot-plugin-alconna==0.59.4 ; python_version >= "3.12" and python_version < "4.0"
nonebot-plugin-apscheduler==0.5.0 ; python_version >= "3.12" and python_version < "4.0"
nonebot-plugin-waiter==0.8.1 ; python_version >= "3.12" and python_version < "4.0"
nonebot2==2.4.3 ; python_version >= "3.12" and python_version < "4.0"
nonechat==0.6.1 ; python_version >= "3.12" and python_version < "4.0"
platformdirs==4.4.0 ; python_version >= "3.12" and python_version < "4.0"
propcache==0.3.2 ; python_version >= "3.12" and python_version < "4.0"
pycares==4.11.0 ; python_version >= "3.12" and python_version < "4.0"
pycparser==2.23 ; python_version >= "3.12" and python_version < "4.0" and implementation_name != "PyPy"
pydantic-core==2.33.2 ; python_version >= "3.12" and python_version < "4.0"
pydantic==2.11.9 ; python_version >= "3.12" and python_version < "4.0"
pygments==2.19.2 ; python_version >= "3.12" and python_version < "4.0"
pygtrie==2.5.0 ; python_version >= "3.12" and python_version < "4.0"
python-dotenv==1.1.1 ; python_version >= "3.12" and python_version < "4.0"
pyyaml==6.0.3 ; python_version >= "3.12" and python_version < "4.0"
requests==2.32.5 ; python_version >= "3.12" and python_version < "4.0"
rich==14.1.0 ; python_version >= "3.12" and python_version < "4.0"
sniffio==1.3.1 ; python_version >= "3.12" and python_version < "4.0"
soupsieve==2.8 ; python_version >= "3.12" and python_version < "4.0"
starlette==0.48.0 ; python_version >= "3.12" and python_version < "4.0"
tarina==0.6.8 ; python_version >= "3.12" and python_version < "4.0"
textual==3.7.1 ; python_version >= "3.12" and python_version < "4.0"
typing-extensions==4.15.0 ; python_version >= "3.12" and python_version < "4.0"
typing-inspection==0.4.1 ; python_version >= "3.12" and python_version < "4.0"
tzdata==2025.2 ; python_version >= "3.12" and python_version < "4.0" and platform_system == "Windows"
tzlocal==5.3.1 ; python_version >= "3.12" and python_version < "4.0"
uc-micro-py==1.0.3 ; python_version >= "3.12" and python_version < "4.0"
urllib3==2.5.0 ; python_version >= "3.12" and python_version < "4.0"
uvicorn==0.37.0 ; python_version >= "3.12" and python_version < "4.0"
uvloop==0.21.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy"
watchfiles==1.1.0 ; python_version >= "3.12" and python_version < "4.0"
websockets==15.0.1 ; python_version >= "3.12" and python_version < "4.0"
win32-setctime==1.2.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32"
yarl==1.20.1 ; python_version >= "3.12" and python_version < "4.0"
zipp==3.23.0 ; python_version >= "3.12" and python_version < "4.0"