unixfs: updated ls
This commit was moved from ipfs/go-ipfs-http-client@bb8d9d1a60e4161c4cf3a33c468746050f267a12
Łukasz Magiera committed
Feb 4, 2019 at 19:46 UTC
93bfcf91cf979b267758c04aa14c6435a687fc36
1 file changed
+75
-19
client/httpapi/unixfs.go
+75
-19
@@ -13,7 +13,6 @@ import (
13
14
"github.com/ipfs/go-ipfs-files"
15
"github.com/ipfs/go-ipld-format"
16
- unixfspb "github.com/ipfs/go-unixfs/pb"
16
mh "github.com/multiformats/go-multihash"
17
)
18
@@ -129,7 +128,7 @@ loop:
128
type lsLink struct {
129
Name, Hash string
130
Size uint64
132
- Type unixfspb.Data_DataType
131
+ Type iface.FileType
132
}
133
134
type lsObject struct {
@@ -141,30 +140,87 @@ type lsOutput struct {
140
Objects []lsObject
141
}
142
144
-func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path) ([]*format.Link, error) {
145
- var out lsOutput
146
- err := api.core().request("ls", p.String()).Exec(ctx, &out)
143
+func (api *UnixfsAPI) Ls(ctx context.Context, p iface.Path, opts ...caopts.UnixfsLsOption) (<-chan iface.LsLink, error) {
144
+ options, err := caopts.UnixfsLsOptions(opts...)
145
if err != nil {
146
return nil, err
147
}
148
151
- if len(out.Objects) != 1 {
152
- return nil, errors.New("unexpected objects len")
149
+ resp, err := api.core().request("ls", p.String()).
150
+ Option("resolve-type", options.ResolveChildren).
151
+ Option("size", options.ResolveChildren).
152
+ Option("stream", true).
153
+ Send(ctx)
154
+ if err != nil {
155
+ return nil, err
156
+ }
157
+ if resp.Error != nil {
158
+ return nil, resp.Error
159
}
160
155
- links := make([]*format.Link, len(out.Objects[0].Links))
156
- for i, l := range out.Objects[0].Links {
157
- c, err := cid.Parse(l.Hash)
158
- if err != nil {
159
- return nil, err
160
- }
161
- links[i] = &format.Link{
162
- Name: l.Name,
163
- Size: l.Size,
164
- Cid: c,
161
+ dec := json.NewDecoder(resp.Output)
162
+ out := make(chan iface.LsLink)
163
+
164
+ go func() {
165
+ defer resp.Close()
166
+ defer close(out)
167
+
168
+ for {
169
+ var link lsOutput
170
+ if err := dec.Decode(&link); err != nil {
171
+ if err == io.EOF {
172
+ return
173
+ }
174
+ select {
175
+ case out <- iface.LsLink{Err: err}:
176
+ case <-ctx.Done():
177
+ }
178
+ return
179
+ }
180
+
181
+ if len(link.Objects) != 1 {
182
+ select {
183
+ case out <- iface.LsLink{Err: errors.New("unexpected Objects len")}:
184
+ case <-ctx.Done():
185
+ }
186
+ return
187
+ }
188
+
189
+ if len(link.Objects[0].Links) != 1 {
190
+ select {
191
+ case out <- iface.LsLink{Err: errors.New("unexpected Links len")}:
192
+ case <-ctx.Done():
193
+ }
194
+ return
195
+ }
196
+
197
+ l0 := link.Objects[0].Links[0]
198
+
199
+ c, err := cid.Decode(l0.Hash)
200
+ if err != nil {
201
+ select {
202
+ case out <- iface.LsLink{Err: err}:
203
+ case <-ctx.Done():
204
+ }
205
+ return
206
+ }
207
+
208
+ select {
209
+ case out <- iface.LsLink{
210
+ Link: &format.Link{
211
+ Cid: c,
212
+ Name: l0.Name,
213
+ Size: l0.Size,
214
+ },
215
+ Size: l0.Size,
216
+ Type: l0.Type,
217
+ }:
218
+ case <-ctx.Done():
219
+ }
220
}
166
- }
167
- return links, nil
221
+ }()
222
+
223
+ return out, nil
224
}
225
226
func (api *UnixfsAPI) core() *HttpApi {