mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
Add /admin/mv to move a file or a folder
This commit is contained in:
parent
8e7f08d04d
commit
77fd5ecd98
|
@ -81,7 +81,11 @@ func (dm *DirectoryManagerInMap) processEachLine(line string) error {
|
|||
return e
|
||||
}
|
||||
case "mov":
|
||||
if e := dm.MoveUnderDirectory(parts[1], parts[2]); e != nil {
|
||||
newName := ""
|
||||
if len(parts) >= 4 {
|
||||
newName = parts[3]
|
||||
}
|
||||
if e := dm.MoveUnderDirectory(parts[1], parts[2], newName); e != nil {
|
||||
return e
|
||||
}
|
||||
case "del":
|
||||
|
@ -188,7 +192,7 @@ func (dm *DirectoryManagerInMap) MakeDirectory(dirPath string) (DirectoryId, err
|
|||
return dir.Id, nil
|
||||
}
|
||||
|
||||
func (dm *DirectoryManagerInMap) MoveUnderDirectory(oldDirPath string, newParentDirPath string) error {
|
||||
func (dm *DirectoryManagerInMap) MoveUnderDirectory(oldDirPath string, newParentDirPath string, newName string) error {
|
||||
oldDir, oe := dm.findDirectory(oldDirPath)
|
||||
if oe != nil {
|
||||
return oe
|
||||
|
@ -197,10 +201,14 @@ func (dm *DirectoryManagerInMap) MoveUnderDirectory(oldDirPath string, newParent
|
|||
if pe != nil {
|
||||
return pe
|
||||
}
|
||||
dm.log("mov", oldDirPath, newParentDirPath, newName)
|
||||
delete(oldDir.Parent.SubDirectories, oldDir.Name)
|
||||
parentDir.SubDirectories[oldDir.Name] = oldDir
|
||||
if newName == "" {
|
||||
newName = oldDir.Name
|
||||
}
|
||||
parentDir.SubDirectories[newName] = oldDir
|
||||
oldDir.Name = newName
|
||||
oldDir.Parent = parentDir
|
||||
dm.log("mov", oldDirPath, newParentDirPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -7,38 +7,44 @@ import (
|
|||
)
|
||||
|
||||
func TestDirectory(t *testing.T) {
|
||||
{
|
||||
dm, _ := NewDirectoryManagerInMap("/tmp/dir.log")
|
||||
dm.MakeDirectory("/a/b/c")
|
||||
dm.MakeDirectory("/a/b/d")
|
||||
dm.MakeDirectory("/a/b/e")
|
||||
dm.MakeDirectory("/a/b/e/f")
|
||||
dm.MakeDirectory("/a/b/e/f/g")
|
||||
dm.MoveUnderDirectory("/a/b/e/f/g", "/a/b")
|
||||
dm.MakeDirectory("/a/b/g/h/i")
|
||||
dm.DeleteDirectory("/a/b/e/f")
|
||||
dm.DeleteDirectory("/a/b/e")
|
||||
dirNames, _ := dm.ListDirectories("/a/b/e")
|
||||
for _, v := range dirNames {
|
||||
println("sub1 dir:", v.Name, "id", v.Id)
|
||||
dm, _ := NewDirectoryManagerInMap("/tmp/dir.log")
|
||||
defer func() {
|
||||
if true {
|
||||
os.Remove("/tmp/dir.log")
|
||||
}
|
||||
dm.logFile.Close()
|
||||
|
||||
var path []string
|
||||
printTree(dm.Root, path)
|
||||
|
||||
dm2, e := NewDirectoryManagerInMap("/tmp/dir.log")
|
||||
if e != nil {
|
||||
println("load error", e.Error())
|
||||
}
|
||||
if !compare(dm.Root, dm2.Root) {
|
||||
t.Fatal("restored dir not the same!")
|
||||
}
|
||||
printTree(dm2.Root, path)
|
||||
}()
|
||||
dm.MakeDirectory("/a/b/c")
|
||||
dm.MakeDirectory("/a/b/d")
|
||||
dm.MakeDirectory("/a/b/e")
|
||||
dm.MakeDirectory("/a/b/e/f")
|
||||
dm.MakeDirectory("/a/b/e/f/g")
|
||||
dm.MoveUnderDirectory("/a/b/e/f/g", "/a/b")
|
||||
if _, err := dm.FindDirectory("/a/b/e/f/g"); err == nil {
|
||||
t.Fatal("/a/b/e/f/g should not exist any more after moving")
|
||||
}
|
||||
if true {
|
||||
os.Remove("/tmp/dir.log")
|
||||
if _, err := dm.FindDirectory("/a/b/g"); err != nil {
|
||||
t.Fatal("/a/b/g should exist after moving")
|
||||
}
|
||||
dm.MakeDirectory("/a/b/g/h/i")
|
||||
dm.DeleteDirectory("/a/b/e/f")
|
||||
dm.DeleteDirectory("/a/b/e")
|
||||
dirNames, _ := dm.ListDirectories("/a/b/e")
|
||||
for _, v := range dirNames {
|
||||
println("sub1 dir:", v.Name, "id", v.Id)
|
||||
}
|
||||
dm.logFile.Close()
|
||||
|
||||
var path []string
|
||||
printTree(dm.Root, path)
|
||||
|
||||
dm2, e := NewDirectoryManagerInMap("/tmp/dir.log")
|
||||
if e != nil {
|
||||
println("load error", e.Error())
|
||||
}
|
||||
if !compare(dm.Root, dm2.Root) {
|
||||
t.Fatal("restored dir not the same!")
|
||||
}
|
||||
printTree(dm2.Root, path)
|
||||
}
|
||||
|
||||
func printTree(node *DirectoryEntryInMap, path []string) {
|
||||
|
|
|
@ -12,8 +12,10 @@ type FileEntry struct {
|
|||
type Filer interface {
|
||||
CreateFile(filePath string, fid string) (err error)
|
||||
FindFile(filePath string) (fid string, err error)
|
||||
FindDirectory(dirPath string) (dirId DirectoryId, err error)
|
||||
ListDirectories(dirPath string) (dirs []DirectoryEntry, err error)
|
||||
ListFiles(dirPath string, lastFileName string, limit int) (files []FileEntry, err error)
|
||||
DeleteDirectory(dirPath string, recursive bool) (err error)
|
||||
DeleteFile(filePath string) (fid string, err error)
|
||||
Move(fromPath string, toPath string) (err error)
|
||||
}
|
||||
|
|
|
@ -47,6 +47,9 @@ func (filer *FilerEmbedded) FindFile(filePath string) (fid string, err error) {
|
|||
}
|
||||
return filer.files.FindFile(dirId, file)
|
||||
}
|
||||
func (filer *FilerEmbedded) FindDirectory(dirPath string) (dirId DirectoryId, err error) {
|
||||
return filer.directories.FindDirectory(dirPath)
|
||||
}
|
||||
func (filer *FilerEmbedded) ListDirectories(dirPath string) (dirs []DirectoryEntry, err error) {
|
||||
return filer.directories.ListDirectories(dirPath)
|
||||
}
|
||||
|
@ -98,6 +101,7 @@ func (filer *FilerEmbedded) DeleteDirectory(dirPath string, recursive bool) (err
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func (filer *FilerEmbedded) DeleteFile(filePath string) (fid string, err error) {
|
||||
dir, file := filepath.Split(filePath)
|
||||
dirId, e := filer.directories.FindDirectory(dir)
|
||||
|
@ -106,3 +110,32 @@ func (filer *FilerEmbedded) DeleteFile(filePath string) (fid string, err error)
|
|||
}
|
||||
return filer.files.DeleteFile(dirId, file)
|
||||
}
|
||||
|
||||
/*
|
||||
Move a folder or a file, with 4 Use cases:
|
||||
mv fromDir toNewDir
|
||||
mv fromDir toOldDir
|
||||
mv fromFile toDir
|
||||
mv fromFile toFile
|
||||
*/
|
||||
func (filer *FilerEmbedded) Move(fromPath string, toPath string) error {
|
||||
if _, dir_err := filer.FindDirectory(fromPath); dir_err == nil {
|
||||
if _, err := filer.FindDirectory(toPath); err == nil {
|
||||
// move folder under an existing folder
|
||||
return filer.directories.MoveUnderDirectory(fromPath, toPath, "")
|
||||
} else {
|
||||
// move folder to a new folder
|
||||
return filer.directories.MoveUnderDirectory(fromPath, filepath.Dir(toPath), filepath.Base(toPath))
|
||||
}
|
||||
}
|
||||
if fid, file_err := filer.DeleteFile(fromPath); file_err == nil {
|
||||
if _, err := filer.FindDirectory(toPath); err == nil {
|
||||
// move file under an existing folder
|
||||
return filer.CreateFile(filepath.Join(toPath, filepath.Base(fromPath)), fid)
|
||||
} else {
|
||||
// move to a folder with new name
|
||||
return filer.CreateFile(toPath, fid)
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("File %s is not found!", fromPath)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,13 @@ import (
|
|||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
)
|
||||
|
||||
/*
|
||||
The entry in level db has this format:
|
||||
key: genKey(dirId, fileName)
|
||||
value: []byte(fid)
|
||||
And genKey(dirId, fileName) use first 4 bytes to store dirId, and rest for fileName
|
||||
*/
|
||||
|
||||
type FileListInLevelDb struct {
|
||||
db *leveldb.DB
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ func Resized(ext string, data []byte, width, height int) (resized []byte, w int,
|
|||
} else {
|
||||
dstImage = imaging.Resize(srcImage, width, height, imaging.Lanczos)
|
||||
}
|
||||
}else{
|
||||
return data, bounds.Dx(), bounds.Dy()
|
||||
} else {
|
||||
return data, bounds.Dx(), bounds.Dy()
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
switch ext {
|
||||
|
|
|
@ -26,6 +26,7 @@ func NewFilerServer(r *http.ServeMux, port int, master string, dir string, colle
|
|||
return
|
||||
}
|
||||
|
||||
r.HandleFunc("/admin/mv", fs.moveHandler)
|
||||
r.HandleFunc("/", fs.filerHandler)
|
||||
|
||||
return fs, nil
|
||||
|
|
28
go/weed/weed_server/filer_server_handlers_admin.go
Normal file
28
go/weed/weed_server/filer_server_handlers_admin.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package weed_server
|
||||
|
||||
import (
|
||||
"code.google.com/p/weed-fs/go/glog"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
/*
|
||||
Move a folder or a file, with 4 Use cases:
|
||||
mv fromDir toNewDir
|
||||
mv fromDir toOldDir
|
||||
mv fromFile toDir
|
||||
mv fromFile toFile
|
||||
|
||||
Wildcard is not supported.
|
||||
|
||||
*/
|
||||
func (fs *FilerServer) moveHandler(w http.ResponseWriter, r *http.Request) {
|
||||
from := r.FormValue("from")
|
||||
to := r.FormValue("to")
|
||||
err := fs.filer.Move(from, to)
|
||||
if err != nil {
|
||||
glog.V(4).Infoln("moving", from, "->", to, err.Error())
|
||||
writeJsonError(w, r, err)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
}
|
|
@ -99,7 +99,7 @@ func (ms *MasterServer) volumeGrowHandler(w http.ResponseWriter, r *http.Request
|
|||
w.WriteHeader(http.StatusNotAcceptable)
|
||||
writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
|
||||
} else {
|
||||
w.WriteHeader(http.StatusNotAcceptable)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
writeJsonQuiet(w, r, map[string]interface{}{"count": count})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue