1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-03 20:32:14 +08:00
Files
kubo/core/commands/pin.go
2015-01-21 04:28:02 +00:00

206 lines
4.7 KiB
Go

package commands
import (
"bytes"
"fmt"
"io"
cmds "github.com/jbenet/go-ipfs/commands"
corerepo "github.com/jbenet/go-ipfs/core/repo"
u "github.com/jbenet/go-ipfs/util"
)
var PinCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Pin (and unpin) objects to local storage",
},
Subcommands: map[string]*cmds.Command{
"add": addPinCmd,
"rm": rmPinCmd,
"ls": listPinCmd,
},
}
type PinOutput struct {
Pinned []u.Key
}
var addPinCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Pins objects to local storage",
ShortDescription: `
Retrieves the object named by <ipfs-path> and stores it locally
on disk.
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("ipfs-path", true, true, "Path to object(s) to be pinned").EnableStdin(),
},
Options: []cmds.Option{
cmds.BoolOption("recursive", "r", "Recursively pin the object linked to by the specified object(s)"),
},
Type: PinOutput{},
Run: func(req cmds.Request) (interface{}, error) {
n, err := req.Context().GetNode()
if err != nil {
return nil, err
}
// set recursive flag
recursive, found, err := req.Option("recursive").Bool()
if err != nil {
return nil, err
}
if !found {
recursive = false
}
added, err := corerepo.Pin(n, req.Arguments(), recursive)
if err != nil {
return nil, err
}
return &PinOutput{added}, nil
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
added, ok := res.Output().(*PinOutput)
if !ok {
return nil, u.ErrCast()
}
var pintype string
rec, _, _ := res.Request().Option("recursive").Bool()
if rec {
pintype = "recursively"
} else {
pintype = "directly"
}
buf := new(bytes.Buffer)
for _, k := range added.Pinned {
fmt.Fprintf(buf, "pinned %s %s\n", k, pintype)
}
return buf, nil
},
},
}
var rmPinCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Unpin an object from local storage",
ShortDescription: `
Removes the pin from the given object allowing it to be garbage
collected if needed.
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("ipfs-path", true, true, "Path to object(s) to be unpinned").EnableStdin(),
},
Options: []cmds.Option{
cmds.BoolOption("recursive", "r", "Recursively unpin the object linked to by the specified object(s)"),
},
Type: PinOutput{},
Run: func(req cmds.Request) (interface{}, error) {
n, err := req.Context().GetNode()
if err != nil {
return nil, err
}
// set recursive flag
recursive, found, err := req.Option("recursive").Bool()
if err != nil {
return nil, err
}
if !found {
recursive = false // default
}
removed, err := corerepo.Unpin(n, req.Arguments(), recursive)
if err != nil {
return nil, err
}
return &PinOutput{removed}, nil
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
added, ok := res.Output().(*PinOutput)
if !ok {
return nil, u.ErrCast()
}
buf := new(bytes.Buffer)
for _, k := range added.Pinned {
fmt.Fprintf(buf, "unpinned %s\n", k)
}
return buf, nil
},
},
}
var listPinCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "List objects pinned to local storage",
ShortDescription: `
Returns a list of hashes of objects being pinned. Objects that are indirectly
or recursively pinned are not included in the list.
`,
LongDescription: `
Returns a list of hashes of objects being pinned. Objects that are indirectly
or recursively pinned are not included in the list.
Use --type=<type> to specify the type of pinned keys to list. Valid values are:
* "direct"
* "indirect"
* "recursive"
* "all"
(Defaults to "direct")
`,
},
Options: []cmds.Option{
cmds.StringOption("type", "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\". Defaults to \"direct\""),
},
Run: func(req cmds.Request) (interface{}, error) {
n, err := req.Context().GetNode()
if err != nil {
return nil, err
}
typeStr, found, err := req.Option("type").String()
if err != nil {
return nil, err
}
if !found {
typeStr = "direct"
}
switch typeStr {
case "all", "direct", "indirect", "recursive":
default:
return nil, cmds.ClientError("Invalid type '" + typeStr + "', must be one of {direct, indirect, recursive, all}")
}
keys := make([]u.Key, 0)
if typeStr == "direct" || typeStr == "all" {
keys = append(keys, n.Pinning.DirectKeys()...)
}
if typeStr == "indirect" || typeStr == "all" {
keys = append(keys, n.Pinning.IndirectKeys()...)
}
if typeStr == "recursive" || typeStr == "all" {
keys = append(keys, n.Pinning.RecursiveKeys()...)
}
return &KeyList{Keys: keys}, nil
},
Type: KeyList{},
Marshalers: cmds.MarshalerMap{
cmds.Text: KeyListTextMarshaler,
},
}