diff --git a/bootstrap/cache.go b/bootstrap/cache.go new file mode 100644 index 00000000000..94a02f6b1b5 --- /dev/null +++ b/bootstrap/cache.go @@ -0,0 +1,15 @@ +package bootstrap + +import ( + "github.com/Xhofe/alist/conf" + "github.com/patrickmn/go-cache" + log "github.com/sirupsen/logrus" + "time" +) + +func InitCache() { + if conf.Conf.Cache.Enable { + log.Infof("初始化缓存...") + conf.Cache=cache.New(time.Duration(conf.Conf.Cache.Expiration)*time.Minute,time.Duration(conf.Conf.Cache.CleanupInterval)*time.Minute) + } +} diff --git a/bootstrap/cmd.go b/bootstrap/cmd.go index 319895670a6..28c9e7bc615 100644 --- a/bootstrap/cmd.go +++ b/bootstrap/cmd.go @@ -48,6 +48,7 @@ func start() { log.Errorf("初始化阿里云盘出现错误,启动失败.") return } + InitCache() InitCron() server() } diff --git a/conf.yml.example b/conf.yml.example index 5a7b0442acf..559474b4268 100644 --- a/conf.yml.example +++ b/conf.yml.example @@ -1,15 +1,22 @@ info: - title: AList - site_url: http://localhost - logo: + title: AList #标题 + site_url: http://localhost:5277 #前端地址 + backend_url: http://localhost:5244 #后端地址 + logo: "" #网站logo 如果填写,则会替换掉默认的 + footer_text: Xhofe's Blog #网页底部文字 + footer_url: https://www.nn.ci #网页底部文字链接 + music_img: https://img.oez.cc/2020/12/19/0f8b57866bdb5.gif #预览音乐文件时的图片 server: - port: "5244" - search: true - static: dist + port: "5244" #程序监听端口 + search: true #是否开启搜索接口,开启搜索之后密码和根目录都会失效,所以前端暂时不做搜索 + static: dist #前端文件目录 +cache: + cache: true #是否开启缓存 + expiration: 5 #缓存失效时间(单位:分钟) + cleanup_interval: 10 #清理失效缓存间隔 + refresh_password: password #手动清理缓存密码 ali_drive: - api_url: https://api.aliyundrive.com/v2 - root_folder: root - token: - access_token: + api_url: https://api.aliyundrive.com/v2 #阿里云盘api,无需修改 + root_folder: root #根目录 refresh_token: need - max_files_count: 3000 \ No newline at end of file + max_files_count: 3000 diff --git a/conf/config.go b/conf/config.go index 9e5e8231b88..e07abe3bbf7 100644 --- a/conf/config.go +++ b/conf/config.go @@ -15,6 +15,12 @@ type Config struct { Search bool `yaml:"search" json:"search"`//允许搜索 Static string `yaml:"static"` } `yaml:"server"` + Cache struct{ + Enable bool `yaml:"cache"` + Expiration int `yaml:"expiration"` + CleanupInterval int `yaml:"cleanup_interval"` + RefreshPassword string `yaml:"refresh_password"` + } AliDrive struct{ ApiUrl string `yaml:"api_url"`//阿里云盘api RootFolder string `yaml:"root_folder"`//根目录id diff --git a/conf/const.go b/conf/const.go index 966c5a01399..1675502855e 100644 --- a/conf/const.go +++ b/conf/const.go @@ -1,6 +1,7 @@ package conf import ( + "github.com/patrickmn/go-cache" "net/http" ) @@ -10,6 +11,8 @@ var( Con string Client *http.Client Authorization string + + Cache *cache.Cache ) var Conf = new(Config) diff --git a/go.mod b/go.mod index a5038cb2fbb..adfa0fbb403 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/leodido/go-urn v1.2.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible github.com/robfig/cron/v3 v3.0.0 github.com/sirupsen/logrus v1.7.0 github.com/ugorji/go v1.2.2 // indirect diff --git a/go.sum b/go.sum index a077363360c..092693f021c 100644 --- a/go.sum +++ b/go.sum @@ -66,6 +66,9 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/patrickmn/go-cache v1.0.0 h1:3gD5McaYs9CxjyK5AXGcq8gdeCARtd/9gJDUvVeaZ0Y= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E= diff --git a/server/controllers.go b/server/controllers.go deleted file mode 100644 index 89a13e0f44c..00000000000 --- a/server/controllers.go +++ /dev/null @@ -1,118 +0,0 @@ -package server - -import ( - "github.com/Xhofe/alist/alidrive" - "github.com/Xhofe/alist/conf" - "github.com/gin-gonic/gin" - log "github.com/sirupsen/logrus" - "strings" -) - -func Info(c *gin.Context) { - c.JSON(200,dataResponse(conf.Conf.Info)) -} - -func Get(c *gin.Context) { - var get alidrive.GetReq - if err := c.ShouldBindJSON(&get); err != nil { - c.JSON(200,metaResponse(400,"Bad Request")) - return - } - log.Debugf("get:%v",get) - file,err:=alidrive.GetFile(get.FileId) - if err !=nil { - c.JSON(200,metaResponse(500,err.Error())) - return - } - paths,err:=alidrive.GetPaths(get.FileId) - if err!=nil { - c.JSON(200,metaResponse(500,err.Error())) - return - } - file.Paths=*paths - c.JSON(200,dataResponse(file)) -} - -func List(c *gin.Context) { - var list ListReq - if err := c.ShouldBindJSON(&list);err!=nil { - c.JSON(200,metaResponse(400,"Bad Request")) - return - } - log.Debugf("list:%v",list) - var ( - files *alidrive.Files - err error - ) - if list.Limit == 0 { - list.Limit=50 - } - if conf.Conf.AliDrive.MaxFilesCount!=0 { - list.Limit=conf.Conf.AliDrive.MaxFilesCount - } - if list.ParentFileId == "root" { - files,err=alidrive.GetRoot(list.Limit,list.Marker,list.OrderBy,list.OrderDirection) - }else { - files,err=alidrive.GetList(list.ParentFileId,list.Limit,list.Marker,list.OrderBy,list.OrderDirection) - } - if err!=nil { - c.JSON(200,metaResponse(500,err.Error())) - return - } - password:=alidrive.HasPassword(files) - if password!="" && password!=list.Password { - if list.Password=="" { - c.JSON(200,metaResponse(401,"need password.")) - return - } - c.JSON(200,metaResponse(401,"wrong password.")) - return - } - paths,err:=alidrive.GetPaths(list.ParentFileId) - if err!=nil { - c.JSON(200,metaResponse(500,err.Error())) - return - } - files.Paths=*paths - files.Readme=alidrive.HasReadme(files) - c.JSON(200,dataResponse(files)) -} - -func Search(c *gin.Context) { - if !conf.Conf.Server.Search { - c.JSON(200,metaResponse(403,"Not allow search.")) - return - } - var search alidrive.SearchReq - if err := c.ShouldBindJSON(&search); err != nil { - c.JSON(200,metaResponse(400,"Bad Request")) - return - } - log.Debugf("search:%v",search) - if search.Limit == 0 { - search.Limit=50 - } - // Search只支持0-100 - //if conf.Conf.AliDrive.MaxFilesCount!=0 { - // search.Limit=conf.Conf.AliDrive.MaxFilesCount - //} - files,err:=alidrive.Search(search.Query,search.Limit,search.OrderBy) - if err != nil { - c.JSON(200,metaResponse(500,err.Error())) - return - } - c.JSON(200,dataResponse(files)) -} - -func Down(c *gin.Context) { - fileIdParam:=c.Param("file_id") - log.Debugf("down:%s",fileIdParam) - fileId:=strings.Split(fileIdParam,"/")[1] - file,err:=alidrive.GetFile(fileId) - if err != nil { - c.JSON(200,metaResponse(500,err.Error())) - return - } - c.Redirect(301,file.DownloadUrl) - return -} \ No newline at end of file diff --git a/server/common.go b/server/controllers/common.go similarity index 92% rename from server/common.go rename to server/controllers/common.go index 0b9d773d249..533a6d5ab93 100644 --- a/server/common.go +++ b/server/controllers/common.go @@ -1,4 +1,4 @@ -package server +package controllers import "github.com/gin-gonic/gin" @@ -19,4 +19,4 @@ func dataResponse(data interface{}) gin.H { }, "data":data, } -} \ No newline at end of file +} diff --git a/server/controllers/get.go b/server/controllers/get.go new file mode 100644 index 00000000000..1cb9da5b12f --- /dev/null +++ b/server/controllers/get.go @@ -0,0 +1,70 @@ +package controllers + +import ( + "fmt" + "github.com/Xhofe/alist/alidrive" + "github.com/Xhofe/alist/conf" + "github.com/gin-gonic/gin" + "github.com/patrickmn/go-cache" + log "github.com/sirupsen/logrus" + "strings" +) + +func Get(c *gin.Context) { + var get alidrive.GetReq + if err := c.ShouldBindJSON(&get); err != nil { + c.JSON(200,metaResponse(400,"Bad Request")) + return + } + log.Debugf("get:%v",get) + // cache + cacheKey:=fmt.Sprintf("%s-%s","g",get.FileId) + if conf.Conf.Cache.Enable { + file,exist:=conf.Cache.Get(cacheKey) + if exist { + log.Debugf("使用了缓存:%s",cacheKey) + c.JSON(200,dataResponse(file)) + return + } + } + file,err:=alidrive.GetFile(get.FileId) + if err !=nil { + c.JSON(200,metaResponse(500,err.Error())) + return + } + paths,err:=alidrive.GetPaths(get.FileId) + if err!=nil { + c.JSON(200,metaResponse(500,err.Error())) + return + } + file.Paths=*paths + if conf.Conf.Cache.Enable { + conf.Cache.Set(cacheKey,file,cache.DefaultExpiration) + } + c.JSON(200,dataResponse(file)) +} + +func Down(c *gin.Context) { + fileIdParam:=c.Param("file_id") + log.Debugf("down:%s",fileIdParam) + fileId:=strings.Split(fileIdParam,"/")[1] + cacheKey:=fmt.Sprintf("%s-%s","d",fileId) + if conf.Conf.Cache.Enable { + downloadUrl,exist:=conf.Cache.Get(cacheKey) + if exist { + log.Debugf("使用了缓存:%s",cacheKey) + c.Redirect(301,downloadUrl.(string)) + return + } + } + file,err:=alidrive.GetFile(fileId) + if err != nil { + c.JSON(200, metaResponse(500,err.Error())) + return + } + if conf.Conf.Cache.Enable { + conf.Cache.Set(cacheKey,file.DownloadUrl,cache.DefaultExpiration) + } + c.Redirect(301,file.DownloadUrl) + return +} \ No newline at end of file diff --git a/server/controllers/list.go b/server/controllers/list.go new file mode 100644 index 00000000000..acd9f89670d --- /dev/null +++ b/server/controllers/list.go @@ -0,0 +1,68 @@ +package controllers + +import ( + "fmt" + "github.com/Xhofe/alist/alidrive" + "github.com/Xhofe/alist/conf" + "github.com/gin-gonic/gin" + "github.com/patrickmn/go-cache" + log "github.com/sirupsen/logrus" +) + +func List(c *gin.Context) { + var list ListReq + if err := c.ShouldBindJSON(&list);err!=nil { + c.JSON(200, metaResponse(400,"Bad Request")) + return + } + log.Debugf("list:%v",list) + // cache + cacheKey:=fmt.Sprintf("%s-%s-%s","l",list.ParentFileId,list.Password) + if conf.Conf.Cache.Enable { + files,exist:=conf.Cache.Get(cacheKey) + if exist { + log.Debugf("使用了缓存:%s",cacheKey) + c.JSON(200, dataResponse(files)) + return + } + } + var ( + files *alidrive.Files + err error + ) + if list.Limit == 0 { + list.Limit=50 + } + if conf.Conf.AliDrive.MaxFilesCount!=0 { + list.Limit=conf.Conf.AliDrive.MaxFilesCount + } + if list.ParentFileId == "root" { + files,err=alidrive.GetRoot(list.Limit,list.Marker,list.OrderBy,list.OrderDirection) + }else { + files,err=alidrive.GetList(list.ParentFileId,list.Limit,list.Marker,list.OrderBy,list.OrderDirection) + } + if err!=nil { + c.JSON(200, metaResponse(500,err.Error())) + return + } + password:=alidrive.HasPassword(files) + if password!="" && password!=list.Password { + if list.Password=="" { + c.JSON(200, metaResponse(401,"need password.")) + return + } + c.JSON(200, metaResponse(401,"wrong password.")) + return + } + paths,err:=alidrive.GetPaths(list.ParentFileId) + if err!=nil { + c.JSON(200, metaResponse(500,err.Error())) + return + } + files.Paths=*paths + files.Readme=alidrive.HasReadme(files) + if conf.Conf.Cache.Enable { + conf.Cache.Set(cacheKey,files,cache.DefaultExpiration) + } + c.JSON(200, dataResponse(files)) +} \ No newline at end of file diff --git a/server/req_bean.go b/server/controllers/req_bean.go similarity index 85% rename from server/req_bean.go rename to server/controllers/req_bean.go index 2c335b4d888..d964463fdb1 100644 --- a/server/req_bean.go +++ b/server/controllers/req_bean.go @@ -1,4 +1,4 @@ -package server +package controllers import "github.com/Xhofe/alist/alidrive" diff --git a/server/controllers/search.go b/server/controllers/search.go new file mode 100644 index 00000000000..bb831dd1869 --- /dev/null +++ b/server/controllers/search.go @@ -0,0 +1,49 @@ +package controllers + +import ( + "fmt" + "github.com/Xhofe/alist/alidrive" + "github.com/Xhofe/alist/conf" + "github.com/gin-gonic/gin" + "github.com/patrickmn/go-cache" + log "github.com/sirupsen/logrus" +) + +func Search(c *gin.Context) { + if !conf.Conf.Server.Search { + c.JSON(200, metaResponse(403,"Not allow search.")) + return + } + var search alidrive.SearchReq + if err := c.ShouldBindJSON(&search); err != nil { + c.JSON(200, metaResponse(400,"Bad Request")) + return + } + log.Debugf("search:%v",search) + // cache + cacheKey:=fmt.Sprintf("%s-%s","s",search.Query) + if conf.Conf.Cache.Enable { + files,exist:=conf.Cache.Get(cacheKey) + if exist { + log.Debugf("使用了缓存:%s",cacheKey) + c.JSON(200, dataResponse(files)) + return + } + } + if search.Limit == 0 { + search.Limit=50 + } + // Search只支持0-100 + //if conf.Conf.AliDrive.MaxFilesCount!=0 { + // search.Limit=conf.Conf.AliDrive.MaxFilesCount + //} + files,err:=alidrive.Search(search.Query,search.Limit,search.OrderBy) + if err != nil { + c.JSON(200, metaResponse(500,err.Error())) + return + } + if conf.Conf.Cache.Enable { + conf.Cache.Set(cacheKey,files,cache.DefaultExpiration) + } + c.JSON(200, dataResponse(files)) +} \ No newline at end of file diff --git a/server/controllers/utils.go b/server/controllers/utils.go new file mode 100644 index 00000000000..971a96aaf46 --- /dev/null +++ b/server/controllers/utils.go @@ -0,0 +1,25 @@ +package controllers + +import ( + "github.com/Xhofe/alist/conf" + "github.com/gin-gonic/gin" +) + +func Info(c *gin.Context) { + c.JSON(200, dataResponse(conf.Conf.Info)) +} + +func RefreshCache(c *gin.Context) { + password:=c.Param("password") + if conf.Conf.Cache.Enable { + if password == conf.Conf.Cache.RefreshPassword { + conf.Cache.Flush() + c.JSON(200,metaResponse(200,"flush success.")) + return + } + c.JSON(200,metaResponse(401,"wrong password.")) + return + } + c.JSON(200,metaResponse(400,"disabled cache.")) + return +} \ No newline at end of file diff --git a/server/middlewares.go b/server/middlewares.go index b696c48852b..bf121b06c52 100644 --- a/server/middlewares.go +++ b/server/middlewares.go @@ -19,7 +19,7 @@ func CrosHandler() gin.HandlerFunc { //context.Set("content-type", "application/json") //设置返回格式是json if method == "OPTIONS" { - context.JSON(http.StatusOK, metaResponse(200,"Options Request!")) + context.JSON(http.StatusOK, gin.H{}) } //处理请求 diff --git a/server/router.go b/server/router.go index 215d381980e..8f47cdda16d 100644 --- a/server/router.go +++ b/server/router.go @@ -2,6 +2,7 @@ package server import ( "github.com/Xhofe/alist/conf" + "github.com/Xhofe/alist/server/controllers" "github.com/gin-contrib/static" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" @@ -20,10 +21,11 @@ func InitApiRouter(engine *gin.Engine) { }) v2:=engine.Group("/api") { - v2.GET("/info",Info) - v2.POST("/get",Get) - v2.POST("/list",List) - v2.POST("/search",Search) + v2.GET("/info",controllers.Info) + v2.POST("/get",controllers.Get) + v2.POST("/list",controllers.List) + v2.POST("/search",controllers.Search) } - engine.GET("/d/*file_id",Down) + engine.GET("/d/*file_id",controllers.Down) + engine.GET("/cache/:password",controllers.RefreshCache) } \ No newline at end of file