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 return e
} }
case "mov": 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 return e
} }
case "del": case "del":
@ -188,7 +192,7 @@ func (dm *DirectoryManagerInMap) MakeDirectory(dirPath string) (DirectoryId, err
return dir.Id, nil 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) oldDir, oe := dm.findDirectory(oldDirPath)
if oe != nil { if oe != nil {
return oe return oe
@ -197,10 +201,14 @@ func (dm *DirectoryManagerInMap) MoveUnderDirectory(oldDirPath string, newParent
if pe != nil { if pe != nil {
return pe return pe
} }
dm.log("mov", oldDirPath, newParentDirPath, newName)
delete(oldDir.Parent.SubDirectories, oldDir.Name) 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 oldDir.Parent = parentDir
dm.log("mov", oldDirPath, newParentDirPath)
return nil return nil
} }

View file

@ -7,38 +7,44 @@ import (
) )
func TestDirectory(t *testing.T) { func TestDirectory(t *testing.T) {
{ dm, _ := NewDirectoryManagerInMap("/tmp/dir.log")
dm, _ := NewDirectoryManagerInMap("/tmp/dir.log") defer func() {
dm.MakeDirectory("/a/b/c") if true {
dm.MakeDirectory("/a/b/d") os.Remove("/tmp/dir.log")
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.logFile.Close() }()
dm.MakeDirectory("/a/b/c")
var path []string dm.MakeDirectory("/a/b/d")
printTree(dm.Root, path) dm.MakeDirectory("/a/b/e")
dm.MakeDirectory("/a/b/e/f")
dm2, e := NewDirectoryManagerInMap("/tmp/dir.log") dm.MakeDirectory("/a/b/e/f/g")
if e != nil { dm.MoveUnderDirectory("/a/b/e/f/g", "/a/b")
println("load error", e.Error()) 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 !compare(dm.Root, dm2.Root) {
t.Fatal("restored dir not the same!")
}
printTree(dm2.Root, path)
} }
if true { if _, err := dm.FindDirectory("/a/b/g"); err != nil {
os.Remove("/tmp/dir.log") 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) { func printTree(node *DirectoryEntryInMap, path []string) {

View file

@ -12,8 +12,10 @@ type FileEntry struct {
type Filer interface { type Filer interface {
CreateFile(filePath string, fid string) (err error) CreateFile(filePath string, fid string) (err error)
FindFile(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) ListDirectories(dirPath string) (dirs []DirectoryEntry, err error)
ListFiles(dirPath string, lastFileName string, limit int) (files []FileEntry, err error) ListFiles(dirPath string, lastFileName string, limit int) (files []FileEntry, err error)
DeleteDirectory(dirPath string, recursive bool) (err error) DeleteDirectory(dirPath string, recursive bool) (err error)
DeleteFile(filePath string) (fid string, 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) 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) { func (filer *FilerEmbedded) ListDirectories(dirPath string) (dirs []DirectoryEntry, err error) {
return filer.directories.ListDirectories(dirPath) 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) { func (filer *FilerEmbedded) DeleteFile(filePath string) (fid string, err error) {
dir, file := filepath.Split(filePath) dir, file := filepath.Split(filePath)
dirId, e := filer.directories.FindDirectory(dir) 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) 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" "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 { type FileListInLevelDb struct {
db *leveldb.DB db *leveldb.DB
} }

View file

@ -23,8 +23,8 @@ func Resized(ext string, data []byte, width, height int) (resized []byte, w int,
} else { } else {
dstImage = imaging.Resize(srcImage, width, height, imaging.Lanczos) dstImage = imaging.Resize(srcImage, width, height, imaging.Lanczos)
} }
}else{ } else {
return data, bounds.Dx(), bounds.Dy() return data, bounds.Dx(), bounds.Dy()
} }
var buf bytes.Buffer var buf bytes.Buffer
switch ext { switch ext {

View file

@ -26,6 +26,7 @@ func NewFilerServer(r *http.ServeMux, port int, master string, dir string, colle
return return
} }
r.HandleFunc("/admin/mv", fs.moveHandler)
r.HandleFunc("/", fs.filerHandler) r.HandleFunc("/", fs.filerHandler)
return fs, nil 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) w.WriteHeader(http.StatusNotAcceptable)
writeJsonQuiet(w, r, map[string]string{"error": err.Error()}) writeJsonQuiet(w, r, map[string]string{"error": err.Error()})
} else { } else {
w.WriteHeader(http.StatusNotAcceptable) w.WriteHeader(http.StatusOK)
writeJsonQuiet(w, r, map[string]interface{}{"count": count}) writeJsonQuiet(w, r, map[string]interface{}{"count": count})
} }
} }