mirror of
				https://github.com/cloudreve/cloudreve.git
				synced 2025-10-31 16:49:03 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			158 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package bootstrap
 | |
| 
 | |
| import (
 | |
| 	"encoding/json"
 | |
| 	"github.com/HFO4/cloudreve/pkg/conf"
 | |
| 	"github.com/HFO4/cloudreve/pkg/util"
 | |
| 	_ "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
 | |
| }
 | |
| 
 | |
| type staticVersion struct {
 | |
| 	Name    string `json:"name"`
 | |
| 	Version string `json:"version"`
 | |
| }
 | |
| 
 | |
| // StaticFS 内置静态文件资源
 | |
| var StaticFS static.ServeFileSystem
 | |
| 
 | |
| // Open 打开文件
 | |
| func (b *GinFS) Open(name string) (http.File, error) {
 | |
| 	return b.FS.Open(name)
 | |
| }
 | |
| 
 | |
| // Exists 文件是否存在
 | |
| func (b *GinFS) Exists(prefix string, filepath string) bool {
 | |
| 
 | |
| 	if _, err := b.FS.Open(filepath); err != nil {
 | |
| 		return false
 | |
| 	}
 | |
| 	return true
 | |
| 
 | |
| }
 | |
| 
 | |
| // InitStatic 初始化静态资源文件
 | |
| func InitStatic() {
 | |
| 	var err error
 | |
| 
 | |
| 	if util.Exists(util.RelativePath(StaticFolder)) {
 | |
| 		util.Log().Info("检测到 statics 目录存在,将使用此目录下的静态资源文件")
 | |
| 		StaticFS = static.LocalFile(util.RelativePath("statics"), false)
 | |
| 
 | |
| 		// 检查静态资源的版本
 | |
| 		f, err := StaticFS.Open("version.json")
 | |
| 		if err != nil {
 | |
| 			util.Log().Warning("静态资源版本标识文件不存在,请重新构建或删除 statics 目录")
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		b, err := ioutil.ReadAll(f)
 | |
| 		if err != nil {
 | |
| 			util.Log().Warning("无法读取静态资源文件版本,请重新构建或删除 statics 目录")
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		var v staticVersion
 | |
| 		if err := json.Unmarshal(b, &v); err != nil {
 | |
| 			util.Log().Warning("无法解析静态资源文件版本, %s", err)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		staticName := "cloudreve-frontend"
 | |
| 		if conf.IsPro == "true" {
 | |
| 			staticName += "-pro"
 | |
| 		}
 | |
| 
 | |
| 		if v.Name != staticName {
 | |
| 			util.Log().Warning("静态资源版本不匹配,请重新构建或删除 statics 目录")
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		if v.Version != conf.RequiredStaticVersion {
 | |
| 			util.Log().Warning("静态资源版本不匹配 [当前 %s, 需要: %s],请重新构建或删除 statics 目录", v.Version, conf.RequiredStaticVersion)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 	} else {
 | |
| 		StaticFS = &GinFS{}
 | |
| 		StaticFS.(*GinFS).FS, err = fs.New()
 | |
| 		if err != nil {
 | |
| 			util.Log().Panic("无法初始化静态资源, %s", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| }
 | |
| 
 | |
| // 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("内置静态资源导出完成")
 | |
| }
 | 
