From 8bb3f15bd9306890d13d4a7a10a340415f04f514 Mon Sep 17 00:00:00 2001 From: snowykami Date: Sat, 31 Aug 2024 19:05:37 +0800 Subject: [PATCH] =?UTF-8?q?:memo:=20=E6=96=87=E6=A1=A3=E5=88=9D=E6=AD=A5?= =?UTF-8?q?=E5=A4=A7=E8=BF=81=E7=A7=BB=20`vuepress`=20->=20`vitepress`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 +- docs/.vitepress/config/common.ts | 121 +++++++++++++++++++++++++++++++ docs/.vitepress/config/en.ts | 28 +++++++ docs/.vitepress/config/index.ts | 6 ++ docs/.vitepress/config/utils.ts | 40 ++++++++++ docs/.vitepress/config/zh.ts | 28 +++++++ docs/en/deploy/install.md | 2 +- docs/en/dev/comm.md | 98 +++++++++++++++++++++++++ docs/en/dev/lyfunc.md | 72 ++++++++++++++++++ docs/en/dev/plugin.md | 80 ++++++++++++++++++++ docs/en/dev/resource.md | 51 +++++++++++++ docs/zh/deploy/install.md | 2 +- docs/zh/dev/comm.md | 4 +- docs/zh/dev/resource.md | 2 +- 14 files changed, 534 insertions(+), 6 deletions(-) create mode 100644 docs/.vitepress/config/common.ts create mode 100644 docs/.vitepress/config/en.ts create mode 100644 docs/.vitepress/config/index.ts create mode 100644 docs/.vitepress/config/utils.ts create mode 100644 docs/.vitepress/config/zh.ts create mode 100644 docs/en/dev/comm.md create mode 100644 docs/en/dev/lyfunc.md create mode 100644 docs/en/dev/plugin.md create mode 100644 docs/en/dev/resource.md diff --git a/.gitignore b/.gitignore index 10a7fa59..062e1fdb 100644 --- a/.gitignore +++ b/.gitignore @@ -59,4 +59,8 @@ result.json # litedoc docs/zh/dev/api docs/en/dev/api -mkdoc.bat \ No newline at end of file +mkdoc.bat + +# vitepress +docs/.vitepress/dist/ +docs/.vitepress/cache \ No newline at end of file diff --git a/docs/.vitepress/config/common.ts b/docs/.vitepress/config/common.ts new file mode 100644 index 00000000..c31a37e5 --- /dev/null +++ b/docs/.vitepress/config/common.ts @@ -0,0 +1,121 @@ +// 共有配置项,导入index用 + +import {defineConfig} from 'vitepress' +import {generateSidebar} from 'vitepress-sidebar'; +import {zh} from "./zh"; +import {en} from "./en"; + +let defaultLocale = 'zh'; +const commonSidebarOptions = { + collapsed: true, + convertSameNameSubFileToGroupIndexPage: true, + useTitleFromFrontmatter: true, + useTitleFromFileHeading: true, + useFolderTitleFromIndexFile: true, + useFolderLinkFromIndexFile: true, + includeFolderIndexFile: true, + sortMenusByFrontmatterOrder: true, + rootGroupText: 'LITEYUKIBOT', +} + +/** + * Generate sidebar config + * multiple languages and sections + * @returns {any[]} + */ +function generateSidebarConfig(): any[] { + let sections = ["dev", "store", "usage", "deploy"] + let languages = ['zh', 'en'] + let ret = [] + for (let language of languages) { + for (let section of sections) { + if (language === defaultLocale) { + ret.push({ + basePath: `/${section}/`, + scanStartPath: `${language}/${section}`, + resolvePath: `/${section}/`, + ...commonSidebarOptions + }) + } else { + ret.push({ + basePath: `/${language}/${section}/`, + scanStartPath: `${language}/${section}`, + resolvePath: `/${language}/${section}/`, + ...commonSidebarOptions + }) + } + } + } + return ret +} + +console.log(generateSidebarConfig()) + +export const common = defineConfig({ + head: [ + // 配置favicon.ico + ['link', {rel: 'icon', type: 'image/x-icon', href: 'favicon.ico'}], + ['link', {rel: 'stylesheet', href: 'https://fonts.font.im/css?family=Cousine:400,400i,700,700i|Poppins:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i'}], + ], + rewrites: { + [`${defaultLocale}/:rest*`]: ":rest*", + }, + themeConfig: { + logo: '/liteyuki.svg', + sidebar: generateSidebar( + [ + ...generateSidebarConfig() + ] + ), + socialLinks: [ + {icon: 'github', link: 'https://github.com/LiteyukiStudio/LiteyukiBot'} + ], + search: { + provider: 'local', + options: { + locales: { + root: { + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '打开搜索框', + }, + modal: { + noResultsText: '没有找到搜索结果', + resetButtonTitle: '清除查询条件', + footer: { + selectText: '选择', + navigateText: '切换', + } + } + }, + }, + en: { + translations: { + button: { + buttonText: 'Search', + buttonAriaLabel: 'Search', + }, + modal: { + noResultsText: 'No results found', + resetButtonTitle: 'Reset search query', + footer: { + selectText: 'Select', + navigateText: 'Navigate', + } + } + } + }, + } + } + } + }, + sitemap: { + hostname: 'https://bot.liteyuki.icu' + }, + lastUpdated: true, + locales: { + root: {label: "简体中文", ...zh}, + en: {label: "English", ...en}, + }, +}) \ No newline at end of file diff --git a/docs/.vitepress/config/en.ts b/docs/.vitepress/config/en.ts new file mode 100644 index 00000000..438c5360 --- /dev/null +++ b/docs/.vitepress/config/en.ts @@ -0,0 +1,28 @@ +import {defineConfig} from 'vitepress' +import {ThemeConfig} from "./utils"; + +export const en = defineConfig({ + lang: "en-US", + title: "LiteyukiBot", + description: "A high-performance, easy-to-use chatbot framework and application", + themeConfig: { + nav: [ + {text: 'Deploy', link: '/en/deploy/install'}, + {text: 'Usage', link: '/en/usage/basic'}, + {text: 'Extension', link: '/en/store/resource'}, + {text: 'Develop', link: '/en/dev/api'}, + ], + docFooter: { + prev: 'Prev Page', + next: 'Next Page' + }, + editLink: ThemeConfig.getEditLink( + 'Edit this page on GitHub', + ), + footer: { + message: 'Documentation built with VitePress | API references generated by litedoc', + copyright: ThemeConfig.copyright + }, + outline: ThemeConfig.getOutLine("Page Content"), + }, +}) \ No newline at end of file diff --git a/docs/.vitepress/config/index.ts b/docs/.vitepress/config/index.ts new file mode 100644 index 00000000..f79dc256 --- /dev/null +++ b/docs/.vitepress/config/index.ts @@ -0,0 +1,6 @@ +import {defineConfig} from "vitepress"; + +import {common} from './common' +export default defineConfig({ + ...common, +}) \ No newline at end of file diff --git a/docs/.vitepress/config/utils.ts b/docs/.vitepress/config/utils.ts new file mode 100644 index 00000000..2270774e --- /dev/null +++ b/docs/.vitepress/config/utils.ts @@ -0,0 +1,40 @@ +// 本模块储存一些工具函数和引用 + +/** + * GetEditLink Options + * @param text Edit link text + */ +export const ThemeConfig = { + getEditLink: (editPageText: string): { pattern: (params: { filePath: string; }) => string; text: string; } => { + return { + pattern: ({filePath}: { filePath: string; }): string => { + // 匹配 /dev/api或 /{lang}/dev/api + const regex = /^[^\/]+\/dev\/api/; + console.log(filePath); + if (regex.test(filePath)) { + // remove {lang}/api prefix + filePath = filePath.replace(regex, '') + .replace('index.md', '__init__.py') + .replace('.md', '.py'); + // 若文件名(不含扩展)和上级文件夹相同,返回文件夹/__init__.py + if (filePath.split('/').pop().split('.')[0] === filePath.split('/').slice(-2, -1)[0]) { + filePath = filePath.split('/').slice(0, -1).join('/') + '/__init__.py'; + } + return `https://github.com/LiteyukiStudio/LiteyukiBot/tree/main/liteyuki${filePath}`; + } else { + return `https://github.com/LiteyukiStudio/LiteyukiBot/tree/main/docs${filePath}`; + } + }, + text: editPageText + }; + }, + + getOutLine: (label: string): { label: string; level: [number, number]; } => { + return { + label: label, + level: [2, 6] + }; + }, + + copyright: 'Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved' +} \ No newline at end of file diff --git a/docs/.vitepress/config/zh.ts b/docs/.vitepress/config/zh.ts new file mode 100644 index 00000000..492b6e9c --- /dev/null +++ b/docs/.vitepress/config/zh.ts @@ -0,0 +1,28 @@ +import {defineConfig} from 'vitepress' +import {ThemeConfig} from "./utils"; + +export const zh = defineConfig({ + lang: "zh-Hans", + title: "轻雪机器人", + description: "一个综合性的机器人应用及管理框架", + themeConfig: { + nav: [ + {text: '部署', link: '/deploy/install'}, + {text: '使用', link: '/usage/basic'}, + {text: '扩展', link: '/store/resource'}, + {text: '开发', link: '/dev/api'}, + ], + docFooter: { + prev: '上一页', + next: '下一页' + }, + editLink: ThemeConfig.getEditLink( + '在 GitHub 上编辑此页', + ), + footer: { + message: '文档由 VitePress 构建 | API引用由 litedoc 生成', + copyright: ThemeConfig.copyright + }, + outline: ThemeConfig.getOutLine("页面内容"), + }, +}) \ No newline at end of file diff --git a/docs/en/deploy/install.md b/docs/en/deploy/install.md index 89e7ea09..2c4098da 100644 --- a/docs/en/deploy/install.md +++ b/docs/en/deploy/install.md @@ -54,4 +54,4 @@ python main.py > [!warning] > Liteyuki's update function depends on Git. If you do not have Git installed and run the source code directly, you will not be able to use the update function -#### For other questions, please refer to [FAQ](/deployment/fandq) \ No newline at end of file +#### For other questions, please refer to [FAQ](./fandq) \ No newline at end of file diff --git a/docs/en/dev/comm.md b/docs/en/dev/comm.md new file mode 100644 index 00000000..9ab49557 --- /dev/null +++ b/docs/en/dev/comm.md @@ -0,0 +1,98 @@ +--- +title: 进程通信 +order: 4 +--- + +# **Channel Communication** + +### Introduction + +LiteyukiBot is running in the main process MainProcess, and other plugin framework processes are child processes that come with it. +Therefore, it is impossible to communicate through shared memory and direct object transfer. +Liteyuki provides a channel [`Channel`](./api/comm/channel#class-channel-generic-t) for inter-process communication like `go`. +You can send messages to other processes through [`Channel`](./api/comm/channel#class-channel-generic-t) and listen to messages from other processes. + +### Example + +The channel is full-duplex, with two receiving modes, but only one mode can be used for a channel, that is, passive mode and active mode, passive mode is implemented by the `chan.on_receive()` decorator callback function, and active mode needs to call `chan.receive()` to implement + +- 创建子进程的同时会初始化一个被动通道和一个主动通道,且通道标识为`{process_name}-active`和`{process_name}-passive`, +- 主进程中通过`get_channel`函数获取通道对象 +- 子进程中导入单例`active_channel`及`passive_channel`即可 + +> 在轻雪插件中(主进程中) + +```python +import asyncio + +from liteyuki.comm import get_channel, Channel +from liteyuki import get_bot + +# get_channel函数获取通道对象,参数为调用set_channel时的通道标识 +channel_passive = get_channel("nonebot-passive") # 获取被动通道 +channel_active = get_channel("nonebot-active") # 获取主动通道 +liteyuki_bot = get_bot() + + +# 注册一个函数在轻雪启动后运行 +@liteyuki_bot.on_after_start +async def send_data(): + while True: + channel_passive.send("I am liteyuki main process passive") + channel_active.send("I am liteyuki main process active") + await asyncio.sleep(3) # 每3秒发送一次消息 +``` + +> 在子进程中(例如NoneBot插件中) + +```python +from nonebot import get_driver +from liteyuki.comm import active_channel, passive_channel # 子进程中获取通道直接导入进程全局单例即可 +from liteyuki.log import logger + +driver = get_driver() + + +# 被动模式,通过装饰器注册一个函数在接收到消息时运行,每次接收到字符串数据时都会运行 +@passive_channel.on_receive(filter_func=lambda data: isinstance(data, str)) +async def on_passive_receive(data): + logger.info(f"Passive receive: {data}") + + +# 注册一个函数在NoneBot启动后运行 +@driver.on_startup +def on_startup(): + while True: + data = active_channel.receive() + logger.info(f"Active receive: {data}") +``` + +> 启动后控制台输出 + +```log +0000-00-00 00:00:00 [ℹ️信息] Passive receive: I am liteyuki main process passive +0000-00-00 00:00:00 [ℹ️信息] Active receive: I am liteyuki main process active +0000-00-00 00:00:03 [ℹ️信息] Passive receive: I am liteyuki main process passive +0000-00-00 00:00:03 [ℹ️信息] Active receive: I am liteyuki main process active +... +``` + +## **共享内存通信** + +### 简介 + +- 相比于普通进程通信,内存共享使得代码编写更加简洁,轻雪框架提供了一个内存共享通信的接口,你可以通过`storage`模块实现内存共享通信,该模块封装通道实现 +- 内存共享是线程安全的,你可以在多个线程中读写共享内存,线程锁会自动保护共享内存的读写操作 + +### 示例 + +> 在任意进程中均可使用 + +```python +from liteyuki.comm.storage import shared_memory + +shared_memory.set("key", "value") # 设置共享内存 +value = shared_memory.get("key") # 获取共享内存 +``` + +源代码:[liteyuki/comm/storage.py](https://github.com/LiteyukiStudio/LiteyukiBot/blob/main/liteyuki/comm/storage.py) diff --git a/docs/en/dev/lyfunc.md b/docs/en/dev/lyfunc.md new file mode 100644 index 00000000..74626b88 --- /dev/null +++ b/docs/en/dev/lyfunc.md @@ -0,0 +1,72 @@ +--- +title: 轻雪函数 +order: 2 +--- + +# **轻雪函数** + +轻雪函数 Liteyuki Function 是轻雪的一个功能,它允许你在轻雪中运行一些自定义的由数据驱动的命令,类似于Minecraft的mcfunction,属于资源包的一部分,但需单独起篇幅. + +### **函数文件** + +函数文件放在资源包的`functions`目录下,文件名以`.mcfunction` `.lyfunction` `.lyf`结尾,例如`test.mcfunction`,文件内容为一系列的命令,每行一个命令,支持单行注释`#`(编辑时的语法高亮可采取`shell`格式),例如: + +```shell +# 在发信器输出"hello world" +cmd echo hello world + +# 如果你想同时输出多行内容可以尝试换行符(Python格式) +cmd echo hello world\nLiteyuki bot +``` + +也支持句末注释,例如: +```shell +cmd echo hello world # 输出"hello world" +``` + +### **命令文档** + +```shell +var [var2=value2] ... # 定义变量 +cmd # 在设备上执行命令 +api [var=value...] # 调用Bot API +function # 调用函数,可递归 +sleep