添加静态文件自动下载的功能
This commit is contained in:
parent
29cfee9d4e
commit
95920064be
|
@ -27,3 +27,5 @@ jobs:
|
|||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.TOKEN }}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,10 +9,14 @@ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/local/go/bin:/usr/sbin:/usr/bin:/sb
|
|||
SHELL=/bin/bash \
|
||||
PS1="\u@\h:\w \$ " \
|
||||
QL_DIR=/ql \
|
||||
QL_BRANCH=${QL_BRANCH}
|
||||
QL_BRANCH=${QL_BRANCH} \
|
||||
GO111MODULE=on \
|
||||
GOPROXY=https://goproxy.cn
|
||||
|
||||
WORKDIR ${QL_DIR}
|
||||
|
||||
COPY --from=golang:1.18-alpine /usr/local/go/ /usr/local/go/
|
||||
|
||||
RUN set -x \
|
||||
&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
|
||||
&& apk update -f \
|
||||
|
@ -46,7 +50,6 @@ RUN set -x \
|
|||
|
||||
COPY ./dist/docker_linux_$TARGETARCH*/qinglong-go ${QL_DIR}/ql
|
||||
|
||||
RUN chmod -R 777 /ql/ql
|
||||
|
||||
EXPOSE 5700
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"github.com/gin-contrib/gzip"
|
||||
"github.com/gin-contrib/static"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/huoxue1/qinglong-go/api"
|
||||
|
@ -11,6 +12,7 @@ func Router() *gin.Engine {
|
|||
engine := gin.New()
|
||||
engine.Use(gin.Logger())
|
||||
engine.Use(gin.Recovery())
|
||||
engine.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||
engine.Use(static.Serve("/", static.LocalFile("static/dist/", false)))
|
||||
engine.NoRoute(func(ctx *gin.Context) {
|
||||
if ctx.Request.Method == http.MethodGet {
|
||||
|
|
2
go.mod
2
go.mod
|
@ -21,7 +21,9 @@ require (
|
|||
|
||||
require (
|
||||
github.com/cheekybits/genny v1.0.0 // indirect
|
||||
github.com/dablelv/go-huge-util v0.0.31 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gin-contrib/gzip v0.0.6 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
|
|
8
go.sum
8
go.sum
|
@ -59,6 +59,8 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/dablelv/go-huge-util v0.0.31 h1:V6OFWmGwjdl1s+dGImF/S6crESVzm8x9+PaUF7KrYBk=
|
||||
github.com/dablelv/go-huge-util v0.0.31/go.mod h1:CTdXt+L11UBDS+dg9LPgslqDMXcCvhTv51IikcQDxGA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -86,6 +88,8 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV
|
|||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Swm1U=
|
||||
|
@ -339,6 +343,7 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
|||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
|
@ -404,6 +409,7 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
|
|||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
|
@ -675,6 +681,7 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -768,6 +775,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
|||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
|
|
27
main.go
27
main.go
|
@ -1,9 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
nested "github.com/Lyrics-you/sail-logrus-formatter/sailor"
|
||||
"github.com/dablelv/go-huge-util/zip"
|
||||
"github.com/huoxue1/qinglong-go/controller"
|
||||
"github.com/huoxue1/qinglong-go/service"
|
||||
"github.com/huoxue1/qinglong-go/service/config"
|
||||
"github.com/huoxue1/qinglong-go/utils"
|
||||
rotates "github.com/lestrrat-go/file-rotatelogs"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io"
|
||||
|
@ -37,7 +41,30 @@ func init() {
|
|||
}
|
||||
|
||||
func main() {
|
||||
checkStatic()
|
||||
service.AppInit()
|
||||
engine := controller.Router()
|
||||
_ = engine.Run(":5700")
|
||||
}
|
||||
|
||||
func checkStatic() {
|
||||
if !utils.FileExist("./static/") {
|
||||
log.Warningln("检测到静态文件资源不存在,即将自动下载文件!")
|
||||
log.Infoln("downloading file from ", fmt.Sprintf("https://github.com/huoxue1/qinglong/releases/download/%s/static.zip", config.GetVersion()))
|
||||
response, err := utils.GetClient().R().Get(fmt.Sprintf("https://github.com/huoxue1/qinglong/releases/download/%s/static.zip", config.GetVersion()))
|
||||
if err != nil {
|
||||
log.Errorln("下载静态资源文件失败 " + err.Error())
|
||||
return
|
||||
}
|
||||
err = os.WriteFile("static.zip", response.Bytes(), 0666)
|
||||
if err != nil {
|
||||
log.Errorln("写入压缩文件错误 " + err.Error())
|
||||
return
|
||||
}
|
||||
err = zip.Unzip("static.zip", ".")
|
||||
if err != nil {
|
||||
log.Errorln(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,16 @@ import (
|
|||
"regexp"
|
||||
)
|
||||
|
||||
var VERSION = "test"
|
||||
var VERSION = "v1.0.0"
|
||||
|
||||
func GetKey(key string) string {
|
||||
func GetKey(key, defaultValue string) string {
|
||||
file, err := os.ReadFile(path.Join("data", "config", "config.sh"))
|
||||
if err != nil {
|
||||
return ""
|
||||
return defaultValue
|
||||
}
|
||||
compile := regexp.MustCompile(key + `="(.*?)"`)
|
||||
if !compile.Match(file) {
|
||||
return ""
|
||||
return defaultValue
|
||||
}
|
||||
datas := compile.FindAllStringSubmatch(string(file), 1)
|
||||
return datas[0][1]
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"github.com/huoxue1/qinglong-go/models"
|
||||
"github.com/huoxue1/qinglong-go/service/config"
|
||||
"github.com/huoxue1/qinglong-go/service/env"
|
||||
"github.com/huoxue1/qinglong-go/utils"
|
||||
"github.com/robfig/cron/v3"
|
||||
|
@ -156,13 +157,18 @@ func AddTask(crontabs *models.Crontabs) {
|
|||
func handCommand(command string) *task {
|
||||
ta := new(task)
|
||||
commands := strings.Split(command, " ")
|
||||
|
||||
pythonCmd := config.GetKey("PythonCmd", "python")
|
||||
JsCmd := config.GetKey("JsCmd", "node")
|
||||
ShCmd := config.GetKey("ShCmd", "bash")
|
||||
|
||||
if commands[0] == "task" {
|
||||
if strings.HasSuffix(commands[1], ".py") {
|
||||
ta.cmd = "python3 " + commands[1]
|
||||
ta.cmd = pythonCmd + " " + commands[1]
|
||||
} else if strings.HasSuffix(commands[1], ".js") {
|
||||
ta.cmd = "node " + commands[1]
|
||||
ta.cmd = JsCmd + " " + commands[1]
|
||||
} else if strings.HasSuffix(commands[1], ".sh") {
|
||||
ta.cmd = "bash " + commands[1]
|
||||
ta.cmd = ShCmd + " " + commands[1]
|
||||
} else if strings.HasSuffix(commands[1], ".ts") {
|
||||
ta.cmd = "ts-node-transpile-only " + commands[1]
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ func downloadFiles(subscriptions *models.Subscriptions) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
if config.GetKey("AutoAddCron") == "true" {
|
||||
if config.GetKey("AutoAddCron", "true") == "true" {
|
||||
addScripts(subscriptions)
|
||||
} else {
|
||||
log.Infoln("未配置自动添加定时任务,不添加任务!")
|
||||
|
@ -141,7 +141,7 @@ func addScripts(subscriptions *models.Subscriptions) {
|
|||
if subscriptions.Extensions != "" {
|
||||
extensions = strings.Split(subscriptions.Extensions, " ")
|
||||
} else {
|
||||
extensions = strings.Split(config.GetKey("RepoFileExtensions"), " ")
|
||||
extensions = strings.Split(config.GetKey("RepoFileExtensions", "js py sh"), " ")
|
||||
}
|
||||
dir, err := os.ReadDir(path.Join("data", "repo", subscriptions.Alias))
|
||||
if err != nil {
|
||||
|
@ -194,7 +194,7 @@ func addScripts(subscriptions *models.Subscriptions) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if config.GetKey("AutoDelCron") == "true" {
|
||||
if config.GetKey("AutoDelCron", "true") == "true" {
|
||||
for _, m := range cronMap {
|
||||
file.WriteString("已删除失效的任务 " + m.Name + "\n")
|
||||
models.DeleteCron(m.Id)
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func UnTar(dst, src string) (err error) {
|
||||
// 打开准备解压的 tar 包
|
||||
fr, err := os.Open(src)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// 将打开的文件先解压
|
||||
gr, err := gzip.NewReader(fr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer gr.Close()
|
||||
|
||||
// 通过 gr 创建 tar.Reader
|
||||
tr := tar.NewReader(gr)
|
||||
|
||||
// 现在已经获得了 tar.Reader 结构了,只需要循环里面的数据写入文件就可以了
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
return nil
|
||||
case err != nil:
|
||||
return err
|
||||
case hdr == nil:
|
||||
continue
|
||||
}
|
||||
|
||||
// 处理下保存路径,将要保存的目录加上 header 中的 Name
|
||||
// 这个变量保存的有可能是目录,有可能是文件,所以就叫 FileDir 了……
|
||||
dstFileDir := filepath.Join(dst, hdr.Name)
|
||||
|
||||
// 根据 header 的 Typeflag 字段,判断文件的类型
|
||||
switch hdr.Typeflag {
|
||||
case tar.TypeDir: // 如果是目录时候,创建目录
|
||||
// 判断下目录是否存在,不存在就创建
|
||||
if b := ExistDir(dstFileDir); !b {
|
||||
// 使用 MkdirAll 不使用 Mkdir ,就类似 Linux 终端下的 mkdir -p,
|
||||
// 可以递归创建每一级目录
|
||||
if err := os.MkdirAll(dstFileDir, 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case tar.TypeReg: // 如果是文件就写入到磁盘
|
||||
// 创建一个可以读写的文件,权限就使用 header 中记录的权限
|
||||
// 因为操作系统的 FileMode 是 int32 类型的,hdr 中的是 int64,所以转换下
|
||||
file, err := os.OpenFile(dstFileDir, os.O_CREATE|os.O_RDWR, os.FileMode(hdr.Mode))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n, err := io.Copy(file, tr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 将解压结果输出显示
|
||||
fmt.Printf("成功解压: %s , 共处理了 %d 个字符\n", dstFileDir, n)
|
||||
|
||||
// 不要忘记关闭打开的文件,因为它是在 for 循环中,不能使用 defer
|
||||
// 如果想使用 defer 就放在一个单独的函数中
|
||||
file.Close()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 判断目录是否存在
|
||||
func ExistDir(dirname string) bool {
|
||||
fi, err := os.Stat(dirname)
|
||||
return (err == nil || os.IsExist(err)) && fi.IsDir()
|
||||
}
|
Loading…
Reference in New Issue