From 8d99d3ba5d16e90ad6c27e7eac076bd4405943d5 Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Mon, 28 Sep 2020 19:34:16 -0500 Subject: [PATCH] Just about ready to implement `blob create` --- project/blob.go | 61 +++++++++++++++++++++++++++++++++++++++++++ project/blob_test.go | 13 +++++++++ project/cli.go | 12 +++++++++ project/encoders.go | 4 +++ project/filesystem.go | 26 ++++++++++-------- 5 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 project/blob.go create mode 100644 project/blob_test.go diff --git a/project/blob.go b/project/blob.go new file mode 100644 index 0000000..24e69c0 --- /dev/null +++ b/project/blob.go @@ -0,0 +1,61 @@ +package main + +import ( + "crypto/sha256" + "fmt" + "log" + "os" + "path" +) + +const blobByteLimit = 360_000 + +// Turn a blob mhash into a filepath per bundle spec. +func pathFor(mhash string) string { + validateMhash(mhash) + b32 := mhash[len(BlobSigil):] + chunks := []string{ + b32[0:7], + b32[7:14], + b32[14:21], + b32[21:28], + b32[28:35], + b32[35:42], + fmt.Sprintf("%s.%s", b32[42:49], b32[49:52]), + } + return path.Join(chunks...) +} + +func addBlob(data []byte) { + size := len(data) + if size > blobByteLimit { + panicf("Expected blob smaller than %d. Got: %d", blobByteLimit, size) + } + mhash := encodeBlobMhash(sha256.Sum256(data)) + path := path.Join(pigeonHomeDir(), pathFor(mhash)) + write(path, data) +} + +func write(path string, data []byte) { + // Open a new file for writing only + file, err := os.OpenFile( + path, + os.O_WRONLY|os.O_TRUNC|os.O_CREATE, + 0600, + ) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + _, err2 := file.Write(data) + if err2 != nil { + log.Fatal(err) + } +} + +// def get_blob(mhash) +// path1 = File.join(pathFor(mhash) +// path2 = File.join(DEFAULT_BLOB_DIR, path1) +// File.read(path2) if File.file?(path2) +// end diff --git a/project/blob_test.go b/project/blob_test.go new file mode 100644 index 0000000..e1834da --- /dev/null +++ b/project/blob_test.go @@ -0,0 +1,13 @@ +package main + +import ( + "testing" +) + +func TestPathForBlob(t *testing.T) { + mhash := "FILE.FV0FJ0YZADY7C5JTTFYPKDBHTZJ5JVVP5TCKP0605WWXYJG4VMRG" + expected := "FV0FJ0Y/ZADY7C5/JTTFYPK/DBHTZJ5/JVVP5TC/KP0605W/WXYJG4V.MRG" + if pathFor(mhash) != expected { + t.Fail() + } +} diff --git a/project/cli.go b/project/cli.go index 602b474..864e2ed 100644 --- a/project/cli.go +++ b/project/cli.go @@ -106,6 +106,15 @@ var peerUntrackedCmd = &cobra.Command{ }, } +// CLI: `pigeon identity` +var blobRootCmd = &cobra.Command{ + Use: "file(s)", + Short: "File related commands", + Aliases: []string{"file", "blob", "files", "blobs"}, + Run: func(cmd *cobra.Command, args []string) { + }, +} + // BootstrapCLI wires up all the relevant commands. func BootstrapCLI() { rootCmd.AddCommand(versionCmd) @@ -119,6 +128,9 @@ func BootstrapCLI() { peerRootCmd.AddCommand(peerFollowCmd) peerRootCmd.AddCommand(peerUntrackedCmd) peerRootCmd.AddCommand(peerListCmd) + + rootCmd.AddCommand(blobRootCmd) + if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) diff --git a/project/encoders.go b/project/encoders.go index 1ce522a..f91ffd1 100644 --- a/project/encoders.go +++ b/project/encoders.go @@ -15,3 +15,7 @@ func B32Encode(data []byte) string { func encodePeerMhash(pubKey []byte) string { return PeerSigil + B32Encode(pubKey) } + +func encodeBlobMhash(sha256 [32]byte) string { + return BlobSigil + B32Encode(sha256[:]) +} diff --git a/project/filesystem.go b/project/filesystem.go index b7dfcdb..bcf7888 100644 --- a/project/filesystem.go +++ b/project/filesystem.go @@ -7,18 +7,22 @@ import ( "github.com/mitchellh/go-homedir" ) -func maybeSetupPigeonDir() string { - var pigeonDataDir string +func pigeonHomeDir() string { customPath, hasCustomPath := os.LookupEnv("PIGEON_PATH") if hasCustomPath { - pigeonDataDir = customPath - } else { - home, err := homedir.Dir() - if err != nil { - panicf("Home directory resolution error %s", err) - } - pigeonDataDir = path.Join(home, ".pigeon") + return customPath } - os.MkdirAll(pigeonDataDir, 0700) - return pigeonDataDir + home, err := homedir.Dir() + if err != nil { + panicf("Home directory resolution error %s", err) + } + return path.Join(home, ".pigeon") +} + +func maybeSetupPigeonDir() string { + err := os.MkdirAll(pigeonHomeDir(), 0700) + if err != nil { + panicf("maybeSetupPigeonDir: %s", err) + } + return pigeonHomeDir() }