🎇 多盘支持

This commit is contained in:
微凉
2021-03-16 21:25:16 +08:00
parent 8e9ddcf81e
commit 4d0d892ce7
19 changed files with 177 additions and 173 deletions

View File

@ -2,77 +2,44 @@ package alidrive
import ( import (
"encoding/json" "encoding/json"
"fmt"
"github.com/Xhofe/alist/conf" "github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/utils" "github.com/Xhofe/alist/utils"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// use token login
func TokenLogin() (*TokenLoginResp, error) {
log.Infof("尝试使用token登录...")
url := "https://auth.aliyundrive.com/v2/oauth/token_login"
req := TokenLoginReq{Token: conf.Conf.AliDrive.LoginToken}
log.Debugf("token_login_req:%+v", req)
var tokenLogin TokenLoginResp
if body, err := DoPost(url, req, false); err != nil {
log.Errorf("tokenLogin-doPost出错:%s", err.Error())
return nil, err
} else {
if err = json.Unmarshal(body, &tokenLogin); err != nil {
log.Errorf("解析json[%s]出错:%s", string(body), err.Error())
return nil, err
}
}
if tokenLogin.IsAvailable() {
return &tokenLogin, nil
}
return nil, fmt.Errorf("登录token失效,请更换:%s", tokenLogin.Message)
}
// get access token
func GetToken(tokenLogin *TokenLoginResp) (*TokenResp, error) {
log.Infof("获取API token...")
url := "https://websv.aliyundrive.com/token/get"
code := utils.GetCode(tokenLogin.Goto)
if code == "" {
return nil, fmt.Errorf("获取code出错")
}
req := GetTokenReq{Code: code}
var token TokenResp
if body, err := DoPost(url, req, false); err != nil {
log.Errorf("tokenLogin-doPost出错:%s", err.Error())
return nil, err
} else {
if err = json.Unmarshal(body, &token); err != nil {
log.Errorf("解析json[%s]出错:%s", string(body), err.Error())
log.Errorf("此处json解析失败应该是code失效")
return nil, fmt.Errorf("code失效")
}
}
return &token, nil
}
// refresh access_token token by refresh_token // refresh access_token token by refresh_token
func RefreshToken() bool { func RefreshToken(drive *conf.Drive) bool {
log.Infof("刷新token...") log.Infof("刷新[%s]token...", drive.Name)
url := "https://websv.aliyundrive.com/token/refresh" url := "https://websv.aliyundrive.com/token/refresh"
req := RefreshTokenReq{RefreshToken: conf.Conf.AliDrive.RefreshToken} req := RefreshTokenReq{RefreshToken: drive.RefreshToken}
var token TokenResp var token TokenResp
if body, err := DoPost(url, req, false); err != nil { if body, err := DoPost(url, req, ""); err != nil {
log.Errorf("tokenLogin-doPost出错:%s", err.Error()) log.Errorf("tokenLogin-doPost出错:%s", err.Error())
return false return false
} else { } else {
if err = json.Unmarshal(body, &token); err != nil { if err = json.Unmarshal(body, &token); err != nil {
log.Errorf("解析json[%s]出错:%s", string(body), err.Error()) log.Errorf("解析json[%s]出错:%s", string(body), err.Error())
log.Errorf("此处json解析失败应该是refresh_token失效") log.Errorf("此处json解析失败应该是[%s]refresh_token失效", drive.Name)
return false return false
} }
} }
//刷新成功 更新token并写入文件 //刷新成功 更新token
conf.Conf.AliDrive.AccessToken = token.AccessToken drive.AccessToken = token.AccessToken
conf.Conf.AliDrive.RefreshToken = token.RefreshToken drive.RefreshToken = token.RefreshToken
conf.Authorization = token.TokenType + "\t" + token.AccessToken
utils.WriteToYml(conf.Con, conf.Conf)
return true return true
} }
func RefreshTokenAll() string {
log.Infof("刷新所有token...")
res := ""
for i, drive := range conf.Conf.AliDrive.Drives {
if !RefreshToken(&conf.Conf.AliDrive.Drives[i]) {
res = res + drive.Name + ","
}
}
utils.WriteToYml(conf.ConfigFile, conf.Conf)
if res != "" {
return res[:len(res)-1]
}
return ""
}

View File

@ -1,5 +0,0 @@
package alidrive
var (
User *UserInfo
)

View File

@ -13,41 +13,41 @@ import (
) )
// get file // get file
func GetFile(fileId string) (*File, error) { func GetFile(fileId string, drive *conf.Drive) (*File, error) {
url := conf.Conf.AliDrive.ApiUrl + "/file/get" url := conf.Conf.AliDrive.ApiUrl + "/file/get"
req := GetReq{ req := GetReq{
DriveId: User.DefaultDriveId, DriveId: drive.DefaultDriveId,
FileId: fileId, FileId: fileId,
ImageThumbnailProcess: conf.ImageThumbnailProcess, ImageThumbnailProcess: conf.ImageThumbnailProcess,
VideoThumbnailProcess: conf.VideoThumbnailProcess, VideoThumbnailProcess: conf.VideoThumbnailProcess,
} }
var resp File var resp File
if err := BodyToJson(url, req, &resp, true); err != nil { if err := BodyToJson(url, req, &resp, drive); err != nil {
return nil, err return nil, err
} }
return &resp, nil return &resp, nil
} }
// get download_url // get download_url
func GetDownLoadUrl(fileId string) (*DownloadResp, error) { func GetDownLoadUrl(fileId string, drive *conf.Drive) (*DownloadResp, error) {
url := conf.Conf.AliDrive.ApiUrl + "/file/get_download_url" url := conf.Conf.AliDrive.ApiUrl + "/file/get_download_url"
req := DownloadReq{ req := DownloadReq{
DriveId: User.DefaultDriveId, DriveId: drive.DefaultDriveId,
FileId: fileId, FileId: fileId,
ExpireSec: 14400, ExpireSec: 14400,
} }
var resp DownloadResp var resp DownloadResp
if err := BodyToJson(url, req, &resp, true); err != nil { if err := BodyToJson(url, req, &resp, drive); err != nil {
return nil, err return nil, err
} }
return &resp, nil return &resp, nil
} }
// search by keyword // search by keyword
func Search(key string, limit int, marker string) (*Files, error) { func Search(key string, limit int, marker string, drive *conf.Drive) (*Files, error) {
url := conf.Conf.AliDrive.ApiUrl + "/file/search" url := conf.Conf.AliDrive.ApiUrl + "/file/search"
req := SearchReq{ req := SearchReq{
DriveId: User.DefaultDriveId, DriveId: drive.DefaultDriveId,
ImageThumbnailProcess: conf.ImageThumbnailProcess, ImageThumbnailProcess: conf.ImageThumbnailProcess,
ImageUrlProcess: conf.ImageUrlProcess, ImageUrlProcess: conf.ImageUrlProcess,
Limit: limit, Limit: limit,
@ -57,22 +57,22 @@ func Search(key string, limit int, marker string) (*Files, error) {
VideoThumbnailProcess: conf.VideoThumbnailProcess, VideoThumbnailProcess: conf.VideoThumbnailProcess,
} }
var resp Files var resp Files
if err := BodyToJson(url, req, &resp, true); err != nil { if err := BodyToJson(url, req, &resp, drive); err != nil {
return nil, err return nil, err
} }
return &resp, nil return &resp, nil
} }
// get root folder // get root folder
func GetRoot(limit int, marker string, orderBy string, orderDirection string) (*Files, error) { func GetRoot(limit int, marker string, orderBy string, orderDirection string, drive *conf.Drive) (*Files, error) {
return GetList(conf.Conf.AliDrive.RootFolder, limit, marker, orderBy, orderDirection) return GetList(drive.RootFolder, limit, marker, orderBy, orderDirection, drive)
} }
// get folder list by file_id // get folder list by file_id
func GetList(parent string, limit int, marker string, orderBy string, orderDirection string) (*Files, error) { func GetList(parent string, limit int, marker string, orderBy string, orderDirection string, drive *conf.Drive) (*Files, error) {
url := conf.Conf.AliDrive.ApiUrl + "/file/list" url := conf.Conf.AliDrive.ApiUrl + "/file/list"
req := ListReq{ req := ListReq{
DriveId: User.DefaultDriveId, DriveId: drive.DefaultDriveId,
Fields: "*", Fields: "*",
ImageThumbnailProcess: conf.ImageThumbnailProcess, ImageThumbnailProcess: conf.ImageThumbnailProcess,
ImageUrlProcess: conf.ImageUrlProcess, ImageUrlProcess: conf.ImageUrlProcess,
@ -84,40 +84,40 @@ func GetList(parent string, limit int, marker string, orderBy string, orderDirec
VideoThumbnailProcess: conf.VideoThumbnailProcess, VideoThumbnailProcess: conf.VideoThumbnailProcess,
} }
var resp Files var resp Files
if err := BodyToJson(url, req, &resp, true); err != nil { if err := BodyToJson(url, req, &resp, drive); err != nil {
return nil, err return nil, err
} }
return &resp, nil return &resp, nil
} }
// get user info // get user info
func GetUserInfo() (*UserInfo, error) { func GetUserInfo(drive *conf.Drive) (*UserInfo, error) {
url := conf.Conf.AliDrive.ApiUrl + "/user/get" url := conf.Conf.AliDrive.ApiUrl + "/user/get"
var resp UserInfo var resp UserInfo
if err := BodyToJson(url, map[string]interface{}{}, &resp, true); err != nil { if err := BodyToJson(url, map[string]interface{}{}, &resp, drive); err != nil {
return nil, err return nil, err
} }
return &resp, nil return &resp, nil
} }
// get office preview url and token // get office preview url and token
func GetOfficePreviewUrl(fileId string) (*OfficePreviewUrlResp, error) { func GetOfficePreviewUrl(fileId string, drive *conf.Drive) (*OfficePreviewUrlResp, error) {
url := conf.Conf.AliDrive.ApiUrl + "/file/get_office_preview_url" url := conf.Conf.AliDrive.ApiUrl + "/file/get_office_preview_url"
req := OfficePreviewUrlReq{ req := OfficePreviewUrlReq{
AccessToken: conf.Conf.AliDrive.AccessToken, AccessToken: drive.AccessToken,
DriveId: User.DefaultDriveId, DriveId: drive.DefaultDriveId,
FileId: fileId, FileId: fileId,
} }
var resp OfficePreviewUrlResp var resp OfficePreviewUrlResp
if err := BodyToJson(url, req, &resp, true); err != nil { if err := BodyToJson(url, req, &resp, drive); err != nil {
return nil, err return nil, err
} }
return &resp, nil return &resp, nil
} }
// convert body to json // convert body to json
func BodyToJson(url string, req interface{}, resp RespHandle, auth bool) error { func BodyToJson(url string, req interface{}, resp RespHandle, drive *conf.Drive) error {
if body, err := DoPost(url, req, auth); err != nil { if body, err := DoPost(url, req, drive.AccessToken); err != nil {
log.Errorf("doPost出错:%s", err.Error()) log.Errorf("doPost出错:%s", err.Error())
return err return err
} else { } else {
@ -131,15 +131,15 @@ func BodyToJson(url string, req interface{}, resp RespHandle, auth bool) error {
} }
if resp.GetCode() == conf.AccessTokenInvalid { if resp.GetCode() == conf.AccessTokenInvalid {
resp.SetCode("") resp.SetCode("")
if RefreshToken() { if RefreshToken(drive) {
return BodyToJson(url, req, resp, auth) return BodyToJson(url, req, resp, drive)
} }
} }
return fmt.Errorf(resp.GetMessage()) return fmt.Errorf(resp.GetMessage())
} }
// do post request // do post request
func DoPost(url string, request interface{}, auth bool) (body []byte, err error) { func DoPost(url string, request interface{}, auth string) (body []byte, err error) {
var ( var (
resp *http.Response resp *http.Response
) )
@ -154,8 +154,8 @@ func DoPost(url string, request interface{}, auth bool) (body []byte, err error)
log.Errorf("创建request出错:%s", err.Error()) log.Errorf("创建request出错:%s", err.Error())
return return
} }
if auth { if auth != "" {
req.Header.Set("authorization", conf.Authorization) req.Header.Set("authorization", conf.Bearer + auth)
} }
req.Header.Add("content-type", "application/json") req.Header.Add("content-type", "application/json")
req.Header.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36") req.Header.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")
@ -181,24 +181,3 @@ func DoPost(url string, request interface{}, auth bool) (body []byte, err error)
log.Debugf("请求返回信息:%s", string(body)) log.Debugf("请求返回信息:%s", string(body))
return return
} }
func GetPaths(fileId string) (*[]Path, error) {
paths := make([]Path, 0)
for fileId != conf.Conf.AliDrive.RootFolder && fileId != "root" {
file, err := GetFile(fileId)
if err != nil {
log.Errorf("获取path出错:%s", err.Error())
return nil, err
}
paths = append(paths, Path{
Name: file.Name,
FileId: file.FileId,
})
fileId = file.ParentFileId
}
paths = append(paths, Path{
Name: "Root",
FileId: "root",
})
return &paths, nil
}

View File

@ -10,28 +10,24 @@ import (
func InitAliDrive() bool { func InitAliDrive() bool {
log.Infof("初始化阿里云盘...") log.Infof("初始化阿里云盘...")
//首先token_login //首先token_login
if conf.Conf.AliDrive.RefreshToken == "" { res := alidrive.RefreshTokenAll()
tokenLogin, err := alidrive.TokenLogin() if res != "" {
if err != nil { log.Errorf("盘[%s]refresh_token失效,请检查", res)
log.Errorf("登录失败:%s", err.Error())
return false
}
//然后get_token
token, err := alidrive.GetToken(tokenLogin)
if err != nil {
return false
}
conf.Authorization = token.TokenType + "\t" + token.AccessToken
} else {
conf.Authorization = conf.Bearer + conf.Conf.AliDrive.AccessToken
} }
log.Debugf("token:%s", conf.Authorization) log.Debugf("config:%+v", conf.Conf)
user, err := alidrive.GetUserInfo() for i, _ := range conf.Conf.AliDrive.Drives {
if err != nil { InitDriveId(&conf.Conf.AliDrive.Drives[i])
log.Errorf("初始化用户失败:%s", err.Error())
return false
} }
log.Infof("当前用户信息:%+v", user) return true
alidrive.User = user }
func InitDriveId(drive *conf.Drive) bool {
user, err := alidrive.GetUserInfo(drive)
if err != nil {
log.Errorf("初始化盘[%s]失败:%s", drive.Name, err.Error())
return false
}
drive.DefaultDriveId = user.DefaultDriveId
log.Infof("初始化盘[%s]成功:%+v", drive.Name, user)
return true return true
} }

View File

@ -13,7 +13,7 @@ func init() {
flag.BoolVar(&conf.Debug, "debug", false, "use debug mode") flag.BoolVar(&conf.Debug, "debug", false, "use debug mode")
flag.BoolVar(&conf.Help, "help", false, "show usage help") flag.BoolVar(&conf.Help, "help", false, "show usage help")
flag.BoolVar(&conf.Version, "version", false, "show version info") flag.BoolVar(&conf.Version, "version", false, "show version info")
flag.StringVar(&conf.Con, "conf", "conf.yml", "config file") flag.StringVar(&conf.ConfigFile, "conf", "conf.yml", "config file")
flag.BoolVar(&conf.SkipUpdate, "skip-update", false, "skip update") flag.BoolVar(&conf.SkipUpdate, "skip-update", false, "skip update")
} }
@ -52,7 +52,7 @@ func start() {
if !conf.SkipUpdate { if !conf.SkipUpdate {
CheckUpdate() CheckUpdate()
} }
if !ReadConf(conf.Con) { if !ReadConf(conf.ConfigFile) {
log.Errorf("读取配置文件时出现错误,启动失败.") log.Errorf("读取配置文件时出现错误,启动失败.")
return return
} }

View File

@ -27,6 +27,7 @@ func ReadConf(config string) bool {
return false return false
} }
log.Debugf("config:%+v", conf.Conf) log.Debugf("config:%+v", conf.Conf)
conf.Conf.Info.Roots = utils.GetNames()
conf.Origins = strings.Split(conf.Conf.Server.SiteUrl, ",") conf.Origins = strings.Split(conf.Conf.Server.SiteUrl, ",")
return true return true
} }

View File

@ -10,7 +10,7 @@ var Cron *cron.Cron
// refresh token func for cron // refresh token func for cron
func refreshToken() { func refreshToken() {
alidrive.RefreshToken() alidrive.RefreshTokenAll()
} }
// init cron jobs // init cron jobs

View File

@ -33,9 +33,7 @@ func InitModel() bool {
log.Errorf("数据库迁移失败:%s", err.Error()) log.Errorf("数据库迁移失败:%s", err.Error())
return false return false
} }
if err := models.BuildTree(); err != nil { models.BuildTreeAll()
log.Errorf("构建目录树失败:%s", err.Error())
}
} }
return true return true
} }

View File

@ -1,16 +1,27 @@
package conf package conf
type Drive struct {
AccessToken string `yaml:"-"`
RefreshToken string `yaml:"refresh_token"`
RootFolder string `yaml:"root_folder"` //根目录id
Name string `yaml:"name"`
Password string `yaml:"password"`
Hide bool `yaml:"hide"`
DefaultDriveId string `yaml:"-"`
}
// config struct // config struct
type Config struct { type Config struct {
Info struct { Info struct {
Title string `yaml:"title" json:"title"` Title string `yaml:"title" json:"title"`
Logo string `yaml:"logo" json:"logo"` Roots []string `yaml:"-" json:"roots"`
FooterText string `yaml:"footer_text" json:"footer_text"` Logo string `yaml:"logo" json:"logo"`
FooterUrl string `yaml:"footer_url" json:"footer_url"` FooterText string `yaml:"footer_text" json:"footer_text"`
MusicImg string `yaml:"music_img" json:"music_img"` FooterUrl string `yaml:"footer_url" json:"footer_url"`
CheckUpdate bool `yaml:"check_update" json:"check_update"` MusicImg string `yaml:"music_img" json:"music_img"`
Script string `yaml:"script" json:"script"` CheckUpdate bool `yaml:"check_update" json:"check_update"`
Autoplay bool `yaml:"autoplay" json:"autoplay"` Script string `yaml:"script" json:"script"`
Autoplay bool `yaml:"autoplay" json:"autoplay"`
Preview struct { Preview struct {
Url string `yaml:"url" json:"url"` Url string `yaml:"url" json:"url"`
PreProcess []string `yaml:"pre_process" json:"pre_process"` PreProcess []string `yaml:"pre_process" json:"pre_process"`
@ -27,13 +38,9 @@ type Config struct {
Password string `yaml:"password"` Password string `yaml:"password"`
} `yaml:"server"` } `yaml:"server"`
AliDrive struct { AliDrive struct {
ApiUrl string `yaml:"api_url"` //阿里云盘api ApiUrl string `yaml:"api_url"` //阿里云盘api
RootFolder string `yaml:"root_folder"` //根目录id MaxFilesCount int `yaml:"max_files_count"`
//Authorization string `yaml:"authorization"`//授权token Drives []Drive `yaml:"drives"`
LoginToken string `yaml:"login_token"`
AccessToken string `yaml:"access_token"`
RefreshToken string `yaml:"refresh_token"`
MaxFilesCount int `yaml:"max_files_count"`
} `yaml:"ali_drive"` } `yaml:"ali_drive"`
Database struct { Database struct {
Type string `yaml:"type"` Type string `yaml:"type"`

View File

@ -9,11 +9,10 @@ var (
Debug bool // is debug command Debug bool // is debug command
Help bool // is help command Help bool // is help command
Version bool // is print version command Version bool // is print version command
Con string // config file ConfigFile string // config file
SkipUpdate bool // skip update SkipUpdate bool // skip update
Client *http.Client // request client Client *http.Client // request client
Authorization string // authorization string
DB *gorm.DB DB *gorm.DB

View File

@ -7,6 +7,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"path/filepath" "path/filepath"
"strings"
) )
type DownReq struct { type DownReq struct {
@ -44,7 +45,12 @@ func Down(c *gin.Context) {
c.JSON(200, MetaResponse(406, "无法下载目录.")) c.JSON(200, MetaResponse(406, "无法下载目录."))
return return
} }
file, err := alidrive.GetDownLoadUrl(fileModel.FileId) drive := utils.GetDriveByName(strings.Split(dir,"/")[0])
if drive == nil {
c.JSON(200, MetaResponse(500, "找不到drive."))
return
}
file, err := alidrive.GetDownLoadUrl(fileModel.FileId, drive)
if err != nil { if err != nil {
c.JSON(200, MetaResponse(500, err.Error())) c.JSON(200, MetaResponse(500, err.Error()))
return return

View File

@ -3,9 +3,11 @@ package controllers
import ( import (
"github.com/Xhofe/alist/alidrive" "github.com/Xhofe/alist/alidrive"
"github.com/Xhofe/alist/server/models" "github.com/Xhofe/alist/server/models"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"path/filepath" "path/filepath"
"strings"
) )
// get request bean // get request bean
@ -40,7 +42,12 @@ func Get(c *gin.Context) {
} }
return return
} }
down, err := alidrive.GetDownLoadUrl(file.FileId) drive := utils.GetDriveByName(strings.Split(dir,"/")[0])
if drive == nil {
c.JSON(200, MetaResponse(500, "找不到drive."))
return
}
down, err := alidrive.GetDownLoadUrl(file.FileId, drive)
if err != nil { if err != nil {
c.JSON(200, MetaResponse(500, err.Error())) c.JSON(200, MetaResponse(500, err.Error()))
return return

View File

@ -2,6 +2,7 @@ package controllers
import ( import (
"github.com/Xhofe/alist/alidrive" "github.com/Xhofe/alist/alidrive"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@ -12,13 +13,18 @@ type OfficePreviewReq struct {
// handle office_preview request // handle office_preview request
func OfficePreview(c *gin.Context) { func OfficePreview(c *gin.Context) {
drive := utils.GetDriveByName(c.Param("drive"))
if drive == nil {
c.JSON(200, MetaResponse(400, "drive isn't exist."))
return
}
var req OfficePreviewReq var req OfficePreviewReq
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(200, MetaResponse(400, "Bad Request:"+err.Error())) c.JSON(200, MetaResponse(400, "Bad Request:"+err.Error()))
return return
} }
log.Debugf("preview_req:%+v", req) log.Debugf("preview_req:%+v", req)
preview, err := alidrive.GetOfficePreviewUrl(req.FileId) preview, err := alidrive.GetOfficePreviewUrl(req.FileId, drive)
if err != nil { if err != nil {
c.JSON(200, MetaResponse(500, err.Error())) c.JSON(200, MetaResponse(500, err.Error()))
return return

View File

@ -55,7 +55,11 @@ func Path(c *gin.Context) {
} }
// delete password // delete password
for i, _ := range *files { for i, _ := range *files {
(*files)[i].Password = "" if (*files)[i].Password == "" {
(*files)[i].Password = "n"
}else {
(*files)[i].Password = "y"
}
} }
c.JSON(200, DataResponse(files)) c.JSON(200, DataResponse(files))
} }

View File

@ -3,6 +3,7 @@ package controllers
import ( import (
"github.com/Xhofe/alist/conf" "github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/server/models" "github.com/Xhofe/alist/server/models"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -13,7 +14,12 @@ func Info(c *gin.Context) {
// rebuild tree // rebuild tree
func RebuildTree(c *gin.Context) { func RebuildTree(c *gin.Context) {
password := c.Param("password")[1:] drive := utils.GetDriveByName(c.Param("drive"))
if drive == nil {
c.JSON(200, MetaResponse(400, "drive isn't exist."))
return
}
password := c.Param("password")
if password != conf.Conf.Server.Password { if password != conf.Conf.Server.Password {
if password == "" { if password == "" {
c.JSON(200, MetaResponse(401, "need password.")) c.JSON(200, MetaResponse(401, "need password."))
@ -22,11 +28,11 @@ func RebuildTree(c *gin.Context) {
c.JSON(200, MetaResponse(401, "wrong password.")) c.JSON(200, MetaResponse(401, "wrong password."))
return return
} }
if err := models.Clear(); err != nil { if err := models.Clear(drive); err != nil {
c.JSON(200, MetaResponse(500, err.Error())) c.JSON(200, MetaResponse(500, err.Error()))
return return
} }
if err := models.BuildTree(); err != nil { if err := models.BuildTree(drive); err != nil {
c.JSON(200, MetaResponse(500, err.Error())) c.JSON(200, MetaResponse(500, err.Error()))
return return
} }

View File

@ -9,8 +9,18 @@ import (
"strings" "strings"
) )
func BuildTreeAll() {
for i, _ := range conf.Conf.AliDrive.Drives {
if err := BuildTree(&conf.Conf.AliDrive.Drives[i]); err != nil {
log.Errorf("盘[%s]构建目录树失败:%s", err.Error())
}else {
log.Infof("盘[%s]构建目录树成功")
}
}
}
// build tree // build tree
func BuildTree() error { func BuildTree(drive *conf.Drive) error {
log.Infof("开始构建目录树...") log.Infof("开始构建目录树...")
tx := conf.DB.Begin() tx := conf.DB.Begin()
defer func() { defer func() {
@ -22,24 +32,25 @@ func BuildTree() error {
return err return err
} }
rootFile := File{ rootFile := File{
Dir: "", Dir: "",
FileId: conf.Conf.AliDrive.RootFolder, FileId: drive.RootFolder,
Name: "root", Name: drive.Name,
Type: "folder", Type: "folder",
Password: drive.Password,
} }
if err := tx.Create(&rootFile).Error; err != nil { if err := tx.Create(&rootFile).Error; err != nil {
tx.Rollback() tx.Rollback()
return err return err
} }
if err := BuildOne(conf.Conf.AliDrive.RootFolder, "root/", tx, ""); err != nil { if err := BuildOne(drive.RootFolder, drive.Name+"/", tx, drive.Password, drive); err != nil {
tx.Rollback() tx.Rollback()
return err return err
} }
return tx.Commit().Error return tx.Commit().Error
} }
func BuildOne(parent string, path string, tx *gorm.DB, parentPassword string) error { func BuildOne(parent string, path string, tx *gorm.DB, parentPassword string, drive *conf.Drive) error {
files, err := alidrive.GetList(parent, conf.Conf.AliDrive.MaxFilesCount, "", "", "") files, err := alidrive.GetList(parent, conf.Conf.AliDrive.MaxFilesCount, "", "", "", drive)
if err != nil { if err != nil {
return err return err
} }
@ -71,7 +82,7 @@ func BuildOne(parent string, path string, tx *gorm.DB, parentPassword string) er
return err return err
} }
if file.Type == "folder" { if file.Type == "folder" {
if err := BuildOne(file.FileId, fmt.Sprintf("%s%s/", path, name), tx, password); err != nil { if err := BuildOne(file.FileId, fmt.Sprintf("%s%s/", path, name), tx, password, drive); err != nil {
return err return err
} }
} }

View File

@ -24,8 +24,8 @@ func (file *File) Create() error {
return conf.DB.Create(file).Error return conf.DB.Create(file).Error
} }
func Clear() error { func Clear(drive *conf.Drive) error {
return conf.DB.Where("1 = 1").Delete(&File{}).Error return conf.DB.Where("dir like ?", fmt.Sprintf("%s%%", drive.Name)).Delete(&File{}).Error
} }
func GetFileByDirAndName(dir, name string) (*File, error) { func GetFileByDirAndName(dir, name string) (*File, error) {

View File

@ -26,10 +26,10 @@ func InitApiRouter(engine *gin.Engine) {
apiV2.GET("/info", controllers.Info) apiV2.GET("/info", controllers.Info)
apiV2.POST("/get", controllers.Get) apiV2.POST("/get", controllers.Get)
apiV2.POST("/path", controllers.Path) apiV2.POST("/path", controllers.Path)
apiV2.POST("/office_preview", controllers.OfficePreview) apiV2.POST("/office_preview/:drive", controllers.OfficePreview)
apiV2.POST("/local_search", controllers.LocalSearch) apiV2.POST("/local_search", controllers.LocalSearch)
apiV2.POST("/global_search", controllers.GlobalSearch) apiV2.POST("/global_search", controllers.GlobalSearch)
apiV2.GET("/rebuild/*password", controllers.RebuildTree) apiV2.GET("/rebuild/:drive/:password", controllers.RebuildTree)
} }
engine.GET("/d/*path", controllers.Down) engine.GET("/d/*path", controllers.Down)
} }

22
utils/config.go Normal file
View File

@ -0,0 +1,22 @@
package utils
import "github.com/Xhofe/alist/conf"
func GetDriveByName(name string) *conf.Drive {
for i, drive := range conf.Conf.AliDrive.Drives{
if drive.Name == name {
return &conf.Conf.AliDrive.Drives[i]
}
}
return nil
}
func GetNames() []string {
res := make([]string, 0)
for _, drive := range conf.Conf.AliDrive.Drives{
if !drive.Hide {
res = append(res, drive.Name)
}
}
return res
}