1
0
Эх сурвалжийг харах

проход по дереву и вывод списка файлов

kpmy 8 жил өмнө
parent
commit
35f8129d58
5 өөрчлөгдсөн 205 нэмэгдсэн , 33 устгасан
  1. 137 27
      fs.go
  2. 19 0
      fs_test.go
  3. 4 4
      ipfs_api/api.go
  4. 2 2
      ipfs_api/ipfs_api_test.go
  5. 43 0
      trav.go

+ 137 - 27
fs.go

@@ -4,56 +4,156 @@ import (
 	"os"
 	"time"
 
-	ipfs_api "github.com/ipfs/go-ipfs-api"
+	"github.com/ipfs/go-ipfs-api"
 
-	ipfs "github.com/kpmy/mipfs/ipfs_api"
+	"github.com/kpmy/mipfs/ipfs_api"
 	. "github.com/kpmy/ypk/tc"
 	"golang.org/x/net/webdav"
 )
 
-type dir struct {
-	ipfs_api.UnixLsObject
+type file struct {
+	go_ipfs_api.UnixLsLink
 }
 
-func (d *dir) Name() string {
-	return d.UnixLsObject.Hash
+func (f *file) Name() string {
+	return f.UnixLsLink.Name
 }
 
-func (d *dir) Size() int64 {
+func (f *file) Size() int64 {
+	return int64(f.UnixLsLink.Size)
+}
+
+func (f *file) Mode() os.FileMode {
 	return 0
 }
 
-func (d *dir) Mode() os.FileMode { return os.ModeDir }
+func (f *file) ModTime() time.Time {
+	return time.Now()
+}
+
+func (f *file) IsDir() bool {
+	return false
+}
+func (f *file) Sys() interface{} {
+	return nil
+}
+
+func (f *file) Close() error {
+	return nil
+}
+
+func (f *file) Read(p []byte) (n int, err error) {
+	panic(100)
+}
+
+func (f *file) Seek(offset int64, whence int) (int64, error) {
+	panic(100)
+}
+
+func (f *file) Readdir(count int) (ret []os.FileInfo, err error) {
+	panic(100)
+}
+
+func (f *file) Stat() (os.FileInfo, error) {
+	return &link{f.UnixLsLink}, nil
+}
+
+func (f *file) Write(p []byte) (n int, err error) {
+	panic(100)
+}
+
+type link struct {
+	go_ipfs_api.UnixLsLink
+}
+
+func (l *link) Name() string {
+	return l.UnixLsLink.Name
+}
+
+func (l *link) Size() int64 {
+	return int64(l.UnixLsLink.Size)
+}
+
+func (l *link) Mode() os.FileMode {
+	if l.Type == "Directory" {
+		return os.ModeDir
+	} else if l.Type == "File" {
+		return 0
+	}
+	panic(100)
+}
+
+func (l *link) ModTime() time.Time {
+	return time.Now()
+}
+
+func (l *link) IsDir() bool {
+	return l.Type == "Directory"
+}
+func (l *link) Sys() interface{} {
+	return nil
+}
+
+type loc struct {
+	go_ipfs_api.UnixLsObject
+}
 
-func (d *dir) ModTime() time.Time {
+func (l *loc) Name() string {
+	return l.Hash
+}
+
+func (l *loc) Size() int64 {
+	return int64(l.UnixLsObject.Size)
+}
+
+func (l *loc) Mode() os.FileMode {
+	return os.ModeDir
+}
+
+func (l *loc) ModTime() time.Time {
 	return time.Now()
 }
 
-func (d *dir) IsDir() bool      { return true }
-func (d *dir) Sys() interface{} { return nil }
+func (l *loc) IsDir() bool {
+	return true
+}
+func (l *loc) Sys() interface{} {
+	return nil
+}
 
-func (d *dir) Close() error {
+func (l *loc) Close() error {
 	return nil
 }
 
-func (d *dir) Read(p []byte) (n int, err error) {
+func (l *loc) Read(p []byte) (n int, err error) {
 	panic(100)
 }
 
-func (d *dir) Seek(offset int64, whence int) (int64, error) {
+func (l *loc) Seek(offset int64, whence int) (int64, error) {
 	panic(100)
 }
 
-func (d *dir) Readdir(count int) ([]os.FileInfo, error) {
-	return []os.FileInfo{}, nil
+func (l *loc) Readdir(count int) (ret []os.FileInfo, err error) {
+	ls, _ := ipfs_api.Shell().FileList(l.Hash)
+	for _, l := range ls.Links {
+		switch l.Type {
+		case "File":
+			fallthrough
+		case "Directory":
+			ret = append(ret, &link{*l})
+		default:
+			Halt(100)
+		}
+	}
+	return
 }
 
-func (d *dir) Stat() (os.FileInfo, error) {
-	ls, _ := ipfs.Shell().FileList(d.Hash)
-	return &dir{*ls}, nil
+func (l *loc) Stat() (os.FileInfo, error) {
+	ls, _ := ipfs_api.Shell().FileList(l.Hash)
+	return &loc{*ls}, nil
 }
 
-func (d *dir) Write(p []byte) (n int, err error) {
+func (l *loc) Write(p []byte) (n int, err error) {
 	panic(100)
 }
 
@@ -68,8 +168,13 @@ func (f *filesystem) Mkdir(name string, perm os.FileMode) error {
 }
 
 func (f *filesystem) OpenFile(name string, flag int, perm os.FileMode) (webdav.File, error) {
-	ls, _ := ipfs.Shell().FileList(f.root)
-	return &dir{*ls}, nil
+	if li, fi := trav(f.root, name); fi != nil {
+		return &file{fi.UnixLsLink}, nil
+	} else if li != nil {
+		return li, nil
+	} else {
+		panic(0)
+	}
 }
 
 func (f *filesystem) RemoveAll(name string) error {
@@ -81,14 +186,19 @@ func (f *filesystem) Rename(oldName, newName string) error {
 }
 
 func (f *filesystem) Stat(name string) (os.FileInfo, error) {
-	ls, _ := ipfs.Shell().FileList(f.root)
-	return &dir{*ls}, nil
+	if li, fi := trav(f.root, name); fi != nil {
+		return fi, nil
+	} else if li != nil {
+		return li, nil
+	} else {
+		panic(0)
+	}
 }
 
-var nodeID *ipfs_api.IdOutput;
+var nodeID *go_ipfs_api.IdOutput
 
-func init()  {
-	nodeID, _ = ipfs.Shell().ID()
+func init() {
+	nodeID, _ = ipfs_api.Shell().ID()
 }
 
 func NewFS() webdav.FileSystem {

+ 19 - 0
fs_test.go

@@ -1,6 +1,8 @@
 package mipfs
 
 import (
+	"os"
+	"path/filepath"
 	"testing"
 )
 
@@ -8,3 +10,20 @@ func TestFS(t *testing.T) {
 	NewFS()
 	NewLS()
 }
+
+func TestTrav(t *testing.T) {
+	root := string([]rune{os.PathSeparator})
+	var trav func(string) interface{}
+	trav = func(name string) interface{} {
+		if name == root {
+			return ""
+		} else {
+			_, last := filepath.Split(name)
+			trav(filepath.Dir(name))
+			t.Log(last)
+			return nil
+		}
+	}
+
+	trav("/user/data/pic.gif")
+}

+ 4 - 4
ipfs_api/api.go

@@ -3,14 +3,14 @@ package ipfs_api
 import (
 	"log"
 
-	ipfs "github.com/ipfs/go-ipfs-api"
+	"github.com/ipfs/go-ipfs-api"
 )
 
-var sh *ipfs.Shell
+var sh *go_ipfs_api.Shell
 
 func reset() {
 	if sh == nil || !sh.IsUp() {
-		sh = ipfs.NewShell("127.0.0.1:5001")
+		sh = go_ipfs_api.NewShell("127.0.0.1:5001")
 		if id, err := sh.ID(); err == nil {
 			v0, _, _ := sh.Version()
 			log.Println("ipfs version", v0, "node", id.ID, "online")
@@ -18,7 +18,7 @@ func reset() {
 	}
 }
 
-func Shell() *ipfs.Shell {
+func Shell() *go_ipfs_api.Shell {
 	reset()
 	return sh
 }

+ 2 - 2
ipfs_api/ipfs_api_test.go

@@ -5,11 +5,11 @@ import (
 
 	"net/http"
 
-	ipfs "github.com/ipfs/go-ipfs-api"
+	"github.com/ipfs/go-ipfs-api"
 )
 
 func TestShell(t *testing.T) {
-	sh := ipfs.NewShellWithClient("127.0.0.1:5001", http.DefaultClient)
+	sh := go_ipfs_api.NewShellWithClient("127.0.0.1:5001", http.DefaultClient)
 	id, _ := sh.ID()
 	t.Log(id)
 	root, _ := sh.Resolve("/ipns/" + id.ID)

+ 43 - 0
trav.go

@@ -0,0 +1,43 @@
+package mipfs
+
+import (
+	"github.com/kpmy/mipfs/ipfs_api"
+	"os"
+	"path/filepath"
+)
+
+var root = string([]rune{os.PathSeparator})
+
+func find(li *loc, name string) (ret *loc) {
+	for _, i := range li.Links {
+		if i.Type == "Directory" && i.Name == name {
+			ls, _ := ipfs_api.Shell().FileList(i.Hash)
+			return &loc{*ls}
+		}
+	}
+	return
+}
+
+func find2(li *loc, name string) (ret *link) {
+	for _, i := range li.Links {
+		if i.Type == "File" && i.Name == name {
+			return &link{*i}
+		}
+	}
+	return
+}
+
+func trav(rootHash string, name string) (*loc, *link) {
+	if name == root {
+		ls, _ := ipfs_api.Shell().FileList(rootHash)
+		return &loc{*ls}, nil
+	} else {
+		_, last := filepath.Split(name)
+		l, _ := trav(rootHash, filepath.Dir(name))
+		if li := find(l, last); li != nil {
+			return li, nil
+		} else {
+			return l, find2(l, last)
+		}
+	}
+}