Browse Source

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

pull/10/head
Chris Lu 11 years ago
parent
commit
77fd5ecd98
  1. 16
      go/filer/directory_in_map.go
  2. 60
      go/filer/directory_test.go
  3. 2
      go/filer/filer.go
  4. 33
      go/filer/filer_embedded.go
  5. 7
      go/filer/files_in_leveldb.go
  6. 4
      go/images/resizing.go
  7. 1
      go/weed/weed_server/filer_server.go
  8. 28
      go/weed/weed_server/filer_server_handlers_admin.go
  9. 2
      go/weed/weed_server/master_server_handlers_admin.go

16
go/filer/directory_in_map.go

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

60
go/filer/directory_test.go

@ -7,38 +7,44 @@ import (
) )
func TestDirectory(t *testing.T) { 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()
}()
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 _, 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)
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)
dm2, e := NewDirectoryManagerInMap("/tmp/dir.log")
if e != nil {
println("load error", e.Error())
} }
if true {
os.Remove("/tmp/dir.log")
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) {

2
go/filer/filer.go

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

33
go/filer/filer_embedded.go

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

7
go/filer/files_in_leveldb.go

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

4
go/images/resizing.go

@ -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{
return data, bounds.Dx(), bounds.Dy()
} else {
return data, bounds.Dx(), bounds.Dy()
} }
var buf bytes.Buffer var buf bytes.Buffer
switch ext { switch ext {

1
go/weed/weed_server/filer_server.go

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

28
go/weed/weed_server/filer_server_handlers_admin.go

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

2
go/weed/weed_server/master_server_handlers_admin.go

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

Loading…
Cancel
Save