Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit ec15ca9

Browse files
committed
add files api
Signed-off-by: Max Peng <[email protected]>
1 parent 1c7f5d0 commit ec15ca9

File tree

2 files changed

+564
-0
lines changed

2 files changed

+564
-0
lines changed

mfs.go

Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
package shell
2+
3+
import (
4+
"context"
5+
"io"
6+
7+
files "github.com/ipfs/go-ipfs-files"
8+
)
9+
10+
type MfsLsEntry struct {
11+
Name string
12+
Type uint8
13+
Size uint64
14+
Hash string
15+
}
16+
17+
type filesLsOutput struct {
18+
Entries []*MfsLsEntry
19+
}
20+
21+
type filesFlushOutput struct {
22+
Cid string
23+
}
24+
25+
type filesStatOutput struct {
26+
Blocks int
27+
CumulativeSize uint64
28+
Hash string
29+
Local bool
30+
Size uint64
31+
SizeLocal uint64
32+
Type string
33+
WithLocality bool
34+
}
35+
36+
type filesOpt func(*RequestBuilder) error
37+
type filesLs struct{}
38+
type filesChcid struct{}
39+
type filesMkdir struct{}
40+
type filesRead struct{}
41+
type filesWrite struct{}
42+
type filesStat struct{}
43+
44+
var (
45+
FilesLs filesLs
46+
FilesChcid filesChcid
47+
FilesMkdir filesMkdir
48+
FilesRead filesRead
49+
FilesWrite filesWrite
50+
FilesStat filesStat
51+
)
52+
53+
// Long use long listing format
54+
func (filesLs) Long(long bool) filesOpt {
55+
return func(rb *RequestBuilder) error {
56+
rb.Option("long", long)
57+
return nil
58+
}
59+
}
60+
61+
// U do not sort; list entries in directory order
62+
func (filesLs) U(u bool) filesOpt {
63+
return func(rb *RequestBuilder) error {
64+
rb.Option("U", u)
65+
return nil
66+
}
67+
}
68+
69+
// CidVersion cid version to use. (experimental)
70+
func (filesChcid) CidVersion(version int) filesOpt {
71+
return func(rb *RequestBuilder) error {
72+
rb.Option("cid-version", version)
73+
return nil
74+
}
75+
}
76+
77+
// Hash hash function to use. Will set Cid version to 1 if used. (experimental)
78+
func (filesChcid) Hash(hash string) filesOpt {
79+
return func(rb *RequestBuilder) error {
80+
rb.Option("hash", hash)
81+
return nil
82+
}
83+
}
84+
85+
// Parents no error if existing, make parent directories as needed
86+
func (filesMkdir) Parents(parents bool) filesOpt {
87+
return func(rb *RequestBuilder) error {
88+
rb.Option("parents", parents)
89+
return nil
90+
}
91+
}
92+
93+
// CidVersion cid version to use. (experimental)
94+
func (filesMkdir) CidVersion(version int) filesOpt {
95+
return func(rb *RequestBuilder) error {
96+
rb.Option("cid-version", version)
97+
return nil
98+
}
99+
}
100+
101+
// Hash hash function to use. Will set Cid version to 1 if used. (experimental)
102+
func (filesMkdir) Hash(hash string) filesOpt {
103+
return func(rb *RequestBuilder) error {
104+
rb.Option("hash", hash)
105+
return nil
106+
}
107+
}
108+
109+
// Offset byte offset to begin reading from
110+
func (filesRead) Offset(offset int64) filesOpt {
111+
return func(rb *RequestBuilder) error {
112+
rb.Option("offset", offset)
113+
return nil
114+
}
115+
}
116+
117+
// Count maximum number of bytes to read
118+
func (filesRead) Count(count int64) filesOpt {
119+
return func(rb *RequestBuilder) error {
120+
rb.Option("count", count)
121+
return nil
122+
}
123+
}
124+
125+
// Format print statistics in given format. Allowed tokens: <hash> <size> <cumulsize> <type> <childs>. Conflicts with other format options.
126+
func (filesStat) Format(format string) filesOpt {
127+
return func(rb *RequestBuilder) error {
128+
rb.Option("format", format)
129+
return nil
130+
}
131+
}
132+
133+
// Hash print only hash. Implies '--format=<hash>'. Conflicts with other format options.
134+
func (filesStat) Hash(hash bool) filesOpt {
135+
return func(rb *RequestBuilder) error {
136+
rb.Option("hash", hash)
137+
return nil
138+
}
139+
}
140+
141+
// Size print only size. Implies '--format=<cumulsize>'. Conflicts with other format options.
142+
func (filesStat) Size(size bool) filesOpt {
143+
return func(rb *RequestBuilder) error {
144+
rb.Option("size", size)
145+
return nil
146+
}
147+
}
148+
149+
// WithLocal compute the amount of the dag that is local, and if possible the total size.
150+
func (filesStat) WithLocal(withLocal bool) filesOpt {
151+
return func(rb *RequestBuilder) error {
152+
rb.Option("with-local", withLocal)
153+
return nil
154+
}
155+
}
156+
157+
// Offset byte offset to begin writing at
158+
func (filesWrite) Offset(offset int64) filesOpt {
159+
return func(rb *RequestBuilder) error {
160+
rb.Option("offset", offset)
161+
return nil
162+
}
163+
}
164+
165+
// Create create the file if it does not exist
166+
func (filesWrite) Create(create bool) filesOpt {
167+
return func(rb *RequestBuilder) error {
168+
rb.Option("create", create)
169+
return nil
170+
}
171+
}
172+
173+
// Parents make parent directories as needed
174+
func (filesWrite) Parents(parents bool) filesOpt {
175+
return func(rb *RequestBuilder) error {
176+
rb.Option("parents", parents)
177+
return nil
178+
}
179+
}
180+
181+
// Truncate truncate the file to size zero before writing
182+
func (filesWrite) Truncate(truncate bool) filesOpt {
183+
return func(rb *RequestBuilder) error {
184+
rb.Option("truncate", truncate)
185+
return nil
186+
}
187+
}
188+
189+
// Count maximum number of bytes to write
190+
func (filesWrite) Count(count int64) filesOpt {
191+
return func(rb *RequestBuilder) error {
192+
rb.Option("count", count)
193+
return nil
194+
}
195+
}
196+
197+
// RawLeaves use raw blocks for newly created leaf nodes. (experimental)
198+
func (filesWrite) RawLeaves(rawLeaves bool) filesOpt {
199+
return func(rb *RequestBuilder) error {
200+
rb.Option("raw-leaves", rawLeaves)
201+
return nil
202+
}
203+
}
204+
205+
// CidVersion cid version to use. (experimental)
206+
func (filesWrite) CidVersion(version int) filesOpt {
207+
return func(rb *RequestBuilder) error {
208+
rb.Option("cid-version", version)
209+
return nil
210+
}
211+
}
212+
213+
// Hash hash function to use. Will set Cid version to 1 if used. (experimental)
214+
func (filesWrite) Hash(hash string) filesOpt {
215+
return func(rb *RequestBuilder) error {
216+
rb.Option("hash", hash)
217+
return nil
218+
}
219+
}
220+
221+
// FilesChcid change the cid version or hash function of the root node of a given path
222+
func (s *Shell) FilesChcid(path string, options ...filesOpt) error {
223+
if len(path) == 0 {
224+
path = "/"
225+
}
226+
227+
rb := s.Request("files/chcid", path)
228+
for _, opt := range options {
229+
if err := opt(rb); err != nil {
230+
return err
231+
}
232+
}
233+
234+
resp, err := rb.Send(context.Background())
235+
return handleResponse(resp, err)
236+
}
237+
238+
// FilesCp copy any IPFS files and directories into MFS (or copy within MFS)
239+
func (s *Shell) FilesCp(src string, dest string) error {
240+
resp, err := s.Request("files/cp", src, dest).
241+
Send(context.Background())
242+
return handleResponse(resp, err)
243+
}
244+
245+
// FilesFlush flush a given path's data to disk
246+
func (s *Shell) FilesFlush(path string) (string, error) {
247+
if len(path) == 0 {
248+
path = "/"
249+
}
250+
out := &filesFlushOutput{}
251+
if err := s.Request("files/flush", path).
252+
Exec(context.Background(), out); err != nil {
253+
return "", err
254+
}
255+
256+
return out.Cid, nil
257+
}
258+
259+
// FilesLs list directories in the local mutable namespace
260+
func (s *Shell) FilesLs(path string, options ...filesOpt) ([]*MfsLsEntry, error) {
261+
if len(path) == 0 {
262+
path = "/"
263+
}
264+
265+
var out filesLsOutput
266+
rb := s.Request("files/ls", path)
267+
for _, opt := range options {
268+
if err := opt(rb); err != nil {
269+
return nil, err
270+
}
271+
}
272+
if err := rb.Exec(context.Background(), &out); err != nil {
273+
return nil, err
274+
}
275+
return out.Entries, nil
276+
}
277+
278+
// FilesMkdir make directories
279+
func (s *Shell) FilesMkdir(path string, options ...filesOpt) error {
280+
rb := s.Request("files/mkdir", path)
281+
for _, opt := range options {
282+
if err := opt(rb); err != nil {
283+
return err
284+
}
285+
}
286+
287+
resp, err := rb.Send(context.Background())
288+
return handleResponse(resp, err)
289+
}
290+
291+
// FilesMv move files
292+
func (s *Shell) FilesMv(src string, dest string) error {
293+
resp, err := s.Request("files/mv", src, dest).
294+
Send(context.Background())
295+
return handleResponse(resp, err)
296+
}
297+
298+
// FilesRead read a file in a given MFS
299+
func (s *Shell) FilesRead(path string, options ...filesOpt) (io.ReadCloser, error) {
300+
rb := s.Request("files/read", path)
301+
for _, opt := range options {
302+
if err := opt(rb); err != nil {
303+
return nil, err
304+
}
305+
}
306+
307+
resp, err := rb.Send(context.Background())
308+
if err != nil {
309+
return nil, err
310+
}
311+
if resp.Error != nil {
312+
return nil, resp.Error
313+
}
314+
315+
return resp.Output, nil
316+
}
317+
318+
// FilesRm remove a file
319+
func (s *Shell) FilesRm(path string, force bool) error {
320+
resp, err := s.Request("files/rm", path).
321+
Option("force", force).
322+
Send(context.Background())
323+
return handleResponse(resp, err)
324+
}
325+
326+
// FilesStat display file status
327+
func (s *Shell) FilesStat(path string, options ...filesOpt) (*filesStatOutput, error) {
328+
out := &filesStatOutput{}
329+
330+
rb := s.Request("files/stat", path)
331+
for _, opt := range options {
332+
if err := opt(rb); err != nil {
333+
return nil, err
334+
}
335+
}
336+
337+
if err := rb.Exec(context.Background(), out); err != nil {
338+
return nil, err
339+
}
340+
341+
return out, nil
342+
}
343+
344+
// FilesWrite write to a mutable file in a given filesystem
345+
func (s *Shell) FilesWrite(path string, data io.Reader, options ...filesOpt) error {
346+
fr := files.NewReaderFile(data)
347+
slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry("", fr)})
348+
fileReader := files.NewMultiFileReader(slf, true)
349+
350+
rb := s.Request("files/write", path)
351+
for _, opt := range options {
352+
if err := opt(rb); err != nil {
353+
return err
354+
}
355+
}
356+
357+
resp, err := rb.Body(fileReader).Send(context.Background())
358+
return handleResponse(resp, err)
359+
}
360+
361+
func handleResponse(resp *Response, err error) error {
362+
if err != nil {
363+
return err
364+
}
365+
if resp.Error != nil {
366+
return resp.Error
367+
}
368+
369+
return nil
370+
}

0 commit comments

Comments
 (0)