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 |
|-----|------------|-----------|---------------|-----------|
| |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 | |

View File

@ -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

View File

@ -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()
}
}

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.
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)

View File

@ -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 {