From 0835250cc65fb13ff94fb1880dcf4715fb1ad4f2 Mon Sep 17 00:00:00 2001 From: Rick Carlino Date: Wed, 30 Sep 2020 07:56:20 -0500 Subject: [PATCH] Blob creation works --- README.md | 4 ++-- project/blob.go | 41 ++++++++++++++++++++++++++++++++--------- project/blob_test.go | 18 ++++++++++++++++-- project/cli.go | 10 ++++++++++ project/filesystem.go | 4 ++++ 5 files changed, 64 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 12ecb04..09008db 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,6 @@ You can override this value by specifying a `PIGEON_PATH` ENV var. |Done?|Noun |Verb | Flag / arg 1 | Flag 2 | |-----|------------|-----------|---------------|-----------| - | |blob |create | file path | | - | |blob |create | pipe | | | |blob |find | | | | |draft |create | | | | |draft |publish | | | @@ -34,6 +32,8 @@ You can override this value by specifying a `PIGEON_PATH` ENV var. | |message |show | message mhash | | | |bundle |create | | | | |bundle |ingest | | | + | |blob |add | pipe (later) | | + | X |blob |add | file path | | | X |peer |untrack | peer mhash | | | X |peers |list | | | | X |peer |block | peer mhash | | diff --git a/project/blob.go b/project/blob.go index 24e69c0..3a726bb 100644 --- a/project/blob.go +++ b/project/blob.go @@ -3,6 +3,7 @@ package main import ( "crypto/sha256" "fmt" + "io/ioutil" "log" "os" "path" @@ -10,30 +11,52 @@ import ( const blobByteLimit = 360_000 -// Turn a blob mhash into a filepath per bundle spec. -func pathFor(mhash string) string { +func pathAndFilename(mhash string) (dirPath string, fileName string) { validateMhash(mhash) b32 := mhash[len(BlobSigil):] - chunks := []string{ + pathChunks := []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...) + + f := fmt.Sprintf("%s.%s", b32[42:49], b32[49:52]) + p := path.Join(pigeonBlobDir(), path.Join(pathChunks...)) + return p, f } -func addBlob(data []byte) { +// Create a set of nested set of directories to place a blob +// as outlined in bundle spec. +func createBlobDirectory(mhash string) string { + dirPath, fileName := pathAndFilename(mhash) + err := os.MkdirAll(dirPath, 0700) + if err != nil { + panicf("createBlobDirectory: %s", err) + } + + return path.Join(dirPath, fileName) +} + +func addBlob(data []byte) string { 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) + blobPath := createBlobDirectory(mhash) + write(blobPath, data) + return blobPath +} + +func addBlobFromPath(path string) string { + dat, err := ioutil.ReadFile(path) + if err != nil { + panicf("Unable to read %s: %s", path, err) + } + return addBlob(dat) } func write(path string, data []byte) { @@ -55,7 +78,7 @@ func write(path string, data []byte) { } // def get_blob(mhash) -// path1 = File.join(pathFor(mhash) +// path1 = File.join(createBlobDirectory(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 index e1834da..90bae8b 100644 --- a/project/blob_test.go +++ b/project/blob_test.go @@ -1,13 +1,27 @@ package main import ( + "fmt" + "path" "testing" ) func TestPathForBlob(t *testing.T) { mhash := "FILE.FV0FJ0YZADY7C5JTTFYPKDBHTZJ5JVVP5TCKP0605WWXYJG4VMRG" - expected := "FV0FJ0Y/ZADY7C5/JTTFYPK/DBHTZJ5/JVVP5TC/KP0605W/WXYJG4V.MRG" - if pathFor(mhash) != expected { + expected := path.Join(pigeonBlobDir(), + "FV0FJ0Y", + "ZADY7C5", + "JTTFYPK", + "DBHTZJ5", + "JVVP5TC", + "KP0605W", + "WXYJG4V.MRG") + p, f := pathAndFilename(mhash) + actual := path.Join(p, f) + + if actual != expected { + fmt.Printf("Expected %s\n", expected) + fmt.Printf("Got %s\n", actual) t.Fail() } } diff --git a/project/cli.go b/project/cli.go index 864e2ed..96c1981 100644 --- a/project/cli.go +++ b/project/cli.go @@ -115,6 +115,15 @@ var blobRootCmd = &cobra.Command{ }, } +var blobAddCommand = &cobra.Command{ + Use: "add", + Short: "Begin tracking a file in the database", + Aliases: []string{"create"}, + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("%s\n", addBlobFromPath(args[0])) + }, +} + // BootstrapCLI wires up all the relevant commands. func BootstrapCLI() { rootCmd.AddCommand(versionCmd) @@ -130,6 +139,7 @@ func BootstrapCLI() { peerRootCmd.AddCommand(peerListCmd) rootCmd.AddCommand(blobRootCmd) + blobRootCmd.AddCommand(blobAddCommand) if err := rootCmd.Execute(); err != nil { fmt.Println(err) diff --git a/project/filesystem.go b/project/filesystem.go index bcf7888..9f7f516 100644 --- a/project/filesystem.go +++ b/project/filesystem.go @@ -19,6 +19,10 @@ func pigeonHomeDir() string { return path.Join(home, ".pigeon") } +func pigeonBlobDir() string { + return path.Join(pigeonHomeDir(), "blobs") +} + func maybeSetupPigeonDir() string { err := os.MkdirAll(pigeonHomeDir(), 0700) if err != nil {