From e27c1bc3532e21263c6c03ae671b112ac9995bc1 Mon Sep 17 00:00:00 2001 From: Azide Date: Thu, 10 Mar 2022 23:42:01 +0800 Subject: [PATCH 01/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=85=B3?= =?UTF-8?q?=E4=BA=8EBISON=5FUSE=5FPIC=5FMERGE=E9=85=8D=E7=BD=AE=E9=A1=B9?= =?UTF-8?q?=E7=9A=84=E7=9B=B8=E5=85=B3=E6=96=87=E6=A1=A3=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/usage/README.md | 10 ++++++++++ docs/usage/pic/forward-msg-simple1.png | Bin 0 -> 36821 bytes docs/usage/pic/forward-msg-simple2.png | Bin 0 -> 11817 bytes 3 files changed, 10 insertions(+) create mode 100644 docs/usage/pic/forward-msg-simple1.png create mode 100644 docs/usage/pic/forward-msg-simple2.png diff --git a/docs/usage/README.md b/docs/usage/README.md index ed88c54..b88299f 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -115,6 +115,16 @@ sidebar: auto 开启,默认关 - `BISON_USE_QUEUE`: 是否用队列的方式发送消息,降低发送频率,默认开 - `BISON_RESEND_TIMES`: 最大重发次数,默认 0 +- `BISON_USE_PIC_MERGE`: 是否启用多图片时合并转发(仅限群) + - `0`: 不启用(默认) + - `1`: 首条消息单独发送,剩余图片合并转发 + - `2`: 所有消息全部合并转发 + ::: details 配置项示例 + - 当`BISON_USE_PIC_MERGE=1`时: + ![simple1](./pic/forward-msg-simple1.png) + - 当`BISON_USE_PIC_MERGE=2`时: + ![simple1](./pic/forward-msg-simple2.png) + ::: ## 使用 diff --git a/docs/usage/pic/forward-msg-simple1.png b/docs/usage/pic/forward-msg-simple1.png new file mode 100644 index 0000000000000000000000000000000000000000..c10e60fa3a96384da580e673f063495a3e984e05 GIT binary patch literal 36821 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 literal 0 HcmV?d00001 diff --git a/docs/usage/pic/forward-msg-simple2.png b/docs/usage/pic/forward-msg-simple2.png new file mode 100644 index 0000000000000000000000000000000000000000..a3f807b031a61f8fe7f5f9e554e77eaf06d3d96e GIT binary patch literal 11817 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 PALx;~j#` Date: Thu, 10 Mar 2022 15:47:26 +0000 Subject: [PATCH 02/25] auto fix by pre-commit hooks --- docs/usage/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/usage/README.md b/docs/usage/README.md index b88299f..0ac89ff 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -119,12 +119,12 @@ sidebar: auto - `0`: 不启用(默认) - `1`: 首条消息单独发送,剩余图片合并转发 - `2`: 所有消息全部合并转发 - ::: details 配置项示例 + ::: details 配置项示例 - 当`BISON_USE_PIC_MERGE=1`时: - ![simple1](./pic/forward-msg-simple1.png) + ![simple1](./pic/forward-msg-simple1.png) - 当`BISON_USE_PIC_MERGE=2`时: - ![simple1](./pic/forward-msg-simple2.png) - ::: + ![simple1](./pic/forward-msg-simple2.png) + ::: ## 使用 From 897e8f3f2cf727b7eaf34331a63c36a2e57d42d5 Mon Sep 17 00:00:00 2001 From: Azide Date: Fri, 11 Mar 2022 00:18:50 +0800 Subject: [PATCH 03/25] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E7=BC=A9=E8=BF=9B=E6=96=B9=E5=BC=8F=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?bison-use-pic-merge=E9=85=8D=E7=BD=AE=E9=A1=B9=E8=AD=A6?= =?UTF-8?q?=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.temp/internal/clientAppEnhances.js | 11 ++ .../.temp/internal/clientAppRootComponents.js | 5 + .../.temp/internal/clientAppSetups.js | 9 + .../.temp/internal/layoutComponents.js | 6 + .../.temp/internal/pagesComponents.js | 12 ++ docs/.vuepress/.temp/internal/pagesData.js | 10 ++ docs/.vuepress/.temp/internal/pagesRoutes.js | 33 ++++ docs/.vuepress/.temp/internal/siteData.js | 21 +++ docs/.vuepress/.temp/internal/themeData.js | 62 +++++++ docs/.vuepress/.temp/pages/404.html.js | 26 +++ docs/.vuepress/.temp/pages/404.html.vue | 1 + docs/.vuepress/.temp/pages/dev/index.html.js | 65 +++++++ docs/.vuepress/.temp/pages/dev/index.html.vue | 78 +++++++++ docs/.vuepress/.temp/pages/index.html.js | 59 +++++++ docs/.vuepress/.temp/pages/index.html.vue | 1 + .../.vuepress/.temp/pages/usage/index.html.js | 101 +++++++++++ .../.temp/pages/usage/index.html.vue | 162 ++++++++++++++++++ docs/.vuepress/.temp/styles/index.scss | 0 docs/.vuepress/.temp/styles/palette.scss | 0 docs/.vuepress/.temp/vite-root/index.html | 13 ++ docs/usage/README.md | 7 +- 21 files changed, 680 insertions(+), 2 deletions(-) create mode 100644 docs/.vuepress/.temp/internal/clientAppEnhances.js create mode 100644 docs/.vuepress/.temp/internal/clientAppRootComponents.js create mode 100644 docs/.vuepress/.temp/internal/clientAppSetups.js create mode 100644 docs/.vuepress/.temp/internal/layoutComponents.js create mode 100644 docs/.vuepress/.temp/internal/pagesComponents.js create mode 100644 docs/.vuepress/.temp/internal/pagesData.js create mode 100644 docs/.vuepress/.temp/internal/pagesRoutes.js create mode 100644 docs/.vuepress/.temp/internal/siteData.js create mode 100644 docs/.vuepress/.temp/internal/themeData.js create mode 100644 docs/.vuepress/.temp/pages/404.html.js create mode 100644 docs/.vuepress/.temp/pages/404.html.vue create mode 100644 docs/.vuepress/.temp/pages/dev/index.html.js create mode 100644 docs/.vuepress/.temp/pages/dev/index.html.vue create mode 100644 docs/.vuepress/.temp/pages/index.html.js create mode 100644 docs/.vuepress/.temp/pages/index.html.vue create mode 100644 docs/.vuepress/.temp/pages/usage/index.html.js create mode 100644 docs/.vuepress/.temp/pages/usage/index.html.vue create mode 100644 docs/.vuepress/.temp/styles/index.scss create mode 100644 docs/.vuepress/.temp/styles/palette.scss create mode 100644 docs/.vuepress/.temp/vite-root/index.html diff --git a/docs/.vuepress/.temp/internal/clientAppEnhances.js b/docs/.vuepress/.temp/internal/clientAppEnhances.js new file mode 100644 index 0000000..9ce5486 --- /dev/null +++ b/docs/.vuepress/.temp/internal/clientAppEnhances.js @@ -0,0 +1,11 @@ +import clientAppEnhance0 from 'E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/plugin-external-link-icon/lib/client/clientAppEnhance.js' +import clientAppEnhance1 from 'E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/plugin-medium-zoom/lib/client/clientAppEnhance.js' +import clientAppEnhance2 from 'E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/plugin-theme-data/lib/client/clientAppEnhance.js' +import clientAppEnhance3 from 'E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/theme-default/lib/client/clientAppEnhance.js' + +export const clientAppEnhances = [ + clientAppEnhance0, + clientAppEnhance1, + clientAppEnhance2, + clientAppEnhance3, +] diff --git a/docs/.vuepress/.temp/internal/clientAppRootComponents.js b/docs/.vuepress/.temp/internal/clientAppRootComponents.js new file mode 100644 index 0000000..5853e99 --- /dev/null +++ b/docs/.vuepress/.temp/internal/clientAppRootComponents.js @@ -0,0 +1,5 @@ +import clientAppRootComponent0 from 'E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/plugin-back-to-top/lib/client/components/BackToTop.js' + +export const clientAppRootComponents = [ + clientAppRootComponent0, +] diff --git a/docs/.vuepress/.temp/internal/clientAppSetups.js b/docs/.vuepress/.temp/internal/clientAppSetups.js new file mode 100644 index 0000000..45f3b50 --- /dev/null +++ b/docs/.vuepress/.temp/internal/clientAppSetups.js @@ -0,0 +1,9 @@ +import clientAppSetup0 from 'E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/plugin-active-header-links/lib/client/clientAppSetup.js' +import clientAppSetup1 from 'E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/plugin-nprogress/lib/client/clientAppSetup.js' +import clientAppSetup2 from 'E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/theme-default/lib/client/clientAppSetup.js' + +export const clientAppSetups = [ + clientAppSetup0, + clientAppSetup1, + clientAppSetup2, +] diff --git a/docs/.vuepress/.temp/internal/layoutComponents.js b/docs/.vuepress/.temp/internal/layoutComponents.js new file mode 100644 index 0000000..2abe096 --- /dev/null +++ b/docs/.vuepress/.temp/internal/layoutComponents.js @@ -0,0 +1,6 @@ +import { defineAsyncComponent } from 'vue' + +export const layoutComponents = { + "404": defineAsyncComponent(() => import("E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/theme-default/lib/client/layouts/404.vue")), + "Layout": defineAsyncComponent(() => import("E:/Azide/nonebot/nonebot-bison/node_modules/@vuepress/theme-default/lib/client/layouts/Layout.vue")), +} diff --git a/docs/.vuepress/.temp/internal/pagesComponents.js b/docs/.vuepress/.temp/internal/pagesComponents.js new file mode 100644 index 0000000..e16bc2d --- /dev/null +++ b/docs/.vuepress/.temp/internal/pagesComponents.js @@ -0,0 +1,12 @@ +import { defineAsyncComponent } from 'vue' + +export const pagesComponents = { + // path: / + "v-8daa1a0e": defineAsyncComponent(() => import(/* webpackChunkName: "v-8daa1a0e" */"E:/Azide/nonebot/nonebot-bison/docs/.vuepress/.temp/pages/index.html.vue")), + // path: /dev/ + "v-7445cd33": defineAsyncComponent(() => import(/* webpackChunkName: "v-7445cd33" */"E:/Azide/nonebot/nonebot-bison/docs/.vuepress/.temp/pages/dev/index.html.vue")), + // path: /usage/ + "v-d0736a32": defineAsyncComponent(() => import(/* webpackChunkName: "v-d0736a32" */"E:/Azide/nonebot/nonebot-bison/docs/.vuepress/.temp/pages/usage/index.html.vue")), + // path: /404.html + "v-3706649a": defineAsyncComponent(() => import(/* webpackChunkName: "v-3706649a" */"E:/Azide/nonebot/nonebot-bison/docs/.vuepress/.temp/pages/404.html.vue")), +} diff --git a/docs/.vuepress/.temp/internal/pagesData.js b/docs/.vuepress/.temp/internal/pagesData.js new file mode 100644 index 0000000..1c59595 --- /dev/null +++ b/docs/.vuepress/.temp/internal/pagesData.js @@ -0,0 +1,10 @@ +export const pagesData = { + // path: / + "v-8daa1a0e": () => import(/* webpackChunkName: "v-8daa1a0e" */"E:/Azide/nonebot/nonebot-bison/docs/.vuepress/.temp/pages/index.html.js").then(({ data }) => data), + // path: /dev/ + "v-7445cd33": () => import(/* webpackChunkName: "v-7445cd33" */"E:/Azide/nonebot/nonebot-bison/docs/.vuepress/.temp/pages/dev/index.html.js").then(({ data }) => data), + // path: /usage/ + "v-d0736a32": () => import(/* webpackChunkName: "v-d0736a32" */"E:/Azide/nonebot/nonebot-bison/docs/.vuepress/.temp/pages/usage/index.html.js").then(({ data }) => data), + // path: /404.html + "v-3706649a": () => import(/* webpackChunkName: "v-3706649a" */"E:/Azide/nonebot/nonebot-bison/docs/.vuepress/.temp/pages/404.html.js").then(({ data }) => data), +} diff --git a/docs/.vuepress/.temp/internal/pagesRoutes.js b/docs/.vuepress/.temp/internal/pagesRoutes.js new file mode 100644 index 0000000..9fb3e2b --- /dev/null +++ b/docs/.vuepress/.temp/internal/pagesRoutes.js @@ -0,0 +1,33 @@ +import { Vuepress } from '@vuepress/client/lib/components/Vuepress' + +const routeItems = [ + ["v-8daa1a0e","/",{"title":""},["/index.html","/README.md"]], + ["v-7445cd33","/dev/",{"title":"开发指南"},["/dev/index.html","/dev/README.md"]], + ["v-d0736a32","/usage/",{"title":"部署和使用"},["/usage/index.html","/usage/README.md"]], + ["v-3706649a","/404.html",{"title":""},["/404"]], +] + +export const pagesRoutes = routeItems.reduce( + (result, [name, path, meta, redirects]) => { + result.push( + { + name, + path, + component: Vuepress, + meta, + }, + ...redirects.map((item) => ({ + path: item, + redirect: path, + })) + ) + return result + }, + [ + { + name: "404", + path: "/:catchAll(.*)", + component: Vuepress, + } + ] +) diff --git a/docs/.vuepress/.temp/internal/siteData.js b/docs/.vuepress/.temp/internal/siteData.js new file mode 100644 index 0000000..538a815 --- /dev/null +++ b/docs/.vuepress/.temp/internal/siteData.js @@ -0,0 +1,21 @@ +export const siteData = { + "base": "/", + "lang": "en-US", + "title": "Nonebot Bison", + "description": "Docs for Nonebot Bison", + "head": [], + "locales": {} +} + +if (import.meta.webpackHot) { + import.meta.webpackHot.accept() + if (__VUE_HMR_RUNTIME__.updateSiteData) { + __VUE_HMR_RUNTIME__.updateSiteData(siteData) + } +} + +if (import.meta.hot) { + import.meta.hot.accept(({ siteData }) => { + __VUE_HMR_RUNTIME__.updateSiteData(siteData) + }) +} diff --git a/docs/.vuepress/.temp/internal/themeData.js b/docs/.vuepress/.temp/internal/themeData.js new file mode 100644 index 0000000..7c257d1 --- /dev/null +++ b/docs/.vuepress/.temp/internal/themeData.js @@ -0,0 +1,62 @@ +export const themeData = { + "nav": [ + { + "text": "主页", + "link": "/" + }, + { + "text": "部署与使用", + "link": "/usage/" + }, + { + "text": "开发", + "link": "/dev/" + }, + { + "text": "Github", + "link": "https://github.com/felinae98/nonebot-bison" + } + ], + "locales": { + "/": { + "selectLanguageName": "English" + } + }, + "navbar": [], + "logo": null, + "darkMode": true, + "repo": null, + "selectLanguageText": "Languages", + "selectLanguageAriaLabel": "Select language", + "sidebar": "auto", + "sidebarDepth": 2, + "editLink": true, + "editLinkText": "Edit this page", + "lastUpdated": true, + "lastUpdatedText": "Last Updated", + "contributors": true, + "contributorsText": "Contributors", + "notFound": [ + "There's nothing here.", + "How did we get here?", + "That's a Four-Oh-Four.", + "Looks like we've got some broken links." + ], + "backToHome": "Take me home", + "openInNewWindow": "open in new window", + "toggleDarkMode": "toggle dark mode", + "toggleSidebar": "toggle sidebar" +} + +if (import.meta.webpackHot) { + import.meta.webpackHot.accept() + if (__VUE_HMR_RUNTIME__.updateThemeData) { + __VUE_HMR_RUNTIME__.updateThemeData(themeData) + } +} + +if (import.meta.hot) { + import.meta.hot.accept(({ themeData }) => { + __VUE_HMR_RUNTIME__.updateThemeData(themeData) + }) +} diff --git a/docs/.vuepress/.temp/pages/404.html.js b/docs/.vuepress/.temp/pages/404.html.js new file mode 100644 index 0000000..09dc53f --- /dev/null +++ b/docs/.vuepress/.temp/pages/404.html.js @@ -0,0 +1,26 @@ +export const data = { + "key": "v-3706649a", + "path": "/404.html", + "title": "", + "lang": "en-US", + "frontmatter": { + "layout": "404" + }, + "excerpt": "", + "headers": [], + "git": {}, + "filePathRelative": null +} + +if (import.meta.webpackHot) { + import.meta.webpackHot.accept() + if (__VUE_HMR_RUNTIME__.updatePageData) { + __VUE_HMR_RUNTIME__.updatePageData(data) + } +} + +if (import.meta.hot) { + import.meta.hot.accept(({ data }) => { + __VUE_HMR_RUNTIME__.updatePageData(data) + }) +} diff --git a/docs/.vuepress/.temp/pages/404.html.vue b/docs/.vuepress/.temp/pages/404.html.vue new file mode 100644 index 0000000..cc340bc --- /dev/null +++ b/docs/.vuepress/.temp/pages/404.html.vue @@ -0,0 +1 @@ + diff --git a/docs/.vuepress/.temp/pages/dev/index.html.js b/docs/.vuepress/.temp/pages/dev/index.html.js new file mode 100644 index 0000000..4281b8b --- /dev/null +++ b/docs/.vuepress/.temp/pages/dev/index.html.js @@ -0,0 +1,65 @@ +export const data = { + "key": "v-7445cd33", + "path": "/dev/", + "title": "开发指南", + "lang": "en-US", + "frontmatter": { + "sidebar": "auto" + }, + "excerpt": "", + "headers": [ + { + "level": 2, + "title": "基本概念", + "slug": "基本概念", + "children": [] + }, + { + "level": 2, + "title": "快速上手", + "slug": "快速上手", + "children": [] + }, + { + "level": 2, + "title": "类的方法与成员变量", + "slug": "类的方法与成员变量", + "children": [] + }, + { + "level": 2, + "title": "方法与变量的定义", + "slug": "方法与变量的定义", + "children": [] + } + ], + "git": { + "updatedTime": 1645018969000, + "contributors": [ + { + "name": "felinae98", + "email": "731499577@qq.com", + "commits": 4 + }, + { + "name": "hemengyang", + "email": "hmy0119@gmail.com", + "commits": 1 + } + ] + }, + "filePathRelative": "dev/README.md" +} + +if (import.meta.webpackHot) { + import.meta.webpackHot.accept() + if (__VUE_HMR_RUNTIME__.updatePageData) { + __VUE_HMR_RUNTIME__.updatePageData(data) + } +} + +if (import.meta.hot) { + import.meta.hot.accept(({ data }) => { + __VUE_HMR_RUNTIME__.updatePageData(data) + }) +} diff --git a/docs/.vuepress/.temp/pages/dev/index.html.vue b/docs/.vuepress/.temp/pages/dev/index.html.vue new file mode 100644 index 0000000..8d6f9e2 --- /dev/null +++ b/docs/.vuepress/.temp/pages/dev/index.html.vue @@ -0,0 +1,78 @@ + diff --git a/docs/.vuepress/.temp/pages/index.html.js b/docs/.vuepress/.temp/pages/index.html.js new file mode 100644 index 0000000..badb334 --- /dev/null +++ b/docs/.vuepress/.temp/pages/index.html.js @@ -0,0 +1,59 @@ +export const data = { + "key": "v-8daa1a0e", + "path": "/", + "title": "", + "lang": "en-US", + "frontmatter": { + "home": true, + "heroText": "Nonebot Bison", + "tagline": "本bot励志做全泰拉骑车最快的信使", + "actionText": "快速部署", + "actionLink": "/usage/", + "features": [ + { + "title": "拓展性强", + "details": "没有自己想要的网站?只要简单的爬虫知识就可以给它适配一个新的网站" + }, + { + "title": "通用,强大", + "details": "社交媒体?网站更新?游戏开服?只要能爬就都能推,还支持自定义过滤" + }, + { + "title": "后台管理", + "details": "提供后台管理页面,简单快捷修改配置" + } + ], + "footer": "MIT Licensed" + }, + "excerpt": "", + "headers": [], + "git": { + "updatedTime": 1644411914000, + "contributors": [ + { + "name": "felinae98", + "email": "731499577@qq.com", + "commits": 7 + }, + { + "name": "hemengyang", + "email": "hmy0119@gmail.com", + "commits": 1 + } + ] + }, + "filePathRelative": "README.md" +} + +if (import.meta.webpackHot) { + import.meta.webpackHot.accept() + if (__VUE_HMR_RUNTIME__.updatePageData) { + __VUE_HMR_RUNTIME__.updatePageData(data) + } +} + +if (import.meta.hot) { + import.meta.hot.accept(({ data }) => { + __VUE_HMR_RUNTIME__.updatePageData(data) + }) +} diff --git a/docs/.vuepress/.temp/pages/index.html.vue b/docs/.vuepress/.temp/pages/index.html.vue new file mode 100644 index 0000000..cc340bc --- /dev/null +++ b/docs/.vuepress/.temp/pages/index.html.vue @@ -0,0 +1 @@ + diff --git a/docs/.vuepress/.temp/pages/usage/index.html.js b/docs/.vuepress/.temp/pages/usage/index.html.js new file mode 100644 index 0000000..2850f11 --- /dev/null +++ b/docs/.vuepress/.temp/pages/usage/index.html.js @@ -0,0 +1,101 @@ +export const data = { + "key": "v-d0736a32", + "path": "/usage/", + "title": "部署和使用", + "lang": "en-US", + "frontmatter": { + "sidebar": "auto" + }, + "excerpt": "", + "headers": [ + { + "level": 2, + "title": "部署", + "slug": "部署", + "children": [ + { + "level": 3, + "title": "作为 Bot 使用", + "slug": "作为-bot-使用", + "children": [] + }, + { + "level": 3, + "title": "作为插件使用", + "slug": "作为插件使用", + "children": [] + }, + { + "level": 3, + "title": "自动安装", + "slug": "自动安装", + "children": [] + } + ] + }, + { + "level": 2, + "title": "配置", + "slug": "配置", + "children": [] + }, + { + "level": 2, + "title": "使用", + "slug": "使用", + "children": [ + { + "level": 3, + "title": "命令", + "slug": "命令", + "children": [] + }, + { + "level": 3, + "title": "所支持平台的 uid", + "slug": "所支持平台的-uid", + "children": [] + } + ] + } + ], + "git": { + "updatedTime": 1646927246000, + "contributors": [ + { + "name": "felinae98", + "email": "731499577@qq.com", + "commits": 10 + }, + { + "name": "Azide", + "email": "rukuy@qq.com", + "commits": 1 + }, + { + "name": "hemengyang", + "email": "hmy0119@gmail.com", + "commits": 1 + }, + { + "name": "pre-commit-ci[bot]", + "email": "66853113+pre-commit-ci[bot]@users.noreply.github.com", + "commits": 1 + } + ] + }, + "filePathRelative": "usage/README.md" +} + +if (import.meta.webpackHot) { + import.meta.webpackHot.accept() + if (__VUE_HMR_RUNTIME__.updatePageData) { + __VUE_HMR_RUNTIME__.updatePageData(data) + } +} + +if (import.meta.hot) { + import.meta.hot.accept(({ data }) => { + __VUE_HMR_RUNTIME__.updatePageData(data) + }) +} diff --git a/docs/.vuepress/.temp/pages/usage/index.html.vue b/docs/.vuepress/.temp/pages/usage/index.html.vue new file mode 100644 index 0000000..8892514 --- /dev/null +++ b/docs/.vuepress/.temp/pages/usage/index.html.vue @@ -0,0 +1,162 @@ + diff --git a/docs/.vuepress/.temp/styles/index.scss b/docs/.vuepress/.temp/styles/index.scss new file mode 100644 index 0000000..e69de29 diff --git a/docs/.vuepress/.temp/styles/palette.scss b/docs/.vuepress/.temp/styles/palette.scss new file mode 100644 index 0000000..e69de29 diff --git a/docs/.vuepress/.temp/vite-root/index.html b/docs/.vuepress/.temp/vite-root/index.html new file mode 100644 index 0000000..459371d --- /dev/null +++ b/docs/.vuepress/.temp/vite-root/index.html @@ -0,0 +1,13 @@ + + + + + + + +
+ + + diff --git a/docs/usage/README.md b/docs/usage/README.md index 0ac89ff..989a14c 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -120,11 +120,14 @@ sidebar: auto - `1`: 首条消息单独发送,剩余图片合并转发 - `2`: 所有消息全部合并转发 ::: details 配置项示例 - - 当`BISON_USE_PIC_MERGE=1`时: + - 当`BISON_USE_PIC_MERGE=1`时: ![simple1](./pic/forward-msg-simple1.png) - - 当`BISON_USE_PIC_MERGE=2`时: + - 当`BISON_USE_PIC_MERGE=2`时: ![simple1](./pic/forward-msg-simple2.png) ::: + ::: warning + 启用此功能时,可能会因为待推送图片过大/过多而导致文字消息与合并转发图片消息推送间隔过大(选择模式`1`时),请谨慎考虑开启。或者选择模式`2`,使图文消息一同合并转发(可能会使消息推送延迟过长) + ::: ## 使用 From d02d206fd537110849cf4f8a4f532d0e2faea653 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 10 Mar 2022 16:19:39 +0000 Subject: [PATCH 04/25] auto fix by pre-commit hooks --- docs/usage/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/usage/README.md b/docs/usage/README.md index 989a14c..82a0719 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -121,13 +121,13 @@ sidebar: auto - `2`: 所有消息全部合并转发 ::: details 配置项示例 - 当`BISON_USE_PIC_MERGE=1`时: - ![simple1](./pic/forward-msg-simple1.png) + ![simple1](./pic/forward-msg-simple1.png) - 当`BISON_USE_PIC_MERGE=2`时: - ![simple1](./pic/forward-msg-simple2.png) - ::: - ::: warning - 启用此功能时,可能会因为待推送图片过大/过多而导致文字消息与合并转发图片消息推送间隔过大(选择模式`1`时),请谨慎考虑开启。或者选择模式`2`,使图文消息一同合并转发(可能会使消息推送延迟过长) - ::: + ![simple1](./pic/forward-msg-simple2.png) + ::: + ::: warning + 启用此功能时,可能会因为待推送图片过大/过多而导致文字消息与合并转发图片消息推送间隔过大(选择模式`1`时),请谨慎考虑开启。或者选择模式`2`,使图文消息一同合并转发(可能会使消息推送延迟过长) + ::: ## 使用 From 550dc9f74c313854675d938b1e50f43b45a7dd81 Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Fri, 11 Mar 2022 00:22:39 +0800 Subject: [PATCH 05/25] update doc --- .gitignore | 1 + docs/.vuepress/config.js | 2 +- docs/usage/README.md | 8 ++++++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 8b8f3e5..d6029a3 100644 --- a/.gitignore +++ b/.gitignore @@ -274,6 +274,7 @@ dist # vuepress build output .vuepress/dist +docs/.vuepress/.temp/ # Serverless directories .serverless/ diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 6f6c566..c002680 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -2,7 +2,7 @@ module.exports = { title: 'Nonebot Bison', description: 'Docs for Nonebot Bison', themeConfig: { - nav: [ + navbar: [ { text: '主页', link: '/' }, { text: '部署与使用', link: '/usage/' }, { text: '开发', link: '/dev/' }, diff --git a/docs/usage/README.md b/docs/usage/README.md index 0ac89ff..dee0122 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -116,15 +116,19 @@ sidebar: auto - `BISON_USE_QUEUE`: 是否用队列的方式发送消息,降低发送频率,默认开 - `BISON_RESEND_TIMES`: 最大重发次数,默认 0 - `BISON_USE_PIC_MERGE`: 是否启用多图片时合并转发(仅限群) + - `0`: 不启用(默认) - `1`: 首条消息单独发送,剩余图片合并转发 - `2`: 所有消息全部合并转发 - ::: details 配置项示例 + + ::: details 配置项示例 + - 当`BISON_USE_PIC_MERGE=1`时: ![simple1](./pic/forward-msg-simple1.png) - 当`BISON_USE_PIC_MERGE=2`时: ![simple1](./pic/forward-msg-simple2.png) - ::: + + ::: ## 使用 From 026390e6f2cc562c1d081650de185c47b3c47daa Mon Sep 17 00:00:00 2001 From: Azide Date: Fri, 11 Mar 2022 23:57:06 +0800 Subject: [PATCH 06/25] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AE=A2=E9=98=85?= =?UTF-8?q?=E8=BF=87=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/nonebot_bison/config_manager.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/plugins/nonebot_bison/config_manager.py b/src/plugins/nonebot_bison/config_manager.py index e2cd220..3d330a6 100644 --- a/src/plugins/nonebot_bison/config_manager.py +++ b/src/plugins/nonebot_bison/config_manager.py @@ -112,7 +112,7 @@ def do_add_sub(add_sub: Type[Matcher]): if platform_manager[state["platform"]].has_target: state[ "_prompt" - ] = "请输入订阅用户的id,详情查阅https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + ] = "请输入订阅用户的id:\n查询id获取方法请回复:“查询”" else: state["id"] = "default" state["name"] = await platform_manager[state["platform"]].get_target_name( @@ -124,6 +124,8 @@ def do_add_sub(add_sub: Type[Matcher]): return target = str(event.get_message()).strip() try: + if target == "查询": + raise LookupError if target == "取消": raise KeyboardInterrupt name = await check_sub_target(state["platform"], target) @@ -131,10 +133,19 @@ def do_add_sub(add_sub: Type[Matcher]): raise ValueError state["id"] = target state["name"] = name + except (LookupError): + url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + title="Bison所支持的平台UID" + content="查询相关平台的uid格式或获取方式" + image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" + getId_share=f"[CQ:share,url={url},title={title},content={content},image={image}"#缩短字符串格式长度,以及方便后续修改为消息段格式 + await add_sub.reject(Message(getId_share)) except (KeyboardInterrupt): await add_sub.finish("已中止订阅") except (ValueError): await add_sub.reject("id输入错误") + else: + await add_sub.send("即将订阅的用户为:{} {} {}\n如有错误请输入“取消”重新订阅".format(state["platform"],state["name"],state["id"])) @add_sub.got("id", _gen_prompt_template("{_prompt}"), [Depends(parse_id)]) async def init_cat(state: T_State): From 62feeb84897dabb484e36307fab9e2fe37805e0c Mon Sep 17 00:00:00 2001 From: Azide Date: Sat, 12 Mar 2022 00:30:36 +0800 Subject: [PATCH 07/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9test=5Fconfig=5Fmanager?= =?UTF-8?q?=E5=86=85=E6=B7=BB=E5=8A=A0=E8=AE=A2=E9=98=85test=E7=9A=84?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_config_manager.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/test_config_manager.py b/tests/test_config_manager.py index 1119223..bacd128 100644 --- a/tests/test_config_manager.py +++ b/tests/test_config_manager.py @@ -142,7 +142,7 @@ async def test_add_with_target(app: App): ctx.should_call_send( event_3, Message( - "请输入订阅用户的id,详情查阅https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + "请输入订阅用户的id:\n查询id获取方法请回复:“查询”" ), True, ) @@ -156,6 +156,13 @@ async def test_add_with_target(app: App): message=Message("6279793937"), sender=fake_admin_user ) ctx.receive_event(bot, event_4_ok) + ctx.should_call_send( + event_4_ok, + Message( + "即将订阅的用户为:weibo 明日方舟Arknights 6279793937\n如有错误请输入“取消”重新订阅" + ), + True + ) ctx.should_call_send( event_4_ok, Message( @@ -241,7 +248,7 @@ async def test_add_with_target_no_cat(app: App): ctx.should_call_send( event_3, Message( - "请输入订阅用户的id,详情查阅https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + "请输入订阅用户的id:\n查询id获取方法请回复:“查询”" ), True, ) @@ -249,6 +256,13 @@ async def test_add_with_target_no_cat(app: App): message=Message("32540734"), sender=fake_admin_user ) ctx.receive_event(bot, event_4_ok) + ctx.should_call_send( + event_4_ok, + Message( + "即将订阅的用户为:ncm-artist 塞壬唱片-MSR 32540734\n如有错误请输入“取消”重新订阅" + ), + True + ) ctx.should_call_send(event_4_ok, ("添加 塞壬唱片-MSR 成功"), True) ctx.should_finished() subs = config.list_subscribe(10000, "group") @@ -302,6 +316,13 @@ async def test_add_no_target(app: App): message=Message("arknights"), sender=fake_admin_user ) ctx.receive_event(bot, event_3) + ctx.should_call_send( + event_3, + Message( + "即将订阅的用户为:arknights 明日方舟游戏信息 default\n如有错误请输入“取消”重新订阅" + ), + True + ) ctx.should_call_send( event_3, Message( From 15f605b719c55b8c78f5e2d297d7edd2e1fd2589 Mon Sep 17 00:00:00 2001 From: Azide Date: Sat, 12 Mar 2022 12:59:45 +0800 Subject: [PATCH 08/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86test=5Fconfig?= =?UTF-8?q?=5Fmanager=5F*.py=E6=96=87=E4=BB=B6=E7=9A=84=E7=BB=93=E6=9E=84?= =?UTF-8?q?=EF=BC=8C=E5=B0=9D=E8=AF=95=E6=8A=BD=E5=8F=96=E5=87=BA=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E9=83=A8=E5=88=86(=E6=9C=AA=E9=AA=8C=E8=AF=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_config_manager_query_del.py | 101 ++++++++ ..._manager.py => test_config_manages_add.py} | 224 ++---------------- tests/utils.py | 49 ++++ 3 files changed, 173 insertions(+), 201 deletions(-) create mode 100644 tests/test_config_manager_query_del.py rename tests/{test_config_manager.py => test_config_manages_add.py} (54%) diff --git a/tests/test_config_manager_query_del.py b/tests/test_config_manager_query_del.py new file mode 100644 index 0000000..0ae3f2d --- /dev/null +++ b/tests/test_config_manager_query_del.py @@ -0,0 +1,101 @@ +import pytest +import respx +from httpx import Response +from nonebug.app import App + +from .platforms.utils import get_json +from .utils import fake_admin_user, fake_group_message_event + + +@pytest.mark.asyncio +async def test_query_sub(app: App): + from nonebot.adapters.onebot.v11.message import Message + from nonebot_bison.config import Config + from nonebot_bison.config_manager import query_sub_matcher + from nonebot_bison.platform import platform_manager + + config = Config() + config.user_target.truncate() + config.add_subscribe( + 10000, + "group", + "6279793937", + "明日方舟Arknights", + "weibo", + [platform_manager["weibo"].reverse_category["图文"]], + ["明日方舟"], + ) + async with app.test_matcher(query_sub_matcher) as ctx: + bot = ctx.create_bot() + event = fake_group_message_event(message=Message("查询订阅"), to_me=True) + ctx.receive_event(bot, event) + ctx.should_pass_rule() + ctx.should_pass_permission() + ctx.should_call_send( + event, Message("订阅的帐号为:\nweibo 明日方舟Arknights 6279793937 [图文] 明日方舟\n"), True + ) + + +@pytest.mark.asyncio +async def test_del_sub(app: App): + from nonebot.adapters.onebot.v11.bot import Bot + from nonebot.adapters.onebot.v11.message import Message + from nonebot_bison.config import Config + from nonebot_bison.config_manager import del_sub_matcher + from nonebot_bison.platform import platform_manager + + config = Config() + config.user_target.truncate() + config.add_subscribe( + 10000, + "group", + "6279793937", + "明日方舟Arknights", + "weibo", + [platform_manager["weibo"].reverse_category["图文"]], + ["明日方舟"], + ) + async with app.test_matcher(del_sub_matcher) as ctx: + bot = ctx.create_bot(base=Bot) + assert isinstance(bot, Bot) + event = fake_group_message_event( + message=Message("删除订阅"), to_me=True, sender=fake_admin_user + ) + ctx.receive_event(bot, event) + ctx.should_pass_rule() + ctx.should_pass_permission() + ctx.should_call_send( + event, + Message( + "订阅的帐号为:\n1 weibo 明日方舟Arknights 6279793937\n [图文] 明日方舟\n请输入要删除的订阅的序号" + ), + True, + ) + event_1_err = fake_group_message_event( + message=Message("2"), sender=fake_admin_user + ) + ctx.receive_event(bot, event_1_err) + ctx.should_call_send(event_1_err, "删除错误", True) + ctx.should_rejected() + event_1_ok = fake_group_message_event( + message=Message("1"), sender=fake_admin_user + ) + ctx.receive_event(bot, event_1_ok) + ctx.should_call_send(event_1_ok, "删除成功", True) + ctx.should_finished() + subs = config.list_subscribe(10000, "group") + assert len(subs) == 0 + + +async def test_test(app: App): + from nonebot.adapters.onebot.v11.bot import Bot + from nonebot.adapters.onebot.v11.message import Message + from nonebot_bison.config_manager import test_matcher + + async with app.test_matcher(test_matcher) as ctx: + bot = ctx.create_bot(base=Bot) + event = fake_group_message_event(message=Message("testtt")) + ctx.receive_event(bot, event) + ctx.should_pass_permission() + ctx.should_pass_rule() + ctx.should_call_send(event, "666", True) diff --git a/tests/test_config_manager.py b/tests/test_config_manages_add.py similarity index 54% rename from tests/test_config_manager.py rename to tests/test_config_manages_add.py index bacd128..34ca2a8 100644 --- a/tests/test_config_manager.py +++ b/tests/test_config_manages_add.py @@ -4,8 +4,9 @@ from httpx import Response from nonebug.app import App from .platforms.utils import get_json -from .utils import fake_admin_user, fake_group_message_event +from .utils import fake_admin_user, fake_group_message_event, BotReply +bot_reply=BotReply() @pytest.mark.asyncio async def test_configurable_at_me_true_failed(app: App): @@ -31,7 +32,6 @@ async def test_configurable_at_me_true_failed(app: App): ctx.should_pass_rule() ctx.should_not_pass_permission() - @pytest.mark.asyncio async def test_configurable_at_me_false(app: App): from nonebot.adapters.onebot.v11.bot import Bot @@ -49,24 +49,12 @@ async def test_configurable_at_me_false(app: App): ctx.receive_event(bot, event) ctx.should_call_send( event, - Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" - ), + bot_reply.add_reply_on_platform(platform_manager,common_platform), True, ) ctx.should_pass_rule() ctx.should_pass_permission() - @pytest.mark.asyncio @respx.mock async def test_add_with_target(app: App): @@ -103,18 +91,7 @@ async def test_add_with_target(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" - ), + bot_reply.add_reply_on_platform(platform_manager,common_platform), True, ) event_2 = fake_group_message_event( @@ -124,15 +101,7 @@ async def test_add_with_target(app: App): ctx.should_rejected() ctx.should_call_send( event_2, - ( - "全部平台\n" - + "\n".join( - [ - "{}:{}".format(platform_name, platform.name) - for platform_name, platform in platform_manager.items() - ] - ) - ), + bot_reply.add_reply_on_platform_input_allplatform(platform_manager), True, ) event_3 = fake_group_message_event( @@ -141,16 +110,14 @@ async def test_add_with_target(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - Message( - "请输入订阅用户的id:\n查询id获取方法请回复:“查询”" - ), + bot_reply.add_reply_on_id, True, ) event_4_err = fake_group_message_event( message=Message("000"), sender=fake_admin_user ) ctx.receive_event(bot, event_4_err) - ctx.should_call_send(event_4_err, "id输入错误", True) + ctx.should_call_send(event_4_err, bot_reply.add_reply_on_id_input_error, True) ctx.should_rejected() event_4_ok = fake_group_message_event( message=Message("6279793937"), sender=fake_admin_user @@ -158,36 +125,30 @@ async def test_add_with_target(app: App): ctx.receive_event(bot, event_4_ok) ctx.should_call_send( event_4_ok, - Message( - "即将订阅的用户为:weibo 明日方舟Arknights 6279793937\n如有错误请输入“取消”重新订阅" - ), + bot_reply.add_reply_on_target_confirm("weibo","明日方舟Arknights","6279793937"), True ) ctx.should_call_send( event_4_ok, - Message( - "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( - " ".join(list(platform_manager["weibo"].categories.values())) - ) - ), + bot_reply.add_reply_on_cats(platform_manager,"weibo"), True, ) event_5_err = fake_group_message_event( message=Message("图文 文字 err"), sender=fake_admin_user ) ctx.receive_event(bot, event_5_err) - ctx.should_call_send(event_5_err, "不支持 err", True) + ctx.should_call_send(event_5_err, bot_reply.add_reply_on_cats_input_error("err"), True) ctx.should_rejected() event_5_ok = fake_group_message_event( message=Message("图文 文字"), sender=fake_admin_user ) ctx.receive_event(bot, event_5_ok) - ctx.should_call_send(event_5_ok, Message('请输入要订阅的tag,订阅所有tag输入"全部标签"'), True) + ctx.should_call_send(event_5_ok, bot_reply.add_reply_on_tags, True) event_6 = fake_group_message_event( message=Message("全部标签"), sender=fake_admin_user ) ctx.receive_event(bot, event_6) - ctx.should_call_send(event_6, ("添加 明日方舟Arknights 成功"), True) + ctx.should_call_send(event_6, bot_reply.add_reply_subscribe_success("明日方舟Arknights"), True) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -200,7 +161,6 @@ async def test_add_with_target(app: App): assert sub["target_type"] == "weibo" assert sub["target_name"] == "明日方舟Arknights" - @pytest.mark.asyncio @respx.mock async def test_add_with_target_no_cat(app: App): @@ -227,18 +187,7 @@ async def test_add_with_target_no_cat(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" - ), + bot_reply.add_reply_on_platform(platform_manager,common_platform), True, ) event_3 = fake_group_message_event( @@ -247,9 +196,7 @@ async def test_add_with_target_no_cat(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - Message( - "请输入订阅用户的id:\n查询id获取方法请回复:“查询”" - ), + bot_reply.add_reply_on_id, True, ) event_4_ok = fake_group_message_event( @@ -258,12 +205,10 @@ async def test_add_with_target_no_cat(app: App): ctx.receive_event(bot, event_4_ok) ctx.should_call_send( event_4_ok, - Message( - "即将订阅的用户为:ncm-artist 塞壬唱片-MSR 32540734\n如有错误请输入“取消”重新订阅" - ), + bot_reply.add_reply_on_target_confirm("ncm-artist","塞壬唱片-MSR","32540734"), True ) - ctx.should_call_send(event_4_ok, ("添加 塞壬唱片-MSR 成功"), True) + ctx.should_call_send(event_4_ok, bot_reply.add_reply_subscribe_success("塞壬唱片-MSR"), True) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -274,7 +219,6 @@ async def test_add_with_target_no_cat(app: App): assert sub["target_type"] == "ncm-artist" assert sub["target_name"] == "塞壬唱片-MSR" - @pytest.mark.asyncio @respx.mock async def test_add_no_target(app: App): @@ -298,18 +242,7 @@ async def test_add_no_target(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" - ), + bot_reply.add_reply_on_platform(platform_manager,common_platform), True, ) event_3 = fake_group_message_event( @@ -318,25 +251,20 @@ async def test_add_no_target(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - Message( - "即将订阅的用户为:arknights 明日方舟游戏信息 default\n如有错误请输入“取消”重新订阅" - ), + bot_reply.add_reply_on_target_confirm("arknights","明日方舟游戏信息","default") + , True ) ctx.should_call_send( event_3, - Message( - "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( - " ".join(list(platform_manager["arknights"].categories.values())) - ) - ), + bot_reply.add_reply_on_cats(platform_manager,"arknights"), True, ) event_4 = fake_group_message_event( message=Message("游戏公告"), sender=fake_admin_user ) ctx.receive_event(bot, event_4) - ctx.should_call_send(event_4, ("添加 明日方舟游戏信息 成功"), True) + ctx.should_call_send(event_4, bot_reply.add_reply_subscribe_success("明日方舟游戏信息"), True) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -347,7 +275,6 @@ async def test_add_no_target(app: App): assert sub["target_type"] == "arknights" assert sub["target_name"] == "明日方舟游戏信息" - @pytest.mark.asyncio async def test_platform_name_err(app: App): from nonebot.adapters.onebot.v11.event import Sender @@ -369,18 +296,7 @@ async def test_platform_name_err(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" - ), + bot_reply.add_reply_on_platform(platform_manager,common_platform), True, ) event_2 = fake_group_message_event( @@ -391,100 +307,6 @@ async def test_platform_name_err(app: App): ctx.should_rejected() ctx.should_call_send( event_2, - "平台输入错误", + bot_reply.add_reply_on_platform_input_error, True, ) - - -@pytest.mark.asyncio -async def test_query_sub(app: App): - from nonebot.adapters.onebot.v11.message import Message - from nonebot_bison.config import Config - from nonebot_bison.config_manager import query_sub_matcher - from nonebot_bison.platform import platform_manager - - config = Config() - config.user_target.truncate() - config.add_subscribe( - 10000, - "group", - "6279793937", - "明日方舟Arknights", - "weibo", - [platform_manager["weibo"].reverse_category["图文"]], - ["明日方舟"], - ) - async with app.test_matcher(query_sub_matcher) as ctx: - bot = ctx.create_bot() - event = fake_group_message_event(message=Message("查询订阅"), to_me=True) - ctx.receive_event(bot, event) - ctx.should_pass_rule() - ctx.should_pass_permission() - ctx.should_call_send( - event, Message("订阅的帐号为:\nweibo 明日方舟Arknights 6279793937 [图文] 明日方舟\n"), True - ) - - -@pytest.mark.asyncio -async def test_del_sub(app: App): - from nonebot.adapters.onebot.v11.bot import Bot - from nonebot.adapters.onebot.v11.message import Message - from nonebot_bison.config import Config - from nonebot_bison.config_manager import del_sub_matcher - from nonebot_bison.platform import platform_manager - - config = Config() - config.user_target.truncate() - config.add_subscribe( - 10000, - "group", - "6279793937", - "明日方舟Arknights", - "weibo", - [platform_manager["weibo"].reverse_category["图文"]], - ["明日方舟"], - ) - async with app.test_matcher(del_sub_matcher) as ctx: - bot = ctx.create_bot(base=Bot) - assert isinstance(bot, Bot) - event = fake_group_message_event( - message=Message("删除订阅"), to_me=True, sender=fake_admin_user - ) - ctx.receive_event(bot, event) - ctx.should_pass_rule() - ctx.should_pass_permission() - ctx.should_call_send( - event, - Message( - "订阅的帐号为:\n1 weibo 明日方舟Arknights 6279793937\n [图文] 明日方舟\n请输入要删除的订阅的序号" - ), - True, - ) - event_1_err = fake_group_message_event( - message=Message("2"), sender=fake_admin_user - ) - ctx.receive_event(bot, event_1_err) - ctx.should_call_send(event_1_err, "删除错误", True) - ctx.should_rejected() - event_1_ok = fake_group_message_event( - message=Message("1"), sender=fake_admin_user - ) - ctx.receive_event(bot, event_1_ok) - ctx.should_call_send(event_1_ok, "删除成功", True) - ctx.should_finished() - subs = config.list_subscribe(10000, "group") - assert len(subs) == 0 - - -async def test_test(app: App): - from nonebot.adapters.onebot.v11.bot import Bot - from nonebot.adapters.onebot.v11.message import Message - from nonebot_bison.config_manager import test_matcher - - async with app.test_matcher(test_matcher) as ctx: - bot = ctx.create_bot(base=Bot) - event = fake_group_message_event(message=Message("testtt")) - ctx.receive_event(bot, event) - ctx.should_pass_permission() - ctx.should_pass_rule() - ctx.should_call_send(event, "666", True) diff --git a/tests/utils.py b/tests/utils.py index a31b67e..17f009f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -69,3 +69,52 @@ from nonebot.adapters.onebot.v11.event import Sender fake_admin_user = Sender(nickname="test", role="admin") fake_superuser = Sender(user_id=10001, nickname="superuser") + +from nonebot.adapters.onebot.v11.message import Message +class BotReply: + def add_reply_on_platform(platform_manager,common_platform): + return Message( + "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" + + "".join( + [ + "{}:{}\n".format( + platform_name, platform_manager[platform_name].name + ) + for platform_name in common_platform + ] + ) + + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" + ) + + def add_reply_on_platform_input_allplatform(platform_manager): + return "全部平台\n" + "\n".join( + [ + "{}:{}".format(platform_name, platform.name) + for platform_name, platform in platform_manager.items() + ]) + + def add_reply_on_id_input_search(): + search_url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + search_title="Bison所支持的平台UID" + search_content="查询相关平台的uid格式或获取方式" + search_image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" + return Message(f"[CQ:share,url={search_url},title={search_title},content={search_content},image={search_image}") + + def add_reply_on_target_confirm(platform,name,id): + return Message(f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅") + + def add_reply_on_cats(platform_manager,platform:str): + return Message("请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( + " ".join(list(platform_manager[platform].categories.values())))) + + def add_reply_on_cats_input_error(cat:str): + return Message("不支持 {}".format(cat)) + + def add_reply_subscribe_success(name): + return Message("添加 {} 成功".format(name)) + + add_reply_on_id_input_error="id输入错误" + add_reply_on_platform_input_error="平台输入错误" + add_reply_on_id="请输入订阅用户的id:\n查询id获取方法请回复:“查询”" + add_reply_on_tags='请输入要订阅的tag,订阅所有tag输入"全部标签"' + add_reply_abort="已中止订阅" \ No newline at end of file From 29f4abd9f4f4e166c505fe9e3bb4c6c6d906d1db Mon Sep 17 00:00:00 2001 From: Azide Date: Sun, 13 Mar 2022 01:37:15 +0800 Subject: [PATCH 09/25] =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=BE=AE=E8=B0=83test?= =?UTF-8?q?=5Fconfig=5Fmanager=5Fadd=E4=BD=BF=E4=B9=8Bpass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/nonebot_bison/config_manager.py | 4 +- ...ages_add.py => test_config_manager_add.py} | 45 ++++++++----------- tests/utils.py | 12 ++--- 3 files changed, 27 insertions(+), 34 deletions(-) rename tests/{test_config_manages_add.py => test_config_manager_add.py} (85%) diff --git a/src/plugins/nonebot_bison/config_manager.py b/src/plugins/nonebot_bison/config_manager.py index 3d330a6..5e00414 100644 --- a/src/plugins/nonebot_bison/config_manager.py +++ b/src/plugins/nonebot_bison/config_manager.py @@ -134,11 +134,11 @@ def do_add_sub(add_sub: Type[Matcher]): state["id"] = target state["name"] = name except (LookupError): - url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid" title="Bison所支持的平台UID" content="查询相关平台的uid格式或获取方式" image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" - getId_share=f"[CQ:share,url={url},title={title},content={content},image={image}"#缩短字符串格式长度,以及方便后续修改为消息段格式 + getId_share=f"[CQ:share,url={url},title={title},content={content},image={image}]"#缩短字符串格式长度,以及方便后续修改为消息段格式 await add_sub.reject(Message(getId_share)) except (KeyboardInterrupt): await add_sub.finish("已中止订阅") diff --git a/tests/test_config_manages_add.py b/tests/test_config_manager_add.py similarity index 85% rename from tests/test_config_manages_add.py rename to tests/test_config_manager_add.py index 34ca2a8..5e80e3e 100644 --- a/tests/test_config_manages_add.py +++ b/tests/test_config_manager_add.py @@ -6,7 +6,6 @@ from nonebug.app import App from .platforms.utils import get_json from .utils import fake_admin_user, fake_group_message_event, BotReply -bot_reply=BotReply() @pytest.mark.asyncio async def test_configurable_at_me_true_failed(app: App): @@ -49,7 +48,7 @@ async def test_configurable_at_me_false(app: App): ctx.receive_event(bot, event) ctx.should_call_send( event, - bot_reply.add_reply_on_platform(platform_manager,common_platform), + Message(BotReply.add_reply_on_platform(platform_manager,common_platform)), True, ) ctx.should_pass_rule() @@ -91,7 +90,7 @@ async def test_add_with_target(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - bot_reply.add_reply_on_platform(platform_manager,common_platform), + Message(BotReply.add_reply_on_platform(platform_manager=platform_manager,common_platform=common_platform)), True, ) event_2 = fake_group_message_event( @@ -101,7 +100,7 @@ async def test_add_with_target(app: App): ctx.should_rejected() ctx.should_call_send( event_2, - bot_reply.add_reply_on_platform_input_allplatform(platform_manager), + BotReply.add_reply_on_platform_input_allplatform(platform_manager), True, ) event_3 = fake_group_message_event( @@ -110,14 +109,14 @@ async def test_add_with_target(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - bot_reply.add_reply_on_id, + Message(BotReply.add_reply_on_id), True, ) event_4_err = fake_group_message_event( message=Message("000"), sender=fake_admin_user ) ctx.receive_event(bot, event_4_err) - ctx.should_call_send(event_4_err, bot_reply.add_reply_on_id_input_error, True) + ctx.should_call_send(event_4_err, BotReply.add_reply_on_id_input_error, True) ctx.should_rejected() event_4_ok = fake_group_message_event( message=Message("6279793937"), sender=fake_admin_user @@ -125,30 +124,30 @@ async def test_add_with_target(app: App): ctx.receive_event(bot, event_4_ok) ctx.should_call_send( event_4_ok, - bot_reply.add_reply_on_target_confirm("weibo","明日方舟Arknights","6279793937"), + BotReply.add_reply_on_target_confirm("weibo","明日方舟Arknights","6279793937"), True ) ctx.should_call_send( event_4_ok, - bot_reply.add_reply_on_cats(platform_manager,"weibo"), + Message(BotReply.add_reply_on_cats(platform_manager,"weibo")), True, ) event_5_err = fake_group_message_event( message=Message("图文 文字 err"), sender=fake_admin_user ) ctx.receive_event(bot, event_5_err) - ctx.should_call_send(event_5_err, bot_reply.add_reply_on_cats_input_error("err"), True) + ctx.should_call_send(event_5_err, BotReply.add_reply_on_cats_input_error("err"), True) ctx.should_rejected() event_5_ok = fake_group_message_event( message=Message("图文 文字"), sender=fake_admin_user ) ctx.receive_event(bot, event_5_ok) - ctx.should_call_send(event_5_ok, bot_reply.add_reply_on_tags, True) + ctx.should_call_send(event_5_ok, Message(BotReply.add_reply_on_tags), True) event_6 = fake_group_message_event( message=Message("全部标签"), sender=fake_admin_user ) ctx.receive_event(bot, event_6) - ctx.should_call_send(event_6, bot_reply.add_reply_subscribe_success("明日方舟Arknights"), True) + ctx.should_call_send(event_6, BotReply.add_reply_subscribe_success("明日方舟Arknights"), True) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -187,7 +186,7 @@ async def test_add_with_target_no_cat(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - bot_reply.add_reply_on_platform(platform_manager,common_platform), + Message(BotReply.add_reply_on_platform(platform_manager,common_platform)), True, ) event_3 = fake_group_message_event( @@ -196,7 +195,7 @@ async def test_add_with_target_no_cat(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - bot_reply.add_reply_on_id, + Message(BotReply.add_reply_on_id), True, ) event_4_ok = fake_group_message_event( @@ -205,10 +204,10 @@ async def test_add_with_target_no_cat(app: App): ctx.receive_event(bot, event_4_ok) ctx.should_call_send( event_4_ok, - bot_reply.add_reply_on_target_confirm("ncm-artist","塞壬唱片-MSR","32540734"), + BotReply.add_reply_on_target_confirm("ncm-artist","塞壬唱片-MSR","32540734"), True ) - ctx.should_call_send(event_4_ok, bot_reply.add_reply_subscribe_success("塞壬唱片-MSR"), True) + ctx.should_call_send(event_4_ok, BotReply.add_reply_subscribe_success("塞壬唱片-MSR"), True) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -242,7 +241,7 @@ async def test_add_no_target(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - bot_reply.add_reply_on_platform(platform_manager,common_platform), + Message(BotReply.add_reply_on_platform(platform_manager,common_platform)), True, ) event_3 = fake_group_message_event( @@ -251,20 +250,14 @@ async def test_add_no_target(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - bot_reply.add_reply_on_target_confirm("arknights","明日方舟游戏信息","default") - , - True - ) - ctx.should_call_send( - event_3, - bot_reply.add_reply_on_cats(platform_manager,"arknights"), + Message(BotReply.add_reply_on_cats(platform_manager,"arknights")), True, ) event_4 = fake_group_message_event( message=Message("游戏公告"), sender=fake_admin_user ) ctx.receive_event(bot, event_4) - ctx.should_call_send(event_4, bot_reply.add_reply_subscribe_success("明日方舟游戏信息"), True) + ctx.should_call_send(event_4, BotReply.add_reply_subscribe_success("明日方舟游戏信息"), True) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -296,7 +289,7 @@ async def test_platform_name_err(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - bot_reply.add_reply_on_platform(platform_manager,common_platform), + Message(BotReply.add_reply_on_platform(platform_manager,common_platform)), True, ) event_2 = fake_group_message_event( @@ -307,6 +300,6 @@ async def test_platform_name_err(app: App): ctx.should_rejected() ctx.should_call_send( event_2, - bot_reply.add_reply_on_platform_input_error, + BotReply.add_reply_on_platform_input_error, True, ) diff --git a/tests/utils.py b/tests/utils.py index 17f009f..6911ea9 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -73,7 +73,7 @@ fake_superuser = Sender(user_id=10001, nickname="superuser") from nonebot.adapters.onebot.v11.message import Message class BotReply: def add_reply_on_platform(platform_manager,common_platform): - return Message( + return ( "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" + "".join( [ @@ -98,20 +98,20 @@ class BotReply: search_title="Bison所支持的平台UID" search_content="查询相关平台的uid格式或获取方式" search_image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" - return Message(f"[CQ:share,url={search_url},title={search_title},content={search_content},image={search_image}") + return (f"[CQ:share,url={search_url},title={search_title},content={search_content},image={search_image}") def add_reply_on_target_confirm(platform,name,id): - return Message(f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅") + return (f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅") def add_reply_on_cats(platform_manager,platform:str): - return Message("请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( + return ("请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( " ".join(list(platform_manager[platform].categories.values())))) def add_reply_on_cats_input_error(cat:str): - return Message("不支持 {}".format(cat)) + return ("不支持 {}".format(cat)) def add_reply_subscribe_success(name): - return Message("添加 {} 成功".format(name)) + return ("添加 {} 成功".format(name)) add_reply_on_id_input_error="id输入错误" add_reply_on_platform_input_error="平台输入错误" From 48bca0447045892d5b226de818c353c53ef445af Mon Sep 17 00:00:00 2001 From: Azide Date: Sun, 13 Mar 2022 01:50:49 +0800 Subject: [PATCH 10/25] =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=BE=AE=E8=B0=83test?= =?UTF-8?q?=5Fconfig=5Fmanager=5Fabort=E4=BD=BF=E4=B9=8Bpass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_config_manager_abort.py | 84 +++++++++--------------------- 1 file changed, 25 insertions(+), 59 deletions(-) diff --git a/tests/test_config_manager_abort.py b/tests/test_config_manager_abort.py index 5e9e1c5..bcc5c95 100644 --- a/tests/test_config_manager_abort.py +++ b/tests/test_config_manager_abort.py @@ -4,7 +4,7 @@ from httpx import Response from nonebug.app import App from .platforms.utils import get_json -from .utils import fake_admin_user, fake_group_message_event +from .utils import fake_admin_user, fake_group_message_event,BotReply # 选择platform阶段中止 @@ -44,16 +44,7 @@ async def test_abort_add_on_platform(app: App): ctx.should_call_send( event_1, Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" + BotReply.add_reply_on_platform(platform_manager,common_platform) ), True, ) @@ -63,7 +54,7 @@ async def test_abort_add_on_platform(app: App): ctx.receive_event(bot, event_abort) ctx.should_call_send( event_abort, - "已中止订阅", + BotReply.add_reply_abort, True, ) ctx.should_finished() @@ -106,16 +97,7 @@ async def test_abort_add_on_id(app: App): ctx.should_call_send( event_1, Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" + BotReply.add_reply_on_platform(platform_manager,common_platform) ), True, ) @@ -126,7 +108,7 @@ async def test_abort_add_on_id(app: App): ctx.should_call_send( event_2, Message( - "请输入订阅用户的id,详情查阅https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + BotReply.add_reply_on_id ), True, ) @@ -136,7 +118,7 @@ async def test_abort_add_on_id(app: App): ctx.receive_event(bot, event_abort) ctx.should_call_send( event_abort, - "已中止订阅", + BotReply.add_reply_abort, True, ) ctx.should_finished() @@ -179,16 +161,7 @@ async def test_abort_add_on_cats(app: App): ctx.should_call_send( event_1, Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" + BotReply.add_reply_on_platform(platform_manager=platform_manager,common_platform=common_platform) ), True, ) @@ -199,7 +172,7 @@ async def test_abort_add_on_cats(app: App): ctx.should_call_send( event_2, Message( - "请输入订阅用户的id,详情查阅https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + BotReply.add_reply_on_id ), True, ) @@ -209,11 +182,12 @@ async def test_abort_add_on_cats(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - Message( - "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( - " ".join(list(platform_manager["weibo"].categories.values())) - ) - ), + BotReply.add_reply_on_target_confirm("weibo","明日方舟Arknights","6279793937"), + True + ) + ctx.should_call_send( + event_3, + Message(BotReply.add_reply_on_cats(platform_manager,"weibo")), True, ) event_abort = fake_group_message_event( @@ -222,7 +196,7 @@ async def test_abort_add_on_cats(app: App): ctx.receive_event(bot, event_abort) ctx.should_call_send( event_abort, - "已中止订阅", + BotReply.add_reply_abort, True, ) ctx.should_finished() @@ -265,16 +239,7 @@ async def test_abort_add_on_tag(app: App): ctx.should_call_send( event_1, Message( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" + BotReply.add_reply_on_platform(platform_manager=platform_manager,common_platform=common_platform) ), True, ) @@ -285,7 +250,7 @@ async def test_abort_add_on_tag(app: App): ctx.should_call_send( event_2, Message( - "请输入订阅用户的id,详情查阅https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + BotReply.add_reply_on_id ), True, ) @@ -295,25 +260,26 @@ async def test_abort_add_on_tag(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - Message( - "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( - " ".join(list(platform_manager["weibo"].categories.values())) - ) - ), + BotReply.add_reply_on_target_confirm("weibo","明日方舟Arknights","6279793937"), + True + ) + ctx.should_call_send( + event_3, + Message(BotReply.add_reply_on_cats(platform_manager,"weibo")), True, ) event_4 = fake_group_message_event( message=Message("图文 文字"), sender=fake_admin_user ) ctx.receive_event(bot, event_4) - ctx.should_call_send(event_4, Message('请输入要订阅的tag,订阅所有tag输入"全部标签"'), True) + ctx.should_call_send(event_4, Message(BotReply.add_reply_on_tags), True) event_abort = fake_group_message_event( message=Message("取消"), sender=Sender(card="", nickname="test", role="admin") ) ctx.receive_event(bot, event_abort) ctx.should_call_send( event_abort, - "已中止订阅", + BotReply.add_reply_abort, True, ) ctx.should_finished() From c9bea2a780fe70608005c6bed53a0b07ee160564 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 12 Mar 2022 17:54:25 +0000 Subject: [PATCH 11/25] auto fix by pre-commit hooks --- src/plugins/nonebot_bison/config_manager.py | 20 +++--- tests/test_config_manager_abort.py | 46 ++++++------- tests/test_config_manager_add.py | 51 +++++++++----- tests/utils.py | 74 +++++++++++---------- 4 files changed, 107 insertions(+), 84 deletions(-) diff --git a/src/plugins/nonebot_bison/config_manager.py b/src/plugins/nonebot_bison/config_manager.py index 5e00414..de0f3bd 100644 --- a/src/plugins/nonebot_bison/config_manager.py +++ b/src/plugins/nonebot_bison/config_manager.py @@ -110,9 +110,7 @@ def do_add_sub(add_sub: Type[Matcher]): ) async def init_id(state: T_State): if platform_manager[state["platform"]].has_target: - state[ - "_prompt" - ] = "请输入订阅用户的id:\n查询id获取方法请回复:“查询”" + state["_prompt"] = "请输入订阅用户的id:\n查询id获取方法请回复:“查询”" else: state["id"] = "default" state["name"] = await platform_manager[state["platform"]].get_target_name( @@ -134,18 +132,22 @@ def do_add_sub(add_sub: Type[Matcher]): state["id"] = target state["name"] = name except (LookupError): - url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid" - title="Bison所支持的平台UID" - content="查询相关平台的uid格式或获取方式" - image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" - getId_share=f"[CQ:share,url={url},title={title},content={content},image={image}]"#缩短字符串格式长度,以及方便后续修改为消息段格式 + url = "https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid" + title = "Bison所支持的平台UID" + content = "查询相关平台的uid格式或获取方式" + image = "https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" + getId_share = f"[CQ:share,url={url},title={title},content={content},image={image}]" # 缩短字符串格式长度,以及方便后续修改为消息段格式 await add_sub.reject(Message(getId_share)) except (KeyboardInterrupt): await add_sub.finish("已中止订阅") except (ValueError): await add_sub.reject("id输入错误") else: - await add_sub.send("即将订阅的用户为:{} {} {}\n如有错误请输入“取消”重新订阅".format(state["platform"],state["name"],state["id"])) + await add_sub.send( + "即将订阅的用户为:{} {} {}\n如有错误请输入“取消”重新订阅".format( + state["platform"], state["name"], state["id"] + ) + ) @add_sub.got("id", _gen_prompt_template("{_prompt}"), [Depends(parse_id)]) async def init_cat(state: T_State): diff --git a/tests/test_config_manager_abort.py b/tests/test_config_manager_abort.py index bcc5c95..da307f4 100644 --- a/tests/test_config_manager_abort.py +++ b/tests/test_config_manager_abort.py @@ -4,7 +4,7 @@ from httpx import Response from nonebug.app import App from .platforms.utils import get_json -from .utils import fake_admin_user, fake_group_message_event,BotReply +from .utils import BotReply, fake_admin_user, fake_group_message_event # 选择platform阶段中止 @@ -43,9 +43,7 @@ async def test_abort_add_on_platform(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message( - BotReply.add_reply_on_platform(platform_manager,common_platform) - ), + Message(BotReply.add_reply_on_platform(platform_manager, common_platform)), True, ) event_abort = fake_group_message_event( @@ -96,9 +94,7 @@ async def test_abort_add_on_id(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message( - BotReply.add_reply_on_platform(platform_manager,common_platform) - ), + Message(BotReply.add_reply_on_platform(platform_manager, common_platform)), True, ) event_2 = fake_group_message_event( @@ -107,9 +103,7 @@ async def test_abort_add_on_id(app: App): ctx.receive_event(bot, event_2) ctx.should_call_send( event_2, - Message( - BotReply.add_reply_on_id - ), + Message(BotReply.add_reply_on_id), True, ) event_abort = fake_group_message_event( @@ -161,7 +155,9 @@ async def test_abort_add_on_cats(app: App): ctx.should_call_send( event_1, Message( - BotReply.add_reply_on_platform(platform_manager=platform_manager,common_platform=common_platform) + BotReply.add_reply_on_platform( + platform_manager=platform_manager, common_platform=common_platform + ) ), True, ) @@ -171,9 +167,7 @@ async def test_abort_add_on_cats(app: App): ctx.receive_event(bot, event_2) ctx.should_call_send( event_2, - Message( - BotReply.add_reply_on_id - ), + Message(BotReply.add_reply_on_id), True, ) event_3 = fake_group_message_event( @@ -182,12 +176,14 @@ async def test_abort_add_on_cats(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - BotReply.add_reply_on_target_confirm("weibo","明日方舟Arknights","6279793937"), - True + BotReply.add_reply_on_target_confirm( + "weibo", "明日方舟Arknights", "6279793937" + ), + True, ) ctx.should_call_send( event_3, - Message(BotReply.add_reply_on_cats(platform_manager,"weibo")), + Message(BotReply.add_reply_on_cats(platform_manager, "weibo")), True, ) event_abort = fake_group_message_event( @@ -239,7 +235,9 @@ async def test_abort_add_on_tag(app: App): ctx.should_call_send( event_1, Message( - BotReply.add_reply_on_platform(platform_manager=platform_manager,common_platform=common_platform) + BotReply.add_reply_on_platform( + platform_manager=platform_manager, common_platform=common_platform + ) ), True, ) @@ -249,9 +247,7 @@ async def test_abort_add_on_tag(app: App): ctx.receive_event(bot, event_2) ctx.should_call_send( event_2, - Message( - BotReply.add_reply_on_id - ), + Message(BotReply.add_reply_on_id), True, ) event_3 = fake_group_message_event( @@ -260,12 +256,14 @@ async def test_abort_add_on_tag(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - BotReply.add_reply_on_target_confirm("weibo","明日方舟Arknights","6279793937"), - True + BotReply.add_reply_on_target_confirm( + "weibo", "明日方舟Arknights", "6279793937" + ), + True, ) ctx.should_call_send( event_3, - Message(BotReply.add_reply_on_cats(platform_manager,"weibo")), + Message(BotReply.add_reply_on_cats(platform_manager, "weibo")), True, ) event_4 = fake_group_message_event( diff --git a/tests/test_config_manager_add.py b/tests/test_config_manager_add.py index 5e80e3e..497b135 100644 --- a/tests/test_config_manager_add.py +++ b/tests/test_config_manager_add.py @@ -4,7 +4,7 @@ from httpx import Response from nonebug.app import App from .platforms.utils import get_json -from .utils import fake_admin_user, fake_group_message_event, BotReply +from .utils import BotReply, fake_admin_user, fake_group_message_event @pytest.mark.asyncio @@ -31,6 +31,7 @@ async def test_configurable_at_me_true_failed(app: App): ctx.should_pass_rule() ctx.should_not_pass_permission() + @pytest.mark.asyncio async def test_configurable_at_me_false(app: App): from nonebot.adapters.onebot.v11.bot import Bot @@ -48,12 +49,13 @@ async def test_configurable_at_me_false(app: App): ctx.receive_event(bot, event) ctx.should_call_send( event, - Message(BotReply.add_reply_on_platform(platform_manager,common_platform)), + Message(BotReply.add_reply_on_platform(platform_manager, common_platform)), True, ) ctx.should_pass_rule() ctx.should_pass_permission() + @pytest.mark.asyncio @respx.mock async def test_add_with_target(app: App): @@ -90,7 +92,11 @@ async def test_add_with_target(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message(BotReply.add_reply_on_platform(platform_manager=platform_manager,common_platform=common_platform)), + Message( + BotReply.add_reply_on_platform( + platform_manager=platform_manager, common_platform=common_platform + ) + ), True, ) event_2 = fake_group_message_event( @@ -124,19 +130,23 @@ async def test_add_with_target(app: App): ctx.receive_event(bot, event_4_ok) ctx.should_call_send( event_4_ok, - BotReply.add_reply_on_target_confirm("weibo","明日方舟Arknights","6279793937"), - True + BotReply.add_reply_on_target_confirm( + "weibo", "明日方舟Arknights", "6279793937" + ), + True, ) ctx.should_call_send( event_4_ok, - Message(BotReply.add_reply_on_cats(platform_manager,"weibo")), + Message(BotReply.add_reply_on_cats(platform_manager, "weibo")), True, ) event_5_err = fake_group_message_event( message=Message("图文 文字 err"), sender=fake_admin_user ) ctx.receive_event(bot, event_5_err) - ctx.should_call_send(event_5_err, BotReply.add_reply_on_cats_input_error("err"), True) + ctx.should_call_send( + event_5_err, BotReply.add_reply_on_cats_input_error("err"), True + ) ctx.should_rejected() event_5_ok = fake_group_message_event( message=Message("图文 文字"), sender=fake_admin_user @@ -147,7 +157,9 @@ async def test_add_with_target(app: App): message=Message("全部标签"), sender=fake_admin_user ) ctx.receive_event(bot, event_6) - ctx.should_call_send(event_6, BotReply.add_reply_subscribe_success("明日方舟Arknights"), True) + ctx.should_call_send( + event_6, BotReply.add_reply_subscribe_success("明日方舟Arknights"), True + ) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -160,6 +172,7 @@ async def test_add_with_target(app: App): assert sub["target_type"] == "weibo" assert sub["target_name"] == "明日方舟Arknights" + @pytest.mark.asyncio @respx.mock async def test_add_with_target_no_cat(app: App): @@ -186,7 +199,7 @@ async def test_add_with_target_no_cat(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message(BotReply.add_reply_on_platform(platform_manager,common_platform)), + Message(BotReply.add_reply_on_platform(platform_manager, common_platform)), True, ) event_3 = fake_group_message_event( @@ -204,10 +217,12 @@ async def test_add_with_target_no_cat(app: App): ctx.receive_event(bot, event_4_ok) ctx.should_call_send( event_4_ok, - BotReply.add_reply_on_target_confirm("ncm-artist","塞壬唱片-MSR","32540734"), - True + BotReply.add_reply_on_target_confirm("ncm-artist", "塞壬唱片-MSR", "32540734"), + True, + ) + ctx.should_call_send( + event_4_ok, BotReply.add_reply_subscribe_success("塞壬唱片-MSR"), True ) - ctx.should_call_send(event_4_ok, BotReply.add_reply_subscribe_success("塞壬唱片-MSR"), True) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -218,6 +233,7 @@ async def test_add_with_target_no_cat(app: App): assert sub["target_type"] == "ncm-artist" assert sub["target_name"] == "塞壬唱片-MSR" + @pytest.mark.asyncio @respx.mock async def test_add_no_target(app: App): @@ -241,7 +257,7 @@ async def test_add_no_target(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message(BotReply.add_reply_on_platform(platform_manager,common_platform)), + Message(BotReply.add_reply_on_platform(platform_manager, common_platform)), True, ) event_3 = fake_group_message_event( @@ -250,14 +266,16 @@ async def test_add_no_target(app: App): ctx.receive_event(bot, event_3) ctx.should_call_send( event_3, - Message(BotReply.add_reply_on_cats(platform_manager,"arknights")), + Message(BotReply.add_reply_on_cats(platform_manager, "arknights")), True, ) event_4 = fake_group_message_event( message=Message("游戏公告"), sender=fake_admin_user ) ctx.receive_event(bot, event_4) - ctx.should_call_send(event_4, BotReply.add_reply_subscribe_success("明日方舟游戏信息"), True) + ctx.should_call_send( + event_4, BotReply.add_reply_subscribe_success("明日方舟游戏信息"), True + ) ctx.should_finished() subs = config.list_subscribe(10000, "group") assert len(subs) == 1 @@ -268,6 +286,7 @@ async def test_add_no_target(app: App): assert sub["target_type"] == "arknights" assert sub["target_name"] == "明日方舟游戏信息" + @pytest.mark.asyncio async def test_platform_name_err(app: App): from nonebot.adapters.onebot.v11.event import Sender @@ -289,7 +308,7 @@ async def test_platform_name_err(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message(BotReply.add_reply_on_platform(platform_manager,common_platform)), + Message(BotReply.add_reply_on_platform(platform_manager, common_platform)), True, ) event_2 = fake_group_message_event( diff --git a/tests/utils.py b/tests/utils.py index 6911ea9..aee9e2f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -71,50 +71,54 @@ fake_admin_user = Sender(nickname="test", role="admin") fake_superuser = Sender(user_id=10001, nickname="superuser") from nonebot.adapters.onebot.v11.message import Message + + class BotReply: - def add_reply_on_platform(platform_manager,common_platform): + def add_reply_on_platform(platform_manager, common_platform): return ( - "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" - + "".join( - [ - "{}:{}\n".format( - platform_name, platform_manager[platform_name].name - ) - for platform_name in common_platform - ] - ) - + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" + "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" + + "".join( + [ + "{}:{}\n".format( + platform_name, platform_manager[platform_name].name + ) + for platform_name in common_platform + ] ) + + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" + ) def add_reply_on_platform_input_allplatform(platform_manager): return "全部平台\n" + "\n".join( - [ - "{}:{}".format(platform_name, platform.name) - for platform_name, platform in platform_manager.items() - ]) + [ + "{}:{}".format(platform_name, platform.name) + for platform_name, platform in platform_manager.items() + ] + ) def add_reply_on_id_input_search(): - search_url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" - search_title="Bison所支持的平台UID" - search_content="查询相关平台的uid格式或获取方式" - search_image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" - return (f"[CQ:share,url={search_url},title={search_title},content={search_content},image={search_image}") - - def add_reply_on_target_confirm(platform,name,id): - return (f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅") - - def add_reply_on_cats(platform_manager,platform:str): - return ("请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( - " ".join(list(platform_manager[platform].categories.values())))) + search_url = "https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + search_title = "Bison所支持的平台UID" + search_content = "查询相关平台的uid格式或获取方式" + search_image = "https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" + return f"[CQ:share,url={search_url},title={search_title},content={search_content},image={search_image}" - def add_reply_on_cats_input_error(cat:str): - return ("不支持 {}".format(cat)) + def add_reply_on_target_confirm(platform, name, id): + return f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅" + + def add_reply_on_cats(platform_manager, platform: str): + return "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( + " ".join(list(platform_manager[platform].categories.values())) + ) + + def add_reply_on_cats_input_error(cat: str): + return "不支持 {}".format(cat) def add_reply_subscribe_success(name): - return ("添加 {} 成功".format(name)) + return "添加 {} 成功".format(name) - add_reply_on_id_input_error="id输入错误" - add_reply_on_platform_input_error="平台输入错误" - add_reply_on_id="请输入订阅用户的id:\n查询id获取方法请回复:“查询”" - add_reply_on_tags='请输入要订阅的tag,订阅所有tag输入"全部标签"' - add_reply_abort="已中止订阅" \ No newline at end of file + add_reply_on_id_input_error = "id输入错误" + add_reply_on_platform_input_error = "平台输入错误" + add_reply_on_id = "请输入订阅用户的id:\n查询id获取方法请回复:“查询”" + add_reply_on_tags = '请输入要订阅的tag,订阅所有tag输入"全部标签"' + add_reply_abort = "已中止订阅" From 098aa959cc9bd3e97d167984d1e3dd82442336b0 Mon Sep 17 00:00:00 2001 From: Azide Date: Sun, 13 Mar 2022 14:56:07 +0800 Subject: [PATCH 12/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=9C=A8?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=A2=E9=98=85=E8=BF=87=E7=A8=8B=E4=B8=AD?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0id=E6=AD=A5=E9=AA=A4=E8=BE=93=E5=85=A5=20?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=20=E6=97=B6bot=E5=BA=94=E5=9B=9E=E5=A4=8D?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E7=9A=84test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_config_manager_add.py | 76 ++++++++++++++++++++++++++++++++ tests/utils.py | 16 +++++-- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/tests/test_config_manager_add.py b/tests/test_config_manager_add.py index 5e80e3e..afd4e3d 100644 --- a/tests/test_config_manager_add.py +++ b/tests/test_config_manager_add.py @@ -303,3 +303,79 @@ async def test_platform_name_err(app: App): BotReply.add_reply_on_platform_input_error, True, ) + +@pytest.mark.asyncio +@respx.mock +async def test_add_with_get_id(app: App): + from nonebot.adapters.onebot.v11.event import Sender + from nonebot.adapters.onebot.v11.message import Message,MessageSegment + from nonebot_bison.config import Config + from nonebot_bison.config_manager import add_sub_matcher, common_platform + from nonebot_bison.platform import platform_manager + + config = Config() + config.user_target.truncate() + + ak_list_router = respx.get( + "https://m.weibo.cn/api/container/getIndex?containerid=1005056279793937" + ) + ak_list_router.mock( + return_value=Response(200, json=get_json("weibo_ak_profile.json")) + ) + ak_list_bad_router = respx.get( + "https://m.weibo.cn/api/container/getIndex?containerid=100505000" + ) + ak_list_bad_router.mock( + return_value=Response(200, json=get_json("weibo_err_profile.json")) + ) + + async with app.test_matcher(add_sub_matcher) as ctx: + bot = ctx.create_bot() + event_1 = fake_group_message_event( + message=Message("添加订阅"), + sender=Sender(card="", nickname="test", role="admin"), + to_me=True, + ) + ctx.receive_event(bot, event_1) + ctx.should_pass_rule() + ctx.should_call_send( + event_1, + Message(BotReply.add_reply_on_platform(platform_manager=platform_manager,common_platform=common_platform)), + True, + ) + event_3 = fake_group_message_event( + message=Message("weibo"), sender=fake_admin_user + ) + ctx.receive_event(bot, event_3) + ctx.should_call_send( + event_3, + Message(BotReply.add_reply_on_id), + True, + ) + event_4_query = fake_group_message_event( + message=Message("查询"), sender=fake_admin_user + ) + ctx.receive_event(bot, event_4_query) + ctx.should_rejected() + ctx.should_call_send( + event_4_query, + [MessageSegment(*BotReply.add_reply_on_id_input_search())], + True + ) + ''' + line 362: + 鬼知道为什么要在这里这样写, + 没有[]的话assert不了(should_call_send使用[MessageSegment(...)]的格式进行比较) + 不在这里MessageSegment()的话也assert不了(指不能让add_reply_on_id_input_search直接返回一个MessageSegment对象) + amen + ''' + event_abort = fake_group_message_event( + message=Message("取消"), sender=Sender(card="", nickname="test", role="admin") + ) + ctx.receive_event(bot, event_abort) + ctx.should_call_send( + event_abort, + BotReply.add_reply_abort, + True, + ) + ctx.should_finished() \ No newline at end of file diff --git a/tests/utils.py b/tests/utils.py index 6911ea9..796bd61 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -70,7 +70,7 @@ from nonebot.adapters.onebot.v11.event import Sender fake_admin_user = Sender(nickname="test", role="admin") fake_superuser = Sender(user_id=10001, nickname="superuser") -from nonebot.adapters.onebot.v11.message import Message +from nonebot.adapters.onebot.v11.message import Message,MessageSegment class BotReply: def add_reply_on_platform(platform_manager,common_platform): return ( @@ -94,11 +94,19 @@ class BotReply: ]) def add_reply_on_id_input_search(): - search_url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84uid" + search_url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid" search_title="Bison所支持的平台UID" search_content="查询相关平台的uid格式或获取方式" - search_image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" - return (f"[CQ:share,url={search_url},title={search_title},content={search_content},image={search_image}") + search_image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" + type='share' + data={ + 'url':search_url, + 'title':search_title, + 'content':search_content, + 'image':search_image + } + msg=[type,data] + return msg def add_reply_on_target_confirm(platform,name,id): return (f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅") From 036ab31f850675c77b9b110ecbd859a542173a37 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 13 Mar 2022 07:01:33 +0000 Subject: [PATCH 13/25] auto fix by pre-commit hooks --- tests/test_config_manager_add.py | 17 ++++++++---- tests/utils.py | 47 +++++++++++++++++--------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/tests/test_config_manager_add.py b/tests/test_config_manager_add.py index a4f681a..65447ed 100644 --- a/tests/test_config_manager_add.py +++ b/tests/test_config_manager_add.py @@ -323,11 +323,12 @@ async def test_platform_name_err(app: App): True, ) + @pytest.mark.asyncio @respx.mock async def test_add_with_get_id(app: App): from nonebot.adapters.onebot.v11.event import Sender - from nonebot.adapters.onebot.v11.message import Message,MessageSegment + from nonebot.adapters.onebot.v11.message import Message, MessageSegment from nonebot_bison.config import Config from nonebot_bison.config_manager import add_sub_matcher, common_platform from nonebot_bison.platform import platform_manager @@ -359,7 +360,11 @@ async def test_add_with_get_id(app: App): ctx.should_pass_rule() ctx.should_call_send( event_1, - Message(BotReply.add_reply_on_platform(platform_manager=platform_manager,common_platform=common_platform)), + Message( + BotReply.add_reply_on_platform( + platform_manager=platform_manager, common_platform=common_platform + ) + ), True, ) event_3 = fake_group_message_event( @@ -379,15 +384,15 @@ async def test_add_with_get_id(app: App): ctx.should_call_send( event_4_query, [MessageSegment(*BotReply.add_reply_on_id_input_search())], - True + True, ) - ''' + """ line 362: 鬼知道为什么要在这里这样写, 没有[]的话assert不了(should_call_send使用[MessageSegment(...)]的格式进行比较) 不在这里MessageSegment()的话也assert不了(指不能让add_reply_on_id_input_search直接返回一个MessageSegment对象) amen - ''' + """ event_abort = fake_group_message_event( message=Message("取消"), sender=Sender(card="", nickname="test", role="admin") ) @@ -397,4 +402,4 @@ async def test_add_with_get_id(app: App): BotReply.add_reply_abort, True, ) - ctx.should_finished() \ No newline at end of file + ctx.should_finished() diff --git a/tests/utils.py b/tests/utils.py index 3005f10..4d957f4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -70,7 +70,9 @@ from nonebot.adapters.onebot.v11.event import Sender fake_admin_user = Sender(nickname="test", role="admin") fake_superuser = Sender(user_id=10001, nickname="superuser") -from nonebot.adapters.onebot.v11.message import Message,MessageSegment +from nonebot.adapters.onebot.v11.message import Message, MessageSegment + + class BotReply: def add_reply_on_platform(platform_manager, common_platform): return ( @@ -95,29 +97,30 @@ class BotReply: ) def add_reply_on_id_input_search(): - search_url="https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid" - search_title="Bison所支持的平台UID" - search_content="查询相关平台的uid格式或获取方式" - search_image="https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" - type='share' - data={ - 'url':search_url, - 'title':search_title, - 'content':search_content, - 'image':search_image - } - msg=[type,data] + search_url = "https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid" + search_title = "Bison所支持的平台UID" + search_content = "查询相关平台的uid格式或获取方式" + search_image = "https://s3.bmp.ovh/imgs/2022/03/ab3cc45d83bd3dd3.jpg" + type = "share" + data = { + "url": search_url, + "title": search_title, + "content": search_content, + "image": search_image, + } + msg = [type, data] return msg - - def add_reply_on_target_confirm(platform,name,id): - return (f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅") - - def add_reply_on_cats(platform_manager,platform:str): - return ("请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( - " ".join(list(platform_manager[platform].categories.values())))) - def add_reply_on_cats_input_error(cat:str): - return ("不支持 {}".format(cat)) + def add_reply_on_target_confirm(platform, name, id): + return f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅" + + def add_reply_on_cats(platform_manager, platform: str): + return "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( + " ".join(list(platform_manager[platform].categories.values())) + ) + + def add_reply_on_cats_input_error(cat: str): + return "不支持 {}".format(cat) def add_reply_subscribe_success(name): return "添加 {} 成功".format(name) From 8226c526662527c212940714bcbb68cefa0fae75 Mon Sep 17 00:00:00 2001 From: Azide Date: Sun, 13 Mar 2022 15:59:41 +0800 Subject: [PATCH 14/25] =?UTF-8?q?=E8=A1=A5=E5=85=85README.MD=E7=9A=84?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ docs/usage/README.md | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d3c6348..916d729 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,8 @@ yarn && yarn build 本项目使用了 Python 3.9 的语法,请将 Python 版本升级到 3.9 及以上,推荐使用 docker 部署 2. bot 不理我 请确认自己是群主或者管理员,并且检查`COMMAND_START`环境变量是否设为`[""]` + 或者按照`COMMAND_START`中的设置添加命令前缀,例: + `COMMAND_START=["/"]`则应发送`/添加订阅` 3. 微博漏订阅了 微博更新了新的风控措施,某些含有某些关键词的微博会获取不到。 diff --git a/docs/usage/README.md b/docs/usage/README.md index 530b908..099fb7c 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -136,8 +136,9 @@ sidebar: auto ## 使用 ::: warning -本节假设`COMMAND_START`设置中包含`''`,如果出现 bot 不响应的问题,请先 -排查这个设置 +本节假设`COMMAND_START`设置中包含`''` +- 如果出现 bot 不响应的问题,请先排查这个设置 +- 尝试在命令前添加设置的命令前缀,如`COMMAND_START=['/']`,则尝试使用`/添加订阅` ::: ### 命令 From 8d6d5c9e8b7bbe5187ed04b6d75877deccf8ea87 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 13 Mar 2022 08:20:02 +0000 Subject: [PATCH 15/25] auto fix by pre-commit hooks --- docs/usage/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/usage/README.md b/docs/usage/README.md index 099fb7c..bcc48fc 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -137,9 +137,10 @@ sidebar: auto ::: warning 本节假设`COMMAND_START`设置中包含`''` + - 如果出现 bot 不响应的问题,请先排查这个设置 - 尝试在命令前添加设置的命令前缀,如`COMMAND_START=['/']`,则尝试使用`/添加订阅` -::: + ::: ### 命令 From 05ec0659d1876a0712c1833f6f4b829ccb9e9f9a Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Sun, 13 Mar 2022 16:45:50 +0800 Subject: [PATCH 16/25] add @staticmethod for util class --- tests/utils.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index 4d957f4..bd1930d 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -70,10 +70,9 @@ from nonebot.adapters.onebot.v11.event import Sender fake_admin_user = Sender(nickname="test", role="admin") fake_superuser = Sender(user_id=10001, nickname="superuser") -from nonebot.adapters.onebot.v11.message import Message, MessageSegment - class BotReply: + @staticmethod def add_reply_on_platform(platform_manager, common_platform): return ( "请输入想要订阅的平台,目前支持,请输入冒号左边的名称:\n" @@ -88,6 +87,7 @@ class BotReply: + "要查看全部平台请输入:“全部”\n中止订阅过程请输入:“取消”" ) + @staticmethod def add_reply_on_platform_input_allplatform(platform_manager): return "全部平台\n" + "\n".join( [ @@ -96,6 +96,7 @@ class BotReply: ] ) + @staticmethod def add_reply_on_id_input_search(): search_url = "https://nonebot-bison.vercel.app/usage/#%E6%89%80%E6%94%AF%E6%8C%81%E5%B9%B3%E5%8F%B0%E7%9A%84-uid" search_title = "Bison所支持的平台UID" @@ -111,17 +112,21 @@ class BotReply: msg = [type, data] return msg + @staticmethod def add_reply_on_target_confirm(platform, name, id): return f"即将订阅的用户为:{platform} {name} {id}\n如有错误请输入“取消”重新订阅" + @staticmethod def add_reply_on_cats(platform_manager, platform: str): return "请输入要订阅的类别,以空格分隔,支持的类别有:{}".format( " ".join(list(platform_manager[platform].categories.values())) ) + @staticmethod def add_reply_on_cats_input_error(cat: str): return "不支持 {}".format(cat) + @staticmethod def add_reply_subscribe_success(name): return "添加 {} 成功".format(name) From e189845d7b9ab8fbb29572df1587f1155323ab62 Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Wed, 16 Mar 2022 00:25:08 +0800 Subject: [PATCH 17/25] update image path --- .../public/images}/forward-msg-simple1.png | Bin .../public/images}/forward-msg-simple2.png | Bin docs/usage/README.md | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename docs/{usage/pic => .vuepress/public/images}/forward-msg-simple1.png (100%) rename docs/{usage/pic => .vuepress/public/images}/forward-msg-simple2.png (100%) diff --git a/docs/usage/pic/forward-msg-simple1.png b/docs/.vuepress/public/images/forward-msg-simple1.png similarity index 100% rename from docs/usage/pic/forward-msg-simple1.png rename to docs/.vuepress/public/images/forward-msg-simple1.png diff --git a/docs/usage/pic/forward-msg-simple2.png b/docs/.vuepress/public/images/forward-msg-simple2.png similarity index 100% rename from docs/usage/pic/forward-msg-simple2.png rename to docs/.vuepress/public/images/forward-msg-simple2.png diff --git a/docs/usage/README.md b/docs/usage/README.md index bcc48fc..24a8be0 100644 --- a/docs/usage/README.md +++ b/docs/usage/README.md @@ -124,9 +124,9 @@ sidebar: auto ::: details 配置项示例 - 当`BISON_USE_PIC_MERGE=1`时: - ![simple1](./pic/forward-msg-simple1.png) + ![simple1](/images/forward-msg-simple1.png) - 当`BISON_USE_PIC_MERGE=2`时: - ![simple1](./pic/forward-msg-simple2.png) + ![simple1](/images/forward-msg-simple2.png) ::: ::: warning From 029f21defbe09232802dc694cc30a9a70cf1f1be Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Wed, 16 Mar 2022 00:32:02 +0800 Subject: [PATCH 18/25] fix site action --- docs/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 704fce1..e1c53d8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,8 +2,9 @@ home: true heroText: Nonebot Bison tagline: 本bot励志做全泰拉骑车最快的信使 -actionText: 快速部署 -actionLink: /usage/ +actions: + - text: 快速部署 + link: /usage/ features: - title: 拓展性强 details: 没有自己想要的网站?只要简单的爬虫知识就可以给它适配一个新的网站 From 5f613bd6c8fb0fb0c38a460619d63d9fc2468aff Mon Sep 17 00:00:00 2001 From: Azide Date: Mon, 14 Mar 2022 17:46:27 +0800 Subject: [PATCH 19/25] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E6=9D=83=E9=99=90=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/nonebot_bison/config_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/nonebot_bison/config_manager.py b/src/plugins/nonebot_bison/config_manager.py index de0f3bd..8d8b483 100644 --- a/src/plugins/nonebot_bison/config_manager.py +++ b/src/plugins/nonebot_bison/config_manager.py @@ -317,11 +317,11 @@ del_sub_matcher = on_command( del_sub_matcher.handle()(set_target_user_info) do_del_sub(del_sub_matcher) -group_manage_matcher = on_command("群管理") +group_manage_matcher = on_command("群管理",rule=to_me(),permission=SUPERUSER,priority=4) @group_manage_matcher.handle() -async def send_group_list(bot: Bot, state: T_State): +async def send_group_list(bot: Bot, event: PrivateMessageEvent, state: T_State): groups = await bot.call_api("get_group_list") res_text = "请选择需要管理的群:\n" group_number_idx = {} From 27bef47dc189c3e549d9b74f8992645300c6816f Mon Sep 17 00:00:00 2001 From: Azide Date: Mon, 14 Mar 2022 20:04:14 +0800 Subject: [PATCH 20/25] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86group=5Fmanage?= =?UTF-8?q?=5Fmatcher=E7=9A=84=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/nonebot_bison/config_manager.py | 5 +++- tests/test_config_manager_admin.py | 26 +++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/plugins/nonebot_bison/config_manager.py b/src/plugins/nonebot_bison/config_manager.py index 8d8b483..5a148d0 100644 --- a/src/plugins/nonebot_bison/config_manager.py +++ b/src/plugins/nonebot_bison/config_manager.py @@ -12,7 +12,7 @@ from nonebot.internal.params import ArgStr from nonebot.internal.rule import Rule from nonebot.log import logger from nonebot.matcher import Matcher -from nonebot.params import Depends, EventMessage, EventPlainText, EventToMe +from nonebot.params import Depends, EventMessage, EventPlainText, EventToMe, EventType from nonebot.permission import SUPERUSER from nonebot.rule import to_me from nonebot.typing import T_State @@ -319,6 +319,9 @@ do_del_sub(del_sub_matcher) group_manage_matcher = on_command("群管理",rule=to_me(),permission=SUPERUSER,priority=4) +@group_manage_matcher.handle() +async def send_group_list(bot: Bot, event: GroupMessageEvent, state: T_State): + await group_manage_matcher.finish(Message("该功能只支持私聊使用,请私聊Bot")) @group_manage_matcher.handle() async def send_group_list(bot: Bot, event: PrivateMessageEvent, state: T_State): diff --git a/tests/test_config_manager_admin.py b/tests/test_config_manager_admin.py index fc6581d..77e9ac1 100644 --- a/tests/test_config_manager_admin.py +++ b/tests/test_config_manager_admin.py @@ -1,9 +1,11 @@ from nonebug import App -from .utils import fake_admin_user, fake_private_message_event, fake_superuser +from .utils import fake_admin_user, fake_private_message_event, fake_group_message_event, fake_superuser +import pytest -async def test_query(app: App): +@pytest.mark.asyncio +async def test_query_with_superuser_private(app: App): from nonebot.adapters.onebot.v11.bot import Bot from nonebot.adapters.onebot.v11.message import Message from nonebot_bison.config_manager import group_manage_matcher @@ -43,3 +45,23 @@ async def test_query(app: App): message=Message("查询订阅"), sender=fake_superuser ) ctx.receive_event(bot, event_2_ok) + ctx.should_pass_rule() + ctx.should_pass_permission() + +@pytest.mark.asyncio +async def test_query_with_superuser_group_tome(app: App): + from nonebot.adapters.onebot.v11.bot import Bot + from nonebot.adapters.onebot.v11.message import Message + from nonebot_bison.config_manager import group_manage_matcher + + async with app.test_matcher(group_manage_matcher) as ctx: + bot = ctx.create_bot(base=Bot) + event = fake_group_message_event( + message=Message("群管理"), sender=fake_superuser,to_me=True + ) + ctx.receive_event(bot, event) + ctx.should_pass_rule() + ctx.should_pass_permission() + ctx.should_call_send( + event, '', True + ) \ No newline at end of file From 82e4ad1bb67ad51414a7bbbb3492ec2255a7bed9 Mon Sep 17 00:00:00 2001 From: felinae98 <731499577@qq.com> Date: Mon, 14 Mar 2022 23:26:50 +0800 Subject: [PATCH 21/25] fix some bug --- tests/test_config_manager_admin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_config_manager_admin.py b/tests/test_config_manager_admin.py index 77e9ac1..34f8586 100644 --- a/tests/test_config_manager_admin.py +++ b/tests/test_config_manager_admin.py @@ -13,7 +13,10 @@ async def test_query_with_superuser_private(app: App): async with app.test_matcher(group_manage_matcher) as ctx: bot = ctx.create_bot(base=Bot) event = fake_private_message_event( - message=Message("群管理"), sender=fake_superuser + message=Message("群管理"), + sender=fake_superuser, + to_me=True, + user_id=fake_superuser.user_id, ) ctx.receive_event(bot, event) ctx.should_pass_rule() From 53273d2d6f109a048ad58e22dc1113349ad25721 Mon Sep 17 00:00:00 2001 From: Azide Date: Mon, 14 Mar 2022 23:47:42 +0800 Subject: [PATCH 22/25] =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=BA=86test=5Fconfig?= =?UTF-8?q?=5Fmanager=5Fadmin=E4=B8=AD=E7=9A=84test=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_config_manager_admin.py | 43 +++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/tests/test_config_manager_admin.py b/tests/test_config_manager_admin.py index 34f8586..1d8ebf8 100644 --- a/tests/test_config_manager_admin.py +++ b/tests/test_config_manager_admin.py @@ -1,8 +1,13 @@ +import pytest from nonebug import App -from .utils import fake_admin_user, fake_private_message_event, fake_group_message_event, fake_superuser +from .utils import ( + fake_admin_user, + fake_group_message_event, + fake_private_message_event, + fake_superuser, +) -import pytest @pytest.mark.asyncio async def test_query_with_superuser_private(app: App): @@ -28,29 +33,42 @@ async def test_query_with_superuser_private(app: App): event, Message("请选择需要管理的群:\n1. 101 - test group\n请输入左侧序号"), True ) event_1_err = fake_private_message_event( - message=Message("0"), sender=fake_superuser + message=Message("0"), + sender=fake_superuser, + to_me=True, + user_id=fake_superuser.user_id, ) ctx.receive_event(bot, event_1_err) - ctx.should_rejected() ctx.should_call_send(event_1_err, "请输入正确序号", True) + ctx.should_rejected() event_1_ok = fake_private_message_event( - message=Message("1"), sender=fake_superuser + message=Message("1"), + sender=fake_superuser, + to_me=True, + user_id=fake_superuser.user_id, ) ctx.receive_event(bot, event_1_ok) ctx.should_call_send(event_1_ok, "请输入需要使用的命令:添加订阅,查询订阅,删除订阅", True) event_2_err = fake_private_message_event( - message=Message("222"), sender=fake_superuser + message=Message("222"), + sender=fake_superuser, + to_me=True, + user_id=fake_superuser.user_id, ) ctx.receive_event(bot, event_2_err) - ctx.should_rejected() ctx.should_call_send(event_2_err, "请输入正确的命令", True) + ctx.should_rejected() event_2_ok = fake_private_message_event( - message=Message("查询订阅"), sender=fake_superuser + message=Message("查询订阅"), + sender=fake_superuser, + to_me=True, + user_id=fake_superuser.user_id, ) ctx.receive_event(bot, event_2_ok) ctx.should_pass_rule() ctx.should_pass_permission() + @pytest.mark.asyncio async def test_query_with_superuser_group_tome(app: App): from nonebot.adapters.onebot.v11.bot import Bot @@ -60,11 +78,12 @@ async def test_query_with_superuser_group_tome(app: App): async with app.test_matcher(group_manage_matcher) as ctx: bot = ctx.create_bot(base=Bot) event = fake_group_message_event( - message=Message("群管理"), sender=fake_superuser,to_me=True + message=Message("群管理"), + sender=fake_superuser, + to_me=True, + user_id=fake_superuser.user_id, ) ctx.receive_event(bot, event) ctx.should_pass_rule() ctx.should_pass_permission() - ctx.should_call_send( - event, '', True - ) \ No newline at end of file + ctx.should_call_send(event, "", True) From 067317d6df7d539b134f42c671ff37c6c0ce0d2e Mon Sep 17 00:00:00 2001 From: Azide Date: Wed, 16 Mar 2022 12:39:36 +0800 Subject: [PATCH 23/25] =?UTF-8?q?=E5=90=8C=E6=AD=A5fix=E5=88=86=E6=94=AF?= =?UTF-8?q?=E7=9A=84test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_config_manager_admin.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/test_config_manager_admin.py b/tests/test_config_manager_admin.py index 1d8ebf8..51d7e35 100644 --- a/tests/test_config_manager_admin.py +++ b/tests/test_config_manager_admin.py @@ -1,12 +1,7 @@ import pytest from nonebug import App -from .utils import ( - fake_admin_user, - fake_group_message_event, - fake_private_message_event, - fake_superuser, -) +from .utils import fake_group_message_event, fake_private_message_event, fake_superuser @pytest.mark.asyncio @@ -86,4 +81,4 @@ async def test_query_with_superuser_group_tome(app: App): ctx.receive_event(bot, event) ctx.should_pass_rule() ctx.should_pass_permission() - ctx.should_call_send(event, "", True) + ctx.should_call_send(event, Message("该功能只支持私聊使用,请私聊Bot"), True) From 0daf27abdcd06b8b29f8fc109db6545642e1eed4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 16 Mar 2022 14:09:42 +0000 Subject: [PATCH 24/25] auto fix by pre-commit hooks --- src/plugins/nonebot_bison/config_manager.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/nonebot_bison/config_manager.py b/src/plugins/nonebot_bison/config_manager.py index 5a148d0..afb4f3b 100644 --- a/src/plugins/nonebot_bison/config_manager.py +++ b/src/plugins/nonebot_bison/config_manager.py @@ -317,12 +317,14 @@ del_sub_matcher = on_command( del_sub_matcher.handle()(set_target_user_info) do_del_sub(del_sub_matcher) -group_manage_matcher = on_command("群管理",rule=to_me(),permission=SUPERUSER,priority=4) +group_manage_matcher = on_command("群管理", rule=to_me(), permission=SUPERUSER, priority=4) + @group_manage_matcher.handle() async def send_group_list(bot: Bot, event: GroupMessageEvent, state: T_State): await group_manage_matcher.finish(Message("该功能只支持私聊使用,请私聊Bot")) + @group_manage_matcher.handle() async def send_group_list(bot: Bot, event: PrivateMessageEvent, state: T_State): groups = await bot.call_api("get_group_list") From dc55a6bf631b92a8241f3ba56b5e4a7096f2a4d6 Mon Sep 17 00:00:00 2001 From: AzideCupric <57004769+AzideCupric@users.noreply.github.com> Date: Wed, 16 Mar 2022 22:23:39 +0800 Subject: [PATCH 25/25] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=9C=AA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=9A=84EventType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/nonebot_bison/config_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/nonebot_bison/config_manager.py b/src/plugins/nonebot_bison/config_manager.py index afb4f3b..301cf25 100644 --- a/src/plugins/nonebot_bison/config_manager.py +++ b/src/plugins/nonebot_bison/config_manager.py @@ -12,7 +12,7 @@ from nonebot.internal.params import ArgStr from nonebot.internal.rule import Rule from nonebot.log import logger from nonebot.matcher import Matcher -from nonebot.params import Depends, EventMessage, EventPlainText, EventToMe, EventType +from nonebot.params import Depends, EventMessage, EventPlainText, EventToMe from nonebot.permission import SUPERUSER from nonebot.rule import to_me from nonebot.typing import T_State