-
Notifications
You must be signed in to change notification settings - Fork 176
Add DefaultShell as required by #69 #106
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ import ( | |
"os" | ||
"path" | ||
"strings" | ||
"sync" | ||
"time" | ||
|
||
files "github.com/ipfs/go-ipfs-cmdkit/files" | ||
|
@@ -27,6 +28,13 @@ const ( | |
DefaultPathRoot = "~/" + DefaultPathName | ||
DefaultApiFile = "api" | ||
EnvDir = "IPFS_PATH" | ||
DefaultGateway = "https://ipfs.io" | ||
DefaultAPIAddr = "/ip4/127.0.0.1/tcp/5001" | ||
) | ||
|
||
var ( | ||
defaultShellAddr string | ||
defaultShellAddrLoadOnce sync.Once | ||
) | ||
|
||
type Shell struct { | ||
|
@@ -84,6 +92,94 @@ func NewShellWithClient(url string, c *gohttp.Client) *Shell { | |
} | ||
} | ||
|
||
// Load all shell urls with error checking | ||
func NewShellWithCheck(urls ...string) (*Shell, error) { | ||
encountered := map[string]struct{}{} | ||
for _, url := range urls { | ||
if _, ok := encountered[url]; !ok { | ||
encountered[url] = struct{}{} | ||
sh := NewShell(url) | ||
_, _, err := sh.Version() | ||
if err == nil { | ||
return sh, nil | ||
} | ||
} | ||
} | ||
return nil, errors.New(fmt.Sprintf("No working server in %v", urls)) | ||
|
||
} | ||
|
||
func NewShellFromDefaultGateway() (*Shell, error) { | ||
return NewShellWithCheck(DefaultGateway) | ||
} | ||
|
||
// Get all shell urls from api files | ||
func newShellFromAPIFiles(files ...string) (urls []string) { | ||
for _, apifile := range files { | ||
if data, err := ioutil.ReadFile(apifile); err == nil { | ||
url := strings.Trim(string(data), "\n\t ") | ||
urls = append(urls, url) | ||
} | ||
} | ||
return | ||
} | ||
|
||
func NewShellFromAPIFiles(files ...string) (*Shell, error) { | ||
return NewShellWithCheck(newShellFromAPIFiles(files...)...) | ||
} | ||
|
||
// Get api url from ~/.ipfs/api | ||
func newShellFromDefaultAPIFile() (urls []string) { | ||
apifile, err := homedir.Expand(path.Join(DefaultPathRoot, DefaultApiFile)) | ||
if err != nil { | ||
return urls | ||
} | ||
return newShellFromAPIFiles(apifile) | ||
} | ||
|
||
func NewShellFromDefaultAPIFile() (*Shell, error) { | ||
return NewShellWithCheck(newShellFromDefaultAPIFile()...) | ||
} | ||
|
||
// get all shell urls from environmental variable IPFS_API and IPFS_PATH | ||
func newShellFromEnv() (urls []string) { | ||
if ipfsAPI := os.Getenv("IPFS_API"); ipfsAPI != "" { | ||
urls = append(urls, ipfsAPI) | ||
} | ||
if ipfsPath := os.Getenv("IPFS_PATH"); ipfsPath != "" { | ||
apifile := path.Join(ipfsPath, DefaultApiFile) | ||
urls = append(urls, newShellFromAPIFiles(apifile)...) | ||
} | ||
return | ||
} | ||
|
||
func NewShellFromEnv() (*Shell, error) { | ||
return NewShellWithCheck(newShellFromEnv()...) | ||
} | ||
|
||
// Load working default shell address once | ||
func defaultShell() { | ||
fmt.Println("ran defaultShell") | ||
var urls []string | ||
urls = append(urls, newShellFromEnv()...) | ||
urls = append(urls, newShellFromDefaultAPIFile()...) | ||
urls = append(urls, DefaultAPIAddr, DefaultGateway) | ||
if sh, err := NewShellWithCheck(urls...); err == nil { | ||
defaultShellAddr = sh.url | ||
} | ||
} | ||
|
||
func DefaultShell() *Shell { | ||
// Load once and cache working default shell address | ||
defaultShellAddrLoadOnce.Do(defaultShell) | ||
return NewShell(defaultShellAddr) | ||
|
||
} | ||
|
||
func DefaultShellWithCheck() (*Shell, error) { | ||
// Load once and cache working default shell address | ||
defaultShellAddrLoadOnce.Do(defaultShell) | ||
return NewShellWithCheck(defaultShellAddr) | ||
} | ||
|
||
func (s *Shell) SetTimeout(d time.Duration) { | ||
s.httpcli.Timeout = d | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
TryNewShell
? Not happy with the name but can't think of a better one.Anyways, this should probably have some more documentation (the description doesn't explain what "error checking" means and would otherwise lead me to believe that it returns a slice of shells).