1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-05-22 01:17:11 +08:00
Files
kubo/core/commands/tour.go
Richard Littauer 28fe2e4f4c Capitalized beginning of line messages, added periods
License: MIT
Signed-off-by: Richard Littauer <richard.littauer@gmail.com>
2016-01-24 22:39:34 +00:00

203 lines
4.2 KiB
Go

package commands
import (
"bytes"
"fmt"
"html/template"
"io"
cmds "github.com/ipfs/go-ipfs/commands"
config "github.com/ipfs/go-ipfs/repo/config"
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
tour "github.com/ipfs/go-ipfs/tour"
)
var tourCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "An introduction to IPFS.",
ShortDescription: `
This is a tour that takes you through various IPFS concepts,
features, and tools to make sure you get up to speed with
IPFS very quickly. To start, run:
ipfs tour
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("id", false, false, "The id of the topic you would like to tour."),
},
Subcommands: map[string]*cmds.Command{
"list": cmdIpfsTourList,
"next": cmdIpfsTourNext,
"restart": cmdIpfsTourRestart,
},
Run: tourRunFunc,
}
func tourRunFunc(req cmds.Request, res cmds.Response) {
cfg, err := req.InvocContext().GetConfig()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
id := tour.TopicID(cfg.Tour.Last)
if len(req.Arguments()) > 0 {
id = tour.TopicID(req.Arguments()[0])
}
w := new(bytes.Buffer)
t, err := tourGet(id)
if err != nil {
// If no topic exists for this id, we handle this error right here.
// To help the user achieve the task, we construct a response
// comprised of...
// 1) a simple error message
// 2) the full list of topics
fmt.Fprintln(w, "ERROR")
fmt.Fprintln(w, err)
fmt.Fprintln(w, "")
fprintTourList(w, tour.TopicID(cfg.Tour.Last))
res.SetOutput(w)
return
}
fprintTourShow(w, t)
res.SetOutput(w)
}
var cmdIpfsTourNext = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Show the next IPFS Tour topic.",
},
Run: func(req cmds.Request, res cmds.Response) {
w := new(bytes.Buffer)
path := req.InvocContext().ConfigRoot
cfg, err := req.InvocContext().GetConfig()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
id := tour.NextTopic(tour.TopicID(cfg.Tour.Last))
topic, err := tourGet(id)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
if err := fprintTourShow(w, topic); err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
// topic changed, not last. write it out.
if string(id) != cfg.Tour.Last {
cfg.Tour.Last = string(id)
err := writeConfig(path, cfg)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
}
res.SetOutput(w)
},
}
var cmdIpfsTourRestart = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Restart the IPFS Tour.",
},
Run: func(req cmds.Request, res cmds.Response) {
path := req.InvocContext().ConfigRoot
cfg, err := req.InvocContext().GetConfig()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
cfg.Tour.Last = ""
err = writeConfig(path, cfg)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
},
}
var cmdIpfsTourList = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Show a list of IPFS Tour topics.",
},
Run: func(req cmds.Request, res cmds.Response) {
cfg, err := req.InvocContext().GetConfig()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
w := new(bytes.Buffer)
fprintTourList(w, tour.TopicID(cfg.Tour.Last))
res.SetOutput(w)
},
}
func fprintTourList(w io.Writer, lastid tour.ID) {
for _, id := range tour.IDs {
c := ' '
switch {
case id == lastid:
c = '*'
case id.LessThan(lastid):
c = '✓'
}
t := tour.Topics[id]
fmt.Fprintf(w, "- %c %-5.5s %s\n", c, id, t.Title)
}
}
// fprintTourShow writes a text-formatted topic to the writer
func fprintTourShow(w io.Writer, t *tour.Topic) error {
tmpl := `
Tour {{ .ID }} - {{ .Title }}
{{ .Text }}
`
ttempl, err := template.New("tour").Parse(tmpl)
if err != nil {
return err
}
return ttempl.Execute(w, t)
}
// tourGet returns the topic given its ID. Returns an error if topic does not
// exist.
func tourGet(id tour.ID) (*tour.Topic, error) {
t, found := tour.Topics[id]
if !found {
return nil, fmt.Errorf("no topic with id: %s", id)
}
return &t, nil
}
// TODO share func
func writeConfig(path string, cfg *config.Config) error {
// NB: This needs to run on the daemon.
r, err := fsrepo.Open(path)
if err != nil {
return err
}
defer r.Close()
return r.SetConfig(cfg)
}