Add /admin/mv to move a file or a folder

This commit is contained in:
Chris Lu 2014-07-20 23:12:49 -07:00
parent 8e7f08d04d
commit 77fd5ecd98
9 changed files with 121 additions and 36 deletions

View file

@ -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
}

View file

@ -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) {

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -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 {

View file

@ -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

View 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)
}
}

View file

@ -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})
}
}