From 61fa6f38a8c060021929069f3c62fd09a4f06c54 Mon Sep 17 00:00:00 2001 From: Noah Hsu Date: Mon, 8 Aug 2022 00:51:05 +0800 Subject: [PATCH] feat: add type to fs read api --- go.mod | 2 +- internal/bootstrap/config.go | 2 +- internal/bootstrap/data/setting.go | 3 +++ internal/conf/const.go | 12 ++++++++++++ internal/conf/var.go | 2 ++ internal/db/settingitem.go | 25 +++++++++++++++++++++---- pkg/utils/file.go | 23 ++++++++++++++++++++++- pkg/utils/json.go | 7 ++++--- pkg/utils/slice.go | 5 ++++- server/handles/down.go | 10 +++------- server/handles/fsread.go | 8 ++++++++ 11 files changed, 81 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index a06eaed9..33e3ad7d 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/pquerna/otp v1.3.0 github.com/sirupsen/logrus v1.8.1 + github.com/spf13/cobra v1.5.0 github.com/winfsp/cgofuse v1.5.0 gorm.io/driver/mysql v1.3.4 gorm.io/driver/postgres v1.3.7 @@ -49,7 +50,6 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect - github.com/spf13/cobra v1.5.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/ugorji/go/codec v1.2.7 // indirect golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect diff --git a/internal/bootstrap/config.go b/internal/bootstrap/config.go index af8fecdf..ad9f6492 100644 --- a/internal/bootstrap/config.go +++ b/internal/bootstrap/config.go @@ -21,7 +21,7 @@ func InitConfig() { log.Fatalf("failed to create config file: %+v", err) } conf.Conf = conf.DefaultConfig() - if !utils.WriteToJson(flags.Config, conf.Conf) { + if !utils.WriteJsonToFile(flags.Config, conf.Conf) { log.Fatalf("failed to create default config file") } } else { diff --git a/internal/bootstrap/data/setting.go b/internal/bootstrap/data/setting.go index 3efff2c7..406691c6 100644 --- a/internal/bootstrap/data/setting.go +++ b/internal/bootstrap/data/setting.go @@ -47,6 +47,7 @@ func initSettings() { log.Fatalf("failed get setting: %+v", err) } } + db.ResetTypeMap() } func isActive(key string) bool { @@ -80,6 +81,8 @@ func initialSettings() { {Key: conf.TextTypes, Value: "txt,htm,html,xml,java,properties,sql,js,md,json,conf,ini,vue,php,py,bat,gitignore,yml,go,sh,c,cpp,h,hpp,tsx,vtt,srt,ass,rs,lrc", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE}, {Key: conf.AudioTypes, Value: "mp3,flac,ogg,m4a,wav,opus", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE}, {Key: conf.VideoTypes, Value: "mp4,mkv,avi,mov,rmvb,webm,flv", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE}, + {Key: conf.ImageTypes, Value: "jpg,tiff,jpeg,png,gif,bmp,svg,ico,swf,webp", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE}, + {Key: conf.OfficeTypes, Value: "doc,docx,xls,xlsx,ppt,pptx,pdf", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE}, {Key: conf.ProxyTypes, Value: "m3u8", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE}, {Key: conf.PdfViewerUrl, Value: "https://alist-org.github.io/pdf.js/web/viewer.html?file=$url", Type: conf.TypeString, Group: model.PREVIEW}, {Key: conf.AudioAutoplay, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW}, diff --git a/internal/conf/const.go b/internal/conf/const.go index 5ce1fb58..324b59b5 100644 --- a/internal/conf/const.go +++ b/internal/conf/const.go @@ -21,6 +21,8 @@ const ( TextTypes = "text_types" AudioTypes = "audio_types" VideoTypes = "video_types" + ImageTypes = "image_types" + OfficeTypes = "office_types" ProxyTypes = "proxy_types" PdfViewerUrl = "pdf_viewer_url" AudioAutoplay = "audio_autoplay" @@ -37,3 +39,13 @@ const ( Token = "token" ) + +const ( + UNKNOWN = iota + FOLDER + OFFICE + VIDEO + AUDIO + TEXT + IMAGE +) diff --git a/internal/conf/var.go b/internal/conf/var.go index 951ff63f..93637157 100644 --- a/internal/conf/var.go +++ b/internal/conf/var.go @@ -12,3 +12,5 @@ var ( var ( Conf *Config ) + +var TypesMap = make(map[string][]string) diff --git a/internal/db/settingitem.go b/internal/db/settingitem.go index f3bac34a..93f63255 100644 --- a/internal/db/settingitem.go +++ b/internal/db/settingitem.go @@ -2,7 +2,9 @@ package db import ( "fmt" + "strings" + "github.com/alist-org/alist/v3/internal/conf" "github.com/alist-org/alist/v3/internal/model" "github.com/pkg/errors" log "github.com/sirupsen/logrus" @@ -11,8 +13,23 @@ import ( var settingsMap map[string]string var publicSettingsMap map[string]string +func ResetTypeMap() { + settingsMap := GetSettingsMap() + conf.TypesMap[conf.AudioTypes] = strings.Split(settingsMap[conf.AudioTypes], ",") + conf.TypesMap[conf.VideoTypes] = strings.Split(settingsMap[conf.VideoTypes], ",") + conf.TypesMap[conf.ImageTypes] = strings.Split(settingsMap[conf.ImageTypes], ",") + conf.TypesMap[conf.TextTypes] = strings.Split(settingsMap[conf.TextTypes], ",") + conf.TypesMap[conf.OfficeTypes] = strings.Split(settingsMap[conf.OfficeTypes], ",") +} + +func settingsUpdate() { + settingsMap = nil + publicSettingsMap = nil + ResetTypeMap() +} + func GetPublicSettingsMap() map[string]string { - if settingsMap == nil || publicSettingsMap == nil { + if publicSettingsMap == nil { publicSettingsMap = make(map[string]string) settingItems, err := GetPublicSettingItems() if err != nil { @@ -88,12 +105,12 @@ func GetSettingItemsInGroups(groups []int) ([]model.SettingItem, error) { } func SaveSettingItems(items []model.SettingItem) error { - settingsMap = nil + settingsUpdate() return errors.WithStack(db.Save(items).Error) } func SaveSettingItem(item model.SettingItem) error { - settingsMap = nil + settingsUpdate() return errors.WithStack(db.Save(item).Error) } @@ -108,6 +125,6 @@ func DeleteSettingItemByKey(key string) error { if !old.IsDeprecated() { return errors.Errorf("setting [%s] is not deprecated", key) } - settingsMap = nil + settingsUpdate() return errors.WithStack(db.Delete(&settingItem).Error) } diff --git a/pkg/utils/file.go b/pkg/utils/file.go index dcd95c8d..867ed4c8 100644 --- a/pkg/utils/file.go +++ b/pkg/utils/file.go @@ -1,12 +1,12 @@ package utils import ( - "github.com/alist-org/alist/v3/internal/conf" "io" "io/ioutil" "os" "path/filepath" + "github.com/alist-org/alist/v3/internal/conf" log "github.com/sirupsen/logrus" ) @@ -49,3 +49,24 @@ func CreateTempFile(r io.ReadCloser) (*os.File, error) { } return f, nil } + +// GetFileType get file type +func GetFileType(filename string) int { + ext := Ext(filename) + if SliceContains(conf.TypesMap[conf.OfficeTypes], ext) { + return conf.OFFICE + } + if SliceContains(conf.TypesMap[conf.AudioTypes], ext) { + return conf.AUDIO + } + if SliceContains(conf.TypesMap[conf.VideoTypes], ext) { + return conf.VIDEO + } + if SliceContains(conf.TypesMap[conf.ImageTypes], ext) { + return conf.IMAGE + } + if SliceContains(conf.TypesMap[conf.TextTypes], ext) { + return conf.TEXT + } + return conf.UNKNOWN +} diff --git a/pkg/utils/json.go b/pkg/utils/json.go index 3f67e1bb..f4389e6b 100644 --- a/pkg/utils/json.go +++ b/pkg/utils/json.go @@ -1,15 +1,16 @@ package utils import ( + "io/ioutil" + json "github.com/json-iterator/go" log "github.com/sirupsen/logrus" - "io/ioutil" ) var Json = json.ConfigCompatibleWithStandardLibrary -// WriteToJson write struct to json file -func WriteToJson(src string, conf interface{}) bool { +// WriteJsonToFile write struct to json file +func WriteJsonToFile(src string, conf interface{}) bool { data, err := Json.MarshalIndent(conf, "", " ") if err != nil { log.Errorf("failed convert Conf to []byte:%s", err.Error()) diff --git a/pkg/utils/slice.go b/pkg/utils/slice.go index 207b26aa..5ab5b018 100644 --- a/pkg/utils/slice.go +++ b/pkg/utils/slice.go @@ -1,5 +1,6 @@ package utils +// SliceEqual check if two slices are equal func SliceEqual[T comparable](a, b []T) bool { if len(a) != len(b) { return false @@ -12,6 +13,7 @@ func SliceEqual[T comparable](a, b []T) bool { return true } +// SliceContains check if slice contains element func SliceContains[T comparable](arr []T, v T) bool { for _, vv := range arr { if vv == v { @@ -21,9 +23,10 @@ func SliceContains[T comparable](arr []T, v T) bool { return false } +// SliceConvert convert slice to another type slice func SliceConvert[S any, D any](srcS []S, convert func(src S) (D, error)) ([]D, error) { var res []D - for i, _ := range srcS { + for i := range srcS { dst, err := convert(srcS[i]) if err != nil { return nil, err diff --git a/server/handles/down.go b/server/handles/down.go index 7d8f6bb1..3e9d8ab4 100644 --- a/server/handles/down.go +++ b/server/handles/down.go @@ -9,7 +9,6 @@ import ( "github.com/alist-org/alist/v3/internal/driver" "github.com/alist-org/alist/v3/internal/fs" "github.com/alist-org/alist/v3/internal/model" - "github.com/alist-org/alist/v3/internal/setting" "github.com/alist-org/alist/v3/internal/sign" "github.com/alist-org/alist/v3/pkg/utils" "github.com/alist-org/alist/v3/server/common" @@ -85,8 +84,7 @@ func shouldProxy(storage driver.Driver, filename string) bool { if storage.Config().MustProxy() || storage.GetStorage().WebProxy { return true } - proxyTypes := setting.GetByKey(conf.ProxyTypes) - if strings.Contains(proxyTypes, utils.Ext(filename)) { + if utils.SliceContains(conf.TypesMap[conf.ProxyTypes], utils.Ext(filename)) { return true } return false @@ -103,12 +101,10 @@ func canProxy(storage driver.Driver, filename string) bool { if storage.Config().MustProxy() || storage.GetStorage().WebProxy { return true } - proxyTypes := setting.GetByKey(conf.ProxyTypes) - if strings.Contains(proxyTypes, utils.Ext(filename)) { + if utils.SliceContains(conf.TypesMap[conf.ProxyTypes], utils.Ext(filename)) { return true } - textTypes := setting.GetByKey(conf.TextTypes) - if strings.Contains(textTypes, utils.Ext(filename)) { + if utils.SliceContains(conf.TypesMap[conf.TextTypes], utils.Ext(filename)) { return true } return false diff --git a/server/handles/fsread.go b/server/handles/fsread.go index 7300d62e..b483ce8b 100644 --- a/server/handles/fsread.go +++ b/server/handles/fsread.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.com/alist-org/alist/v3/internal/conf" "github.com/alist-org/alist/v3/internal/db" "github.com/alist-org/alist/v3/internal/errs" "github.com/alist-org/alist/v3/internal/fs" @@ -35,6 +36,7 @@ type ObjResp struct { Modified time.Time `json:"modified"` Sign string `json:"sign"` Thumbnail string `json:"thumbnail"` + Type int `json:"type"` } type FsListResp struct { @@ -171,6 +173,10 @@ func toObjResp(objs []model.Obj) []ObjResp { if t, ok := obj.(model.Thumbnail); ok { thumbnail = t.Thumbnail() } + tp := conf.FOLDER + if !obj.IsDir() { + tp = utils.GetFileType(obj.GetName()) + } resp = append(resp, ObjResp{ Name: obj.GetName(), Size: obj.GetSize(), @@ -178,6 +184,7 @@ func toObjResp(objs []model.Obj) []ObjResp { Modified: obj.ModTime(), Sign: common.Sign(obj), Thumbnail: thumbnail, + Type: tp, }) } return resp @@ -256,6 +263,7 @@ func FsGet(c *gin.Context) { IsDir: obj.IsDir(), Modified: obj.ModTime(), Sign: common.Sign(obj), + Type: utils.GetFileType(obj.GetName()), }, RawURL: rawURL, Readme: getReadme(meta, req.Path),