mirror of
https://github.com/ipfs/kubo.git
synced 2025-07-02 12:20:03 +08:00
Merge pull request #4123 from sherodtaylor/feature/tour/remove-tour
remove tour command from ipfs
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
//go:generate go-bindata -pkg=assets -prefix=$GOPATH/src/gx/ipfs/QmQfeKxQtBN721pekQh6Jq24adFUjnU65YdY3GNczfuG2T init-doc $GOPATH/src/gx/ipfs/QmQfeKxQtBN721pekQh6Jq24adFUjnU65YdY3GNczfuG2T/dir-index-html
|
//go:generate go-bindata -pkg=assets -prefix=$GOPATH/src/gx/ipfs/QmdZ4PvPHFQVLLEve7DgoKDcSY19wwpGBB1GKjjKi2rEL1 init-doc $GOPATH/src/gx/ipfs/QmdZ4PvPHFQVLLEve7DgoKDcSY19wwpGBB1GKjjKi2rEL1/dir-index-html
|
||||||
//go:generate gofmt -w bindata.go
|
//go:generate gofmt -w bindata.go
|
||||||
|
|
||||||
package assets
|
package assets
|
||||||
@ -34,7 +34,7 @@ func SeedInitDocs(nd *core.IpfsNode) (*cid.Cid, error) {
|
|||||||
return addAssetList(nd, initDocPaths)
|
return addAssetList(nd, initDocPaths)
|
||||||
}
|
}
|
||||||
|
|
||||||
var initDirPath = filepath.Join(os.Getenv("GOPATH"), "gx", "ipfs", "QmQfeKxQtBN721pekQh6Jq24adFUjnU65YdY3GNczfuG2T", "dir-index-html")
|
var initDirPath = filepath.Join(os.Getenv("GOPATH"), "gx", "ipfs", "QmdZ4PvPHFQVLLEve7DgoKDcSY19wwpGBB1GKjjKi2rEL1", "dir-index-html")
|
||||||
var initDirIndex = []string{
|
var initDirIndex = []string{
|
||||||
filepath.Join(initDirPath, "knownIcons.txt"),
|
filepath.Join(initDirPath, "knownIcons.txt"),
|
||||||
filepath.Join(initDirPath, "dir-index.html"),
|
filepath.Join(initDirPath, "dir-index.html"),
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
// TestEmbeddedDocs makes sure we don't forget to regenerate after documentation change
|
// TestEmbeddedDocs makes sure we don't forget to regenerate after documentation change
|
||||||
func TestEmbeddedDocs(t *testing.T) {
|
func TestEmbeddedDocs(t *testing.T) {
|
||||||
testNFiles(initDocPaths, 6, t, "documents")
|
testNFiles(initDocPaths, 5, t, "documents")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDirIndex(t *testing.T) {
|
func TestDirIndex(t *testing.T) {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
|||||||
# 0.1 - Quick Start
|
# 0.1 - Quick Start
|
||||||
|
|
||||||
This is a set of short examples with minimal explanation. It is meant as
|
This is a set of short examples with minimal explanation. It is meant as
|
||||||
a "quick start". Soon, we'll write a longer tour :-)
|
a "quick start".
|
||||||
|
|
||||||
|
|
||||||
Add a file to ipfs:
|
Add a file to ipfs:
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
WIP
|
|
||||||
|
|
||||||
# 0.0 - Introduction
|
|
||||||
|
|
||||||
Welcome to IPFS! This tour will guide you through a few of the
|
|
||||||
features of this tool, and the most common commands. Then, it will
|
|
||||||
immerse you into the world of merkledags and the amazing things
|
|
||||||
you can do with them.
|
|
||||||
|
|
||||||
|
|
||||||
This tour has many parts, and can be taken in different sequences.
|
|
||||||
Different people learn different ways, so choose your own adventure:
|
|
||||||
|
|
||||||
To start with the concepts, try:
|
|
||||||
- The Merkle DAG
|
|
||||||
- Data Structures on the Merkle DAG
|
|
||||||
- Representing Files with unixfs
|
|
||||||
- add, cat, ls, refs
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
To start with the examples, try:
|
|
||||||
- add, cat, ls, refs
|
|
||||||
- Representing Files with unixfs
|
|
||||||
- Data Structures on the Merkle DAG
|
|
||||||
- The Merkle DAG
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
To start with the network, try:
|
|
||||||
- IPFS Nodes
|
|
||||||
- Running the daemon
|
|
||||||
- The Swarm
|
|
||||||
- The Web
|
|
@ -122,7 +122,6 @@ var rootSubcommands = map[string]*cmds.Command{
|
|||||||
"stats": StatsCmd,
|
"stats": StatsCmd,
|
||||||
"swarm": SwarmCmd,
|
"swarm": SwarmCmd,
|
||||||
"tar": TarCmd,
|
"tar": TarCmd,
|
||||||
"tour": tourCmd,
|
|
||||||
"file": unixfs.UnixFSCmd,
|
"file": unixfs.UnixFSCmd,
|
||||||
"update": ExternalBinary(),
|
"update": ExternalBinary(),
|
||||||
"version": VersionCmd,
|
"version": VersionCmd,
|
||||||
|
@ -1,202 +0,0 @@
|
|||||||
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: "Provide 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)
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package commands
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-ipfs/tour"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseTourTemplate(t *testing.T) {
|
|
||||||
topic := &tour.Topic{
|
|
||||||
ID: "42",
|
|
||||||
Content: tour.Content{
|
|
||||||
Title: "ipfs CLI test files",
|
|
||||||
Text: `
|
|
||||||
Welcome to the ipfs test files
|
|
||||||
This is where we test our beautiful command line interfaces
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
err := fprintTourShow(buf, topic)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Log(buf.String())
|
|
||||||
}
|
|
@ -18,7 +18,6 @@ a running daemon do not read the config file at runtime.
|
|||||||
- [`ReproviderInterval`](#reproviderinterval)
|
- [`ReproviderInterval`](#reproviderinterval)
|
||||||
- [`SupernodeRouting`](#supernoderouting)
|
- [`SupernodeRouting`](#supernoderouting)
|
||||||
- [`Swarm`](#swarm)
|
- [`Swarm`](#swarm)
|
||||||
- [`Tour`](#tour)
|
|
||||||
|
|
||||||
## `Addresses`
|
## `Addresses`
|
||||||
Contains information about various listener addresses to be used by this node.
|
Contains information about various listener addresses to be used by this node.
|
||||||
@ -221,5 +220,3 @@ improvement, as well as a reduction in memory usage.
|
|||||||
- `DisableNatPortMap`
|
- `DisableNatPortMap`
|
||||||
Disable NAT discovery.
|
Disable NAT discovery.
|
||||||
|
|
||||||
## `Tour`
|
|
||||||
Unused.
|
|
||||||
|
@ -811,26 +811,6 @@ _ipfs_tar_cat()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_ipfs_tour()
|
|
||||||
{
|
|
||||||
_ipfs_comp "list next restart --help"
|
|
||||||
}
|
|
||||||
|
|
||||||
_ipfs_tour_list()
|
|
||||||
{
|
|
||||||
_ipfs_help_only
|
|
||||||
}
|
|
||||||
|
|
||||||
_ipfs_tour_next()
|
|
||||||
{
|
|
||||||
_ipfs_help_only
|
|
||||||
}
|
|
||||||
|
|
||||||
_ipfs_tour_restart()
|
|
||||||
{
|
|
||||||
_ipfs_help_only
|
|
||||||
}
|
|
||||||
|
|
||||||
_ipfs_update()
|
_ipfs_update()
|
||||||
{
|
{
|
||||||
if [[ ${word} == -* ]] ; then
|
if [[ ${word} == -* ]] ; then
|
||||||
@ -964,7 +944,7 @@ _ipfs()
|
|||||||
1)
|
1)
|
||||||
local opts="add bitswap block bootstrap cat commands config daemon dag dht \
|
local opts="add bitswap block bootstrap cat commands config daemon dag dht \
|
||||||
diag dns file files get id init log ls mount name object pin ping pubsub \
|
diag dns file files get id init log ls mount name object pin ping pubsub \
|
||||||
refs repo resolve stats swarm tar tour update version"
|
refs repo resolve stats swarm tar update version"
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${word}) );;
|
COMPREPLY=( $(compgen -W "${opts}" -- ${word}) );;
|
||||||
2)
|
2)
|
||||||
local command="${COMP_WORDS[1]}"
|
local command="${COMP_WORDS[1]}"
|
||||||
|
@ -21,7 +21,6 @@ type Config struct {
|
|||||||
Discovery Discovery // local node's discovery mechanisms
|
Discovery Discovery // local node's discovery mechanisms
|
||||||
Ipns Ipns // Ipns settings
|
Ipns Ipns // Ipns settings
|
||||||
Bootstrap []string // local nodes's bootstrap peer addresses
|
Bootstrap []string // local nodes's bootstrap peer addresses
|
||||||
Tour Tour // local node's tour position
|
|
||||||
Gateway Gateway // local node's gateway server options
|
Gateway Gateway // local node's gateway server options
|
||||||
SupernodeRouting SupernodeClientConfig // local node's routing servers (if SupernodeRouting enabled)
|
SupernodeRouting SupernodeClientConfig // local node's routing servers (if SupernodeRouting enabled)
|
||||||
API API // local node's API settings
|
API API // local node's API settings
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
// Tour stores the 'ipfs tour' read-list and resume point
|
|
||||||
type Tour struct {
|
|
||||||
Last string // last tour topic read
|
|
||||||
// Done []string // all topics done so far
|
|
||||||
}
|
|
@ -25,8 +25,5 @@
|
|||||||
"AutoUpdate": "minor"
|
"AutoUpdate": "minor"
|
||||||
},
|
},
|
||||||
"Bootstrap": [
|
"Bootstrap": [
|
||||||
],
|
]
|
||||||
"Tour": {
|
|
||||||
"Last": ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
"IPFS": "/ipfs",
|
"IPFS": "/ipfs",
|
||||||
"IPNS": "/ipns"
|
"IPNS": "/ipns"
|
||||||
},
|
},
|
||||||
"Tour": {
|
|
||||||
"Last": ""
|
|
||||||
},
|
|
||||||
"Version": {
|
"Version": {
|
||||||
"AutoUpdate": "minor",
|
"AutoUpdate": "minor",
|
||||||
"Check": "error",
|
"Check": "error",
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
"IPFS": "/ipfs",
|
"IPFS": "/ipfs",
|
||||||
"IPNS": "/ipns"
|
"IPNS": "/ipns"
|
||||||
},
|
},
|
||||||
"Tour": {
|
|
||||||
"Last": ""
|
|
||||||
},
|
|
||||||
"Version": {
|
"Version": {
|
||||||
"AutoUpdate": "minor",
|
"AutoUpdate": "minor",
|
||||||
"Check": "error",
|
"Check": "error",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# this file defines several useful hashes used across the test codebase.
|
# this file defines several useful hashes used across the test codebase.
|
||||||
# thus they can be defined + changed in one place
|
# thus they can be defined + changed in one place
|
||||||
|
|
||||||
HASH_WELCOME_DOCS="QmVLDAhCY3X9P2uRudKAryuQFPM5zqA3Yij1dY8FpGbL7T"
|
HASH_WELCOME_DOCS="QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv"
|
||||||
HASH_EMPTY_DIR="QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"
|
HASH_EMPTY_DIR="QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"
|
||||||
|
@ -140,7 +140,7 @@ test_expect_success "refs IPFS directory file through readonly API succeeds" '
|
|||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success "test gateway api is sanitized" '
|
test_expect_success "test gateway api is sanitized" '
|
||||||
for cmd in "add" "block/put" "bootstrap" "config" "dht" "diag" "dns" "get" "id" "mount" "name/publish" "object/put" "object/new" "object/patch" "pin" "ping" "refs/local" "repo" "resolve" "stats" "swarm" "tour" "file" "update" "version" "bitswap"; do
|
for cmd in "add" "block/put" "bootstrap" "config" "dht" "diag" "dns" "get" "id" "mount" "name/publish" "object/put" "object/new" "object/patch" "pin" "ping" "refs/local" "repo" "resolve" "stats" "swarm" "file" "update" "version" "bitswap"; do
|
||||||
test_curl_resp_http_code "http://127.0.0.1:$port/api/v0/$cmd" "HTTP/1.1 404 Not Found"
|
test_curl_resp_http_code "http://127.0.0.1:$port/api/v0/$cmd" "HTTP/1.1 404 Not Found"
|
||||||
done
|
done
|
||||||
'
|
'
|
||||||
|
279
tour/all.go
279
tour/all.go
@ -1,279 +0,0 @@
|
|||||||
package tour
|
|
||||||
|
|
||||||
import "sort"
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
for _, t := range allTopics {
|
|
||||||
Topics[t.ID] = t
|
|
||||||
IDs = append(IDs, t.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(IDSlice(IDs))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO move content into individual files if desired
|
|
||||||
|
|
||||||
// TODO(brian): If sub-topics are needed, write recursively (as tree comprised
|
|
||||||
// of Section nodes:
|
|
||||||
//
|
|
||||||
// type Section interface {
|
|
||||||
// Sections() []Section
|
|
||||||
// Topic() Topic
|
|
||||||
// }
|
|
||||||
|
|
||||||
var (
|
|
||||||
// TODO bootstrapping
|
|
||||||
|
|
||||||
// TODO pinning: ensuring a block is kept in local storage (i.e. not
|
|
||||||
// evicted from cache).
|
|
||||||
|
|
||||||
Introduction = Chapter(0)
|
|
||||||
FileBasics = Chapter(1)
|
|
||||||
NodeBasics = Chapter(2)
|
|
||||||
MerkleDag = Chapter(3)
|
|
||||||
Network = Chapter(4)
|
|
||||||
Daemon = Chapter(5)
|
|
||||||
Routing = Chapter(6)
|
|
||||||
Exchange = Chapter(7)
|
|
||||||
Ipns = Chapter(8)
|
|
||||||
Mounting = Chapter(9)
|
|
||||||
Plumbing = Chapter(10)
|
|
||||||
Formats = Chapter(11)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Topics contains a mapping of Tour Topic ID to Topic
|
|
||||||
var allTopics = []Topic{
|
|
||||||
{ID: Introduction(0), Content: IntroHelloMars},
|
|
||||||
{ID: Introduction(1), Content: IntroTour},
|
|
||||||
{ID: Introduction(2), Content: IntroAboutIpfs},
|
|
||||||
|
|
||||||
{ID: FileBasics(1), Content: FileBasicsFilesystem},
|
|
||||||
{ID: FileBasics(2), Content: FileBasicsGetting},
|
|
||||||
{ID: FileBasics(3), Content: FileBasicsAdding},
|
|
||||||
{ID: FileBasics(4), Content: FileBasicsDirectories},
|
|
||||||
{ID: FileBasics(5), Content: FileBasicsDistributed},
|
|
||||||
{ID: FileBasics(6), Content: FileBasicsMounting},
|
|
||||||
|
|
||||||
{NodeBasics(0), NodeBasicsInit},
|
|
||||||
{NodeBasics(1), NodeBasicsHelp},
|
|
||||||
{NodeBasics(2), NodeBasicsUpdate},
|
|
||||||
{NodeBasics(3), NodeBasicsConfig},
|
|
||||||
|
|
||||||
{MerkleDag(0), MerkleDagIntro},
|
|
||||||
{MerkleDag(1), MerkleDagContentAddressing},
|
|
||||||
{MerkleDag(2), MerkleDagContentAddressingLinks},
|
|
||||||
{MerkleDag(3), MerkleDagRedux},
|
|
||||||
{MerkleDag(4), MerkleDagIpfsObjects},
|
|
||||||
{MerkleDag(5), MerkleDagIpfsPaths},
|
|
||||||
{MerkleDag(6), MerkleDagImmutability},
|
|
||||||
{MerkleDag(7), MerkleDagUseCaseUnixFS},
|
|
||||||
{MerkleDag(8), MerkleDagUseCaseGitObjects},
|
|
||||||
{MerkleDag(9), MerkleDagUseCaseOperationalTransforms},
|
|
||||||
|
|
||||||
{Network(0), Network_Intro},
|
|
||||||
{Network(1), Network_Ipfs_Peers},
|
|
||||||
{Network(2), Network_Daemon},
|
|
||||||
{Network(3), Network_Routing},
|
|
||||||
{Network(4), Network_Exchange},
|
|
||||||
{Network(5), Network_Intro},
|
|
||||||
|
|
||||||
// TODO daemon - {API, API Clients, Example} how old-school http + ftp
|
|
||||||
// clients show it
|
|
||||||
{Daemon(0), Daemon_Intro},
|
|
||||||
{Daemon(1), Daemon_Running_Commands},
|
|
||||||
{Daemon(2), Daemon_Web_UI},
|
|
||||||
|
|
||||||
{Routing(0), Routing_Intro},
|
|
||||||
{Routing(1), Rouing_Interface},
|
|
||||||
{Routing(2), Routing_Resolving},
|
|
||||||
{Routing(3), Routing_DHT},
|
|
||||||
{Routing(4), Routing_Other},
|
|
||||||
|
|
||||||
// TODO Exchange_Providing
|
|
||||||
// TODO Exchange_Providers
|
|
||||||
{Exchange(0), Exchange_Intro},
|
|
||||||
{Exchange(1), Exchange_Getting_Blocks},
|
|
||||||
{Exchange(2), Exchange_Strategies},
|
|
||||||
{Exchange(3), Exchange_Bitswap},
|
|
||||||
|
|
||||||
{Ipns(0), Ipns_Name_System},
|
|
||||||
{Ipns(1), Ipns_Mutability},
|
|
||||||
{Ipns(2), Ipns_PKI_Review},
|
|
||||||
{Ipns(3), Ipns_Publishing},
|
|
||||||
{Ipns(4), Ipns_Resolving},
|
|
||||||
{Ipns(5), Ipns_Consistency},
|
|
||||||
{Ipns(6), Ipns_Records_Etc},
|
|
||||||
|
|
||||||
{Mounting(0), Mounting_General},
|
|
||||||
{Mounting(1), Mounting_Ipfs},
|
|
||||||
{Mounting(2), Mounting_Ipns},
|
|
||||||
|
|
||||||
{Plumbing(0), Plumbing_Intro},
|
|
||||||
{Plumbing(1), Plumbing_Ipfs_Block},
|
|
||||||
{Plumbing(2), Plumbing_Ipfs_Object},
|
|
||||||
{Plumbing(3), Plumbing_Ipfs_Refs},
|
|
||||||
{Plumbing(4), Plumbing_Ipfs_Ping},
|
|
||||||
{Plumbing(5), Plumbing_Ipfs_Id},
|
|
||||||
|
|
||||||
{Formats(0), Formats_MerkleDag},
|
|
||||||
{Formats(1), Formats_Multihash},
|
|
||||||
{Formats(2), Formats_Multiaddr},
|
|
||||||
{Formats(3), Formats_Multicodec},
|
|
||||||
{Formats(4), Formats_Multicodec},
|
|
||||||
{Formats(5), Formats_Multikey},
|
|
||||||
{Formats(6), Formats_Protocol_Specific},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Introduction
|
|
||||||
|
|
||||||
var IntroHelloMars = Content{
|
|
||||||
Title: "Hello Mars",
|
|
||||||
Text: `
|
|
||||||
check things work
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var IntroTour = Content{
|
|
||||||
Title: "Hello Mars",
|
|
||||||
Text: `
|
|
||||||
how this works
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var IntroAboutIpfs = Content{
|
|
||||||
Title: "About IPFS",
|
|
||||||
}
|
|
||||||
|
|
||||||
// File Basics
|
|
||||||
|
|
||||||
var FileBasicsFilesystem = Content{
|
|
||||||
Title: "Filesystem",
|
|
||||||
Text: `
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var FileBasicsGetting = Content{
|
|
||||||
Title: "Getting Files",
|
|
||||||
Text: `ipfs cat
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var FileBasicsAdding = Content{
|
|
||||||
Title: "Adding Files",
|
|
||||||
Text: `ipfs add
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var FileBasicsDirectories = Content{
|
|
||||||
Title: "Directories",
|
|
||||||
Text: `ipfs ls
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var FileBasicsDistributed = Content{
|
|
||||||
Title: "Distributed",
|
|
||||||
Text: `ipfs cat from mars
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var FileBasicsMounting = Content{
|
|
||||||
Title: "Getting Files",
|
|
||||||
Text: `ipfs mount (simple)
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node Basics
|
|
||||||
|
|
||||||
var NodeBasicsInit = Content{
|
|
||||||
Title: "Basics - init",
|
|
||||||
|
|
||||||
// TODO touch on PKI
|
|
||||||
//
|
|
||||||
// This is somewhat relevant at 'ipfs init' since the generated key pair is the
|
|
||||||
// basis for the node's identity in the network. A cursory nod may be
|
|
||||||
// sufficient at that stage, and goes a long way in explaining init's raison
|
|
||||||
// d'être.
|
|
||||||
// NB: user is introduced to 'ipfs init' before 'ipfs add'.
|
|
||||||
Text: `
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var NodeBasicsHelp = Content{
|
|
||||||
Title: "Basics - help",
|
|
||||||
Text: `
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var NodeBasicsUpdate = Content{
|
|
||||||
Title: "Basics - update",
|
|
||||||
Text: `
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var NodeBasicsConfig = Content{
|
|
||||||
Title: "Basics - config",
|
|
||||||
Text: `
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merkle DAG
|
|
||||||
var MerkleDagIntro = Content{}
|
|
||||||
var MerkleDagContentAddressing = Content{}
|
|
||||||
var MerkleDagContentAddressingLinks = Content{}
|
|
||||||
var MerkleDagRedux = Content{}
|
|
||||||
var MerkleDagIpfsObjects = Content{}
|
|
||||||
var MerkleDagIpfsPaths = Content{}
|
|
||||||
var MerkleDagImmutability = Content{
|
|
||||||
Title: "Immutability",
|
|
||||||
Text: `
|
|
||||||
TODO plan9
|
|
||||||
TODO git
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
|
|
||||||
var MerkleDagUseCaseUnixFS = Content{}
|
|
||||||
var MerkleDagUseCaseGitObjects = Content{}
|
|
||||||
var MerkleDagUseCaseOperationalTransforms = Content{}
|
|
||||||
|
|
||||||
var Network_Intro = Content{}
|
|
||||||
var Network_Ipfs_Peers = Content{}
|
|
||||||
var Network_Daemon = Content{}
|
|
||||||
var Network_Routing = Content{}
|
|
||||||
var Network_Exchange = Content{}
|
|
||||||
var Network_Naming = Content{}
|
|
||||||
|
|
||||||
var Daemon_Intro = Content{}
|
|
||||||
var Daemon_Running_Commands = Content{}
|
|
||||||
var Daemon_Web_UI = Content{}
|
|
||||||
|
|
||||||
var Routing_Intro = Content{}
|
|
||||||
var Rouing_Interface = Content{}
|
|
||||||
var Routing_Resolving = Content{}
|
|
||||||
var Routing_DHT = Content{}
|
|
||||||
var Routing_Other = Content{}
|
|
||||||
|
|
||||||
var Exchange_Intro = Content{}
|
|
||||||
var Exchange_Bitswap = Content{}
|
|
||||||
var Exchange_Strategies = Content{}
|
|
||||||
var Exchange_Getting_Blocks = Content{}
|
|
||||||
|
|
||||||
var Ipns_Consistency = Content{}
|
|
||||||
var Ipns_Mutability = Content{}
|
|
||||||
var Ipns_Name_System = Content{}
|
|
||||||
var Ipns_PKI_Review = Content{
|
|
||||||
Title: "PKI Review",
|
|
||||||
Text: `
|
|
||||||
TODO sign verify
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
var Ipns_Publishing = Content{}
|
|
||||||
var Ipns_Records_Etc = Content{}
|
|
||||||
var Ipns_Resolving = Content{}
|
|
||||||
|
|
||||||
var Mounting_General = Content{} // TODO note fuse
|
|
||||||
var Mounting_Ipfs = Content{} // TODO cd, ls, cat
|
|
||||||
var Mounting_Ipns = Content{} // TODO editing
|
|
||||||
|
|
||||||
var Plumbing_Intro = Content{}
|
|
||||||
var Plumbing_Ipfs_Block = Content{}
|
|
||||||
var Plumbing_Ipfs_Object = Content{}
|
|
||||||
var Plumbing_Ipfs_Refs = Content{}
|
|
||||||
var Plumbing_Ipfs_Ping = Content{}
|
|
||||||
var Plumbing_Ipfs_Id = Content{}
|
|
||||||
|
|
||||||
var Formats_MerkleDag = Content{}
|
|
||||||
var Formats_Multihash = Content{}
|
|
||||||
var Formats_Multiaddr = Content{}
|
|
||||||
var Formats_Multicodec = Content{}
|
|
||||||
var Formats_Multikey = Content{}
|
|
||||||
var Formats_Protocol_Specific = Content{}
|
|
@ -1,16 +0,0 @@
|
|||||||
package tour
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// returns a partially applied function.
|
|
||||||
//
|
|
||||||
// It's designed to make it easy to re-order chapters with minimal fuss.
|
|
||||||
//
|
|
||||||
// eg.
|
|
||||||
// Intro := Chapter(1)
|
|
||||||
// ID("1.1") == Intro(1) == Chapter(1)(1)
|
|
||||||
func Chapter(number int) func(topic int) ID {
|
|
||||||
return func(topic int) ID {
|
|
||||||
return ID(fmt.Sprintf("%d.%d", number, topic))
|
|
||||||
}
|
|
||||||
}
|
|
90
tour/tour.go
90
tour/tour.go
@ -1,90 +0,0 @@
|
|||||||
package tour
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
|
|
||||||
)
|
|
||||||
|
|
||||||
var log = logging.Logger("tour")
|
|
||||||
|
|
||||||
// ID is a string identifier for topics
|
|
||||||
type ID string
|
|
||||||
|
|
||||||
// LessThan returns whether this ID is sorted earlier than another.
|
|
||||||
func (i ID) LessThan(o ID) bool {
|
|
||||||
return compareDottedInts(string(i), string(o))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IDSlice implements the sort interface for ID slices.
|
|
||||||
type IDSlice []ID
|
|
||||||
|
|
||||||
func (a IDSlice) Len() int { return len(a) }
|
|
||||||
func (a IDSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
||||||
func (a IDSlice) Less(i, j int) bool { return a[i].LessThan(a[j]) }
|
|
||||||
|
|
||||||
// Topic is a type of objects that structures a tour topic.
|
|
||||||
type Topic struct {
|
|
||||||
ID ID
|
|
||||||
Content
|
|
||||||
}
|
|
||||||
|
|
||||||
type Content struct {
|
|
||||||
Title string
|
|
||||||
Text string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Topics is a sorted list of topic IDs
|
|
||||||
var IDs []ID
|
|
||||||
|
|
||||||
// Topics contains a mapping of Tour Topic ID to Topic
|
|
||||||
var Topics = map[ID]Topic{}
|
|
||||||
|
|
||||||
// NextTopic returns the next in-order topic
|
|
||||||
func NextTopic(topic ID) ID {
|
|
||||||
for _, id := range IDs {
|
|
||||||
if topic.LessThan(id) {
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return topic // last one, it seems.
|
|
||||||
}
|
|
||||||
|
|
||||||
// TopicID returns a valid tour topic ID from given string
|
|
||||||
func TopicID(t string) ID {
|
|
||||||
if t == "" { // if empty, use first ID
|
|
||||||
return IDs[0]
|
|
||||||
}
|
|
||||||
return ID(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareDottedInts(i, o string) bool {
|
|
||||||
is := strings.Split(i, ".")
|
|
||||||
os := strings.Split(o, ".")
|
|
||||||
|
|
||||||
for n, vis := range is {
|
|
||||||
if n >= len(os) {
|
|
||||||
return false // os is smaller.
|
|
||||||
}
|
|
||||||
|
|
||||||
vos := os[n]
|
|
||||||
ivis, err1 := strconv.Atoi(vis)
|
|
||||||
ivos, err2 := strconv.Atoi(vos)
|
|
||||||
if err1 != nil || err2 != nil {
|
|
||||||
log.Debug(err1)
|
|
||||||
log.Debug(err2)
|
|
||||||
panic("tour ID LessThan: not an int")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ivis < ivos {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if ivis > ivos {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(os) > len(is)
|
|
||||||
}
|
|
Reference in New Issue
Block a user