From 2bf09268243ae5651521a9fece0589868dc1c65b Mon Sep 17 00:00:00 2001 From: mildred Date: Tue, 21 May 2019 11:35:22 +0100 Subject: [PATCH] feat: add bookmarks --- http/context.go | 19 ++++++++++++++++++ http/resource.go | 46 ++++++++++++++++++++++++++++++++++---------- settings/defaults.go | 14 ++++++++------ users/bookmark.go | 7 +++++++ users/users.go | 38 ++++++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 16 deletions(-) create mode 100644 http/context.go create mode 100644 users/bookmark.go diff --git a/http/context.go b/http/context.go new file mode 100644 index 00000000..45e78e24 --- /dev/null +++ b/http/context.go @@ -0,0 +1,19 @@ +package http + +import ( + "net/http" + + "github.com/filebrowser/filebrowser/v2/users" +) + +type contextInfo struct { + Bookmarks []users.Bookmark `json:"bookmarks"` +} + +var contextGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { + context := &contextInfo{ + Bookmarks: d.user.Bookmarks, + } + + return renderJSON(w, r, context) +}) diff --git a/http/resource.go b/http/resource.go index 6defa007..1df2c9d0 100644 --- a/http/resource.go +++ b/http/resource.go @@ -15,6 +15,11 @@ import ( "github.com/filebrowser/filebrowser/v2/fileutils" ) +type resourceInfo struct { + *files.FileInfo + Bookmarked bool `json:"bookmarked"` +} + var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { file, err := files.NewFileInfo(files.FileOptions{ Fs: d.user.Fs, @@ -27,13 +32,21 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d return errToStatus(err), err } + resource := &resourceInfo{ + FileInfo: file, + } + if file.IsDir { file.Listing.Sorting = d.user.Sorting file.Listing.ApplySort() - return renderJSON(w, r, file) + for _, bookmark := range d.user.Bookmarks { + if bookmark.Path == file.Path { + resource.Bookmarked = true + } + } } - if checksum := r.URL.Query().Get("checksum"); checksum != "" { + if checksum := r.URL.Query().Get("checksum"); !file.IsDir && checksum != "" { err := file.Checksum(checksum) if err == errors.ErrInvalidOption { return http.StatusBadRequest, nil @@ -45,7 +58,7 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d file.Content = "" } - return renderJSON(w, r, file) + return renderJSON(w, r, resource) }) var resourceDeleteHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { @@ -122,6 +135,7 @@ var resourcePostPutHandler = withUser(func(w http.ResponseWriter, r *http.Reques var resourcePatchHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { src := r.URL.Path dst := r.URL.Query().Get("destination") + name := r.URL.Query().Get("name") action := r.URL.Query().Get("action") dst, err := url.QueryUnescape(dst) @@ -133,26 +147,38 @@ var resourcePatchHandler = withUser(func(w http.ResponseWriter, r *http.Request, return http.StatusForbidden, nil } + var hook func() error + switch action { + case "bookmark": + hook = func() error { + d.user.AddBookmark(src, name) + return d.store.Users.Save(d.user) + } + case "remove-bookmark": + hook = func() error { + d.user.RemoveBookmarkByPath(src) + return d.store.Users.Save(d.user) + } case "copy": if !d.user.Perm.Create { return http.StatusForbidden, nil } + hook = func() error { + return fileutils.Copy(d.user.Fs, src, dst) + } case "rename": default: action = "rename" if !d.user.Perm.Rename { return http.StatusForbidden, nil } + hook = func() error { + return d.user.Fs.Rename(src, dst) + } } - err = d.RunHook(func() error { - if action == "copy" { - return fileutils.Copy(d.user.Fs, src, dst) - } - - return d.user.Fs.Rename(src, dst) - }, action, src, dst, d.user) + err = d.RunHook(hook, action, src, dst, d.user) return errToStatus(err), err }) diff --git a/settings/defaults.go b/settings/defaults.go index b0829655..0ecae49d 100644 --- a/settings/defaults.go +++ b/settings/defaults.go @@ -8,12 +8,13 @@ import ( // UserDefaults is a type that holds the default values // for some fields on User. type UserDefaults struct { - Scope string `json:"scope"` - Locale string `json:"locale"` - ViewMode users.ViewMode `json:"viewMode"` - Sorting files.Sorting `json:"sorting"` - Perm users.Permissions `json:"perm"` - Commands []string `json:"commands"` + Scope string `json:"scope"` + Locale string `json:"locale"` + ViewMode users.ViewMode `json:"viewMode"` + Sorting files.Sorting `json:"sorting"` + Perm users.Permissions `json:"perm"` + Commands []string `json:"commands"` + Bookmarks []users.Bookmark `json:"bookmarks"` } // Apply applies the default options to a user. @@ -24,4 +25,5 @@ func (d *UserDefaults) Apply(u *users.User) { u.Perm = d.Perm u.Sorting = d.Sorting u.Commands = d.Commands + u.Bookmarks = d.Bookmarks } diff --git a/users/bookmark.go b/users/bookmark.go new file mode 100644 index 00000000..640477cd --- /dev/null +++ b/users/bookmark.go @@ -0,0 +1,7 @@ +package users + +// Bookmark represents a bookmark the user has set +type Bookmark struct { + Name string `json:"name"` + Path string `json:"path"` +} diff --git a/users/users.go b/users/users.go index 4fdbef6c..92b12f85 100644 --- a/users/users.go +++ b/users/users.go @@ -33,6 +33,7 @@ type User struct { Sorting files.Sorting `json:"sorting"` Fs afero.Fs `json:"-" yaml:"-"` Rules []rules.Rule `json:"rules"` + Bookmarks []Bookmark `json:"bookmarks"` } // GetRules implements rules.Provider. @@ -48,6 +49,7 @@ var checkableFields = []string{ "Commands", "Sorting", "Rules", + "Bookmarks", } // Clean cleans up a user and verifies if all its fields @@ -83,6 +85,10 @@ func (u *User) Clean(baseScope string, fields ...string) error { if u.Rules == nil { u.Rules = []rules.Rule{} } + case "Bookmarks": + if u.Bookmarks == nil { + u.Bookmarks = []Bookmark{} + } } } @@ -118,3 +124,35 @@ func (u *User) CanExecute(command string) bool { return false } + +// RemoveBookmarkByPath removes a bookmark by path. +func (u *User) RemoveBookmarkByPath(path string) { + var newBookmarks []Bookmark + for _, bookmark := range u.Bookmarks { + if bookmark.Path != path { + newBookmarks = append(newBookmarks, bookmark) + } + } + u.Bookmarks = newBookmarks +} + +// AddBookmark adds a bookmark. +func (u *User) AddBookmark(path, name string) { + for i, bookmark := range u.Bookmarks { + if bookmark.Path == path { + if name != "" { + u.Bookmarks[i].Name = name + } + return + } + } + + if name == "" { + name = filepath.Base(path) + } + + u.Bookmarks = append(u.Bookmarks, Bookmark{ + Path: path, + Name: name, + }) +}