mirror of https://github.com/Xhofe/alist
✨ settings
parent
57ad66b43a
commit
0324ea1fcb
|
@ -67,7 +67,7 @@ func InitModel() {
|
|||
log.Fatalf("not supported database type: %s", config.Type)
|
||||
}
|
||||
log.Infof("auto migrate model")
|
||||
err := conf.DB.AutoMigrate(&model.SettingItem{}, &model.Account{},&model.Meta{})
|
||||
err := conf.DB.AutoMigrate(&model.SettingItem{}, &model.Account{}, &model.Meta{})
|
||||
if err != nil {
|
||||
log.Fatalf("failed to auto migrate")
|
||||
}
|
||||
|
@ -105,8 +105,9 @@ func initSettings() {
|
|||
version = &model.SettingItem{
|
||||
Key: "version",
|
||||
Value: "0.0.0",
|
||||
Type: "string",
|
||||
Description: "version",
|
||||
Type: model.CONST,
|
||||
Group: model.CONST,
|
||||
}
|
||||
}
|
||||
settingsMap := map[string][]model.SettingItem{
|
||||
|
@ -115,25 +116,29 @@ func initSettings() {
|
|||
Key: "title",
|
||||
Value: "Alist",
|
||||
Description: "title",
|
||||
Type: model.PUBLIC,
|
||||
Type: "string",
|
||||
Group: model.PUBLIC,
|
||||
},
|
||||
{
|
||||
Key: "password",
|
||||
Value: "alist",
|
||||
Type: "string",
|
||||
Description: "password",
|
||||
Type: model.PRIVATE,
|
||||
Group: model.PRIVATE,
|
||||
},
|
||||
{
|
||||
Key: "version",
|
||||
Value: "2.0.0",
|
||||
Type: "string",
|
||||
Description: "version",
|
||||
Type: model.CONST,
|
||||
Group: model.CONST,
|
||||
},
|
||||
{
|
||||
Key: "logo",
|
||||
Value: "",
|
||||
Type: "string",
|
||||
Description: "logo",
|
||||
Type: model.PUBLIC,
|
||||
Group: model.PUBLIC,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@ const (
|
|||
VIDEO
|
||||
AUDIO
|
||||
TEXT
|
||||
IMAGE
|
||||
)
|
|
@ -23,4 +23,5 @@ var (
|
|||
OfficeTypes = []string{"doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf"}
|
||||
VideoTypes = []string{"mp4", "mkv", "avi", "mov", "rmvb"}
|
||||
AudioTypes = []string{"mp3", "flac"}
|
||||
ImageTypes = []string{"jpg","jpeg","png","gif","bmp","svg"}
|
||||
)
|
||||
|
|
|
@ -24,7 +24,7 @@ func init() {
|
|||
SetHeader("origin", "https://aliyundrive.com")
|
||||
}
|
||||
|
||||
type AliDrive struct {}
|
||||
type AliDrive struct{}
|
||||
|
||||
func (a AliDrive) Items() []Item {
|
||||
return []Item{
|
||||
|
@ -73,12 +73,18 @@ type AliFile struct {
|
|||
}
|
||||
|
||||
func AliToFile(file AliFile) *model.File {
|
||||
return &model.File{
|
||||
f := &model.File{
|
||||
Name: file.Name,
|
||||
Size: file.Size,
|
||||
Type: utils.GetFileType(file.FileExtension),
|
||||
UpdatedAt: file.UpdatedAt,
|
||||
Thumbnail: file.Thumbnail,
|
||||
}
|
||||
if file.Type == "folder" {
|
||||
f.Type = conf.FOLDER
|
||||
} else {
|
||||
f.Type = utils.GetFileType(file.FileExtension)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (a AliDrive) GetFiles(fileId string, account *model.Account) ([]AliFile, error) {
|
||||
|
@ -105,6 +111,7 @@ func (a AliDrive) GetFiles(fileId string, account *model.Account) ([]AliFile, er
|
|||
"order_direction": account.OrderDirection,
|
||||
"parent_file_id": fileId,
|
||||
"video_thumbnail_process": "video/snapshot,t_0,f_jpg,w_50",
|
||||
//"url_expire_sec": 1600,
|
||||
})).Post("https://api.aliyundrive.com/v2/file/list")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -122,7 +129,7 @@ func (a AliDrive) GetFiles(fileId string, account *model.Account) ([]AliFile, er
|
|||
func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*model.File, error) {
|
||||
path = utils.ParsePath(path)
|
||||
log.Debugf("ali path: %s", path)
|
||||
cache, err := conf.Cache.Get(conf.Ctx, path)
|
||||
cache, err := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path))
|
||||
if err == nil {
|
||||
file, ok := cache.(AliFile)
|
||||
if ok {
|
||||
|
@ -144,7 +151,7 @@ func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*mod
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
parentFiles_, _ := conf.Cache.Get(conf.Ctx, dir)
|
||||
parentFiles_, _ := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, dir))
|
||||
parentFiles, _ := parentFiles_.([]AliFile)
|
||||
found := false
|
||||
for _, file := range parentFiles {
|
||||
|
@ -166,7 +173,7 @@ func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*mod
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
_ = conf.Cache.Set(conf.Ctx, path, files, nil)
|
||||
_ = conf.Cache.Set(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path), files, nil)
|
||||
res := make([]*model.File, 0)
|
||||
for _, file := range files {
|
||||
res = append(res, AliToFile(file))
|
||||
|
@ -244,6 +251,9 @@ func (a AliDrive) Save(account *model.Account, old *model.Account) error {
|
|||
if account.RootFolder == "" {
|
||||
account.RootFolder = "root"
|
||||
}
|
||||
if account.Limit == 0 {
|
||||
account.Limit = 200
|
||||
}
|
||||
refresh, access, err := AliRefreshToken(account.RefreshToken)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -12,7 +12,7 @@ type Account struct {
|
|||
RefreshToken string `json:"refresh_token"`
|
||||
AccessToken string `json:"access_token"`
|
||||
RootFolder string `json:"root_folder"`
|
||||
Status string
|
||||
Status string `json:"status"`
|
||||
CronId int
|
||||
DriveId string
|
||||
Limit int `json:"limit"`
|
||||
|
@ -74,10 +74,10 @@ func GetAccountFiles() []*File {
|
|||
return files
|
||||
}
|
||||
|
||||
func GetAccounts() []*Account {
|
||||
accounts := make([]*Account, 0)
|
||||
func GetAccounts() []Account {
|
||||
accounts := make([]Account, 0)
|
||||
for _, v := range accountsMap {
|
||||
accounts = append(accounts, &v)
|
||||
accounts = append(accounts, v)
|
||||
}
|
||||
return accounts
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@ type File struct {
|
|||
Size int64 `json:"size"`
|
||||
Type int `json:"type"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
}
|
||||
|
|
|
@ -14,16 +14,25 @@ type SettingItem struct {
|
|||
Key string `json:"key" gorm:"primaryKey" validate:"required"`
|
||||
Value string `json:"value"`
|
||||
Description string `json:"description"`
|
||||
Type int `json:"type"`
|
||||
Type string `json:"type"`
|
||||
Group int `json:"group"`
|
||||
}
|
||||
|
||||
func SaveSettings(items []SettingItem) error {
|
||||
return conf.DB.Save(items).Error
|
||||
}
|
||||
|
||||
func GetSettingByType(t int) (*[]SettingItem, error) {
|
||||
func GetSettingsByGroup(t int) (*[]SettingItem, error) {
|
||||
var items []SettingItem
|
||||
if err := conf.DB.Where("type = ?", t).Find(&items).Error; err != nil {
|
||||
if err := conf.DB.Where("group = ?", t).Find(&items).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &items, nil
|
||||
}
|
||||
|
||||
func GetSettings() (*[]SettingItem, error) {
|
||||
var items []SettingItem
|
||||
if err := conf.DB.Find(&items).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &items, nil
|
||||
|
@ -36,4 +45,3 @@ func GetSettingByKey(key string) (*SettingItem, error) {
|
|||
}
|
||||
return &items, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func Auth(ctx *fiber.Ctx) error {
|
||||
token := ctx.Get("token")
|
||||
token := ctx.Get("Authorization")
|
||||
password, err := model.GetSettingByKey("password")
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
|
@ -23,6 +23,15 @@ func Auth(ctx *fiber.Ctx) error {
|
|||
return ctx.Next()
|
||||
}
|
||||
|
||||
func Login(ctx *fiber.Ctx) error {
|
||||
return SuccessResp(ctx)
|
||||
}
|
||||
|
||||
func SetSuccess(ctx *fiber.Ctx) error {
|
||||
ctx.Status(200)
|
||||
return ctx.Next()
|
||||
}
|
||||
|
||||
func CheckAccount(ctx *fiber.Ctx) error {
|
||||
if model.AccountsCount() == 0 {
|
||||
return ErrorResp(ctx,fmt.Errorf("no accounts,please add one first"),1001)
|
||||
|
|
|
@ -13,7 +13,7 @@ var validate = validator.New()
|
|||
|
||||
type Resp struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ func ParsePath(rawPath string) (*model.Account,string,drivers.Driver,error) {
|
|||
func ErrorResp(ctx *fiber.Ctx,err error,code int) error {
|
||||
return ctx.JSON(Resp{
|
||||
Code: code,
|
||||
Msg: err.Error(),
|
||||
Message: err.Error(),
|
||||
Data: nil,
|
||||
})
|
||||
}
|
||||
|
@ -53,13 +53,13 @@ func SuccessResp(ctx *fiber.Ctx, data ...interface{}) error {
|
|||
if len(data) == 0 {
|
||||
return ctx.JSON(Resp{
|
||||
Code: 200,
|
||||
Msg: "success",
|
||||
Message: "success",
|
||||
Data: nil,
|
||||
})
|
||||
}
|
||||
return ctx.JSON(Resp{
|
||||
Code: 200,
|
||||
Msg: "success",
|
||||
Message: "success",
|
||||
Data: data[0],
|
||||
})
|
||||
}
|
|
@ -30,7 +30,7 @@ func Path(ctx *fiber.Ctx) error {
|
|||
if model.AccountsCount() > 1 && req.Path == "/" {
|
||||
return ctx.JSON(Resp{
|
||||
Code: 200,
|
||||
Msg: "folder",
|
||||
Message: "folder",
|
||||
Data: model.GetAccountFiles(),
|
||||
})
|
||||
}
|
||||
|
@ -45,13 +45,13 @@ func Path(ctx *fiber.Ctx) error {
|
|||
if file != nil {
|
||||
return ctx.JSON(Resp{
|
||||
Code: 200,
|
||||
Msg: "file",
|
||||
Message: "file",
|
||||
Data: []*model.File{file},
|
||||
})
|
||||
} else {
|
||||
return ctx.JSON(Resp{
|
||||
Code: 200,
|
||||
Msg: "folder",
|
||||
Message: "folder",
|
||||
Data: files,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -13,17 +13,20 @@ func InitApiRouter(app *fiber.App) {
|
|||
// TODO check allow proxy?
|
||||
app.Get("/p/*", Proxy)
|
||||
|
||||
public := app.Group("/api/public")
|
||||
api := app.Group("/api")
|
||||
api.Use(SetSuccess)
|
||||
public := api.Group("/public")
|
||||
{
|
||||
// TODO check accounts
|
||||
public.Post("/path", CheckAccount, Path)
|
||||
public.Get("/settings", GetSettingsPublic)
|
||||
}
|
||||
|
||||
admin := app.Group("/api/admin")
|
||||
admin := api.Group("/admin")
|
||||
{
|
||||
admin.Use(Auth)
|
||||
admin.Get("/settings", GetSettingsByType)
|
||||
admin.Get("/login", Login)
|
||||
admin.Get("/settings", GetSettings)
|
||||
admin.Post("/settings", SaveSettings)
|
||||
admin.Post("/account", SaveAccount)
|
||||
admin.Get("/accounts", GetAccounts)
|
||||
|
|
|
@ -9,38 +9,42 @@ import (
|
|||
func SaveSettings(ctx *fiber.Ctx) error {
|
||||
var req []model.SettingItem
|
||||
if err := ctx.BodyParser(&req); err != nil {
|
||||
return ErrorResp(ctx,err,400)
|
||||
}
|
||||
if err := validate.Struct(req); err != nil {
|
||||
return ErrorResp(ctx,err,400)
|
||||
return ErrorResp(ctx, err, 400)
|
||||
}
|
||||
//if err := validate.Struct(req); err != nil {
|
||||
// return ErrorResp(ctx, err, 400)
|
||||
//}
|
||||
if err := model.SaveSettings(req); err != nil {
|
||||
return ctx.JSON(Resp{
|
||||
Code: 500,
|
||||
Msg: err.Error(),
|
||||
Data: nil,
|
||||
})
|
||||
return ErrorResp(ctx, err, 500)
|
||||
} else {
|
||||
return SuccessResp(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func GetSettingsByType(ctx *fiber.Ctx) error {
|
||||
func GetSettingsByGroup(ctx *fiber.Ctx) error {
|
||||
t, err := strconv.Atoi(ctx.Query("type"))
|
||||
if err != nil {
|
||||
return ErrorResp(ctx, err, 400)
|
||||
}
|
||||
settings, err := model.GetSettingByType(t)
|
||||
settings, err := model.GetSettingsByGroup(t)
|
||||
if err != nil {
|
||||
return ErrorResp(ctx, err, 400)
|
||||
}
|
||||
return SuccessResp(ctx,settings)
|
||||
return SuccessResp(ctx, settings)
|
||||
}
|
||||
|
||||
func GetSettings(ctx *fiber.Ctx) error {
|
||||
settings, err := model.GetSettings()
|
||||
if err != nil {
|
||||
return ErrorResp(ctx, err, 400)
|
||||
}
|
||||
return SuccessResp(ctx, settings)
|
||||
}
|
||||
|
||||
func GetSettingsPublic(ctx *fiber.Ctx) error {
|
||||
settings, err := model.GetSettingByType(0)
|
||||
settings, err := model.GetSettingsByGroup(0)
|
||||
if err != nil {
|
||||
return ErrorResp(ctx, err, 400)
|
||||
}
|
||||
return SuccessResp(ctx,settings)
|
||||
}
|
||||
return SuccessResp(ctx, settings)
|
||||
}
|
||||
|
|
|
@ -35,18 +35,21 @@ func GetFileType(ext string) int {
|
|||
return conf.UNKNOWN
|
||||
}
|
||||
ext = ext[1:]
|
||||
if IsContain(conf.OfficeTypes,ext) {
|
||||
if IsContain(conf.OfficeTypes, ext) {
|
||||
return conf.OFFICE
|
||||
}
|
||||
if IsContain(conf.AudioTypes,ext) {
|
||||
if IsContain(conf.AudioTypes, ext) {
|
||||
return conf.AUDIO
|
||||
}
|
||||
if IsContain(conf.VideoTypes,ext) {
|
||||
if IsContain(conf.VideoTypes, ext) {
|
||||
return conf.VIDEO
|
||||
}
|
||||
if IsContain(conf.TextTypes,ext) {
|
||||
if IsContain(conf.TextTypes, ext) {
|
||||
return conf.TEXT
|
||||
}
|
||||
if IsContain(conf.ImageTypes, ext) {
|
||||
return conf.IMAGE
|
||||
}
|
||||
return conf.UNKNOWN
|
||||
}
|
||||
|
||||
|
@ -65,7 +68,7 @@ func CreatNestedFile(path string) (*os.File, error) {
|
|||
|
||||
// WriteToJson write struct to json file
|
||||
func WriteToJson(src string, conf interface{}) bool {
|
||||
data, err := json.MarshalIndent(conf,""," ")
|
||||
data, err := json.MarshalIndent(conf, "", " ")
|
||||
if err != nil {
|
||||
log.Errorf("failed convert Conf to []byte:%s", err.Error())
|
||||
return false
|
||||
|
@ -84,4 +87,4 @@ func ParsePath(path string) string {
|
|||
path = "/" + path
|
||||
}
|
||||
return path
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue