Just about ready to implement `blob create`
This commit is contained in:
parent
aabbd29310
commit
8d99d3ba5d
|
@ -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
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.
|
// BootstrapCLI wires up all the relevant commands.
|
||||||
func BootstrapCLI() {
|
func BootstrapCLI() {
|
||||||
rootCmd.AddCommand(versionCmd)
|
rootCmd.AddCommand(versionCmd)
|
||||||
|
@ -119,6 +128,9 @@ func BootstrapCLI() {
|
||||||
peerRootCmd.AddCommand(peerFollowCmd)
|
peerRootCmd.AddCommand(peerFollowCmd)
|
||||||
peerRootCmd.AddCommand(peerUntrackedCmd)
|
peerRootCmd.AddCommand(peerUntrackedCmd)
|
||||||
peerRootCmd.AddCommand(peerListCmd)
|
peerRootCmd.AddCommand(peerListCmd)
|
||||||
|
|
||||||
|
rootCmd.AddCommand(blobRootCmd)
|
||||||
|
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := rootCmd.Execute(); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
@ -15,3 +15,7 @@ func B32Encode(data []byte) string {
|
||||||
func encodePeerMhash(pubKey []byte) string {
|
func encodePeerMhash(pubKey []byte) string {
|
||||||
return PeerSigil + B32Encode(pubKey)
|
return PeerSigil + B32Encode(pubKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeBlobMhash(sha256 [32]byte) string {
|
||||||
|
return BlobSigil + B32Encode(sha256[:])
|
||||||
|
}
|
||||||
|
|
|
@ -7,18 +7,22 @@ import (
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
)
|
)
|
||||||
|
|
||||||
func maybeSetupPigeonDir() string {
|
func pigeonHomeDir() string {
|
||||||
var pigeonDataDir string
|
|
||||||
customPath, hasCustomPath := os.LookupEnv("PIGEON_PATH")
|
customPath, hasCustomPath := os.LookupEnv("PIGEON_PATH")
|
||||||
if hasCustomPath {
|
if hasCustomPath {
|
||||||
pigeonDataDir = customPath
|
return customPath
|
||||||
} else {
|
|
||||||
home, err := homedir.Dir()
|
|
||||||
if err != nil {
|
|
||||||
panicf("Home directory resolution error %s", err)
|
|
||||||
}
|
|
||||||
pigeonDataDir = path.Join(home, ".pigeon")
|
|
||||||
}
|
}
|
||||||
os.MkdirAll(pigeonDataDir, 0700)
|
home, err := homedir.Dir()
|
||||||
return pigeonDataDir
|
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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue