mirror of
https://github.com/PaiGramTeam/PaiGramDocs.git
synced 2024-11-25 09:37:31 +00:00
📝 Add quick-start
This commit is contained in:
parent
2c48ede0be
commit
bea098349b
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
docs/.vitepress/dist
|
||||
docs/.vitepress/cache
|
||||
node_modules/
|
||||
.eslintcache
|
||||
|
11
docs/.vitepress/algolia.ts
Normal file
11
docs/.vitepress/algolia.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export default {
|
||||
appId: 'AU4G7FKYJF',
|
||||
apiKey: 'e934cbf9d54f02be212594ad8b5a1373',
|
||||
indexName: 'grambot',
|
||||
placeholder: '请输入关键词',
|
||||
translations: {
|
||||
button: {
|
||||
buttonText: '搜索',
|
||||
},
|
||||
},
|
||||
}
|
2
docs/.vitepress/components.d.ts
vendored
2
docs/.vitepress/components.d.ts
vendored
@ -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']
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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<PageInfo readTime="${readTime}" words="${words}"/>\n`)
|
||||
@ -33,3 +39,14 @@ export function MarkdownTransform(): Plugin {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export async function getDocsMarkdown() {
|
||||
const ContributorsSection = `## Contributors
|
||||
<Contributors/>`
|
||||
|
||||
const footer = `${ContributorsSection}\n`
|
||||
|
||||
return {
|
||||
footer,
|
||||
}
|
||||
}
|
||||
|
@ -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' },
|
||||
],
|
||||
|
42
docs/.vitepress/theme/components/Contributors.vue
Normal file
42
docs/.vitepress/theme/components/Contributors.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useData } from 'vitepress'
|
||||
|
||||
const defaultAuthor = 'PaigramTeam'
|
||||
const { frontmatter } = useData()
|
||||
|
||||
const contributorsArr = [frontmatter.value?.author, ...frontmatter.value.contributors || []].filter(x => x)
|
||||
const contributors = ref(contributorsArr)
|
||||
|
||||
function reName(name: string) {
|
||||
return name
|
||||
}
|
||||
|
||||
function getAvatarUrl(name: string) {
|
||||
return `https://github.com/${reName(name)}.png`
|
||||
}
|
||||
function getGithubLink(name: string) {
|
||||
return `https://github.com/${reName(name)}`
|
||||
}
|
||||
|
||||
function isNotEmpty(arr: string | string[]) {
|
||||
return Array.isArray(arr) && arr.length
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="isNotEmpty(contributors)" class="flex flex-wrap gap-4">
|
||||
<div v-for="contributor of contributors" :key="contributor" class="flex gap-2 items-center">
|
||||
<a :href="getGithubLink(contributor)" rel="noreferrer" target="_blank">
|
||||
<img :src="getAvatarUrl(contributor)" class="w-8 h-8 rounded-full">
|
||||
</a>
|
||||
{{ contributor }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex gap-2 items-center">
|
||||
<a :href="getGithubLink(defaultAuthor)" rel="noreferrer" target="_blank">
|
||||
<img :src="getAvatarUrl(defaultAuthor)" class="w-8 h-8 rounded-full">
|
||||
</a>
|
||||
{{ 'PaigramTeam' }}
|
||||
</div>
|
||||
</template>
|
@ -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)
|
||||
<section
|
||||
class="border-b-1 border-[var(--vp-c-divider)] w-full border-b-solid mt-[24px] pb-[12px] flex gap-[12px] mb-[12px] flex-wrap max-w-[85%]"
|
||||
>
|
||||
<div class="flex gap-[4px] items-center">
|
||||
<radix-icons:update />
|
||||
更新于:<span>{{ timeFormNow }}</span>
|
||||
</div>
|
||||
<div class="flex gap-[4px] items-center">
|
||||
<bi:file-earmark-word-fill />
|
||||
字数统计:<span>{{ words }} 字</span>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
183
docs/quick-start/config.md
Normal file
183
docs/quick-start/config.md
Normal file
@ -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
|
||||
```
|
@ -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” 的输出了。
|
||||
|
||||
## 系统环境检查
|
||||
|
||||
|
55
docs/quick-start/install.md
Normal file
55
docs/quick-start/install.md
Normal file
@ -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
|
||||
```
|
27
docs/quick-start/run.md
Normal file
27
docs/quick-start/run.md
Normal file
@ -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
|
||||
```
|
@ -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",
|
||||
|
32
scripts/utils.ts
Normal file
32
scripts/utils.ts
Normal file
@ -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 = `<!--${key}_STARTS-->`
|
||||
const END = `<!--${key}_ENDS-->`
|
||||
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<T extends any[]>(a: T) {
|
||||
return Array.from(new Set(a))
|
||||
}
|
Loading…
Reference in New Issue
Block a user