diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3c67599..804cc68 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,8 +63,26 @@ jobs: chmod +x ./build.sh ./build.sh -r b - - name: Upload binary files - uses: actions/upload-artifact@v1 + - name: Upload binary files (windows_amd64) + uses: actions/upload-artifact@v2 with: - name: release - path: release/ + name: cloudreve_windows_amd64 + path: release/cloudreve*windows_amd64.* + + - name: Upload binary files (linux_amd64) + uses: actions/upload-artifact@v2 + with: + name: cloudreve_linux_amd64 + path: release/cloudreve*linux_amd64.* + + - name: Upload binary files (linux_arm) + uses: actions/upload-artifact@v2 + with: + name: cloudreve_linux_arm + path: release/cloudreve*linux_arm.* + + - name: Upload binary files (linux_arm64) + uses: actions/upload-artifact@v2 + with: + name: cloudreve_linux_arm64 + path: release/cloudreve*linux_arm64.* diff --git a/.travis.yml b/.travis.yml index 1391668..8e6abe8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ language: go go: - 1.13.x +node_js: + - 12.16.3 git: depth: 1 install: diff --git a/assets b/assets index b44dc05..54f4e60 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b44dc0514520580fc284937400743123bbb2c6d4 +Subproject commit 54f4e608bd4a91ef5ed81b2f8e5778f4bf8632c5 diff --git a/bootstrap/app.go b/bootstrap/app.go index 616c802..ccb4fdc 100644 --- a/bootstrap/app.go +++ b/bootstrap/app.go @@ -37,11 +37,13 @@ func CheckUpdate() { res, err := client.Request("GET", "https://api.github.com/repos/cloudreve/cloudreve/releases", nil).GetResponse() if err != nil { util.Log().Warning("更新检查失败, %s", err) + return } var list []GitHubRelease if err := json.Unmarshal([]byte(res), &list); err != nil { util.Log().Warning("更新检查失败, %s", err) + return } if len(list) > 0 { diff --git a/bootstrap/static.go b/bootstrap/static.go index e22ebd0..d3f8967 100644 --- a/bootstrap/static.go +++ b/bootstrap/static.go @@ -7,10 +7,14 @@ import ( _ "github.com/HFO4/cloudreve/statik" "github.com/gin-contrib/static" "github.com/rakyll/statik/fs" + "io" "io/ioutil" "net/http" + "path" ) +const StaticFolder = "statics" + type GinFS struct { FS http.FileSystem } @@ -42,7 +46,7 @@ func (b *GinFS) Exists(prefix string, filepath string) bool { func InitStatic() { var err error - if util.Exists(util.RelativePath("statics")) { + if util.Exists(util.RelativePath(StaticFolder)) { util.Log().Info("检测到 statics 目录存在,将使用此目录下的静态资源文件") StaticFS = static.LocalFile(util.RelativePath("statics"), false) @@ -89,3 +93,65 @@ func InitStatic() { } } + +// Eject 抽离内置静态资源 +func Eject() { + staticFS, err := fs.New() + if err != nil { + util.Log().Panic("无法初始化静态资源, %s", err) + } + + root, err := staticFS.Open("/") + if err != nil { + util.Log().Panic("根目录不存在, %s", err) + } + + var walk func(relPath string, object http.File) + walk = func(relPath string, object http.File) { + stat, err := object.Stat() + if err != nil { + util.Log().Error("无法获取[%s]的信息, %s, 跳过...", relPath, err) + return + } + + if !stat.IsDir() { + // 写入文件 + out, err := util.CreatNestedFile(util.RelativePath(StaticFolder + relPath)) + defer out.Close() + + if err != nil { + util.Log().Error("无法创建文件[%s], %s, 跳过...", relPath, err) + return + } + + util.Log().Info("导出 [%s]...", relPath) + if _, err := io.Copy(out, object); err != nil { + util.Log().Error("无法写入文件[%s], %s, 跳过...", relPath, err) + return + } + } else { + // 列出目录 + objects, err := object.Readdir(0) + if err != nil { + util.Log().Error("无法步入子目录[%s], %s, 跳过...", relPath, err) + return + } + + // 递归遍历子目录 + for _, newObject := range objects { + newPath := path.Join(relPath, newObject.Name()) + newRoot, err := staticFS.Open(newPath) + if err != nil { + util.Log().Error("无法打开对象[%s], %s, 跳过...", newPath, err) + continue + } + walk(newPath, newRoot) + } + + } + } + + util.Log().Info("开始导出内置静态资源...") + walk("/", root) + util.Log().Info("内置静态资源导出完成") +} diff --git a/build.sh b/build.sh index 5ebd3da..ea7e101 100755 --- a/build.sh +++ b/build.sh @@ -55,7 +55,12 @@ _build() { export CC=$gcc export CGO_ENABLED=1 - out="release/cloudreve_${VERSION}_${os}_${arch}" + if [ -n "$VERSION" ]; then + out="release/cloudreve_${VERSION}_${os}_${arch}" + else + out="release/cloudreve_${COMMIT_SHA}_${os}_${arch}" + fi + go build -a -o "${out}" -ldflags " -X 'github.com/HFO4/cloudreve/pkg/conf.BackendVersion=$VERSION' -X 'github.com/HFO4/cloudreve/pkg/conf.LastCommit=$COMMIT_SHA'" if [ "$os" = "windows" ]; then diff --git a/main.go b/main.go index a05bd5a..de6bce0 100644 --- a/main.go +++ b/main.go @@ -8,16 +8,38 @@ import ( "github.com/HFO4/cloudreve/routers" ) -var confPath string +var ( + isEject bool + confPath string +) func init() { flag.StringVar(&confPath, "c", util.RelativePath("conf.ini"), "配置文件路径") + flag.BoolVar(&isEject, "eject", false, "导出内置静态资源") flag.Parse() bootstrap.Init(confPath) } func main() { + if isEject { + // 开始导出内置静态资源文件 + bootstrap.Eject() + return + } + api := routers.InitRouter() + + // 如果启用了SSL + if conf.SSLConfig.CertPath != "" { + go func() { + util.Log().Info("开始监听 %s", conf.SSLConfig.Listen) + if err := api.RunTLS(conf.SSLConfig.Listen, + conf.SSLConfig.CertPath, conf.SSLConfig.KeyPath); err != nil { + util.Log().Error("无法监听[%s],%s", conf.SSLConfig.Listen, err) + } + }() + } + util.Log().Info("开始监听 %s", conf.SystemConfig.Listen) if err := api.Run(conf.SystemConfig.Listen); err != nil { util.Log().Error("无法监听[%s],%s", conf.SystemConfig.Listen, err) diff --git a/pkg/conf/conf.go b/pkg/conf/conf.go index d28d043..a19110b 100644 --- a/pkg/conf/conf.go +++ b/pkg/conf/conf.go @@ -27,6 +27,12 @@ type system struct { HashIDSalt string } +type ssl struct { + CertPath string `validate:"omitempty,required"` + KeyPath string `validate:"omitempty,required"` + Listen string `validate:"required"` +} + // slave 作为slave存储端配置 type slave struct { Secret string `validate:"omitempty,gte=64"` @@ -113,6 +119,7 @@ func Init(path string) { sections := map[string]interface{}{ "Database": DatabaseConfig, "System": SystemConfig, + "SSL": SSLConfig, "Captcha": CaptchaConfig, "Redis": RedisConfig, "Thumbnail": ThumbConfig, diff --git a/pkg/conf/defaults.go b/pkg/conf/defaults.go index f4ff903..406a203 100644 --- a/pkg/conf/defaults.go +++ b/pkg/conf/defaults.go @@ -59,3 +59,9 @@ var SlaveConfig = &slave{ CallbackTimeout: 20, SignatureTTL: 60, } + +var SSLConfig = &ssl{ + Listen: ":443", + CertPath: "", + KeyPath: "", +} diff --git a/pkg/conf/version.go b/pkg/conf/version.go index 280ed72..f4b5bf8 100644 --- a/pkg/conf/version.go +++ b/pkg/conf/version.go @@ -1,13 +1,13 @@ package conf // BackendVersion 当前后端版本号 -var BackendVersion = "3.0.0-beta1" +var BackendVersion = "3.1.0" // RequiredDBVersion 与当前版本匹配的数据库版本 -var RequiredDBVersion = "3.0.0-33-g5885661" +var RequiredDBVersion = "3.1.0" // RequiredStaticVersion 与当前版本匹配的静态资源版本 -var RequiredStaticVersion = "3.0.0" +var RequiredStaticVersion = "3.1.0" // IsPro 是否为Pro版本 var IsPro = "false" diff --git a/pkg/util/logger.go b/pkg/util/logger.go index 81e3652..107ec71 100644 --- a/pkg/util/logger.go +++ b/pkg/util/logger.go @@ -3,6 +3,7 @@ package util import ( "fmt" "github.com/fatih/color" + "sync" "time" ) @@ -23,6 +24,7 @@ var Level = LevelDebug // Logger 日志 type Logger struct { level int + mu sync.Mutex } // 日志颜色 @@ -49,6 +51,10 @@ func (ll *Logger) Println(prefix string, msg string) { // color.NoColor = false c := color.New() + + ll.mu.Lock() + defer ll.mu.Unlock() + _, _ = c.Printf( "%s%s %s %s\n", colors[prefix]("["+prefix+"]"), diff --git a/service/explorer/objects.go b/service/explorer/objects.go index 4944551..6275136 100644 --- a/service/explorer/objects.go +++ b/service/explorer/objects.go @@ -146,6 +146,11 @@ func (service *ItemCompressService) CreateCompressTask(c *gin.Context) serialize return serializer.Err(serializer.CodeGroupNotAllowed, "当前用户组无法进行此操作", nil) } + // 补齐压缩文件扩展名(如果没有) + if !strings.HasSuffix(service.Name, ".zip") { + service.Name += ".zip" + } + // 存放目录是否存在,是否重名 if exist, _ := fs.IsPathExist(service.Dst); !exist { return serializer.Err(serializer.CodeNotFound, "存放路径不存在", nil)