🐎 加入缓存

This commit is contained in:
微凉
2020-12-29 13:37:58 +08:00
parent 02e665ae37
commit bf3f741b22
16 changed files with 270 additions and 138 deletions

15
bootstrap/cache.go Normal file
View File

@ -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)
}
}

View File

@ -48,6 +48,7 @@ func start() {
log.Errorf("初始化阿里云盘出现错误,启动失败.") log.Errorf("初始化阿里云盘出现错误,启动失败.")
return return
} }
InitCache()
InitCron() InitCron()
server() server()
} }

View File

@ -1,15 +1,22 @@
info: info:
title: AList title: AList #标题
site_url: http://localhost site_url: http://localhost:5277 #前端地址
logo: 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: server:
port: "5244" port: "5244" #程序监听端口
search: true search: true #是否开启搜索接口,开启搜索之后密码和根目录都会失效,所以前端暂时不做搜索
static: dist static: dist #前端文件目录
cache:
cache: true #是否开启缓存
expiration: 5 #缓存失效时间(单位:分钟)
cleanup_interval: 10 #清理失效缓存间隔
refresh_password: password #手动清理缓存密码
ali_drive: ali_drive:
api_url: https://api.aliyundrive.com/v2 api_url: https://api.aliyundrive.com/v2 #阿里云盘api,无需修改
root_folder: root root_folder: root #根目录
token:
access_token:
refresh_token: need refresh_token: need
max_files_count: 3000 max_files_count: 3000

View File

@ -15,6 +15,12 @@ type Config struct {
Search bool `yaml:"search" json:"search"`//允许搜索 Search bool `yaml:"search" json:"search"`//允许搜索
Static string `yaml:"static"` Static string `yaml:"static"`
} `yaml:"server"` } `yaml:"server"`
Cache struct{
Enable bool `yaml:"cache"`
Expiration int `yaml:"expiration"`
CleanupInterval int `yaml:"cleanup_interval"`
RefreshPassword string `yaml:"refresh_password"`
}
AliDrive struct{ AliDrive struct{
ApiUrl string `yaml:"api_url"`//阿里云盘api ApiUrl string `yaml:"api_url"`//阿里云盘api
RootFolder string `yaml:"root_folder"`//根目录id RootFolder string `yaml:"root_folder"`//根目录id

View File

@ -1,6 +1,7 @@
package conf package conf
import ( import (
"github.com/patrickmn/go-cache"
"net/http" "net/http"
) )
@ -10,6 +11,8 @@ var(
Con string Con string
Client *http.Client Client *http.Client
Authorization string Authorization string
Cache *cache.Cache
) )
var Conf = new(Config) var Conf = new(Config)

1
go.mod
View File

@ -11,6 +11,7 @@ require (
github.com/leodido/go-urn v1.2.1 // indirect github.com/leodido/go-urn v1.2.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // 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/robfig/cron/v3 v3.0.0
github.com/sirupsen/logrus v1.7.0 github.com/sirupsen/logrus v1.7.0
github.com/ugorji/go v1.2.2 // indirect github.com/ugorji/go v1.2.2 // indirect

3
go.sum
View File

@ -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 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 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 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/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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E= github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E=

View File

@ -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
}

View File

@ -1,4 +1,4 @@
package server package controllers
import "github.com/gin-gonic/gin" import "github.com/gin-gonic/gin"

70
server/controllers/get.go Normal file
View File

@ -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
}

View File

@ -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))
}

View File

@ -1,4 +1,4 @@
package server package controllers
import "github.com/Xhofe/alist/alidrive" import "github.com/Xhofe/alist/alidrive"

View File

@ -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))
}

View File

@ -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
}

View File

@ -19,7 +19,7 @@ func CrosHandler() gin.HandlerFunc {
//context.Set("content-type", "application/json") //设置返回格式是json //context.Set("content-type", "application/json") //设置返回格式是json
if method == "OPTIONS" { if method == "OPTIONS" {
context.JSON(http.StatusOK, metaResponse(200,"Options Request!")) context.JSON(http.StatusOK, gin.H{})
} }
//处理请求 //处理请求

View File

@ -2,6 +2,7 @@ package server
import ( import (
"github.com/Xhofe/alist/conf" "github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/server/controllers"
"github.com/gin-contrib/static" "github.com/gin-contrib/static"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -20,10 +21,11 @@ func InitApiRouter(engine *gin.Engine) {
}) })
v2:=engine.Group("/api") v2:=engine.Group("/api")
{ {
v2.GET("/info",Info) v2.GET("/info",controllers.Info)
v2.POST("/get",Get) v2.POST("/get",controllers.Get)
v2.POST("/list",List) v2.POST("/list",controllers.List)
v2.POST("/search",Search) v2.POST("/search",controllers.Search)
} }
engine.GET("/d/*file_id",Down) engine.GET("/d/*file_id",controllers.Down)
engine.GET("/cache/:password",controllers.RefreshCache)
} }