core/commands2: Updated 'add' command for new file API
Matt Bell committed
Nov 16, 2014 at 22:07 UTC
032e9c292f4865606ae755184aa90bdcbf0ee5c4
1 file changed
+72
-65
core/commands2/add.go
+72
-65
@@ -5,6 +5,7 @@ import (
5
"errors"
6
"fmt"
7
"io"
8
+ "strings"
9
10
cmds "github.com/jbenet/go-ipfs/commands"
11
core "github.com/jbenet/go-ipfs/core"
@@ -12,6 +13,7 @@ import (
13
"github.com/jbenet/go-ipfs/importer/chunk"
14
dag "github.com/jbenet/go-ipfs/merkledag"
15
pinning "github.com/jbenet/go-ipfs/pin"
16
+ ft "github.com/jbenet/go-ipfs/unixfs"
17
u "github.com/jbenet/go-ipfs/util"
18
)
19
@@ -34,11 +36,8 @@ remains to be implemented.
36
`,
37
},
38
37
- Options: []cmds.Option{
38
- cmds.BoolOption("recursive", "r", "Must be specified when adding directories"),
39
- },
39
Arguments: []cmds.Argument{
41
- cmds.FileArg("path", true, true, "The path to a file to be added to IPFS"),
40
+ cmds.FileArg("path", true, true, "The path to a file to be added to IPFS").EnableRecursive(),
41
},
42
Run: func(req cmds.Request) (interface{}, error) {
43
added := &AddOutput{}
@@ -47,75 +46,22 @@ remains to be implemented.
46
return nil, err
47
}
48
50
- _, _, err = req.Option("r").Bool()
51
- if err != nil {
52
- return nil, err
53
- }
54
-
55
- // returns the last one
56
- addDagnode := func(name string, dn *dag.Node) error {
57
- o, err := getOutput(dn)
58
- if err != nil {
59
- return err
60
- }
61
-
62
- added.Objects = append(added.Objects, o)
63
- added.Names = append(added.Names, name)
64
- return nil
65
- }
66
-
67
- addFile := func(file cmds.File) (*dag.Node, error) {
68
- dns, err := add(n, []io.Reader{file})
69
- if err != nil {
49
+ for {
50
+ file, err := req.Files().NextFile()
51
+ if err != nil && err != io.EOF {
52
return nil, err
53
}
72
-
73
- log.Infof("adding file: %s", file.FileName())
74
- if err := addDagnode(file.FileName(), dns[len(dns)-1]); err != nil {
75
- return nil, err
54
+ if file == nil {
55
+ break
56
}
77
- return dns[len(dns)-1], nil // last dag node is the file.
78
- }
57
80
- // TODO: handle directories
81
-
82
- file, err := req.Files().NextFile()
83
- for file != nil {
84
- _, err := addFile(file)
58
+ _, err = addFile(n, file, added)
59
if err != nil {
60
return nil, err
61
}
88
-
89
- file, err = req.Files().NextFile()
90
- }
91
- if err != nil && err != io.EOF {
92
- return nil, err
62
}
63
64
return added, nil
96
-
97
- // readers, err := internal.CastToReaders(req.Arguments())
98
- // if err != nil {
99
- // return nil, err
100
- // }
101
- //
102
- // dagnodes, err := add(n, readers)
103
- // if err != nil {
104
- // return nil, err
105
- // }
106
- //
107
- // // TODO: include fs paths in output (will need a way to specify paths in underlying filearg system)
108
- // added := make([]*Object, 0, len(req.Arguments()))
109
- // for _, dagnode := range dagnodes {
110
- // object, err := getOutput(dagnode)
111
- // if err != nil {
112
- // return nil, err
113
- // }
114
- //
115
- // added = append(added, object)
116
- // }
117
- //
118
- // return &AddOutput{added}, nil
65
},
66
Marshalers: cmds.MarshalerMap{
67
cmds.Text: func(res cmds.Response) ([]byte, error) {
@@ -142,8 +88,6 @@ func add(n *core.IpfsNode, readers []io.Reader) ([]*dag.Node, error) {
88
89
dagnodes := make([]*dag.Node, 0)
90
145
- // TODO: allow adding directories (will need support for multiple files in filearg system)
146
-
91
for _, reader := range readers {
92
node, err := importer.BuildDagFromReader(reader, n.DAG, mp, chunk.DefaultSplitter)
93
if err != nil {
@@ -168,3 +112,66 @@ func addNode(n *core.IpfsNode, node *dag.Node) error {
112
113
return nil
114
}
115
+
116
+func addFile(n *core.IpfsNode, file cmds.File, added *AddOutput) (*dag.Node, error) {
117
+ if file.IsDirectory() {
118
+ return addDir(n, file, added)
119
+ }
120
+
121
+ dns, err := add(n, []io.Reader{file})
122
+ if err != nil {
123
+ return nil, err
124
+ }
125
+
126
+ log.Infof("adding file: %s", file.FileName())
127
+ if err := addDagnode(added, file.FileName(), dns[len(dns)-1]); err != nil {
128
+ return nil, err
129
+ }
130
+ return dns[len(dns)-1], nil // last dag node is the file.
131
+}
132
+
133
+func addDir(n *core.IpfsNode, dir cmds.File, added *AddOutput) (*dag.Node, error) {
134
+ log.Infof("adding directory: %s", dir.FileName())
135
+
136
+ tree := &dag.Node{Data: ft.FolderPBData()}
137
+
138
+ for {
139
+ file, err := dir.NextFile()
140
+ if err != nil && err != io.EOF {
141
+ return nil, err
142
+ }
143
+ if file == nil {
144
+ break
145
+ }
146
+
147
+ node, err := addFile(n, file, added)
148
+ if err != nil {
149
+ return nil, err
150
+ }
151
+
152
+ name := file.FileName()
153
+ slashIndex := strings.LastIndex(name, "/")
154
+ name = name[slashIndex+1:]
155
+
156
+ err = tree.AddNodeLink(name, node)
157
+ if err != nil {
158
+ return nil, err
159
+ }
160
+ }
161
+
162
+ addDagnode(added, dir.FileName(), tree)
163
+
164
+ return tree, addNode(n, tree)
165
+}
166
+
167
+// addDagnode adds dagnode info to an output object
168
+func addDagnode(output *AddOutput, name string, dn *dag.Node) error {
169
+ o, err := getOutput(dn)
170
+ if err != nil {
171
+ return err
172
+ }
173
+
174
+ output.Objects = append(output.Objects, o)
175
+ output.Names = append(output.Names, name)
176
+ return nil
177
+}