123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- // Copyright 2017 The go-ethereum Authors
- // This file is part of go-ethereum.
- //
- // go-ethereum is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // go-ethereum is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
- // Command MANIFEST update
- package main
- import (
- "encoding/json"
- "fmt"
- "mime"
- "path/filepath"
- "strings"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/swarm/api"
- swarm "github.com/ethereum/go-ethereum/swarm/api/client"
- "gopkg.in/urfave/cli.v1"
- )
- const bzzManifestJSON = "application/bzz-manifest+json"
- func add(ctx *cli.Context) {
- args := ctx.Args()
- if len(args) < 3 {
- utils.Fatalf("Need at least three arguments <MHASH> <path> <HASH> [<content-type>]")
- }
- var (
- mhash = args[0]
- path = args[1]
- hash = args[2]
- ctype string
- wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name)
- mroot api.Manifest
- )
- if len(args) > 3 {
- ctype = args[3]
- } else {
- ctype = mime.TypeByExtension(filepath.Ext(path))
- }
- newManifest := addEntryToManifest(ctx, mhash, path, hash, ctype)
- fmt.Println(newManifest)
- if !wantManifest {
- // Print the manifest. This is the only output to stdout.
- mrootJSON, _ := json.MarshalIndent(mroot, "", " ")
- fmt.Println(string(mrootJSON))
- return
- }
- }
- func update(ctx *cli.Context) {
- args := ctx.Args()
- if len(args) < 3 {
- utils.Fatalf("Need at least three arguments <MHASH> <path> <HASH>")
- }
- var (
- mhash = args[0]
- path = args[1]
- hash = args[2]
- ctype string
- wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name)
- mroot api.Manifest
- )
- if len(args) > 3 {
- ctype = args[3]
- } else {
- ctype = mime.TypeByExtension(filepath.Ext(path))
- }
- newManifest := updateEntryInManifest(ctx, mhash, path, hash, ctype)
- fmt.Println(newManifest)
- if !wantManifest {
- // Print the manifest. This is the only output to stdout.
- mrootJSON, _ := json.MarshalIndent(mroot, "", " ")
- fmt.Println(string(mrootJSON))
- return
- }
- }
- func remove(ctx *cli.Context) {
- args := ctx.Args()
- if len(args) < 2 {
- utils.Fatalf("Need at least two arguments <MHASH> <path>")
- }
- var (
- mhash = args[0]
- path = args[1]
- wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name)
- mroot api.Manifest
- )
- newManifest := removeEntryFromManifest(ctx, mhash, path)
- fmt.Println(newManifest)
- if !wantManifest {
- // Print the manifest. This is the only output to stdout.
- mrootJSON, _ := json.MarshalIndent(mroot, "", " ")
- fmt.Println(string(mrootJSON))
- return
- }
- }
- func addEntryToManifest(ctx *cli.Context, mhash, path, hash, ctype string) string {
- var (
- bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
- client = swarm.NewClient(bzzapi)
- longestPathEntry = api.ManifestEntry{}
- )
- mroot, err := client.DownloadManifest(mhash)
- if err != nil {
- utils.Fatalf("Manifest download failed: %v", err)
- }
- //TODO: check if the "hash" to add is valid and present in swarm
- _, err = client.DownloadManifest(hash)
- if err != nil {
- utils.Fatalf("Hash to add is not present: %v", err)
- }
- // See if we path is in this Manifest or do we have to dig deeper
- for _, entry := range mroot.Entries {
- if path == entry.Path {
- utils.Fatalf("Path %s already present, not adding anything", path)
- } else {
- if entry.ContentType == bzzManifestJSON {
- prfxlen := strings.HasPrefix(path, entry.Path)
- if prfxlen && len(path) > len(longestPathEntry.Path) {
- longestPathEntry = entry
- }
- }
- }
- }
- if longestPathEntry.Path != "" {
- // Load the child Manifest add the entry there
- newPath := path[len(longestPathEntry.Path):]
- newHash := addEntryToManifest(ctx, longestPathEntry.Hash, newPath, hash, ctype)
- // Replace the hash for parent Manifests
- newMRoot := &api.Manifest{}
- for _, entry := range mroot.Entries {
- if longestPathEntry.Path == entry.Path {
- entry.Hash = newHash
- }
- newMRoot.Entries = append(newMRoot.Entries, entry)
- }
- mroot = newMRoot
- } else {
- // Add the entry in the leaf Manifest
- newEntry := api.ManifestEntry{
- Hash: hash,
- Path: path,
- ContentType: ctype,
- }
- mroot.Entries = append(mroot.Entries, newEntry)
- }
- newManifestHash, err := client.UploadManifest(mroot)
- if err != nil {
- utils.Fatalf("Manifest upload failed: %v", err)
- }
- return newManifestHash
- }
- func updateEntryInManifest(ctx *cli.Context, mhash, path, hash, ctype string) string {
- var (
- bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
- client = swarm.NewClient(bzzapi)
- newEntry = api.ManifestEntry{}
- longestPathEntry = api.ManifestEntry{}
- )
- mroot, err := client.DownloadManifest(mhash)
- if err != nil {
- utils.Fatalf("Manifest download failed: %v", err)
- }
- //TODO: check if the "hash" with which to update is valid and present in swarm
- // See if we path is in this Manifest or do we have to dig deeper
- for _, entry := range mroot.Entries {
- if path == entry.Path {
- newEntry = entry
- } else {
- if entry.ContentType == bzzManifestJSON {
- prfxlen := strings.HasPrefix(path, entry.Path)
- if prfxlen && len(path) > len(longestPathEntry.Path) {
- longestPathEntry = entry
- }
- }
- }
- }
- if longestPathEntry.Path == "" && newEntry.Path == "" {
- utils.Fatalf("Path %s not present in the Manifest, not setting anything", path)
- }
- if longestPathEntry.Path != "" {
- // Load the child Manifest add the entry there
- newPath := path[len(longestPathEntry.Path):]
- newHash := updateEntryInManifest(ctx, longestPathEntry.Hash, newPath, hash, ctype)
- // Replace the hash for parent Manifests
- newMRoot := &api.Manifest{}
- for _, entry := range mroot.Entries {
- if longestPathEntry.Path == entry.Path {
- entry.Hash = newHash
- }
- newMRoot.Entries = append(newMRoot.Entries, entry)
- }
- mroot = newMRoot
- }
- if newEntry.Path != "" {
- // Replace the hash for leaf Manifest
- newMRoot := &api.Manifest{}
- for _, entry := range mroot.Entries {
- if newEntry.Path == entry.Path {
- myEntry := api.ManifestEntry{
- Hash: hash,
- Path: entry.Path,
- ContentType: ctype,
- }
- newMRoot.Entries = append(newMRoot.Entries, myEntry)
- } else {
- newMRoot.Entries = append(newMRoot.Entries, entry)
- }
- }
- mroot = newMRoot
- }
- newManifestHash, err := client.UploadManifest(mroot)
- if err != nil {
- utils.Fatalf("Manifest upload failed: %v", err)
- }
- return newManifestHash
- }
- func removeEntryFromManifest(ctx *cli.Context, mhash, path string) string {
- var (
- bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
- client = swarm.NewClient(bzzapi)
- entryToRemove = api.ManifestEntry{}
- longestPathEntry = api.ManifestEntry{}
- )
- mroot, err := client.DownloadManifest(mhash)
- if err != nil {
- utils.Fatalf("Manifest download failed: %v", err)
- }
- // See if we path is in this Manifest or do we have to dig deeper
- for _, entry := range mroot.Entries {
- if path == entry.Path {
- entryToRemove = entry
- } else {
- if entry.ContentType == bzzManifestJSON {
- prfxlen := strings.HasPrefix(path, entry.Path)
- if prfxlen && len(path) > len(longestPathEntry.Path) {
- longestPathEntry = entry
- }
- }
- }
- }
- if longestPathEntry.Path == "" && entryToRemove.Path == "" {
- utils.Fatalf("Path %s not present in the Manifest, not removing anything", path)
- }
- if longestPathEntry.Path != "" {
- // Load the child Manifest remove the entry there
- newPath := path[len(longestPathEntry.Path):]
- newHash := removeEntryFromManifest(ctx, longestPathEntry.Hash, newPath)
- // Replace the hash for parent Manifests
- newMRoot := &api.Manifest{}
- for _, entry := range mroot.Entries {
- if longestPathEntry.Path == entry.Path {
- entry.Hash = newHash
- }
- newMRoot.Entries = append(newMRoot.Entries, entry)
- }
- mroot = newMRoot
- }
- if entryToRemove.Path != "" {
- // remove the entry in this Manifest
- newMRoot := &api.Manifest{}
- for _, entry := range mroot.Entries {
- if entryToRemove.Path != entry.Path {
- newMRoot.Entries = append(newMRoot.Entries, entry)
- }
- }
- mroot = newMRoot
- }
- newManifestHash, err := client.UploadManifest(mroot)
- if err != nil {
- utils.Fatalf("Manifest upload failed: %v", err)
- }
- return newManifestHash
- }
|