-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #213 from jbenet/tour
ipfs tour
- Loading branch information
Showing
7 changed files
with
273 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// +build linux darwin freebsd | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
config "github.com/jbenet/go-ipfs/config" | ||
tour "github.com/jbenet/go-ipfs/tour" | ||
|
||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander" | ||
) | ||
|
||
var cmdIpfsTour = &commander.Command{ | ||
UsageLine: "tour [<number>]", | ||
Short: "Take the IPFS Tour.", | ||
Long: `ipfs tour - Take the IPFS Tour. | ||
ipfs tour [<number>] - Show tour topic. Default to current. | ||
ipfs tour next - Show the next tour topic. | ||
ipfs tour list - Show a list of topics. | ||
ipfs tour restart - Restart the tour. | ||
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 | ||
`, | ||
Run: tourCmd, | ||
Subcommands: []*commander.Command{ | ||
cmdIpfsTourNext, | ||
cmdIpfsTourList, | ||
cmdIpfsTourRestart, | ||
}, | ||
} | ||
|
||
var cmdIpfsTourNext = &commander.Command{ | ||
UsageLine: "next", | ||
Short: "Show the next IPFS Tour topic.", | ||
Run: tourNextCmd, | ||
} | ||
|
||
var cmdIpfsTourList = &commander.Command{ | ||
UsageLine: "list", | ||
Short: "Show a list of IPFS Tour topics.", | ||
Run: tourListCmd, | ||
} | ||
|
||
var cmdIpfsTourRestart = &commander.Command{ | ||
UsageLine: "restart", | ||
Short: "Restart the IPFS Tour.", | ||
Run: tourRestartCmd, | ||
} | ||
|
||
func tourCmd(c *commander.Command, inp []string) error { | ||
cfg, err := getConfig(c) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
topic := tour.TopicID(cfg.Tour.Last) | ||
if len(inp) > 0 { | ||
topic = tour.TopicID(inp[0]) | ||
} | ||
return tourShow(topic) | ||
} | ||
|
||
func tourNextCmd(c *commander.Command, _ []string) error { | ||
cfg, err := getConfig(c) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
topic := tour.NextTopic(tour.TopicID(cfg.Tour.Last)) | ||
if err := tourShow(topic); err != nil { | ||
return err | ||
} | ||
|
||
// if topic didn't change (last) done | ||
if string(topic) == cfg.Tour.Last { | ||
return nil | ||
} | ||
|
||
// topic changed, not last. write it out. | ||
cfg.Tour.Last = string(topic) | ||
return writeConfig(c, cfg) | ||
} | ||
|
||
func tourListCmd(c *commander.Command, _ []string) error { | ||
cfg, err := getConfig(c) | ||
if err != nil { | ||
return err | ||
} | ||
lastid := tour.TopicID(cfg.Tour.Last) | ||
|
||
for _, id := range tour.IDs { | ||
c := ' ' | ||
switch { | ||
case id == lastid: | ||
c = '*' | ||
case id.LessThan(lastid): | ||
c = '✓' | ||
} | ||
|
||
t := tour.Topics[id] | ||
fmt.Printf("- %c %-5.5s %s\n", c, id, t.Title) | ||
} | ||
return nil | ||
} | ||
|
||
func tourRestartCmd(c *commander.Command, _ []string) error { | ||
cfg, err := getConfig(c) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cfg.Tour.Last = "" | ||
return writeConfig(c, cfg) | ||
} | ||
|
||
func tourShow(id tour.ID) error { | ||
t, found := tour.Topics[id] | ||
if !found { | ||
return fmt.Errorf("no topic with id: %s", id) | ||
} | ||
|
||
fmt.Printf("Tour %s - %s\n\n%s\n", t.ID, t.Title, t.Text) | ||
return nil | ||
} | ||
|
||
func lastTour(cfg *config.Config) string { | ||
return "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package tour | ||
|
||
import "sort" | ||
|
||
func init() { | ||
for _, t := range allTopics { | ||
Topics[t.ID] = t | ||
IDs = append(IDs, t.ID) | ||
} | ||
|
||
sort.Sort(IDSlice(IDs)) | ||
} | ||
|
||
// Topics contains a mapping of Tour Topic ID to Topic | ||
var allTopics = []Topic{ | ||
Topic{ | ||
ID: ID("0"), | ||
Title: "Hello Mars", | ||
Text: "Hello Mars", | ||
}, | ||
Topic{ | ||
ID: ID("0.1"), | ||
Title: "Hello Mars 2", | ||
Text: "Hello Mars 2", | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package tour | ||
|
||
import ( | ||
"strconv" | ||
"strings" | ||
|
||
u "github.com/jbenet/go-ipfs/util" | ||
) | ||
|
||
var log = u.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 | ||
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.Error(err1) | ||
log.Error(err2) | ||
panic("tour ID LessThan: not an int") | ||
} | ||
|
||
if ivis < ivos { | ||
return true | ||
} | ||
|
||
if ivis > ivos { | ||
return false | ||
} | ||
} | ||
|
||
return len(os) > len(is) | ||
} |