From bea098349b23b57c8a236be43ac8e18f09daf3c5 Mon Sep 17 00:00:00 2001 From: xtaodada Date: Sat, 21 Oct 2023 13:28:21 +0800 Subject: [PATCH] :memo: Add quick-start --- .gitignore | 1 + docs/.vitepress/algolia.ts | 11 ++ docs/.vitepress/components.d.ts | 2 + docs/.vitepress/config.ts | 2 + docs/.vitepress/plugins/markdownTransform.ts | 21 +- docs/.vitepress/sidebar.ts | 2 +- .../theme/components/Contributors.vue | 42 ++++ docs/.vitepress/theme/components/PageInfo.vue | 6 +- docs/.vitepress/theme/styles/vars.css | 4 +- docs/quick-start/config.md | 183 ++++++++++++++++++ docs/quick-start/env.md | 12 +- docs/quick-start/install.md | 55 ++++++ docs/quick-start/run.md | 27 +++ package.json | 2 +- scripts/utils.ts | 32 +++ 15 files changed, 387 insertions(+), 15 deletions(-) create mode 100644 docs/.vitepress/algolia.ts create mode 100644 docs/.vitepress/theme/components/Contributors.vue create mode 100644 docs/quick-start/config.md create mode 100644 docs/quick-start/install.md create mode 100644 docs/quick-start/run.md create mode 100644 scripts/utils.ts diff --git a/.gitignore b/.gitignore index 0c2bd66..28f2479 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ docs/.vitepress/dist docs/.vitepress/cache node_modules/ +.eslintcache diff --git a/docs/.vitepress/algolia.ts b/docs/.vitepress/algolia.ts new file mode 100644 index 0000000..6b1addf --- /dev/null +++ b/docs/.vitepress/algolia.ts @@ -0,0 +1,11 @@ +export default { + appId: 'AU4G7FKYJF', + apiKey: 'e934cbf9d54f02be212594ad8b5a1373', + indexName: 'grambot', + placeholder: '请输入关键词', + translations: { + button: { + buttonText: '搜索', + }, + }, +} diff --git a/docs/.vitepress/components.d.ts b/docs/.vitepress/components.d.ts index e91968c..36eb6d3 100644 --- a/docs/.vitepress/components.d.ts +++ b/docs/.vitepress/components.d.ts @@ -12,12 +12,14 @@ declare module 'vue' { Card: typeof import('./theme/components/Card.vue')['default'] ChatMessage: typeof import('./theme/components/ChatMessage.vue')['default'] ChatPanel: typeof import('./theme/components/ChatPanel.vue')['default'] + Contributors: typeof import('./theme/components/Contributors.vue')['default'] CopyRight: typeof import('./theme/components/CopyRight.vue')['default'] DataPanel: typeof import('./theme/components/DataPanel.vue')['default'] HomeContributors: typeof import('./theme/components/HomeContributors.vue')['default'] NavCard: typeof import('./theme/components/NavCard.vue')['default'] 'Ooui:clock': typeof import('~icons/ooui/clock')['default'] PageInfo: typeof import('./theme/components/PageInfo.vue')['default'] + 'RadixIcons:update': typeof import('~icons/radix-icons/update')['default'] VideoLink: typeof import('./theme/components/VideoLink.vue')['default'] } } diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 5af8e64..4091aa5 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -4,6 +4,7 @@ import { description, docsVersion, github, keywords, name, site } from './meta' import { pwa } from './plugins/pwa' import sidebar from './sidebar' import socialLinks from './link' +import algolia from './algolia' export default withPwa(defineConfig({ pwa, @@ -55,6 +56,7 @@ export default withPwa(defineConfig({ ], }, ], + algolia, sidebar, socialLinks, }, diff --git a/docs/.vitepress/plugins/markdownTransform.ts b/docs/.vitepress/plugins/markdownTransform.ts index 212a096..f43e0ad 100644 --- a/docs/.vitepress/plugins/markdownTransform.ts +++ b/docs/.vitepress/plugins/markdownTransform.ts @@ -1,4 +1,5 @@ import type { Plugin } from 'vite' +import { replacer } from '../../../scripts/utils' import { getReadingTime } from './../theme/utils' export function MarkdownTransform(): Plugin { @@ -9,6 +10,8 @@ export function MarkdownTransform(): Plugin { if (!id.match(/\.md\b/)) return null + const [_name, i] = id.split('/').slice(-2) + // convert img const imgRegex = /!\[(.+?)\]\((.+?)\)/g let imgMatches = imgRegex.exec(code) @@ -18,8 +21,11 @@ export function MarkdownTransform(): Plugin { imgMatches = imgRegex.exec(code) } - // const { footer } = await getDocsMarkdown() - // code = replacer(code, footer, 'FOOTER', 'tail') + if (_name === 'docs' && i === 'index.md') + return code + + const { footer } = await getDocsMarkdown() + code = replacer(code, footer, 'FOOTER', 'tail') const { readTime, words } = getReadingTime(code) code = code.replace(/(#\s\S.+)/, `$1\n\n\n`) @@ -33,3 +39,14 @@ export function MarkdownTransform(): Plugin { }, } } + +export async function getDocsMarkdown() { + const ContributorsSection = `## Contributors + ` + + const footer = `${ContributorsSection}\n` + + return { + footer, + } +} diff --git a/docs/.vitepress/sidebar.ts b/docs/.vitepress/sidebar.ts index 0aaba29..f601f44 100644 --- a/docs/.vitepress/sidebar.ts +++ b/docs/.vitepress/sidebar.ts @@ -5,7 +5,7 @@ export default { collapsed: true, items: [ { text: '环境检查', link: '/quick-start/env' }, - { text: '克隆项目', link: '/quick-start/install' }, + { text: '安装项目', link: '/quick-start/install' }, { text: '配置项目', link: '/quick-start/config' }, { text: '启动项目', link: '/quick-start/run' }, ], diff --git a/docs/.vitepress/theme/components/Contributors.vue b/docs/.vitepress/theme/components/Contributors.vue new file mode 100644 index 0000000..8e82966 --- /dev/null +++ b/docs/.vitepress/theme/components/Contributors.vue @@ -0,0 +1,42 @@ + + + diff --git a/docs/.vitepress/theme/components/PageInfo.vue b/docs/.vitepress/theme/components/PageInfo.vue index 4eadaf6..416ac77 100644 --- a/docs/.vitepress/theme/components/PageInfo.vue +++ b/docs/.vitepress/theme/components/PageInfo.vue @@ -7,7 +7,7 @@ defineProps<{ readTime: string words: string }>() -const defaultAuthor = 'Choi Yang' +const defaultAuthor = 'PaigramTeam' const author = ref(defaultAuthor) const { frontmatter, page } = useData() @@ -26,6 +26,10 @@ const timeFormNow = getFromNow(isoDatetime.value)
+
+ + 更新于:{{ timeFormNow }} +
字数统计:{{ words }} 字 diff --git a/docs/.vitepress/theme/styles/vars.css b/docs/.vitepress/theme/styles/vars.css index 15f47d0..ddf3881 100644 --- a/docs/.vitepress/theme/styles/vars.css +++ b/docs/.vitepress/theme/styles/vars.css @@ -13,7 +13,7 @@ --vp-c-brand-light: #ff8f91; --vp-c-text-light-2: rgba(30, 30, 30, 0.7); --cho-code-block-bg: rgba(125, 125, 125, 0.04); - --vp-c-bg-alt: rgba(235, 235, 235, 0.6); + --vp-c-bg-alt: rgba(235, 235, 235); } .dark { @@ -22,7 +22,7 @@ /* fix contrast on gray cards: check the same above (this is the default) */ --vp-c-text-dark-2: rgba(235, 235, 235, 0.6); --vp-c-bg: rgb(10, 11, 10); - --vp-c-bg-alt: rgba(10, 11, 10, 0.6); + --vp-c-bg-alt: rgba(10, 11, 10); } /** diff --git a/docs/quick-start/config.md b/docs/quick-start/config.md new file mode 100644 index 0000000..4350281 --- /dev/null +++ b/docs/quick-start/config.md @@ -0,0 +1,183 @@ +--- +contributors: ["cworld1"] +--- + +# 配置项目 + +## 复制配置模板 + +```bash +cp .env.example .env +``` + +## 修改配置 + +### 基础设置 + +#### Debug 功能 + +提供更多日志反馈和网页模板测试功能。可选参数:`true` / `false` + +```env +DEBUG=false +``` + +#### MySQL 数据库 + +必填。如果使用容器构建,请查阅侧栏的容器构建部分。 + +```env +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_USERNAME=user +DB_PASSWORD="password" +DB_DATABASE=paimon +``` + +#### Redis 数据库 + +可选。用于缓存生成图片的不必要数据。 + +```env +REDIS_HOST=127.0.0.1 +REDIS_PORT=6379 +REDIS_DB=0 +REDIS_PASSWORD="" +``` + +#### Telegram Bot Token + +必填。联系 [Telegram@BotFather](https://t.me/BotFather) 使用 /newbot 命令创建机器人并获取 token。 + +```env +BOT_TOKEN="xxxxxxx" +``` + +#### Bot 管理员 + +可选。`username` 来自 Telegram 用户信息界面;`user_id` 可通过 [Telegram@IDBot](https://t.me/username_to_id_bot) 获取。 + +```env +ADMINS=[{ "username": "", "user_id": -1 }] +``` + +### 其他功能 + +#### 自动记录错误并发送消息通知开发人员 + +可选。 + +```env +ERROR_NOTIFICATION_CHAT_ID=chat_id +``` + +#### 文章推送群组 可选配置项 + +可选。 + +```env +CHANNELS=[{ "name": "", "chat_id": 1}] +``` + +#### 允许机器人邀请到其他群 + +可选。默认不允许;如果允许,可以允许全部人或有认证选项。 + +```env +JOIN_GROUPS = "NO_ALLOW" +``` + +#### 群验证功能 + +可选。 + +```env +VERIFY_GROUPS=[] +``` + +#### Loger 日志输出 + +可选。 + +```env +LOGGER_NAME="TGPaimon" +# 打印时的宽度 +LOGGER_WIDTH=180 +# log 文件存放目录 +LOGGER_LOG_PATH="logs" +# log 时间格式,参考 datetime.strftime +LOGGER_TIME_FORMAT="[%Y-%m-%d %X]" +# log 高亮关键词 +LOGGER_RENDER_KEYWORDS=["BOT"] +# traceback 相关配置 +LOGGER_TRACEBACK_MAX_FRAMES=20 +LOGGER_LOCALS_MAX_DEPTH=0 +LOGGER_LOCALS_MAX_LENGTH=10 +LOGGER_LOCALS_MAX_STRING=80 +# 可被 logger 打印的 record 的名称(默认包含了 LOGGER_NAME ) +LOGGER_FILTERED_NAMES=["uvicorn","ErrorPush","ApiHelper"] +``` + +#### 超时配置 + +可选。 + +```env +TIMEOUT = 10 +READ_TIMEOUT = 2 +WRITE_TIMEOUT = 10 +CONNECT_TIMEOUT = 10 +POOL_TIMEOUT = 10 +``` + +#### mtp 客户端 + +可选。 + +```env +API_ID=12345 +API_HASH="abcdefg" +``` + +#### Enka API 配置 + +可选。默认无,可能会影响 `/player_card` 指令。 + +```env +ENKA_NETWORK_API_AGENT="TGPaimonBot/3.0" +``` + +#### Web Server + +可选。目前只用于预览模板,仅开发环境启动。 + +```env +WEB_URL=http://localhost:8080/ +WEB_HOST=localhost +WEB_PORT=8080 +``` + +#### 错误信息 Log + +可选。 + +```env +ERROR_PB_URL=https://fars.ee +ERROR_PB_SUNSET=43200 +ERROR_PB_MAX_LINES=1000 +ERROR_SENTRY_DSN= +``` + +#### Notice + +可选。会作用于 Telegram 中权限不足时的提示。 + +```env +NOTICE_USER_MISMATCH="再乱点我叫西风骑士团、千岩军、天领奉行、三十人团和风纪官了!" +``` + +## 初始化数据库 + +```bash +alembic upgrade head +``` diff --git a/docs/quick-start/env.md b/docs/quick-start/env.md index 728dbcc..8e3ccf0 100644 --- a/docs/quick-start/env.md +++ b/docs/quick-start/env.md @@ -4,7 +4,7 @@ ### 1.检查Python版本 -首先,我们需要确认你的系统中是否已经安装了Python 3.8。打开终端或命令提示符,然后输入以下命令: +首先,我们需要确认你的系统中是否已经安装了 Python 3.8+ 。打开终端或命令提示符,然后输入以下命令: ```bash python --version @@ -12,9 +12,7 @@ python --version 如果你的系统已经安装了Python 3.8+,那么你应该会看到类似于“Python 3.8.x” “Python 3.9.x” ... 的输出。 -如果你看到的是其他版本的Python,或者你的系统提示你没有安装Python,那么你需要安装Python 3.8+。 - -GitHub Copilot: # Python Poetry环境检查教程 +如果系统提示你没有安装Python,那么你需要安装 Python 3.8+。 ### 2.检查Poetry是否已安装 @@ -28,7 +26,7 @@ poetry --version 如果你的系统提示你没有安装Poetry,那么你需要安装Poetry。 -#### 安装Poetry +#### 通过 pip 安装Poetry 打开终端或命令提示符,然后输入以下命令: @@ -37,9 +35,7 @@ pip install poetry poetry --version ``` -现在你应该能看到“Poetry version x.x.x”的输出了。 - -GitHub Copilot: # Git环境检查教程 +现在你应该能看到 “Poetry version x.x.x” 的输出了。 ## 系统环境检查 diff --git a/docs/quick-start/install.md b/docs/quick-start/install.md new file mode 100644 index 0000000..7d3243c --- /dev/null +++ b/docs/quick-start/install.md @@ -0,0 +1,55 @@ +# 安装项目 + +::: tip + +此处以 PaiGram 为例,其余项目同理 + +::: + +## 克隆项目 + +```bash +git clone https://github.com/PaiGramTeam/PaiGram.git +cd PaiGram +git submodule update --init --recursive +``` + +## 创建虚拟环境 + +```bash +python -m venv venv +``` + +## 激活虚拟环境 + +### linux + +```bash +source venv/bin/activate +``` + +### windows + +```cmd +venv\Scripts\activate.bat +``` + +### windows powershell + +```powershell +.\venv\Scripts\Activate.ps1 +``` + +## 安装项目依赖 + +### 使用 poetry + +```bash +poetry install --extras all +``` + +### 使用 pip + +```bash +pip install -r requirements.txt +``` diff --git a/docs/quick-start/run.md b/docs/quick-start/run.md new file mode 100644 index 0000000..5e32dd8 --- /dev/null +++ b/docs/quick-start/run.md @@ -0,0 +1,27 @@ +# 启动项目 + +## 激活虚拟环境 + +### linux + +```bash +source venv/bin/activate +``` + +### windows + +```cmd +venv\Scripts\activate.bat +``` + +### windows powershell + +```powershell +.\venv\Scripts\Activate.ps1 +``` + +## 运行 + +```bash +python run.py +``` diff --git a/package.json b/package.json index 6af07e0..4b7c3fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "type": "module", - "version": "0.0.1", + "version": "4.0.0", "scripts": { "dev": "vitepress dev docs --port 8080 --max-old-space-size=50000", "build": "vitepress build docs", diff --git a/scripts/utils.ts b/scripts/utils.ts new file mode 100644 index 0000000..7dbe95d --- /dev/null +++ b/scripts/utils.ts @@ -0,0 +1,32 @@ +import { resolve } from 'node:path' +import Git from 'simple-git' + +export const git = Git() + +export const DOCS_URL = 'https://docs.paimon.vip/' + +export const DIR_ROOT = resolve(__dirname, '..') +export const DIR_SRC = resolve(__dirname, '../docs') + +export function replacer(code: string, value: string, key: string, insert: 'head' | 'tail' | 'none' = 'none') { + const START = `` + const END = `` + const regex = new RegExp(`${START}[\\s\\S]*?${END}`, 'im') + + const target = value ? `${START}\n${value}\n${END}` : `${START}${END}` + + if (!code.match(regex)) { + if (insert === 'none') + return code + else if (insert === 'head') + return `${target}\n\n${code}` + else + return `${code}\n\n${target}` + } + + return code.replace(regex, target) +} + +export function uniq(a: T) { + return Array.from(new Set(a)) +}