feat: add bookmarks
This commit is contained in:
parent
6e54dff40d
commit
2bf0926824
19
http/context.go
Normal file
19
http/context.go
Normal file
@ -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)
|
||||||
|
})
|
||||||
@ -15,6 +15,11 @@ import (
|
|||||||
"github.com/filebrowser/filebrowser/v2/fileutils"
|
"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) {
|
var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||||
file, err := files.NewFileInfo(files.FileOptions{
|
file, err := files.NewFileInfo(files.FileOptions{
|
||||||
Fs: d.user.Fs,
|
Fs: d.user.Fs,
|
||||||
@ -27,13 +32,21 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d
|
|||||||
return errToStatus(err), err
|
return errToStatus(err), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource := &resourceInfo{
|
||||||
|
FileInfo: file,
|
||||||
|
}
|
||||||
|
|
||||||
if file.IsDir {
|
if file.IsDir {
|
||||||
file.Listing.Sorting = d.user.Sorting
|
file.Listing.Sorting = d.user.Sorting
|
||||||
file.Listing.ApplySort()
|
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)
|
err := file.Checksum(checksum)
|
||||||
if err == errors.ErrInvalidOption {
|
if err == errors.ErrInvalidOption {
|
||||||
return http.StatusBadRequest, nil
|
return http.StatusBadRequest, nil
|
||||||
@ -45,7 +58,7 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d
|
|||||||
file.Content = ""
|
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) {
|
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) {
|
var resourcePatchHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||||
src := r.URL.Path
|
src := r.URL.Path
|
||||||
dst := r.URL.Query().Get("destination")
|
dst := r.URL.Query().Get("destination")
|
||||||
|
name := r.URL.Query().Get("name")
|
||||||
action := r.URL.Query().Get("action")
|
action := r.URL.Query().Get("action")
|
||||||
dst, err := url.QueryUnescape(dst)
|
dst, err := url.QueryUnescape(dst)
|
||||||
|
|
||||||
@ -133,26 +147,38 @@ var resourcePatchHandler = withUser(func(w http.ResponseWriter, r *http.Request,
|
|||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hook func() error
|
||||||
|
|
||||||
switch action {
|
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":
|
case "copy":
|
||||||
if !d.user.Perm.Create {
|
if !d.user.Perm.Create {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
hook = func() error {
|
||||||
|
return fileutils.Copy(d.user.Fs, src, dst)
|
||||||
|
}
|
||||||
case "rename":
|
case "rename":
|
||||||
default:
|
default:
|
||||||
action = "rename"
|
action = "rename"
|
||||||
if !d.user.Perm.Rename {
|
if !d.user.Perm.Rename {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
hook = func() error {
|
||||||
|
return d.user.Fs.Rename(src, dst)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.RunHook(func() error {
|
err = d.RunHook(hook, action, src, dst, d.user)
|
||||||
if action == "copy" {
|
|
||||||
return fileutils.Copy(d.user.Fs, src, dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
return d.user.Fs.Rename(src, dst)
|
|
||||||
}, action, src, dst, d.user)
|
|
||||||
|
|
||||||
return errToStatus(err), err
|
return errToStatus(err), err
|
||||||
})
|
})
|
||||||
|
|||||||
@ -8,12 +8,13 @@ import (
|
|||||||
// UserDefaults is a type that holds the default values
|
// UserDefaults is a type that holds the default values
|
||||||
// for some fields on User.
|
// for some fields on User.
|
||||||
type UserDefaults struct {
|
type UserDefaults struct {
|
||||||
Scope string `json:"scope"`
|
Scope string `json:"scope"`
|
||||||
Locale string `json:"locale"`
|
Locale string `json:"locale"`
|
||||||
ViewMode users.ViewMode `json:"viewMode"`
|
ViewMode users.ViewMode `json:"viewMode"`
|
||||||
Sorting files.Sorting `json:"sorting"`
|
Sorting files.Sorting `json:"sorting"`
|
||||||
Perm users.Permissions `json:"perm"`
|
Perm users.Permissions `json:"perm"`
|
||||||
Commands []string `json:"commands"`
|
Commands []string `json:"commands"`
|
||||||
|
Bookmarks []users.Bookmark `json:"bookmarks"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply applies the default options to a user.
|
// Apply applies the default options to a user.
|
||||||
@ -24,4 +25,5 @@ func (d *UserDefaults) Apply(u *users.User) {
|
|||||||
u.Perm = d.Perm
|
u.Perm = d.Perm
|
||||||
u.Sorting = d.Sorting
|
u.Sorting = d.Sorting
|
||||||
u.Commands = d.Commands
|
u.Commands = d.Commands
|
||||||
|
u.Bookmarks = d.Bookmarks
|
||||||
}
|
}
|
||||||
|
|||||||
7
users/bookmark.go
Normal file
7
users/bookmark.go
Normal file
@ -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"`
|
||||||
|
}
|
||||||
@ -33,6 +33,7 @@ type User struct {
|
|||||||
Sorting files.Sorting `json:"sorting"`
|
Sorting files.Sorting `json:"sorting"`
|
||||||
Fs afero.Fs `json:"-" yaml:"-"`
|
Fs afero.Fs `json:"-" yaml:"-"`
|
||||||
Rules []rules.Rule `json:"rules"`
|
Rules []rules.Rule `json:"rules"`
|
||||||
|
Bookmarks []Bookmark `json:"bookmarks"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRules implements rules.Provider.
|
// GetRules implements rules.Provider.
|
||||||
@ -48,6 +49,7 @@ var checkableFields = []string{
|
|||||||
"Commands",
|
"Commands",
|
||||||
"Sorting",
|
"Sorting",
|
||||||
"Rules",
|
"Rules",
|
||||||
|
"Bookmarks",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean cleans up a user and verifies if all its fields
|
// 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 {
|
if u.Rules == nil {
|
||||||
u.Rules = []rules.Rule{}
|
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
|
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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user