mirror of https://github.com/Xhofe/alist
feat: add type to fs read api
parent
ccce6a30bb
commit
61fa6f38a8
2
go.mod
2
go.mod
|
@ -15,6 +15,7 @@ require (
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pquerna/otp v1.3.0
|
github.com/pquerna/otp v1.3.0
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
|
github.com/spf13/cobra v1.5.0
|
||||||
github.com/winfsp/cgofuse v1.5.0
|
github.com/winfsp/cgofuse v1.5.0
|
||||||
gorm.io/driver/mysql v1.3.4
|
gorm.io/driver/mysql v1.3.4
|
||||||
gorm.io/driver/postgres v1.3.7
|
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/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.1 // 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/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||||
|
|
|
@ -21,7 +21,7 @@ func InitConfig() {
|
||||||
log.Fatalf("failed to create config file: %+v", err)
|
log.Fatalf("failed to create config file: %+v", err)
|
||||||
}
|
}
|
||||||
conf.Conf = conf.DefaultConfig()
|
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")
|
log.Fatalf("failed to create default config file")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -47,6 +47,7 @@ func initSettings() {
|
||||||
log.Fatalf("failed get setting: %+v", err)
|
log.Fatalf("failed get setting: %+v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
db.ResetTypeMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
func isActive(key string) bool {
|
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.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.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.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.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.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},
|
{Key: conf.AudioAutoplay, Value: "true", Type: conf.TypeBool, Group: model.PREVIEW},
|
||||||
|
|
|
@ -21,6 +21,8 @@ const (
|
||||||
TextTypes = "text_types"
|
TextTypes = "text_types"
|
||||||
AudioTypes = "audio_types"
|
AudioTypes = "audio_types"
|
||||||
VideoTypes = "video_types"
|
VideoTypes = "video_types"
|
||||||
|
ImageTypes = "image_types"
|
||||||
|
OfficeTypes = "office_types"
|
||||||
ProxyTypes = "proxy_types"
|
ProxyTypes = "proxy_types"
|
||||||
PdfViewerUrl = "pdf_viewer_url"
|
PdfViewerUrl = "pdf_viewer_url"
|
||||||
AudioAutoplay = "audio_autoplay"
|
AudioAutoplay = "audio_autoplay"
|
||||||
|
@ -37,3 +39,13 @@ const (
|
||||||
|
|
||||||
Token = "token"
|
Token = "token"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
UNKNOWN = iota
|
||||||
|
FOLDER
|
||||||
|
OFFICE
|
||||||
|
VIDEO
|
||||||
|
AUDIO
|
||||||
|
TEXT
|
||||||
|
IMAGE
|
||||||
|
)
|
||||||
|
|
|
@ -12,3 +12,5 @@ var (
|
||||||
var (
|
var (
|
||||||
Conf *Config
|
Conf *Config
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var TypesMap = make(map[string][]string)
|
||||||
|
|
|
@ -2,7 +2,9 @@ package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
@ -11,8 +13,23 @@ import (
|
||||||
var settingsMap map[string]string
|
var settingsMap map[string]string
|
||||||
var publicSettingsMap 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 {
|
func GetPublicSettingsMap() map[string]string {
|
||||||
if settingsMap == nil || publicSettingsMap == nil {
|
if publicSettingsMap == nil {
|
||||||
publicSettingsMap = make(map[string]string)
|
publicSettingsMap = make(map[string]string)
|
||||||
settingItems, err := GetPublicSettingItems()
|
settingItems, err := GetPublicSettingItems()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -88,12 +105,12 @@ func GetSettingItemsInGroups(groups []int) ([]model.SettingItem, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveSettingItems(items []model.SettingItem) error {
|
func SaveSettingItems(items []model.SettingItem) error {
|
||||||
settingsMap = nil
|
settingsUpdate()
|
||||||
return errors.WithStack(db.Save(items).Error)
|
return errors.WithStack(db.Save(items).Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveSettingItem(item model.SettingItem) error {
|
func SaveSettingItem(item model.SettingItem) error {
|
||||||
settingsMap = nil
|
settingsUpdate()
|
||||||
return errors.WithStack(db.Save(item).Error)
|
return errors.WithStack(db.Save(item).Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +125,6 @@ func DeleteSettingItemByKey(key string) error {
|
||||||
if !old.IsDeprecated() {
|
if !old.IsDeprecated() {
|
||||||
return errors.Errorf("setting [%s] is not deprecated", key)
|
return errors.Errorf("setting [%s] is not deprecated", key)
|
||||||
}
|
}
|
||||||
settingsMap = nil
|
settingsUpdate()
|
||||||
return errors.WithStack(db.Delete(&settingItem).Error)
|
return errors.WithStack(db.Delete(&settingItem).Error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,3 +49,24 @@ func CreateTempFile(r io.ReadCloser) (*os.File, error) {
|
||||||
}
|
}
|
||||||
return f, nil
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
json "github.com/json-iterator/go"
|
json "github.com/json-iterator/go"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"io/ioutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var Json = json.ConfigCompatibleWithStandardLibrary
|
var Json = json.ConfigCompatibleWithStandardLibrary
|
||||||
|
|
||||||
// WriteToJson write struct to json file
|
// WriteJsonToFile write struct to json file
|
||||||
func WriteToJson(src string, conf interface{}) bool {
|
func WriteJsonToFile(src string, conf interface{}) bool {
|
||||||
data, err := Json.MarshalIndent(conf, "", " ")
|
data, err := Json.MarshalIndent(conf, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed convert Conf to []byte:%s", err.Error())
|
log.Errorf("failed convert Conf to []byte:%s", err.Error())
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
|
// SliceEqual check if two slices are equal
|
||||||
func SliceEqual[T comparable](a, b []T) bool {
|
func SliceEqual[T comparable](a, b []T) bool {
|
||||||
if len(a) != len(b) {
|
if len(a) != len(b) {
|
||||||
return false
|
return false
|
||||||
|
@ -12,6 +13,7 @@ func SliceEqual[T comparable](a, b []T) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SliceContains check if slice contains element
|
||||||
func SliceContains[T comparable](arr []T, v T) bool {
|
func SliceContains[T comparable](arr []T, v T) bool {
|
||||||
for _, vv := range arr {
|
for _, vv := range arr {
|
||||||
if vv == v {
|
if vv == v {
|
||||||
|
@ -21,9 +23,10 @@ func SliceContains[T comparable](arr []T, v T) bool {
|
||||||
return false
|
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) {
|
func SliceConvert[S any, D any](srcS []S, convert func(src S) (D, error)) ([]D, error) {
|
||||||
var res []D
|
var res []D
|
||||||
for i, _ := range srcS {
|
for i := range srcS {
|
||||||
dst, err := convert(srcS[i])
|
dst, err := convert(srcS[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
"github.com/alist-org/alist/v3/internal/fs"
|
"github.com/alist-org/alist/v3/internal/fs"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"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/internal/sign"
|
||||||
"github.com/alist-org/alist/v3/pkg/utils"
|
"github.com/alist-org/alist/v3/pkg/utils"
|
||||||
"github.com/alist-org/alist/v3/server/common"
|
"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 {
|
if storage.Config().MustProxy() || storage.GetStorage().WebProxy {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
proxyTypes := setting.GetByKey(conf.ProxyTypes)
|
if utils.SliceContains(conf.TypesMap[conf.ProxyTypes], utils.Ext(filename)) {
|
||||||
if strings.Contains(proxyTypes, utils.Ext(filename)) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -103,12 +101,10 @@ func canProxy(storage driver.Driver, filename string) bool {
|
||||||
if storage.Config().MustProxy() || storage.GetStorage().WebProxy {
|
if storage.Config().MustProxy() || storage.GetStorage().WebProxy {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
proxyTypes := setting.GetByKey(conf.ProxyTypes)
|
if utils.SliceContains(conf.TypesMap[conf.ProxyTypes], utils.Ext(filename)) {
|
||||||
if strings.Contains(proxyTypes, utils.Ext(filename)) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
textTypes := setting.GetByKey(conf.TextTypes)
|
if utils.SliceContains(conf.TypesMap[conf.TextTypes], utils.Ext(filename)) {
|
||||||
if strings.Contains(textTypes, utils.Ext(filename)) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/db"
|
"github.com/alist-org/alist/v3/internal/db"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"github.com/alist-org/alist/v3/internal/fs"
|
"github.com/alist-org/alist/v3/internal/fs"
|
||||||
|
@ -35,6 +36,7 @@ type ObjResp struct {
|
||||||
Modified time.Time `json:"modified"`
|
Modified time.Time `json:"modified"`
|
||||||
Sign string `json:"sign"`
|
Sign string `json:"sign"`
|
||||||
Thumbnail string `json:"thumbnail"`
|
Thumbnail string `json:"thumbnail"`
|
||||||
|
Type int `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FsListResp struct {
|
type FsListResp struct {
|
||||||
|
@ -171,6 +173,10 @@ func toObjResp(objs []model.Obj) []ObjResp {
|
||||||
if t, ok := obj.(model.Thumbnail); ok {
|
if t, ok := obj.(model.Thumbnail); ok {
|
||||||
thumbnail = t.Thumbnail()
|
thumbnail = t.Thumbnail()
|
||||||
}
|
}
|
||||||
|
tp := conf.FOLDER
|
||||||
|
if !obj.IsDir() {
|
||||||
|
tp = utils.GetFileType(obj.GetName())
|
||||||
|
}
|
||||||
resp = append(resp, ObjResp{
|
resp = append(resp, ObjResp{
|
||||||
Name: obj.GetName(),
|
Name: obj.GetName(),
|
||||||
Size: obj.GetSize(),
|
Size: obj.GetSize(),
|
||||||
|
@ -178,6 +184,7 @@ func toObjResp(objs []model.Obj) []ObjResp {
|
||||||
Modified: obj.ModTime(),
|
Modified: obj.ModTime(),
|
||||||
Sign: common.Sign(obj),
|
Sign: common.Sign(obj),
|
||||||
Thumbnail: thumbnail,
|
Thumbnail: thumbnail,
|
||||||
|
Type: tp,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return resp
|
return resp
|
||||||
|
@ -256,6 +263,7 @@ func FsGet(c *gin.Context) {
|
||||||
IsDir: obj.IsDir(),
|
IsDir: obj.IsDir(),
|
||||||
Modified: obj.ModTime(),
|
Modified: obj.ModTime(),
|
||||||
Sign: common.Sign(obj),
|
Sign: common.Sign(obj),
|
||||||
|
Type: utils.GetFileType(obj.GetName()),
|
||||||
},
|
},
|
||||||
RawURL: rawURL,
|
RawURL: rawURL,
|
||||||
Readme: getReadme(meta, req.Path),
|
Readme: getReadme(meta, req.Path),
|
||||||
|
|
Loading…
Reference in New Issue