- A+
基础教程
centos 安装go
参考
https://github.com/zcorky/zgvm
wget -qO- https://raw.githubusercontent.com/zcorky/zgvm/master/install | bash
zgvm install v1.18
source ~/.bashrc
如果无法访问raw.githubusercontent.com 可以看解决办法
beego安装
go get github.com/beego/bee/v2
go install github.com/beego/bee/v2
go get github.com/astaxie/beego
go install github.com/astaxie/beego
Dochub安装
#环境go版本 go1.17 ,新版本应该也行。
# 在你的目录执行下载的命令就行,按顺序
git clone https://gitee.com/truthhun/DocHub
# 进入程序目录
cd DocHub
# 安装依赖包
go mod init Dochub
go mod tidy
go mod vendor
# 编译源码
go build
#执行完会在当前目录下生成
Dochub或者Dochub.exe
git clone https://gitee.com/truthhun/DocHub.git
cd DocHub
go mod init # 初始化
go build -o hello main.go # 会提示缺少哪些依赖 进行安装 即可
go get github.com/astaxie/beego
go get github.com/TruthHun/DocHub/controllers/HomeControllers
运行调试代码
DocHub代码学习
安装分析
安装后,直接请求,会跳转到/install 路径
首先在router.go的init中,判断如果helper.IsInstalled 为false 并且请求的路径不是/install 则会跳转到安装路径
helper.IsInstalled 默认是为false,在helper.go的init中判断, 如果存在 conf/app.conf 则表示安装过,将 helper.IsInstalled 设置为true
因此如果已经安装过,则直接将 conf/app.conf复制过来即可
但是这样操作后,登录时无法通过csrf校验 还没有搞清楚什么原因 在 \adapter\context\context.go文件中返回417错误状态码
先在conf/app.conf中将关闭csrf防护 enablexsrf = false
根据router.go设置,请求/install 则 HomeControllers目录下InstallController.go文件Install函数进行响应
- GET请求,直接显示页面
- POST请求 判断数据库账号和密码是否正确
- 初始化 生成 conf/app.conf 文件 ,内容在config.go 的GenerateAppConf 函数中,存储
- 加载conf/app.conf成功后,models/Models.go中的Init函数,创建数据库,models/Install.go中的install函数 插入相关数据
- 然后在models/SeoModel.go文件的AutoSitemap函数,生成站点信息,并且是死循环监听,到时间后重新生成
至此安装流程结束
提交请求时static\Home\default\js\dochub.js 在.wenku-ajax-form [type=submit] 进行处理
上传文档功能
- 先调用 segwd 路径进行分词操作
分词成功后,变成标签显示在界面上 - 文件上传处理流程 官方说明
- 1、检测用户是否已登录,未登录不允许上传
- 2、检测是否存在了该文档的md5,如果已存在,则根据md5查询存储在文档存档表中的数据;如果文档已经在文档存储表中存在,则该文档不需要再获取封面、大小、页码等数据
- 3、检测文档格式是否符合要求。
- 4、计算文档md5,然后根据md5再比对一次文档是否在存档表中存在
- 5、文档未存在,则将文档数据录入文档存储表(document_store)
- 6、执行文档转pdf,并获取文档页数、封面、摘要等
- 7、获取文档大小
注意后台可设置上传文档得多少金币,当设置为0时,但是发现 models/Utils.go line56 会判断一个用户上传的文档获得多少分,如果不大于0 则不会进行反转文档格式,因此需要将 line32 score初始化为-1, line56行 判断 如果分数为-1则不进行转换
由于main.go引用的都是github.com的地址,因此需要修改 /root/.go 下的问题才可以生效
调试模式
conf/app.conf 设置为dev模式 表示调试模式
静态模板
应该是在 controllers\HomeControllers\BaseController.go 定义的 layout.html 文件为开始
前后台分离
应该可以在router.go将/admin路径全部注释掉,实现只保留前台功能
关闭评论
在 \views\Home\default\View\svg.html line113 注释掉
{{template "Comment" .}}
同时 router.go 注释掉 line 58-59
beego.Router("/comment/:id", &HomeControllers.ViewController{}, "post:Comment")
beego.Router("/comment/list", &HomeControllers.ViewController{}, "get:GetComment")
删除友情链接
footer.html 的line4~line13
<div class="row wenku-flink">
<div class="col-xs-12">
<div><strong>友情链接</strong></div>
<div class="help-block">
{{range (Friends)}}
<a href="{{.Link}}" target="_blank" title="{{.Title}}">{{.Title}}</a>
{{end}}
</div>
</div>
</div>
后台编辑器
static/Editor/kindeditor/themes/default/default.css
存在编辑器,建议删除
svg添加水印
在models\Utils.go 的 line386添加
//添加文字水印 从配置文件读取水印
helper.SvgTextWatermark(svgfile, beego.AppConfig.String("watermark"), width/6, height/4)
在源代码v1.1有这个功能\models\Models.go line585
文字颜色 在 helper\helper.go 文件SvgTextWatermark 函数中进行修改 , 如下代码修改为红色
watermark = append(watermark, fmt.Sprintf(`<text x="%v" y="%v" style="fill:rgba(255,0,0,0.3)" transform="scale(2)">%v</text>`, x, y, text))
模板的设置
模板处理 - beego: 简约 & 强大并存的 Go 应用框架 在controllers\HomeControllers\BaseController.go 定义了this.Layout 其他的controller只需要定义 this.TplName 变量即可 替换 this.Layout 中
不登录直接下载免费文档
在文件 models\UserModel.go 中添加如下方法
func (this *User) CanDownloadFileNoLogin(docId int) (urlStr string, err error) {
if docId <= 0 {
err = errParams
return
}
o := orm.NewOrm()
o.Begin()
defer func() {
if err == nil {
o.Commit()
} else {
o.Rollback()
}
}()
var docInfo = DocumentInfo{Id: docId}
if err = o.Read(&docInfo); err != nil {
helper.Logger.Error(err.Error())
err = errNotFound
return
}
if docInfo.Price < 0 || docInfo.Price > 0 {
err = errCannotDown
return
}
doc := &Document{Id: docId}
if err = o.Read(doc); err != nil {
helper.Logger.Error(err.Error())
err = errNotFound
return
}
store := &DocumentStore{Id: docInfo.DsId}
if err = o.Read(store); err != nil {
helper.Logger.Error(err.Error())
err = errNotFound
return
}
docInfo.Dcnt += 1
if _, err = o.Update(&docInfo); err != nil {
return
}
var cs *CloudStore
cs, err = NewCloudStore(true)
if err != nil {
helper.Logger.Error(err.Error())
err = errFailedToDown
return
}
object := store.Md5 + "." + strings.TrimLeft(store.Ext, ".")
urlStr = cs.GetSignURL(object)
return
}
controllers\HomeControllers\ViewController.go 修改Download 和DownFree
func (this *ViewController) Download() {
id, _ := this.GetInt(":id")
if id <= 0 {
this.ResponseJson(false, "文档id不正确")
}
if this.IsLogin == 0 {
link, err := models.NewUser().CanDownloadFileNoLogin(id)
if err != nil {
this.ResponseJson(false, err.Error())
}
this.ResponseJson(true, "下载链接获取成功", map[string]interface{}{"url": link})
}else {
link, err := models.NewUser().CanDownloadFile(this.IsLogin, id)
if err != nil {
this.ResponseJson(false, err.Error())
}
this.ResponseJson(true, "下载链接获取成功", map[string]interface{}{"url": link})
}
}
func (this *ViewController) DownFree() {
if this.IsLogin > 0 {
did, _ := this.GetInt("id")
if free := models.NewFreeDown().IsFreeDown(this.IsLogin, did); free {
this.ResponseJson(true, fmt.Sprintf("您上次下载过当前文档,且仍在免费下载有效期(%v天)内,本次下载免费", this.Sys.FreeDay))
}
}else{
id, _ := this.GetInt(":id")
if id < 1 {
this.ResponseJson(false, "文档不存在")
}
doc, err := models.NewDocument().GetById(id)
if err != nil || doc.Id <= 0 || doc.Status < models.DocStatusConverting {
this.ResponseJson(false, "文档不存在")
}
if doc.Price == 0 {
this.ResponseJson(true, "免费文档可以直接下载")
}
}
this.ResponseJson(false, "不能免费下载,不在免费下载期限内")
}
pdf 添加水印
controllers\HomeControllers\UploadController.go
func (this *UploadController) Post() {
var (
ext string
dir = fmt.Sprintf("./uploads/%v/%v", time.Now().Format("2006/01/02"), this.IsLogin)
form models.FormUpload
err error
)
if this.IsLogin == 0 {
this.ResponseJson(false, "您当前未登录,请先登录")
}
this.ParseForm(&form)
f, fh, err := this.GetFile("File")
if err == nil {
defer f.Close()
os.MkdirAll(dir, os.ModePerm)
ext = strings.ToLower(filepath.Ext(fh.Filename))
if _, ok := helper.AllowedUploadDocsExt[ext]; !ok {
this.ResponseJson(false, "您上传的文档格式不正确,请上传正确格式的文档")
}
file := fmt.Sprintf("%v-%v-%v", this.IsLogin, time.Now().UnixNano(), ext)
form.TmpFile = filepath.Join(dir, file)
form.Ext = ext
err = this.SaveToFile("File", form.TmpFile)
if err != nil {
helper.Logger.Error(err.Error())
this.ResponseJson(false, "文件保存失败")
} else{
waterfile := fmt.Sprintf("%v-%v-w-%v", this.IsLogin, time.Now().UnixNano(), ext)
outputFile := filepath.Join(dir, waterfile)
args := []string{ form.TmpFile, "stamp", "/root/tools/DocHub/water.pdf","output", outputFile}
cmd := exec.Command("pdftk", args...)
time.AfterFunc(30*time.Second, func() {
if cmd.Process != nil {
cmd.Process.Kill()
}
})
err = cmd.Run()
if err == nil {
os.Remove(form.TmpFile)
form.TmpFile = outputFile
}
}
}
err = models.DocumentProcess(this.IsLogin, form)
if err != nil {
this.ResponseJson(false, err.Error())
}
this.ResponseJson(true, "恭喜您,文档上传成功")
}
制作water文件
from PyPDF2 import PdfFileReader, PdfFileWriter
from reportlab.lib.units import cm
from reportlab.pdfgen import canvas
def create_watermark(content):
"""水印信息"""
file_name = "mark.pdf"
c = canvas.Canvas(file_name, pagesize=(21 * cm, 29.7 * cm))
c.translate(5 * cm, 10 * cm)
c.setFont("Helvetica", 80)
c.setStrokeColorRGB(0, 1, 0)
c.setFillColorRGB(1, 0, 0)
c.rotate(30)
c.setFillColorRGB(1, 0, 0, 0.3)
c.drawString(3 * cm, 0 * cm, content)
c.setFillAlpha(0.6)
c.save()
return file_name
def add_watermark(pdf_file_in, pdf_file_mark, pdf_file_out):
"""把水印添加到pdf中"""
pdf_output = PdfFileWriter()
input_stream = open(pdf_file_in, 'rb')
pdf_input = PdfFileReader(input_stream, strict=False)
pageNum = pdf_input.getNumPages()
pdf_watermark = PdfFileReader(open(pdf_file_mark, 'rb'), strict=False)
for i in range(pageNum):
page = pdf_input.getPage(i)
page.mergePage(pdf_watermark.getPage(0))
page.compressContentStreams()
pdf_output.addPage(page)
pdf_output.write(open(pdf_file_out, 'wb'))
if __name__ == '__main__':
pdf_file_mark = create_watermark('github5.com')
搜索关键词没有URL解码
controllers\HomeControllers\SearchController.go line 115 添加解码 引入包net/url
decodedValue, err := url.QueryUnescape(params["wd"])
if err != nil {
} else {
params["wd"] = decodedValue
}
批量上传文件
文件上传功能 在 controllers\HomeControllers\UploadController.go 文件的Post方法实现, 该函数主要处理文件信息, 生成FormUpload 结构体(在文件\models\struct.go)
Title, Md5, Intro, Tags, Ext, Filename string
Chanel, Pid, Cid, Exist, Size, Price int
TmpFile string
TmpFile
Filename
Title
Tags
Intro
Ext
Price
Chanel
Pid
Cid
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫