mirror of
https://github.com/eiblog/eiblog.git
synced 2026-02-04 22:02:26 +08:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc3e6659b5 | ||
|
|
ca74d13598 | ||
|
|
82fba0ddb4 | ||
|
|
2b6bae1f74 | ||
|
|
6387412776 | ||
|
|
cfaa25e123 | ||
|
|
6ff6acdbda | ||
|
|
b3b3be448f | ||
|
|
78f5bfc1ce | ||
|
|
4b9eb1ff4d | ||
|
|
7d04b8f5c0 | ||
|
|
d000090e30 | ||
|
|
56e396f252 | ||
|
|
f6662fa4c5 | ||
|
|
a570c783f3 | ||
|
|
e2046d0d39 | ||
|
|
cdbe082764 | ||
|
|
3a86c6a65c | ||
|
|
c1c9e6025a | ||
|
|
a15791a792 | ||
|
|
ea87f4b2e6 | ||
|
|
a0653cf67f | ||
|
|
397d47bc00 |
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
package:
|
||||
runs-on: ubuntu-16.04
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Golang env
|
||||
uses: actions/setup-go@v2
|
||||
@@ -35,6 +35,8 @@ jobs:
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
- name: Build image
|
||||
env:
|
||||
GOPROXY: https://goproxy.io,direct
|
||||
run: scripts/run_build.sh deepzz0 ${{ steps.vars.outputs.tag }}
|
||||
|
||||
- name: Package tar
|
||||
@@ -44,6 +46,7 @@ jobs:
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GOPROXY: https://goproxy.io,direct
|
||||
with:
|
||||
files: |
|
||||
*.tar.gz
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,6 +6,7 @@
|
||||
*.dylib
|
||||
*.DS_Store
|
||||
*.tar.gz
|
||||
*.db
|
||||
backend
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
@@ -2,6 +2,38 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [2.1.4](https://github.com/eiblog/eiblog/compare/v2.1.3...v2.1.4) (2021-10-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **release:** github action runner ([82fba0d](https://github.com/eiblog/eiblog/commit/82fba0ddb47c1f66cb659f775c120c08dd2b4447))
|
||||
|
||||
### [2.1.4](https://github.com/eiblog/eiblog/compare/v2.1.3...v2.1.4) (2021-10-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **release:** github action runner ([82fba0d](https://github.com/eiblog/eiblog/commit/82fba0ddb47c1f66cb659f775c120c08dd2b4447))
|
||||
|
||||
### [2.1.3](https://github.com/eiblog/eiblog/compare/v2.1.2...v2.1.3) (2021-10-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auto_save:** fix auto save return empty id ([cfaa25e](https://github.com/eiblog/eiblog/commit/cfaa25e1239aba580e0718d40f1a2bf31158b217))
|
||||
* backup app judge db driver ([78f5bfc](https://github.com/eiblog/eiblog/commit/78f5bfc1ce017bf77a7442f40963a706e608df51))
|
||||
* **pwd:** fix init pwd ([7d04b8f](https://github.com/eiblog/eiblog/commit/7d04b8f5c0846bcd0c7e07d0fc3704a535f6360a))
|
||||
|
||||
### [2.1.2](https://github.com/eiblog/eiblog/compare/v2.1.1...v2.1.2) (2021-07-27)
|
||||
|
||||
### [2.1.1](https://github.com/eiblog/eiblog/compare/v2.1.0...v2.1.1) (2021-07-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* sqlite error ([e2046d0](https://github.com/eiblog/eiblog/commit/e2046d0d39d9914473fe7b8fae3b18246ed133ce))
|
||||
|
||||
### [2.0.6](https://github.com/eiblog/eiblog/compare/v2.0.5...v2.0.6) (2021-05-08)
|
||||
|
||||
|
||||
|
||||
66
README.md
66
README.md
@@ -8,34 +8,52 @@
|
||||
|
||||
### 快速体验
|
||||
|
||||
1、下载程序压缩包:到 [这里](https://github.com/eiblog/eiblog/releases) 下载 eiblog 相应系统压缩包,然后解压缩。
|
||||
这里以 mongodb 为例,更多支持的后端存储服务如下:
|
||||
|
||||
2、启动数据库服务:博客支持多种数据库后端,如MongoDB、MySQL、Postgres、SQLite等。
|
||||
| 类型(driver) | 地址(source)示例 |
|
||||
| -------------- | ------------------------------------------------------------ |
|
||||
| mongodb | mongodb://localhost:27017 |
|
||||
| mysql | user:password@tcp(localhost:3306)/eiblog?charset=utf8mb4&parseTime=True&loc=Local |
|
||||
| postgres | host=localhost port=5432 user=user password=password dbname=eiblog sslmode=disable |
|
||||
| sqlite | /path/eiblog.db |
|
||||
| sqlserver | sqlserver://user:password@localhost:9930?database=eiblog |
|
||||
| clickhouse | tcp://localhost:9000?database=eiblog&username=user&password=password&read_timeout=10&write_timeout=20 |
|
||||
|
||||
1、启动依赖服务,mongodb、elasticsearch:
|
||||
|
||||
```
|
||||
$ docker run --name mongodb \
|
||||
-p 27017:27017 \
|
||||
-v ${PWD}/mgodb:/data/db \
|
||||
mongo:3.2
|
||||
|
||||
$ docker run --name elasticsearch \
|
||||
-p 9200:9200 \
|
||||
-v ${PWD}/esdata:/usr/share/elasticsearch/data \
|
||||
deepzz0/elasticsearch:2.4.1
|
||||
```
|
||||
|
||||
2、下载压缩包,到 [这里](https://github.com/eiblog/eiblog/releases) 下载 eiblog(非backup) 相应系统压缩包,然后解压缩。
|
||||
|
||||
3、修改配置,将数据库与ES地址修改为相应地址:
|
||||
|
||||
```
|
||||
# 修改 conf/app.yml 数据库连接配置
|
||||
# driver可选:mongodb、mysql、postgres、sqlite、sqlserver、clickhouse、redis等
|
||||
# source为相应的连接地址
|
||||
database:
|
||||
driver: postgres
|
||||
source: host=localhost port=5432 user=postgres dbname=eiblog sslmode=disable password=MTI3LjAuMC4x
|
||||
```
|
||||
driver: mongodb
|
||||
source: mongodb://localhost:27017
|
||||
|
||||
3、启动 ES 搜索服务:博客使用 ElasticSearch 2.4.1 做为搜索引擎。
|
||||
|
||||
```
|
||||
# 修改 conf/app.yml ElasticSearch连接配置
|
||||
# 如果不启用搜索功能可以置空
|
||||
# 修改 conf/app.yml ES连接配置,如果不启用搜索功能可以置空
|
||||
eshost: http://localhost:9200
|
||||
```
|
||||
|
||||
4、启动博客程序。
|
||||
4、启动服务:
|
||||
|
||||
```
|
||||
./backend
|
||||
```
|
||||
|
||||
然后访问 `localhost:9000` 就可以了。
|
||||
然后访问 `localhost:9000` 就可以了,后台地址 `localhost:9000/admin/login`,默认账户密码 `deepzz/deepzz`。
|
||||
|
||||
### 功能特性
|
||||
|
||||
@@ -47,16 +65,16 @@ eshost: http://localhost:9200
|
||||
|
||||
功能说明:
|
||||
|
||||
- [x] 博客归档,利用时间线帮助我们将归纳博文,内容少于一年按月归档,大于则按年归档。
|
||||
- [x] 博客专题,有时候博文是同一系列,专题能够帮助我们很好归纳博文,对阅读者是非常友好的。
|
||||
- [x] 标签系统,每篇博文都可以打上不同标签,使得在归档和专题不满足的情况下自定义归档,这块辅助搜索简直完美。
|
||||
- [x] 搜索系统,依托ElasticSearch实现的站内搜索,速度与效率并存,再加上google opensearch,搜索只流畅。
|
||||
- [x] 管理后台,内嵌全功能 `Typecho` 后台系统,全功能 `Markdown` 编辑器让你感觉什么是简洁清爽。
|
||||
- [x] 谷歌统计,由于google api的速度问题,从而实现了后端API异步统计,使得博客页面加载飞速。
|
||||
- [x] Disqus评论,国内评论系统不友好,因此选择disqus,又由于众所周知原因国内不能用,实现另类disqus评论方式。
|
||||
- [x] 多存储后端,支持mongodb、mysql、postgres、sqlite等存储后端。
|
||||
- [x] 七牛CDN,支持在 `Markdown` 编辑器直接上传附件,让你只考虑编辑内容,解放思想。
|
||||
- [x] 自动备份,支持多存储后端的备份功能,备份数据保存到七牛CDN上。
|
||||
* 博客归档,利用时间线帮助我们将归纳博文,内容少于一年按月归档,大于则按年归档。
|
||||
* 博客专题,有时候博文是同一系列,专题能够帮助我们很好归纳博文,对阅读者是非常友好的。
|
||||
* 标签系统,每篇博文都可以打上不同标签,使得在归档和专题不满足的情况下自定义归档,这块辅助搜索简直完美。
|
||||
* 搜索系统,依托ElasticSearch实现的站内搜索,速度与效率并存,再加上google opensearch,搜索只流畅。
|
||||
* 管理后台,内嵌全功能 `Typecho` 后台系统,全功能 `Markdown` 编辑器让你感觉什么是简洁清爽。
|
||||
* 谷歌统计,由于google api的速度问题,从而实现了后端API异步统计,使得博客页面加载飞速。
|
||||
* Disqus评论,国内评论系统不友好,因此选择disqus,又由于众所周知原因国内不能用,实现另类disqus评论方式。
|
||||
* 多存储后端,支持mongodb、mysql、postgres、sqlite等存储后端。
|
||||
* 七牛CDN,支持在 `Markdown` 编辑器直接上传附件,让你只考虑编辑内容,解放思想。
|
||||
* 自动备份,支持多存储后端的备份功能,备份数据保存到七牛CDN上。
|
||||
|
||||
当然,为了让整个系统加载速度更快,还做了更多优化措施:
|
||||
|
||||
|
||||
@@ -1,8 +1,54 @@
|
||||
// Package main provides ...
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/eiblog/eiblog/pkg/config"
|
||||
"github.com/eiblog/eiblog/pkg/core/backup/ping"
|
||||
"github.com/eiblog/eiblog/pkg/core/backup/swag"
|
||||
"github.com/eiblog/eiblog/pkg/core/backup/timer"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("hello world!")
|
||||
fmt.Println("Hi, it's App " + config.Conf.BackupApp.Name)
|
||||
|
||||
endRun := make(chan error, 1)
|
||||
|
||||
runTimer(endRun)
|
||||
|
||||
runHTTPServer(endRun)
|
||||
fmt.Println(<-endRun)
|
||||
}
|
||||
|
||||
func runTimer(endRun chan error) {
|
||||
go func() {
|
||||
endRun <- timer.Start()
|
||||
}()
|
||||
}
|
||||
|
||||
func runHTTPServer(endRun chan error) {
|
||||
if !config.Conf.EiBlogApp.EnableHTTP {
|
||||
return
|
||||
}
|
||||
|
||||
if config.Conf.RunMode == config.ModeProd {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
e := gin.Default()
|
||||
|
||||
// swag
|
||||
swag.RegisterRoutes(e)
|
||||
|
||||
// route
|
||||
ping.RegisterRoutes(e)
|
||||
|
||||
// start
|
||||
address := fmt.Sprintf(":%d", config.Conf.EiBlogApp.HTTPPort)
|
||||
go func() {
|
||||
endRun <- e.Run(address)
|
||||
}()
|
||||
fmt.Println("HTTP server running on: " + address)
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@ import (
|
||||
func main() {
|
||||
fmt.Println("Hi, it's App " + config.Conf.EiBlogApp.Name)
|
||||
|
||||
endRun := make(chan bool, 1)
|
||||
endRun := make(chan error, 1)
|
||||
|
||||
runHTTPServer(endRun)
|
||||
<-endRun
|
||||
fmt.Println(<-endRun)
|
||||
}
|
||||
|
||||
func runHTTPServer(endRun chan bool) {
|
||||
func runHTTPServer(endRun chan error) {
|
||||
if !config.Conf.EiBlogApp.EnableHTTP {
|
||||
return
|
||||
}
|
||||
@@ -65,6 +65,8 @@ func runHTTPServer(endRun chan bool) {
|
||||
|
||||
// start
|
||||
address := fmt.Sprintf(":%d", config.Conf.EiBlogApp.HTTPPort)
|
||||
go e.Run(address)
|
||||
go func() {
|
||||
endRun <- e.Run(address)
|
||||
}()
|
||||
fmt.Println("HTTP server running on: " + address)
|
||||
}
|
||||
|
||||
17
conf/app.yml
17
conf/app.yml
@@ -2,7 +2,7 @@ appname: eiblog
|
||||
database:
|
||||
driver: postgres
|
||||
source: host=localhost port=5432 user=postgres dbname=eiblog sslmode=disable password=MTI3LjAuMC4x
|
||||
eshost: http://localhost:9200
|
||||
eshost:
|
||||
eiblogapp:
|
||||
mode:
|
||||
name: cmd-eiblog
|
||||
@@ -53,6 +53,15 @@ eiblogapp:
|
||||
username: deepzz # *后台登录用户名
|
||||
password: deepzz # *登录明文密码
|
||||
backupapp:
|
||||
name: cmd-backup
|
||||
enablehttp: true
|
||||
httpport: 9001
|
||||
mode:
|
||||
name: cmd-backup
|
||||
enablehttp: true
|
||||
httpport: 9001
|
||||
backupto: qiniu # 备份到七牛云
|
||||
interval: 7d # 多久备份一次
|
||||
validity: 60d # 保存时长
|
||||
qiniu: # 七牛OSS
|
||||
bucket: backup
|
||||
domain: st.deepzz.com
|
||||
accesskey: MB6AXl_Sj_mmFsL-Lt59Dml2Vmy2o8XMmiCbbSeC
|
||||
secretkey: BIrMy0fsZ0_SHNceNXk3eDuo7WmVYzj2-zrmd5Tf
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
> 博客项目结构参考模版:https://github.com/deepzz0/appdemo
|
||||
|
||||
EiBlog 镜像仓库地址:https://hub.docker.com/u/deepzz0
|
||||
|
||||
用过其它博客系统,不喜欢,不够轻,不够快!这是我开发的第二款博客系统,也实在不想再在这件事情上过多纠结了。`EiBlog` 是一个比较稳定的博客系统,现已迭代至 `2.0` 版本,稳定性和维护你是不用担心的。
|
||||
|
||||
但它有着部署简单(上线复杂!)的特点,不推荐没有计算机知识的朋友搭建,欢迎咨询。该博客的个中优点(简洁、轻快,安全),等你体验。
|
||||
|
||||
@@ -1,2 +1,42 @@
|
||||
待完善。。。
|
||||
### 备份数据
|
||||
|
||||
EiBlog 镜像仓库地址:https://hub.docker.com/u/deepzz0,备份镜像为:deepzz0/backup。
|
||||
|
||||
|
||||
|
||||
目前仅支持同步 mongodb 数据到七牛云,参考 `app.yml`:
|
||||
|
||||
```
|
||||
backupapp:
|
||||
mode:
|
||||
name: cmd-backup
|
||||
enablehttp: true
|
||||
httpport: 9001
|
||||
backupto: qiniu # 备份到七牛云
|
||||
interval: 7d # 多久备份一次
|
||||
validity: 60d # 保存时长
|
||||
qiniu: # 七牛OSS
|
||||
bucket: backup
|
||||
domain: st.deepzz.com
|
||||
accesskey: MB6AXl_Sj_mmFsL-Lt59Dml2Vmy2o8XMmiCbbSeC
|
||||
secretkey: BIrMy0fsZ0_SHNceNXk3eDuo7WmVYzj2-zrmd5Tf
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 运行
|
||||
|
||||
1、获取备份镜像:
|
||||
|
||||
```
|
||||
$ docker pull deepzz0/backup
|
||||
```
|
||||
|
||||
2、启动备份镜像:
|
||||
|
||||
```
|
||||
$ docker run --name backup \
|
||||
-v ${PWD}/conf:/app/conf
|
||||
```
|
||||
|
||||
Docker-compose 请参考项目根目录下的 `docker-compose.yml` 文件。
|
||||
|
||||
@@ -43,7 +43,7 @@ $ docker run --name es \
|
||||
修改 `conf/app.yml` 下的 `eshost` 配置:
|
||||
|
||||
```
|
||||
# 如果不部署,请置空
|
||||
# 如果不提供搜索,请置空
|
||||
eshost: http://localhost:9200
|
||||
```
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Examples for your applications and/or public libraries.
|
||||
2
go.mod
2
go.mod
@@ -6,7 +6,7 @@ require (
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/eiblog/blackfriday v0.0.0-20161010144836-c0ec111761ae
|
||||
github.com/gin-contrib/sessions v0.0.3
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/gin-gonic/gin v1.7.2
|
||||
github.com/gofrs/uuid v3.3.0+incompatible
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/lib/pq v1.10.1
|
||||
|
||||
15
go.sum
15
go.sum
@@ -15,7 +15,6 @@ github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPI
|
||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
||||
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff h1:RmdPFa+slIr4SCBg4st/l/vZWVe9QJKMXGO60Bxbe04=
|
||||
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
||||
github.com/bradleypeabody/gorilla-sessions-memcache v0.0.0-20181103040241-659414f458e1/go.mod h1:dkChI7Tbtx7H1Tj7TqGSZMOeGpMP5gLHtjroHd4agiI=
|
||||
@@ -53,8 +52,9 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm
|
||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
||||
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||
@@ -77,8 +77,9 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM
|
||||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
@@ -119,7 +120,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
@@ -131,13 +131,11 @@ github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
@@ -277,7 +275,6 @@ github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAv
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -367,7 +364,6 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
@@ -392,7 +388,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
@@ -422,14 +417,12 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
System init (systemd, upstart, sysv) and process manager/supervisor (runit, supervisord) configs.
|
||||
2
pkg/cache/cache.go
vendored
2
pkg/cache/cache.go
vendored
@@ -443,7 +443,7 @@ func (c *Cache) loadOrInit() error {
|
||||
}
|
||||
}
|
||||
// account
|
||||
pwd := tools.EncryptPasswd(blogapp.Account.Password,
|
||||
pwd := tools.EncryptPasswd(blogapp.Account.Username,
|
||||
blogapp.Account.Password)
|
||||
|
||||
account := &model.Account{
|
||||
|
||||
19
pkg/cache/render/render.go
vendored
19
pkg/cache/render/render.go
vendored
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/eiblog/eiblog/pkg/config"
|
||||
"github.com/eiblog/eiblog/pkg/model"
|
||||
"github.com/eiblog/eiblog/tools"
|
||||
|
||||
"github.com/eiblog/blackfriday"
|
||||
)
|
||||
@@ -41,17 +42,6 @@ var (
|
||||
regHeader = regexp.MustCompile("</nav></div>")
|
||||
)
|
||||
|
||||
// IgnoreHtmlTag 去掉 html tag
|
||||
func IgnoreHtmlTag(src string) string {
|
||||
// 去除所有尖括号内的HTML代码
|
||||
re, _ := regexp.Compile(`<[\S\s]+?>`)
|
||||
src = re.ReplaceAllString(src, "")
|
||||
|
||||
// 去除换行符
|
||||
re, _ = regexp.Compile(`\s+`)
|
||||
return re.ReplaceAllString(src, "")
|
||||
}
|
||||
|
||||
// RenderPage 渲染markdown
|
||||
func RenderPage(md []byte) []byte {
|
||||
renderer := blackfriday.HtmlRenderer(commonHtmlFlags, "", "")
|
||||
@@ -66,7 +56,7 @@ func GenerateExcerptMarkdown(article *model.Article) {
|
||||
index := strings.Index(article.Content, "\r\n")
|
||||
prefix := article.Content[len(blogapp.General.DescPrefix):index]
|
||||
|
||||
article.Desc = IgnoreHtmlTag(prefix)
|
||||
article.Desc = tools.IgnoreHtmlTag(prefix)
|
||||
article.Content = article.Content[index:]
|
||||
}
|
||||
|
||||
@@ -83,12 +73,13 @@ func GenerateExcerptMarkdown(article *model.Article) {
|
||||
// excerpt
|
||||
index = regIdentifier.FindStringIndex(article.Content)
|
||||
if index != nil {
|
||||
article.Excerpt = IgnoreHtmlTag(article.Content[:index[0]])
|
||||
article.Excerpt = tools.IgnoreHtmlTag(article.Content[:index[0]])
|
||||
return
|
||||
}
|
||||
uc := []rune(article.Content)
|
||||
length := blogapp.General.Length
|
||||
if len(uc) < length {
|
||||
length = len(uc)
|
||||
}
|
||||
article.Excerpt = IgnoreHtmlTag(string(uc[0:length]))
|
||||
article.Excerpt = tools.IgnoreHtmlTag(string(uc[0:length]))
|
||||
}
|
||||
|
||||
@@ -121,6 +121,16 @@ type EiBlogApp struct {
|
||||
Blogger Blogger `yaml:"blogger"`
|
||||
}
|
||||
|
||||
// BackupApp config
|
||||
type BackupApp struct {
|
||||
Mode
|
||||
|
||||
BackupTo string `yaml:"backupto"`
|
||||
Interval string `yaml:"interval"` // circle backup, default: 7d
|
||||
Validity string `yaml:"validity"` // storage days, default: 60d
|
||||
Qiniu Qiniu `yaml:"qiniu"` // qiniu config
|
||||
}
|
||||
|
||||
// Config app config
|
||||
type Config struct {
|
||||
RunMode string `yaml:"runmode"`
|
||||
@@ -128,7 +138,7 @@ type Config struct {
|
||||
Database Database `yaml:"database"`
|
||||
ESHost string `yaml:"eshost"`
|
||||
EiBlogApp EiBlogApp `yaml:"eiblogapp"`
|
||||
BackupApp Mode `yaml:"backupapp"`
|
||||
BackupApp BackupApp `yaml:"backupapp"`
|
||||
}
|
||||
|
||||
// load config file
|
||||
|
||||
18
pkg/core/backup/ping/ping.go
Normal file
18
pkg/core/backup/ping/ping.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Package ping provides ...
|
||||
package ping
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// RegisterRoutes register routes
|
||||
func RegisterRoutes(group gin.IRoutes) {
|
||||
group.GET("/ping", handlePing)
|
||||
}
|
||||
|
||||
// handlePing ping
|
||||
func handlePing(c *gin.Context) {
|
||||
c.String(http.StatusOK, "it's ok")
|
||||
}
|
||||
15
pkg/core/backup/swag/swag.go
Normal file
15
pkg/core/backup/swag/swag.go
Normal file
@@ -0,0 +1,15 @@
|
||||
// Package swag provides ...
|
||||
package swag
|
||||
|
||||
import (
|
||||
_ "github.com/eiblog/eiblog/pkg/core/backup/docs" // docs
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
"github.com/swaggo/gin-swagger/swaggerFiles"
|
||||
)
|
||||
|
||||
// RegisterRoutes register routes
|
||||
func RegisterRoutes(group gin.IRoutes) {
|
||||
group.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
}
|
||||
77
pkg/core/backup/timer/qiniu/qiniu.go
Normal file
77
pkg/core/backup/timer/qiniu/qiniu.go
Normal file
@@ -0,0 +1,77 @@
|
||||
// Package qiniu provides ...
|
||||
package qiniu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/eiblog/eiblog/pkg/config"
|
||||
"github.com/eiblog/eiblog/pkg/internal"
|
||||
)
|
||||
|
||||
// Storage qiniu storage
|
||||
type Storage struct{}
|
||||
|
||||
// BackupData implements timer.Storage
|
||||
func (s Storage) BackupData(now time.Time) error {
|
||||
switch config.Conf.Database.Driver {
|
||||
case "mongodb":
|
||||
return backupFromMongoDB(now)
|
||||
default:
|
||||
return errors.New("unsupported database source backup to qiniu")
|
||||
}
|
||||
}
|
||||
|
||||
func backupFromMongoDB(now time.Time) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*20)
|
||||
defer cancel()
|
||||
|
||||
// dump
|
||||
arg := fmt.Sprintf("mongodump -h %s -d eiblog -o /tmp",
|
||||
config.Conf.Database.Source)
|
||||
cmd := exec.CommandContext(ctx, "sh", "-c", arg)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// tar
|
||||
name := fmt.Sprintf("eiblog-%s.tar.gz", now.Format("2006-01-02"))
|
||||
arg = fmt.Sprintf("tar czf %s /tmp/eiblog", name)
|
||||
cmd = exec.CommandContext(ctx, "sh", "-c", arg)
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// upload file
|
||||
f, err := os.Open("/tmp/eiblog/" + name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uploadParams := internal.UploadParams{
|
||||
Name: name,
|
||||
Size: s.Size(),
|
||||
Data: f,
|
||||
|
||||
Conf: config.Conf.BackupApp.Qiniu,
|
||||
}
|
||||
_, err = internal.QiniuUpload(uploadParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// after days delete
|
||||
deleteParams := internal.DeleteParams{
|
||||
Name: name,
|
||||
|
||||
Conf: config.Conf.BackupApp.Qiniu,
|
||||
}
|
||||
return internal.QiniuDelete(deleteParams)
|
||||
}
|
||||
68
pkg/core/backup/timer/timer.go
Normal file
68
pkg/core/backup/timer/timer.go
Normal file
@@ -0,0 +1,68 @@
|
||||
// Package timer provides ...
|
||||
package timer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/eiblog/eiblog/pkg/config"
|
||||
"github.com/eiblog/eiblog/pkg/core/backup/timer/qiniu"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Start to backup with ticker
|
||||
func Start() error {
|
||||
var storage Storage
|
||||
// backup instance
|
||||
switch config.Conf.BackupApp.BackupTo {
|
||||
case "qiniu":
|
||||
storage = qiniu.Storage{}
|
||||
|
||||
default:
|
||||
return errors.New("timer: unknown backup to driver: " +
|
||||
config.Conf.BackupApp.BackupTo)
|
||||
}
|
||||
|
||||
// parse duration
|
||||
interval, err := ParseDuration(config.Conf.BackupApp.Interval)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t := time.NewTicker(interval)
|
||||
for now := range t.C {
|
||||
err = storage.BackupData(now)
|
||||
if err != nil {
|
||||
logrus.Error("timer: Start.BackupData: ", now, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseDuration parse string to duration
|
||||
func ParseDuration(d string) (time.Duration, error) {
|
||||
if len(d) == 0 {
|
||||
return 0, errors.New("timer: incorrect duration input")
|
||||
}
|
||||
|
||||
length := len(d)
|
||||
switch d[length-1] {
|
||||
case 's', 'm', 'h':
|
||||
return time.ParseDuration(d)
|
||||
case 'd':
|
||||
di, err := strconv.Atoi(d[:length-1])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return time.Duration(di) * time.Hour * 24, nil
|
||||
}
|
||||
|
||||
return 0, errors.New("timer: unsupported duration:" + d)
|
||||
}
|
||||
|
||||
// Storage backup backend
|
||||
type Storage interface {
|
||||
BackupData(now time.Time) error
|
||||
}
|
||||
@@ -283,6 +283,9 @@ func handleAPIPostCreate(c *gin.Context) {
|
||||
logrus.Error("handleAPIPostCreate.AddArticle: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
cid = article.ID
|
||||
|
||||
if !article.IsDraft {
|
||||
// 异步执行,快
|
||||
go func() {
|
||||
@@ -467,7 +470,15 @@ func handleAPIQiniuUpload(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
filename := strings.ToLower(header.Filename)
|
||||
url, err := internal.QiniuUpload(filename, s.Size(), file)
|
||||
|
||||
params := internal.UploadParams{
|
||||
Name: filename,
|
||||
Size: s.Size(),
|
||||
Data: file,
|
||||
|
||||
Conf: config.Conf.EiBlogApp.Qiniu,
|
||||
}
|
||||
url, err := internal.QiniuUpload(params)
|
||||
if err != nil {
|
||||
logrus.Error("handleAPIQiniuUpload.QiniuUpload: ", err)
|
||||
c.String(http.StatusBadRequest, err.Error())
|
||||
@@ -491,7 +502,13 @@ func handleAPIQiniuDelete(c *gin.Context) {
|
||||
logrus.Error("handleAPIQiniuDelete.PostForm: 参数错误")
|
||||
return
|
||||
}
|
||||
err := internal.QiniuDelete(name)
|
||||
|
||||
params := internal.DeleteParams{
|
||||
Name: name,
|
||||
|
||||
Conf: config.Conf.EiBlogApp.Qiniu,
|
||||
}
|
||||
err := internal.QiniuDelete(params)
|
||||
if err != nil {
|
||||
logrus.Error("handleAPIQiniuDelete.QiniuDelete: ", err)
|
||||
}
|
||||
|
||||
@@ -13,19 +13,28 @@ import (
|
||||
"github.com/qiniu/go-sdk/v7/storage"
|
||||
)
|
||||
|
||||
// UploadParams upload params
|
||||
type UploadParams struct {
|
||||
Name string
|
||||
Size int64
|
||||
Data io.Reader
|
||||
|
||||
Conf config.Qiniu
|
||||
}
|
||||
|
||||
// QiniuUpload 上传文件
|
||||
func QiniuUpload(name string, size int64, data io.Reader) (string, error) {
|
||||
if config.Conf.EiBlogApp.Qiniu.AccessKey == "" ||
|
||||
config.Conf.EiBlogApp.Qiniu.SecretKey == "" {
|
||||
func QiniuUpload(params UploadParams) (string, error) {
|
||||
if params.Conf.AccessKey == "" ||
|
||||
params.Conf.SecretKey == "" {
|
||||
return "", errors.New("qiniu config error")
|
||||
}
|
||||
key := completeQiniuKey(name)
|
||||
key := completeQiniuKey(params.Name)
|
||||
|
||||
mac := qbox.NewMac(config.Conf.EiBlogApp.Qiniu.AccessKey,
|
||||
config.Conf.EiBlogApp.Qiniu.SecretKey)
|
||||
mac := qbox.NewMac(params.Conf.AccessKey,
|
||||
params.Conf.SecretKey)
|
||||
// 设置上传策略
|
||||
putPolicy := &storage.PutPolicy{
|
||||
Scope: config.Conf.EiBlogApp.Qiniu.Bucket,
|
||||
Scope: params.Conf.Bucket,
|
||||
Expires: 3600,
|
||||
InsertOnly: 1,
|
||||
}
|
||||
@@ -33,7 +42,6 @@ func QiniuUpload(name string, size int64, data io.Reader) (string, error) {
|
||||
uploadToken := putPolicy.UploadToken(mac)
|
||||
// 上传配置
|
||||
cfg := &storage.Config{
|
||||
Zone: &storage.ZoneHuadong,
|
||||
UseHTTPS: true,
|
||||
}
|
||||
// uploader
|
||||
@@ -42,20 +50,28 @@ func QiniuUpload(name string, size int64, data io.Reader) (string, error) {
|
||||
putExtra := &storage.PutExtra{}
|
||||
|
||||
err := uploader.Put(context.Background(), ret, uploadToken,
|
||||
key, data, size, putExtra)
|
||||
key, params.Data, params.Size, putExtra)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
url := "https://" + config.Conf.EiBlogApp.Qiniu.Domain + "/" + key
|
||||
url := "https://" + params.Conf.Domain + "/" + key
|
||||
return url, nil
|
||||
}
|
||||
|
||||
// QiniuDelete 删除文件
|
||||
func QiniuDelete(name string) error {
|
||||
key := completeQiniuKey(name)
|
||||
// DeleteParams delete params
|
||||
type DeleteParams struct {
|
||||
Name string
|
||||
Days int
|
||||
|
||||
mac := qbox.NewMac(config.Conf.EiBlogApp.Qiniu.AccessKey,
|
||||
config.Conf.EiBlogApp.Qiniu.SecretKey)
|
||||
Conf config.Qiniu
|
||||
}
|
||||
|
||||
// QiniuDelete 删除文件
|
||||
func QiniuDelete(params DeleteParams) error {
|
||||
key := completeQiniuKey(params.Name)
|
||||
|
||||
mac := qbox.NewMac(params.Conf.AccessKey,
|
||||
params.Conf.SecretKey)
|
||||
// 上传配置
|
||||
cfg := &storage.Config{
|
||||
Zone: &storage.ZoneHuadong,
|
||||
@@ -64,7 +80,10 @@ func QiniuDelete(name string) error {
|
||||
// manager
|
||||
bucketManager := storage.NewBucketManager(mac, cfg)
|
||||
// Delete
|
||||
return bucketManager.Delete(config.Conf.EiBlogApp.Qiniu.Bucket, key)
|
||||
if params.Days > 0 {
|
||||
return bucketManager.DeleteAfterDays(params.Conf.Bucket, key, params.Days)
|
||||
}
|
||||
return bucketManager.Delete(params.Conf.Bucket, key)
|
||||
}
|
||||
|
||||
// completeQiniuKey 修复路径
|
||||
|
||||
47
pkg/internal/qiniu_test.go
Normal file
47
pkg/internal/qiniu_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
// Package internal provides ...
|
||||
package internal
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/eiblog/eiblog/pkg/config"
|
||||
)
|
||||
|
||||
func TestQiniuUpload(t *testing.T) {
|
||||
|
||||
f, _ := os.Open("qiniu_test.go")
|
||||
fi, _ := f.Stat()
|
||||
|
||||
type args struct {
|
||||
params UploadParams
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{"1", args{params: UploadParams{
|
||||
Name: "test-" + time.Now().Format("200601021504059999") + ".go",
|
||||
Size: fi.Size(),
|
||||
Data: f,
|
||||
Conf: config.Qiniu{
|
||||
AccessKey: os.Getenv("QINIU_ACCESSKEY"),
|
||||
SecretKey: os.Getenv("QINIU_SECRETKEY"),
|
||||
Bucket: os.Getenv("QINIU_BUCKET"),
|
||||
},
|
||||
}}, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := QiniuUpload(tt.args.params)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("QiniuUpload() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
t.Logf("QiniuUpload() = %v", got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,9 @@ type Account struct {
|
||||
PhoneN string `gorm:"column:phone_n;not null" bson:"phone_n"` // 手机号
|
||||
Address string `gorm:"column:address;not null" bson:"address"` // 地址信息
|
||||
|
||||
LogoutAt time.Time `gorm:"column:logout_at;not null" bson:"logout_at"` // 登出时间
|
||||
LoginIP string `gorm:"column:login_ip;not null" bson:"login_ip"` // 最近登录IP
|
||||
LoginUA string `gorm:"column:login_ua;not null" bson:"login_ua"` // 最近登录IP
|
||||
LoginAt time.Time `gorm:"column:login_at;default:now()" bson:"login_at"` // 最近登录时间
|
||||
CreatedAt time.Time `gorm:"column:created_at;default:now()" bson:"created_at"` // 创建时间
|
||||
LogoutAt time.Time `gorm:"column:logout_at;not null" bson:"logout_at"` // 登出时间
|
||||
LoginIP string `gorm:"column:login_ip;not null" bson:"login_ip"` // 最近登录IP
|
||||
LoginUA string `gorm:"column:login_ua;not null" bson:"login_ua"` // 最近登录IP
|
||||
LoginAt time.Time `gorm:"column:login_at;default:current_timestamp" bson:"login_at"` // 最近登录时间
|
||||
CreatedAt time.Time `gorm:"column:created_at;default:current_timestamp" bson:"created_at"` // 创建时间
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ type Article struct {
|
||||
Tags pq.StringArray `gorm:"column:tags;type:text[]" bson:"tags"` // tags
|
||||
IsDraft bool `gorm:"column:is_draft;not null" bson:"is_draft"` // 是否是草稿
|
||||
|
||||
DeletedAt time.Time `gorm:"column:deleted_at;not null" bson:"deleted_at"` // 删除时间
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;default:now()" bson:"updated_at"` // 更新时间
|
||||
CreatedAt time.Time `gorm:"column:created_at;default:now()" bson:"created_at"` // 创建时间
|
||||
DeletedAt time.Time `gorm:"column:deleted_at;not null" bson:"deleted_at"` // 删除时间
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;default:current_timestamp" bson:"updated_at"` // 更新时间
|
||||
CreatedAt time.Time `gorm:"column:created_at;default:current_timestamp" bson:"created_at"` // 创建时间
|
||||
|
||||
Header string `gorm:"-" bson:"-"` // header
|
||||
Excerpt string `gorm:"-" bson:"-"` // 预览信息
|
||||
|
||||
@@ -5,11 +5,11 @@ import "time"
|
||||
|
||||
// Serie 专题
|
||||
type Serie struct {
|
||||
ID int `gorm:"column:id;primaryKey" bson:"id"` // 自增ID
|
||||
Slug string `gorm:"column:slug;not null;uniqueIndex" bson:"slug"` // 缩略名
|
||||
Name string `gorm:"column:name;not null" bson:"name"` // 专题名
|
||||
Desc string `gorm:"column:desc;not null" bson:"desc"` // 专题描述
|
||||
CreatedAt time.Time `gorm:"column:created_at;default:now()" bson:"created_at"` // 创建时间
|
||||
ID int `gorm:"column:id;primaryKey" bson:"id"` // 自增ID
|
||||
Slug string `gorm:"column:slug;not null;uniqueIndex" bson:"slug"` // 缩略名
|
||||
Name string `gorm:"column:name;not null" bson:"name"` // 专题名
|
||||
Desc string `gorm:"column:desc;not null" bson:"desc"` // 专题描述
|
||||
CreatedAt time.Time `gorm:"column:created_at;default:current_timestamp" bson:"created_at"` // 创建时间
|
||||
|
||||
Articles SortedArticles `gorm:"-" bson:"-"` // 专题下的文章
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
_registry="$1"
|
||||
_tag="$2"
|
||||
_platform="linux/amd64,linux/arm64,linux/386"
|
||||
@@ -11,11 +9,14 @@ if [ -z "$_registry" ] || [ -z "$_tag" ]; then
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
# create and use builder
|
||||
docker buildx inspect builder >/dev/null 2>&1
|
||||
if [ "$?" != "0" ]; then
|
||||
docker buildx create --use --name builder
|
||||
fi
|
||||
|
||||
# prepare dir ./bin
|
||||
mkdir -p ./bin
|
||||
# create builder
|
||||
docker buildx create --use --name builder
|
||||
|
||||
# build demo app
|
||||
for file in pkg/core/*; do
|
||||
app="$(basename $file)";
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
External helper tools, forked code and other 3rd party utilities (e.g., Swagger UI).
|
||||
Reference in New Issue
Block a user