From c6007aa9e63a15ee2f14523c162c23caa5fb0caf Mon Sep 17 00:00:00 2001 From: Noah Hsu Date: Mon, 27 Jun 2022 19:10:02 +0800 Subject: [PATCH] feat: sort obj list --- internal/fs/list.go | 51 +++++++++++++++++++++++++++++++++++++----- internal/fs/util.go | 17 ++++++++++++++ internal/model/obj.go | 51 ++++++++++++++++++++++++++++++++++++++++++ internal/model/user.go | 16 +++++++------ 4 files changed, 122 insertions(+), 13 deletions(-) diff --git a/internal/fs/list.go b/internal/fs/list.go index 7439e9bc..02893aff 100644 --- a/internal/fs/list.go +++ b/internal/fs/list.go @@ -2,16 +2,19 @@ package fs import ( "context" + "github.com/alist-org/alist/v3/internal/db" "github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/internal/operations" + "github.com/alist-org/alist/v3/pkg/utils" "github.com/pkg/errors" log "github.com/sirupsen/logrus" ) // List files -// TODO: hide // TODO: sort func list(ctx context.Context, path string) ([]model.Obj, error) { + meta, _ := db.GetNearestMeta(path) + user := ctx.Value("user").(*model.User) account, actualPath, err := operations.GetAccountAndActualPath(path) virtualFiles := operations.GetAccountVirtualFilesByPath(path) if err != nil { @@ -20,18 +23,54 @@ func list(ctx context.Context, path string) ([]model.Obj, error) { } return nil, errors.WithMessage(err, "failed get account") } - files, err := operations.List(ctx, account, actualPath) + objs, err := operations.List(ctx, account, actualPath) if err != nil { log.Errorf("%+v", err) if len(virtualFiles) != 0 { return virtualFiles, nil } - return nil, errors.WithMessage(err, "failed get files") + return nil, errors.WithMessage(err, "failed get objs") } for _, accountFile := range virtualFiles { - if !containsByName(files, accountFile) { - files = append(files, accountFile) + if !containsByName(objs, accountFile) { + objs = append(objs, accountFile) } } - return files, nil + if whetherHide(user, meta, path) { + hide(objs, meta) + } + // sort objs + if account.Config().LocalSort { + model.SortFiles(objs, account.GetAccount().OrderBy, account.GetAccount().OrderDirection) + } + model.ExtractFolder(objs, account.GetAccount().ExtractFolder) + return objs, nil +} + +func whetherHide(user *model.User, meta *model.Meta, path string) bool { + // if is admin, don't hide + if user.IsAdmin() { + return false + } + // if meta is nil, don't hide + if meta == nil { + return false + } + // if meta.Hide is empty, don't hide + if meta.Hide == "" { + return false + } + // if meta doesn't apply to sub_folder, don't hide + if !utils.PathEqual(meta.Path, path) && !meta.SubFolder { + return false + } + // if is guest, hide + if user.IsGuest() { + return true + } + return !user.IgnoreHide +} + +func hide(objs []model.Obj, meta *model.Meta) { + // TODO: hide } diff --git a/internal/fs/util.go b/internal/fs/util.go index 4e328d63..8745b841 100644 --- a/internal/fs/util.go +++ b/internal/fs/util.go @@ -1,6 +1,7 @@ package fs import ( + "github.com/alist-org/alist/v3/pkg/utils" "io" "mime" "net/http" @@ -63,3 +64,19 @@ func getFileStreamFromLink(file model.Obj, link *model.Link) (model.FileStreamer } return stream, nil } + +func canAccess(user *model.User, meta *model.Meta, path string) bool { + // if is not guest, can access + if user.IsAdmin() || user.IgnorePassword { + return true + } + // if meta is nil or password is empty, can access + if meta == nil || meta.Password == "" { + return true + } + // if meta doesn't apply to sub_folder, can access + if !utils.PathEqual(meta.Path, path) && !meta.SubFolder { + return true + } + return false +} diff --git a/internal/model/obj.go b/internal/model/obj.go index 43cd7c20..00b89c0d 100644 --- a/internal/model/obj.go +++ b/internal/model/obj.go @@ -2,6 +2,8 @@ package model import ( "io" + "sort" + "strings" "time" ) @@ -30,3 +32,52 @@ type Thumbnail interface { type SetID interface { SetID(id string) } + +func SortFiles(objs []Obj, orderBy, orderDirection string) { + if orderBy == "" { + return + } + sort.Slice(objs, func(i, j int) bool { + switch orderBy { + case "name": + { + c := strings.Compare(objs[i].GetName(), objs[j].GetName()) + if orderDirection == "DESC" { + return c >= 0 + } + return c <= 0 + } + case "size": + { + if orderDirection == "DESC" { + return objs[i].GetSize() >= objs[j].GetSize() + } + return objs[i].GetSize() <= objs[j].GetSize() + } + case "updated_at": + if orderDirection == "DESC" { + return objs[i].ModTime().After(objs[j].ModTime()) + } + return objs[i].ModTime().Before(objs[j].ModTime()) + } + return false + }) +} + +func ExtractFolder(objs []Obj, extractFolder string) { + if extractFolder == "" { + return + } + front := extractFolder == "front" + sort.SliceStable(objs, func(i, j int) bool { + if objs[i].IsDir() || objs[j].IsDir() { + if !objs[i].IsDir() { + return !front + } + if !objs[j].IsDir() { + return front + } + } + return false + }) +} diff --git a/internal/model/user.go b/internal/model/user.go index 4086b57b..5b4cab2c 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -12,13 +12,15 @@ const ( ) type User struct { - ID uint `json:"id" gorm:"primaryKey"` // unique key - Username string `json:"username" gorm:"unique" binding:"required"` // username - Password string `json:"password"` // password - BasePath string `json:"base_path"` // base path - ReadOnly bool `json:"read_only"` // read only - Webdav bool `json:"webdav"` // allow webdav - Role int `json:"role"` // user's role + ID uint `json:"id" gorm:"primaryKey"` // unique key + Username string `json:"username" gorm:"unique" binding:"required"` // username + Password string `json:"password"` // password + BasePath string `json:"base_path"` // base path + ReadOnly bool `json:"read_only"` // read only + Webdav bool `json:"webdav"` // allow webdav + Role int `json:"role"` // user's role + IgnoreHide bool `json:"can_hide"` // can see hide files + IgnorePassword bool `json:"ignore_password"` // can access without password } func (u User) IsGuest() bool {