Skip to content

Commit 5638193

Browse files
committed
依赖检测
1 parent 60f524d commit 5638193

File tree

6 files changed

+191
-6
lines changed

6 files changed

+191
-6
lines changed

change.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,14 @@
3737
- [x] 支持音频和视频播放管理
3838
- [x] 管理后台,恢复和优化附件管理功能
3939
- [ ] 如果管理员或者用户是书籍项目所有人,则音视频链接支持直链播放,否则对音视频链接进行一定的防盗链处理
40-
- [ ] 内容阅读页面音频视频播放功能
40+
- [ ] 优化程序内的 `cmd` 执行
41+
- [x] 内容阅读页面音频视频播放功能
4142
- [x] 音频和视频播放倍速控制
42-
- [ ] 音视频名称显示
4343
- [x] 视频画中画播放
4444
- [x] 禁止音频和视频直接下载
4545
- [x] 增加和升级API,使小程序和APP支持音频和视频播放,以及图片放大预览
4646
- [x] 优化`html2json`仓库,解析`HTML`内容,使小程序支持音频和视频播放功能,以及图片放大预览功能
47-
- [ ] 检测和隐藏相关功能
48-
- [ ] 未安装 `Git` 依赖,隐藏`克隆项目`的功能
49-
- [ ] 未安装 `Chrome` 或者 `puppeteer`,隐藏采集功能和项目导入功能
50-
- [ ] 未安装 `calibre`,隐藏电子书生成功能以及电子书下载功能
47+
- [x] BookStack 依赖检测,以便程序可以正常使用完整功能进行工作,检测项:chrome、puppeteer、git、calibre
5148

5249
## v2.9 升级日志
5350
- [x] 对无权限创建书籍书籍的用户,隐藏创建书籍入口

conf/app.conf.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ appId=""
1111
# 微信小程序appSecret
1212
appSecret=""
1313

14+
# 是否允许跨域(针对小程序或者APP开发)
15+
allowCors = true
16+
1417
# 是否限制API请求,也就是如果不是上述配置的微信小程序的appId请求的接口,则直接拒绝
1518
limitReferer=false
1619

controllers/ManagerController.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ func (this *ManagerController) Prepare() {
3939
}
4040
}
4141

42+
var installed []installedDependency
43+
44+
type installedDependency struct {
45+
Name string // 依赖名称
46+
IsInstalled bool // 是否已安装
47+
Message string // 相关信息
48+
Error string
49+
}
50+
4251
func (this *ManagerController) Index() {
4352
this.TplName = "manager/index.html"
4453
this.Data["Model"] = models.NewDashboard().Query()
@@ -47,6 +56,55 @@ func (this *ManagerController) Index() {
4756
"keywords": "仪表盘",
4857
"description": this.Sitename + "专注于文档在线写作、协作、分享、阅读与托管,让每个人更方便地发布、分享和获得知识。",
4958
})
59+
if len(installed) == 0 {
60+
var err error
61+
62+
errCalibre := "-"
63+
if err = utils.IsInstalledCalibre("ebook-convert"); err != nil {
64+
errCalibre = err.Error()
65+
}
66+
installed = append(installed, installedDependency{
67+
Name: "calibre",
68+
IsInstalled: err == nil,
69+
Error: errCalibre,
70+
Message: "calibre 用于将书籍转换成PDF、epub和mobi ==> <a class='text-danger' target='_blank' href='https://www.bookstack.cn/read/help/Ubuntu.md'>安装教程</a>",
71+
})
72+
73+
errGit := "-"
74+
if err = utils.IsInstalledGit(); err != nil {
75+
errGit = err.Error()
76+
}
77+
installed = append(installed, installedDependency{
78+
Name: "git",
79+
IsInstalled: err == nil,
80+
Error: errGit,
81+
Message: "git,用于克隆项目",
82+
})
83+
84+
errChrome := "-"
85+
if err = utils.IsInstalledChrome(beego.AppConfig.DefaultString("chrome", "chrome")); err != nil {
86+
errChrome = err.Error()
87+
}
88+
installed = append(installed, installedDependency{
89+
Name: "chrome",
90+
IsInstalled: err == nil,
91+
Error: errChrome,
92+
Message: "chrome浏览器,即谷歌浏览器,或者chromium-browser,用于渲染markdown内容为HTML。",
93+
})
94+
95+
errPuppeteer := "-"
96+
if err = utils.IsInstalledPuppetter(beego.AppConfig.DefaultInt("httpport", 8181)); err != nil {
97+
errPuppeteer = err.Error()
98+
}
99+
installed = append(installed, installedDependency{
100+
Name: "puppeteer",
101+
IsInstalled: err == nil,
102+
Error: errPuppeteer,
103+
Message: "puppeteer, node.js的模块,用于将markdown渲染为HTML以及生成电子书封面。 <a class='text-danger' target='_blank' href='https://www.bookstack.cn/read/help/Ubuntu.md'>安装教程</a>",
104+
})
105+
}
106+
107+
this.Data["Installed"] = installed
50108
this.Data["IsDashboard"] = true
51109
}
52110

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package utils
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"os"
7+
)
8+
9+
const testPuppeteerJS = `'use strict';
10+
const puppeteer = require('puppeteer');
11+
async function test() {
12+
const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox'], headless: true, ignoreHTTPSErrors: true});
13+
const page = await browser.newPage();
14+
await page.goto('http://localhost:%v', {"waitUntil" : ['networkidle2', 'domcontentloaded'], "timeout": 10000});
15+
let content=await page.content();
16+
console.log(content);
17+
await browser.close();
18+
}
19+
test();`
20+
21+
// IsInstalledPuppetter 是否安装了puppeteer
22+
func IsInstalledPuppetter(listenPort int) (err error) {
23+
testFile := "test.js"
24+
defer func() {
25+
os.Remove(testFile)
26+
}()
27+
ioutil.WriteFile(testFile, []byte(fmt.Sprintf(testPuppeteerJS, listenPort)), os.ModePerm)
28+
_, err = ExecCommand("node", []string{testFile})
29+
return
30+
}
31+
32+
// IsInstalledGit 是否安装了Git
33+
func IsInstalledGit() (err error) {
34+
_, err = ExecCommand("git", []string{"--version"})
35+
return
36+
}
37+
38+
// IsInstalledChrome 是否安装了Chrome
39+
func IsInstalledChrome(chrome string) (err error) {
40+
_, err = ExecCommand(chrome, []string{"--version"})
41+
return
42+
}
43+
44+
// IsInstalledCalibre 是否安装了calibre
45+
func IsInstalledCalibre(calibre string) (err error) {
46+
_, err = ExecCommand(calibre, []string{"--version"})
47+
return
48+
}

utils/util.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package utils
22

33
import (
4+
"bytes"
45
"encoding/base64"
56
"encoding/json"
67
"errors"
@@ -1044,3 +1045,31 @@ func SplitMarkdown(segSharp, markdown string) (markdowns []string) {
10441045
}
10451046
return
10461047
}
1048+
1049+
// ExecCommand 执行cmd命令操作
1050+
func ExecCommand(name string, args []string, timeout ...time.Duration) (out string, err error) {
1051+
var (
1052+
stderr, stdout bytes.Buffer
1053+
expire = 30 * time.Minute
1054+
)
1055+
1056+
if len(timeout) > 0 {
1057+
expire = timeout[0]
1058+
}
1059+
1060+
cmd := exec.Command(name, args...)
1061+
cmd.Stdout = &stdout
1062+
cmd.Stderr = &stderr
1063+
time.AfterFunc(expire, func() {
1064+
if cmd.Process != nil && cmd.Process.Pid != 0 {
1065+
out = out + fmt.Sprintf("\nexecute timeout: %v seconds.", expire.Seconds())
1066+
cmd.Process.Kill()
1067+
}
1068+
})
1069+
err = cmd.Run()
1070+
if err != nil {
1071+
err = fmt.Errorf("%v\n%v", err.Error(), stderr.String())
1072+
}
1073+
out = stdout.String()
1074+
return
1075+
}

views/manager/index.html

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
<html lang="zh-CN">
33
<head>
44
{{template "widgets/head.html" .}}
5+
<style>
6+
.min-width{
7+
min-width: 80px;
8+
}
9+
</style>
510
</head>
611
<body>
712
<div class="manual-reader">
@@ -80,6 +85,51 @@
8085
{{/* <span class="fa-class">{{.Model.AttachmentNumber}}</span>*/}}
8186
{{/* </a>*/}}
8287
</div>
88+
<div>
89+
<table class="table table-bordered table-hover ">
90+
<caption>依赖检测</caption>
91+
<thead>
92+
<tr>
93+
<th class="min-width">名称</th>
94+
<th class="min-width">安装</th>
95+
<th>作用</th>
96+
<th>错误</th>
97+
</tr>
98+
</thead>
99+
<tbody>
100+
<tr>
101+
<td>supervisor <br>------<br> pm2 </td>
102+
<td>
103+
<span class="text-danger">不检测</span>
104+
</td>
105+
<td>用于将程序加入系统守护进行。Linux可用supervisor,Windows可用pm2</td>
106+
<td>-</td>
107+
</tr>
108+
<tr>
109+
<td>elasticsearch</td>
110+
<td>
111+
<span class="text-danger">不检测</span>
112+
</td>
113+
<td>内容全文搜索引擎。docker镜像:https://hub.docker.com/r/truthhun/elasticsearch</td>
114+
<td>-</td>
115+
</tr>
116+
{{range .Installed}}
117+
<tr>
118+
<td>{{.Name}}</td>
119+
<td>
120+
{{if .IsInstalled}}
121+
<span class="text-success">已安装</span>
122+
{{else}}
123+
<span class="text-danger">未安装</span>
124+
{{end}}
125+
</td>
126+
<td>{{str2html .Message}}</td>
127+
<td>{{.Error}}</td>
128+
</tr>
129+
{{end}}
130+
</tbody>
131+
</table>
132+
</div>
83133
</div>
84134
</div>
85135
</div>

0 commit comments

Comments
 (0)