Skip to content
This repository was archived by the owner on Oct 5, 2023. It is now read-only.

Commit 5bb7a58

Browse files
committed
Implement Pin API
1 parent 281b2bf commit 5bb7a58

File tree

1 file changed

+87
-5
lines changed

1 file changed

+87
-5
lines changed

pin.go

+87-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package httpapi
22

33
import (
44
"context"
5+
"encoding/json"
56
"github.com/ipfs/go-cid"
7+
"github.com/pkg/errors"
68

79
"github.com/ipfs/go-ipfs/core/coreapi/interface"
810
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
@@ -31,8 +33,14 @@ func (p *pin) Type() string {
3133
return p.typ
3234
}
3335

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)
3644
}
3745

3846
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 {
6573
}
6674

6775
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"`
69106
}
70107

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
73155
}
74156

75157
func (api *PinAPI) core() *HttpApi {

0 commit comments

Comments
 (0)