🚧 add handler di example

This commit is contained in:
yanyongyu
2021-12-31 23:58:59 +08:00
parent ec35f292bd
commit 78d0ec847e
12 changed files with 780 additions and 1055 deletions

View File

@ -15,3 +15,252 @@ options:
## 添加一个处理依赖
## 事件处理流程
## 获取上下文信息
### Bot
```python {7-9}
from typing import Union
from nonebot.adapters import Bot
from nonebot.adapters.ding import Bot as DingBot
from nonebot.adapters.onebot.v11 import Bot as OneBotV11Bot
async def _(foo: Bot): ...
async def _(foo: Union[DingBot, OneBotV11Bot]): ...
async def _(bot): ... # 兼容性处理
```
### Event
```python {6-8}
from typing import Union
from nonebot.adapters import Event
from nonebot.adapters.onebot.v11 import PrivateMessageEvent, GroupMessageEvent
async def _(foo: Event): ...
async def _(foo: Union[PrivateMessageEvent, GroupMessageEvent]): ...
async def _(event): ... # 兼容性处理
```
### EventType
```python {3}
from nonebot.params import EventType
async def _(foo: str = EventType()): ...
```
### EventMessage
```python {4}
from nonebot.adapters import Message
from nonebot.params import EventMessage
async def _(foo: str = EventMessage()): ...
```
### EventPlainText
```python {3}
from nonebot.params import EventPlainText
async def _(foo: str = EventPlainText()): ...
```
### EventToMe
```python {3}
from nonebot.params import EventToMe
async def _(foo: bool = EventToMe()): ...
```
### State
```python {4}
from nonebot.params import State
from nonebot.typing import T_State
async def _(foo: T_State = State()): ...
```
### Command
```python {7}
from nonebot import on_command
from nonebot.params import Command
matcher = on_command("cmd")
@matcher.handle()
async def _(foo: Tuple[str, ...] = Command()): ...
```
### CommandArg
```python {8}
from nonebot import on_command
from nonebot.adapters import Message
from nonebot.params import CommandArg
matcher = on_command("cmd")
@matcher.handle()
async def _(foo: Message = CommandArg()): ...
```
### ShellCommandArgs
```python {7}
from nonebot import on_command
from nonebot.params import ShellCommandArgs
matcher = on_shell_command("cmd", parser)
@matcher.handle()
async def _(foo: Dict[str, Any] = ShellCommandArgs()): ...
```
### ShellCommandArgv
```python {7}
from nonebot import on_command
from nonebot.params import ShellCommandArgs
matcher = on_shell_command("cmd")
@matcher.handle()
async def _(foo: List[str] = ShellCommandArgv()): ...
```
### RegexMatched
```python {7}
from nonebot import on_regex
from nonebot.params import RegexMatched
matcher = on_regex("regex")
@matcher.handle()
async def _(foo: str = RegexMatched()): ...
```
### RegexGroup
```python {7}
from nonebot import on_regex
from nonebot.params import RegexGroup
matcher = on_regex("regex")
@matcher.handle()
async def _(foo: Tuple[Any, ...] = RegexGroup()): ...
```
### RegexDict
```python {7}
from nonebot import on_regex
from nonebot.params import RegexDict
matcher = on_regex("regex")
@matcher.handle()
async def _(foo: Dict[str, Any] = RegexDict()): ...
```
### Matcher
```python {7}
from nonebot import on_message
from nonebot.matcher import Matcher
foo = on_message()
@foo.handle()
async def _(matcher: Matcher): ...
```
### Received
```python {8}
from nonebot import on_message
from nonebot.adapters import Event
from nonebot.params import Received
matcher = on_message()
@matcher.receive("id")
async def _(foo: Event = Received("id")): ...
```
### LastReceived
```python {8}
from nonebot import on_message
from nonebot.adapters import Event
from nonebot.params import LastReceived
matcher = on_message()
@matcher.receive("any")
async def _(foo: Event = LastReceived()): ...
```
### Arg
```python {8-9}
from nonebot.params import Arg
from nonebot import on_message
from nonebot.adapters import Message
matcher = on_message()
@matcher.got("key")
async def _(key: Message = Arg()): ...
async def _(foo: Message = Arg("key")): ...
```
### ArgStr
```python {7-8}
from nonebot import on_message
from nonebot.params import ArgStr
matcher = on_message()
@matcher.got("key")
async def _(key: str = ArgStr()): ...
async def _(foo: str = ArgStr("key")): ...
```
### ArgPlainText
```python {7-8}
from nonebot import on_message
from nonebot.params import ArgPlainText
matcher = on_message()
@matcher.got("key")
async def _(key: str = ArgPlainText()): ...
async def _(foo: str = ArgPlainText("key")): ...
```
### Exception
```python {4}
from nonebot.message import run_postprocessor
@run_postprocessor
async def _(e: Exception): ...
```
### Default
```python {1}
async def _(foo="bar"): ...
```

View File

@ -1,12 +1,20 @@
import React from "react";
import clsx from "clsx";
import React, { useRef, useState } from "react";
import { ChromePicker } from "react-color";
import { usePagination } from "react-use-pagination";
import adapters from "../../static/adapters.json";
import { useFilteredObjs } from "../libs/store";
import { Tag, useFilteredObjs } from "../libs/store";
import Card from "./Card";
import Modal from "./Modal";
import ModalAction from "./ModalAction";
import ModalContent from "./ModalContent";
import ModalTitle from "./ModalTitle";
import Paginate from "./Paginate";
import TagComponent from "./Tag";
export default function Adapter(): JSX.Element {
const [modalOpen, setModalOpen] = useState<boolean>(false);
const {
filter,
setFilter,
@ -20,6 +28,93 @@ export default function Adapter(): JSX.Element {
const { startIndex, endIndex } = props;
const currentAdapters = filteredAdapters.slice(startIndex, endIndex + 1);
const [form, setForm] = useState<{
name: string;
desc: string;
projectLink: string;
moduleName: string;
homepage: string;
}>({ name: "", desc: "", projectLink: "", moduleName: "", homepage: "" });
const ref = useRef<HTMLInputElement>(null);
const [tags, setTags] = useState<Tag[]>([]);
const [label, setLabel] = useState<string>("");
const [color, setColor] = useState<string>("#ea5252");
const onSubmit = () => {
setModalOpen(false);
const title = encodeURIComponent(`Adapter: ${form.name}`).replace(
/%2B/gi,
"+"
);
const body = encodeURIComponent(
`
**协议名称:**
${form.name}
**协议功能:**
${form.desc}
**PyPI 项目名:**
${form.projectLink}
**协议 import 包名:**
${form.moduleName}
**协议项目仓库/主页链接:**
${form.homepage}
**标签:**
${JSON.stringify(tags)}
`.trim()
).replace(/%2B/gi, "+");
window.open(
`https://github.com/nonebot/nonebot2/issues/new?title=${title}&body=${body}&labels=Adapter`
);
};
const onChange = (event) => {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
setForm({
...form,
[name]: value,
});
event.preventDefault();
};
const onChangeLabel = (event) => {
setLabel(event.target.value);
};
const onChangeColor = (color) => {
setColor(color.hex);
};
const validateTag = () => {
return label.length >= 1 && label.length <= 10;
};
const newTag = () => {
if (tags.length >= 3) {
return;
}
if (validateTag()) {
const tag = { label, color };
setTags([...tags, tag]);
}
};
const delTag = (index: number) => {
setTags(tags.filter((_, i) => i !== index));
};
const insertTagType = (text: string) => {
setLabel(text + label);
ref.current.value = text + label;
};
return (
<>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-4 px-4">
@ -29,7 +124,10 @@ export default function Adapter(): JSX.Element {
placeholder="搜索适配器"
onChange={(event) => setFilter(event.target.value)}
/>
<button className="w-full rounded-lg bg-hero text-white">
<button
className="w-full rounded-lg bg-hero text-white"
onClick={() => setModalOpen(true)}
>
</button>
</div>
@ -44,6 +142,129 @@ export default function Adapter(): JSX.Element {
<div className="grid grid-cols-1 p-4">
<Paginate {...props} />
</div>
<Modal active={modalOpen} setActive={setModalOpen}>
<ModalTitle title={"适配器信息"} />
<ModalContent>
<form onSubmit={onSubmit}>
<div className="grid grid-cols-1 gap-4 p-4">
<label className="flex flex-wrap">
<span className="mr-2">:</span>
<input
type="text"
name="name"
maxLength={20}
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">:</span>
<input
type="text"
name="desc"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">PyPI :</span>
<input
type="text"
name="projectLink"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">import :</span>
<input
type="text"
name="moduleName"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">/:</span>
<input
type="text"
name="homepage"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
</div>
</form>
<div className="px-4">
<label className="flex flex-wrap">
<span className="mr-2">:</span>
{tags.map((tag, index) => (
<TagComponent
key={index}
{...tag}
className="cursor-pointer"
onClick={() => delTag(index)}
/>
))}
</label>
</div>
<div className="px-4 pt-4">
<input
ref={ref}
type="text"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChangeLabel}
/>
<ChromePicker
className="mt-2"
color={color}
disableAlpha={true}
onChangeComplete={onChangeColor}
/>
<div className="flex flex-wrap mt-2 items-center">
<span className="mr-2">Type:</span>
<button
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => insertTagType("a:")}
>
Adapter
</button>
<button
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => insertTagType("t:")}
>
Topic
</button>
</div>
<div className="flex mt-2">
<TagComponent label={label} color={color} />
<button
className={clsx(
"px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]",
{ "pointer-events-none opacity-60": !validateTag() }
)}
onClick={newTag}
>
</button>
</div>
</div>
</ModalContent>
<ModalAction>
<button
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => setModalOpen(false)}
>
</button>
<button
className="ml-2 px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={onSubmit}
>
</button>
</ModalAction>
</Modal>
</>
);
}

View File

@ -1,12 +1,20 @@
import React from "react";
import clsx from "clsx";
import React, { useRef, useState } from "react";
import { ChromePicker } from "react-color";
import { usePagination } from "react-use-pagination";
import bots from "../../static/bots.json";
import { useFilteredObjs } from "../libs/store";
import { Tag, useFilteredObjs } from "../libs/store";
import Card from "./Card";
import Modal from "./Modal";
import ModalAction from "./ModalAction";
import ModalContent from "./ModalContent";
import ModalTitle from "./ModalTitle";
import Paginate from "./Paginate";
import TagComponent from "./Tag";
export default function Adapter(): JSX.Element {
const [modalOpen, setModalOpen] = useState<boolean>(false);
const {
filter,
setFilter,
@ -20,6 +28,80 @@ export default function Adapter(): JSX.Element {
const { startIndex, endIndex } = props;
const currentBots = filteredBots.slice(startIndex, endIndex + 1);
const [form, setForm] = useState<{
name: string;
desc: string;
homepage: string;
}>({ name: "", desc: "", homepage: "" });
const ref = useRef<HTMLInputElement>(null);
const [tags, setTags] = useState<Tag[]>([]);
const [label, setLabel] = useState<string>("");
const [color, setColor] = useState<string>("#ea5252");
const onSubmit = () => {
setModalOpen(false);
const title = encodeURIComponent(`Bot: ${form.name}`).replace(/%2B/gi, "+");
const body = encodeURIComponent(
`
**机器人名称:**
${form.name}
**机器人功能:**
${form.desc}
**机器人项目仓库/主页链接:**
${form.homepage}
**标签:**
${JSON.stringify(tags)}
`.trim()
).replace(/%2B/gi, "+");
window.open(
`https://github.com/nonebot/nonebot2/issues/new?title=${title}&body=${body}&labels=Bot`
);
};
const onChange = (event) => {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
setForm({
...form,
[name]: value,
});
event.preventDefault();
};
const onChangeLabel = (event) => {
setLabel(event.target.value);
};
const onChangeColor = (color) => {
setColor(color.hex);
};
const validateTag = () => {
return label.length >= 1 && label.length <= 10;
};
const newTag = () => {
if (tags.length >= 3) {
return;
}
if (validateTag()) {
const tag = { label, color };
setTags([...tags, tag]);
}
};
const delTag = (index: number) => {
setTags(tags.filter((_, i) => i !== index));
};
const insertTagType = (text: string) => {
setLabel(text + label);
ref.current.value = text + label;
};
return (
<>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-4 px-4">
@ -29,7 +111,10 @@ export default function Adapter(): JSX.Element {
placeholder="搜索机器人"
onChange={(event) => setFilter(event.target.value)}
/>
<button className="w-full rounded-lg bg-hero text-white">
<button
className="w-full rounded-lg bg-hero text-white"
onClick={() => setModalOpen(true)}
>
</button>
</div>
@ -44,6 +129,111 @@ export default function Adapter(): JSX.Element {
<div className="grid grid-cols-1 p-4">
<Paginate {...props} />
</div>
<Modal active={modalOpen} setActive={setModalOpen}>
<ModalTitle title={"机器人信息"} />
<ModalContent>
<form onSubmit={onSubmit}>
<div className="grid grid-cols-1 gap-4 p-4">
<label className="flex flex-wrap">
<span className="mr-2">:</span>
<input
type="text"
name="name"
maxLength={20}
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">:</span>
<input
type="text"
name="desc"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">/:</span>
<input
type="text"
name="homepage"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
</div>
</form>
<div className="px-4">
<label className="flex flex-wrap">
<span className="mr-2">:</span>
{tags.map((tag, index) => (
<TagComponent
key={index}
{...tag}
className="cursor-pointer"
onClick={() => delTag(index)}
/>
))}
</label>
</div>
<div className="px-4 pt-4">
<input
ref={ref}
type="text"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChangeLabel}
/>
<ChromePicker
className="mt-2"
color={color}
disableAlpha={true}
onChangeComplete={onChangeColor}
/>
<div className="flex flex-wrap mt-2 items-center">
<span className="mr-2">Type:</span>
<button
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => insertTagType("a:")}
>
Adapter
</button>
<button
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => insertTagType("t:")}
>
Topic
</button>
</div>
<div className="flex mt-2">
<TagComponent label={label} color={color} />
<button
className={clsx(
"px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]",
{ "pointer-events-none opacity-60": !validateTag() }
)}
onClick={newTag}
>
</button>
</div>
</div>
</ModalContent>
<ModalAction>
<button
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => setModalOpen(false)}
>
</button>
<button
className="ml-2 px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={onSubmit}
>
</button>
</ModalAction>
</Modal>
</>
);
}

View File

@ -94,5 +94,13 @@
"homepage": "https://github.com/ssttkkl/PixivBot",
"tags": [],
"is_official": false
},
{
"name": "SeaBot_QQ",
"desc": "一个能够获取新闻资讯并推送至QQ的群聊机器人。",
"author": "B1ue1nWh1te",
"homepage": "https://github.com/B1ue1nWh1te/SeaBot_QQ",
"tags": [],
"is_official": false
}
]

View File

@ -688,5 +688,85 @@
"homepage": "https://github.com/yzyyz1387/nonebot_plugin_heisi",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_picsbank",
"project_link": "nonebot-plugin-picsbank",
"name": "picsbank",
"desc": "匹配图片进行回答",
"author": "Diaosi1111",
"homepage": "https://github.com/Diaosi1111/nonebot_plugin_picsbank",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_tvseries",
"project_link": "nonebot-plugin-tvseries",
"name": "剧集更新列表",
"desc": "获取聚集更新",
"author": "kexue-z",
"homepage": "https://github.com/kexue-z/nonebot-plugin-tvseries",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_lolmatch",
"project_link": "nonebot-plugin-lolmatch",
"name": "lol比赛信息",
"desc": "简单的lol比赛信息插件订阅后会定时推送当日比赛结果",
"author": "Diaosi1111",
"homepage": "https://github.com/Diaosi1111/nonebot_plugin_lolmatch",
"tags": [],
"is_official": false
},
{
"module_name": "OlivOS",
"project_link": "olivos.nb2",
"name": "OlivOS.nb2",
"desc": "在 NoneBot2 中加载 OlivOS 插件",
"author": "j1g5awi",
"homepage": "https://github.com/nonepkg/OlivOS.nb2",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_htmlrender",
"project_link": "nonebot-plugin-htmlrender",
"name": "通过浏览器来生成图片",
"desc": "通过playwright加一点点前端知识来简单的生成图片",
"author": "kexue-z",
"homepage": "https://github.com/kexue-z/nonebot-plugin-htmlrender",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_admin",
"project_link": "nonebot-plugin-admin",
"name": "简易群管",
"desc": "简易群管 踢 禁 改",
"author": "yzyyz1387",
"homepage": "https://github.com/yzyyz1387/nonebot_plugin_admin",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_logo",
"project_link": "nonebot-plugin-logo",
"name": "nonebot-plugin-logo",
"desc": "PornHub、Youtube 等风格logo生成",
"author": "MeetWq",
"homepage": "https://github.com/MeetWq/nonebot-plugin-logo",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_memes",
"project_link": "nonebot-plugin-memes",
"name": "Memes generator",
"desc": "表情包制作",
"author": "MeetWq",
"homepage": "https://github.com/MeetWq/nonebot-plugin-memes",
"tags": [],
"is_official": false
}
]