Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 13 additions & 57 deletions bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,26 @@ package shell

import (
"context"
"encoding/json"
)

func (s *Shell) BootstrapAdd(peers []string) ([]string, error) {
resp, err := s.newRequest(context.Background(), "bootstrap/add", peers...).Send(s.httpcli)
if err != nil {
return nil, err
}
defer resp.Close()

if resp.Error != nil {
return nil, resp.Error
}

addOutput := &struct {
Peers []string
}{}

err = json.NewDecoder(resp.Output).Decode(addOutput)
if err != nil {
return nil, err
}
type PeersList struct {
Peers []string
}

return addOutput.Peers, nil
func (s *Shell) BootstrapAdd(peers []string) ([]string, error) {
var addOutput PeersList
err := s.Request("bootstrap/add", peers...).Exec(context.Background(), &addOutput)
return addOutput.Peers, err
}

func (s *Shell) BootstrapAddDefault() ([]string, error) {
resp, err := s.newRequest(context.Background(), "bootstrap/add/default").Send(s.httpcli)
if err != nil {
return nil, err
}
defer resp.Close()

if resp.Error != nil {
return nil, resp.Error
}

addOutput := &struct {
Peers []string
}{}

err = json.NewDecoder(resp.Output).Decode(addOutput)
if err != nil {
return nil, err
}

return addOutput.Peers, nil
var addOutput PeersList
err := s.Request("bootstrap/add/default").Exec(context.Background(), &addOutput)
return addOutput.Peers, err
}

func (s *Shell) BootstrapRmAll() ([]string, error) {
resp, err := s.newRequest(context.Background(), "bootstrap/rm/all").Send(s.httpcli)
if err != nil {
return nil, err
}
defer resp.Close()

rmAllOutput := &struct {
Peers []string
}{}

err = json.NewDecoder(resp.Output).Decode(rmAllOutput)
if err != nil {
return nil, err
}

return rmAllOutput.Peers, nil
var rmAllOutput PeersList
err := s.Request("bootstrap/rm/all").Exec(context.Background(), &rmAllOutput)
return rmAllOutput.Peers, err
}
45 changes: 8 additions & 37 deletions dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package shell
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
Expand All @@ -13,29 +12,10 @@ import (
)

func (s *Shell) DagGet(ref string, out interface{}) error {
req := s.newRequest(context.Background(), "dag/get")
req.Args = []string{ref}

resp, err := req.Send(s.httpcli)
if err != nil {
return err
}
defer resp.Close()

if resp.Error != nil {
return resp.Error
}

return json.NewDecoder(resp.Output).Decode(out)
return s.Request("dag/get", ref).Exec(context.Background(), out)
}

func (s *Shell) DagPut(data interface{}, ienc, kind string) (string, error) {
req := s.newRequest(context.Background(), "dag/put")
req.Opts = map[string]string{
"input-enc": ienc,
"format": kind,
}

var r io.Reader
switch data := data.(type) {
case string:
Expand All @@ -47,31 +27,22 @@ func (s *Shell) DagPut(data interface{}, ienc, kind string) (string, error) {
default:
return "", fmt.Errorf("cannot current handle putting values of type %T", data)
}

rc := ioutil.NopCloser(r)
fr := files.NewReaderFile("", "", rc, nil)
slf := files.NewSliceFile("", "", []files.File{fr})
fileReader := files.NewMultiFileReader(slf, true)
req.Body = fileReader

resp, err := req.Send(s.httpcli)
if err != nil {
return "", err
}
defer resp.Close()

if resp.Error != nil {
return "", resp.Error
}

var out struct {
Cid struct {
Target string `json:"/"`
}
}
err = json.NewDecoder(resp.Output).Decode(&out)
if err != nil {
return "", err
}

return out.Cid.Target, nil
return out.Cid.Target, s.
Request("dag/put").
Option("input-enc", ienc).
Option("format", kind).
Body(fileReader).
Exec(context.Background(), &out)
}
72 changes: 17 additions & 55 deletions ipns.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package shell

import (
"bytes"
"context"
"encoding/json"
"strconv"
"time"
)

Expand All @@ -15,79 +12,44 @@ type PublishResponse struct {

// Publish updates a mutable name to point to a given value
func (s *Shell) Publish(node string, value string) error {
args := []string{value}
var pubResp PublishResponse
req := s.Request("name/publish")
if node != "" {
args = []string{node, value}
req.Arguments(node)
}
req.Arguments(value)

resp, err := s.newRequest(context.Background(), "name/publish", args...).Send(s.httpcli)
if err != nil {
return err
}
defer resp.Close()

if resp.Error != nil {
return resp.Error
}

return nil
return req.Exec(context.Background(), &pubResp)
}

// PublishWithDetails is used for fine grained control over record publishing
func (s *Shell) PublishWithDetails(contentHash, key string, lifetime, ttl time.Duration, resolve bool) (*PublishResponse, error) {

args := []string{contentHash}
req := s.newRequest(context.Background(), "name/publish", args...)
if key == "" {
key = "self"
var pubResp PublishResponse
req := s.Request("name/publish", contentHash).Option("resolve", resolve)
if key != "" {
req.Option("key", key)
}
req.Opts["key"] = key
if lifetime.Seconds() > 0 {
req.Opts["lifetime"] = lifetime.String()
if lifetime != 0 {
req.Option("lifetime", lifetime)
}
if ttl.Seconds() > 0 {
req.Opts["ttl"] = ttl.String()
req.Option("ttl", ttl)
}
req.Opts["resolve"] = strconv.FormatBool(resolve)
resp, err := req.Send(s.httpcli)
err := req.Exec(context.Background(), &pubResp)
if err != nil {
return nil, err
}
defer resp.Close()
if resp.Error != nil {
return nil, resp.Error
}
buf := new(bytes.Buffer)
buf.ReadFrom(resp.Output)
var pubResp PublishResponse
json.Unmarshal(buf.Bytes(), &pubResp)
return &pubResp, nil
}

// Resolve gets resolves the string provided to an /ipns/[name]. If asked to
// resolve an empty string, resolve instead resolves the node's own /ipns value.
func (s *Shell) Resolve(id string) (string, error) {
var resp *Response
var err error
req := s.Request("name/resolve")
if id != "" {
resp, err = s.newRequest(context.Background(), "name/resolve", id).Send(s.httpcli)
} else {
resp, err = s.newRequest(context.Background(), "name/resolve").Send(s.httpcli)
}
if err != nil {
return "", err
}
defer resp.Close()

if resp.Error != nil {
return "", resp.Error
req.Arguments(id)
}

var out struct{ Path string }
err = json.NewDecoder(resp.Output).Decode(&out)
if err != nil {
return "", err
}

return out.Path, nil
err := req.Exec(context.Background(), &out)
return out.Path, err
}
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@
"hash": "QmQine7gvHncNevKtG9QXxf3nXcwSj6aDDmMm52mHofEEp",
"name": "tar-utils",
"version": "0.0.3"
},
{
"author": "whyrusleeping",
"hash": "QmcoBbyTiL9PFjo1GFixJwqQ8mZLJ36CribuqyKmS1okPu",
"name": "go-libp2p-metrics",
"version": "2.1.3"
}
],
"gxVersion": "0.7.0",
Expand Down
9 changes: 9 additions & 0 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ func (r *Response) Close() error {
return nil
}

func (r *Response) Decode(dec interface{}) error {
defer r.Close()
if r.Error != nil {
return r.Error
}

return json.NewDecoder(r.Output).Decode(dec)
}

type Error struct {
Command string
Message string
Expand Down
97 changes: 97 additions & 0 deletions requestbuilder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package shell

import (
"bytes"
"context"
"fmt"
"io"
"strconv"
"strings"
)

// RequestBuilder is an IPFS commands request builder.
type RequestBuilder struct {
command string
args []string
opts map[string]string
headers map[string]string
body io.Reader

shell *Shell
}

// Arguments adds the arguments to the args.
func (r *RequestBuilder) Arguments(args ...string) *RequestBuilder {
r.args = append(r.args, args...)
return r
}

// BodyString sets the request body to the given string.
func (r *RequestBuilder) BodyString(body string) *RequestBuilder {
return r.Body(strings.NewReader(body))
}

// BodyBytes sets the request body to the given buffer.
func (r *RequestBuilder) BodyBytes(body []byte) *RequestBuilder {
return r.Body(bytes.NewReader(body))
}

// Body sets the request body to the given reader.
func (r *RequestBuilder) Body(body io.Reader) *RequestBuilder {
r.body = body
return r
}

// Option sets the given option.
func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder {
var s string
switch v := value.(type) {
case bool:
s = strconv.FormatBool(v)
case string:
s = v
case []byte:
s = string(v)
default:
// slow case.
s = fmt.Sprint(value)
}
if r.opts == nil {
r.opts = make(map[string]string, 1)
}
r.opts[key] = s
return r
}

// Header sets the given header.
func (r *RequestBuilder) Header(name, value string) *RequestBuilder {
if r.headers == nil {
r.headers = make(map[string]string, 1)
}
r.headers[name] = value
return r
}

// Send sends the request and return the response.
func (r *RequestBuilder) Send(ctx context.Context) (*Response, error) {
req := NewRequest(ctx, r.shell.url, r.command, r.args...)
req.Opts = r.opts
req.Headers = r.headers
req.Body = r.body
return req.Send(r.shell.httpcli)
}

// Exec sends the request a request and decodes the response.
func (r *RequestBuilder) Exec(ctx context.Context, res interface{}) error {
httpRes, err := r.Send(ctx)
if err != nil {
return err
}

if res == nil {
httpRes.Close()
return httpRes.Error
}

return httpRes.Decode(res)
}
Loading