Blob creation works

This commit is contained in:
Netscape Navigator 2020-09-30 07:56:20 -05:00
parent 8d99d3ba5d
commit 0835250cc6
5 changed files with 64 additions and 13 deletions

View File

@ -22,8 +22,6 @@ You can override this value by specifying a `PIGEON_PATH` ENV var.
|Done?|Noun |Verb | Flag / arg 1 | Flag 2 | |Done?|Noun |Verb | Flag / arg 1 | Flag 2 |
|-----|------------|-----------|---------------|-----------| |-----|------------|-----------|---------------|-----------|
| |blob |create | file path | |
| |blob |create | pipe | |
| |blob |find | | | | |blob |find | | |
| |draft |create | | | | |draft |create | | |
| |draft |publish | | | | |draft |publish | | |
@ -34,6 +32,8 @@ You can override this value by specifying a `PIGEON_PATH` ENV var.
| |message |show | message mhash | | | |message |show | message mhash | |
| |bundle |create | | | | |bundle |create | | |
| |bundle |ingest | | | | |bundle |ingest | | |
| |blob |add | pipe (later) | |
| X |blob |add | file path | |
| X |peer |untrack | peer mhash | | | X |peer |untrack | peer mhash | |
| X |peers |list | | | | X |peers |list | | |
| X |peer |block | peer mhash | | | X |peer |block | peer mhash | |

View File

@ -3,6 +3,7 @@ package main
import ( import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"os" "os"
"path" "path"
@ -10,30 +11,52 @@ import (
const blobByteLimit = 360_000 const blobByteLimit = 360_000
// Turn a blob mhash into a filepath per bundle spec. func pathAndFilename(mhash string) (dirPath string, fileName string) {
func pathFor(mhash string) string {
validateMhash(mhash) validateMhash(mhash)
b32 := mhash[len(BlobSigil):] b32 := mhash[len(BlobSigil):]
chunks := []string{ pathChunks := []string{
b32[0:7], b32[0:7],
b32[7:14], b32[7:14],
b32[14:21], b32[14:21],
b32[21:28], b32[21:28],
b32[28:35], b32[28:35],
b32[35:42], 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) size := len(data)
if size > blobByteLimit { if size > blobByteLimit {
panicf("Expected blob smaller than %d. Got: %d", blobByteLimit, size) panicf("Expected blob smaller than %d. Got: %d", blobByteLimit, size)
} }
mhash := encodeBlobMhash(sha256.Sum256(data)) mhash := encodeBlobMhash(sha256.Sum256(data))
path := path.Join(pigeonHomeDir(), pathFor(mhash)) blobPath := createBlobDirectory(mhash)
write(path, data) 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) { func write(path string, data []byte) {
@ -55,7 +78,7 @@ func write(path string, data []byte) {
} }
// def get_blob(mhash) // def get_blob(mhash)
// path1 = File.join(pathFor(mhash) // path1 = File.join(createBlobDirectory(mhash)
// path2 = File.join(DEFAULT_BLOB_DIR, path1) // path2 = File.join(DEFAULT_BLOB_DIR, path1)
// File.read(path2) if File.file?(path2) // File.read(path2) if File.file?(path2)
// end // end

View File

@ -1,13 +1,27 @@
package main package main
import ( import (
"fmt"
"path"
"testing" "testing"
) )
func TestPathForBlob(t *testing.T) { func TestPathForBlob(t *testing.T) {
mhash := "FILE.FV0FJ0YZADY7C5JTTFYPKDBHTZJ5JVVP5TCKP0605WWXYJG4VMRG" mhash := "FILE.FV0FJ0YZADY7C5JTTFYPKDBHTZJ5JVVP5TCKP0605WWXYJG4VMRG"
expected := "FV0FJ0Y/ZADY7C5/JTTFYPK/DBHTZJ5/JVVP5TC/KP0605W/WXYJG4V.MRG" expected := path.Join(pigeonBlobDir(),
if pathFor(mhash) != expected { "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() t.Fail()
} }
} }

View File

@ -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. // BootstrapCLI wires up all the relevant commands.
func BootstrapCLI() { func BootstrapCLI() {
rootCmd.AddCommand(versionCmd) rootCmd.AddCommand(versionCmd)
@ -130,6 +139,7 @@ func BootstrapCLI() {
peerRootCmd.AddCommand(peerListCmd) peerRootCmd.AddCommand(peerListCmd)
rootCmd.AddCommand(blobRootCmd) rootCmd.AddCommand(blobRootCmd)
blobRootCmd.AddCommand(blobAddCommand)
if err := rootCmd.Execute(); err != nil { if err := rootCmd.Execute(); err != nil {
fmt.Println(err) fmt.Println(err)

View File

@ -19,6 +19,10 @@ func pigeonHomeDir() string {
return path.Join(home, ".pigeon") return path.Join(home, ".pigeon")
} }
func pigeonBlobDir() string {
return path.Join(pigeonHomeDir(), "blobs")
}
func maybeSetupPigeonDir() string { func maybeSetupPigeonDir() string {
err := os.MkdirAll(pigeonHomeDir(), 0700) err := os.MkdirAll(pigeonHomeDir(), 0700)
if err != nil { if err != nil {