Implement Pin API
This commit was moved from ipfs/go-ipfs-http-client@5bb7a581323aad4dd765a0916f6552cd5902d1e2
Łukasz Magiera committed
Jan 15, 2019 at 15:02 UTC
9d647d011efa551bae28c50cafb402a35d33b04a
1 file changed
+87
-5
client/httpapi/pin.go
+87
-5
@@ -2,7 +2,9 @@ package httpapi
2
3
import (
4
"context"
5
+ "encoding/json"
6
"github.com/ipfs/go-cid"
7
+ "github.com/pkg/errors"
8
9
"github.com/ipfs/go-ipfs/core/coreapi/interface"
10
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
@@ -31,8 +33,14 @@ func (p *pin) Type() string {
33
return p.typ
34
}
35
34
-func (api *PinAPI) Add(context.Context, iface.Path, ...caopts.PinAddOption) error {
35
- panic("implement me")
36
+func (api *PinAPI) Add(ctx context.Context, p iface.Path, opts ...caopts.PinAddOption) error {
37
+ options, err := caopts.PinAddOptions(opts...)
38
+ if err != nil {
39
+ return err
40
+ }
41
+
42
+ return api.core().request("pin/add", p.String()).
43
+ Option("recursive", options.Recursive).Exec(ctx, nil)
44
}
45
46
func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]iface.Pin, error) {
@@ -65,11 +73,85 @@ func (api *PinAPI) Rm(ctx context.Context, p iface.Path) error {
73
}
74
75
func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, opts ...caopts.PinUpdateOption) error {
68
- panic("implement me")
76
+ options, err := caopts.PinUpdateOptions(opts...)
77
+ if err != nil {
78
+ return err
79
+ }
80
+
81
+ return api.core().request("pin/update").
82
+ Option("unpin", options.Unpin).Exec(ctx, nil)
83
+}
84
+
85
+type pinVerifyRes struct {
86
+ Cid string
87
+ JOk bool `json:"Ok"`
88
+ JBadNodes []*badNode `json:"BadNodes,omitempty"`
89
+}
90
+
91
+func (r *pinVerifyRes) Ok() bool {
92
+ return r.JOk
93
+}
94
+
95
+func (r *pinVerifyRes) BadNodes() []iface.BadPinNode {
96
+ out := make([]iface.BadPinNode, len(r.JBadNodes))
97
+ for i, n := range r.JBadNodes {
98
+ out[i] = n
99
+ }
100
+ return out
101
+}
102
+
103
+type badNode struct {
104
+ Cid string
105
+ JErr string `json:"Err"`
106
}
107
71
-func (api *PinAPI) Verify(context.Context) (<-chan iface.PinStatus, error) {
72
- panic("implement me")
108
+func (n *badNode) Path() iface.ResolvedPath {
109
+ c, err := cid.Parse(n.Cid)
110
+ if err != nil {
111
+ return nil // todo: handle this better
112
+ }
113
+ return iface.IpldPath(c)
114
+}
115
+
116
+func (n *badNode) Err() error {
117
+ if n.JErr != "" {
118
+ return errors.New(n.JErr)
119
+ }
120
+ if _, err := cid.Parse(n.Cid); err != nil {
121
+ return err
122
+ }
123
+ return nil
124
+}
125
+
126
+func (api *PinAPI) Verify(ctx context.Context) (<-chan iface.PinStatus, error) {
127
+ resp, err := api.core().request("pin/verify").Option("verbose", true).Send(ctx)
128
+ if err != nil {
129
+ return nil, err
130
+ }
131
+ if resp.Error != nil {
132
+ return nil, resp.Error
133
+ }
134
+ res := make(chan iface.PinStatus)
135
+
136
+ go func() {
137
+ defer resp.Close()
138
+ defer close(res)
139
+ dec := json.NewDecoder(resp.Output)
140
+ for {
141
+ var out pinVerifyRes
142
+ if err := dec.Decode(&out); err != nil {
143
+ return // todo: handle non io.EOF somehow
144
+ }
145
+
146
+ select {
147
+ case res <- &out:
148
+ case <-ctx.Done():
149
+ return
150
+ }
151
+ }
152
+ }()
153
+
154
+ return res, nil
155
}
156
157
func (api *PinAPI) core() *HttpApi {