gitlab.nesad.fit.vutbr.cz/blended/libblended@v0.0.0-20221202124402-2bee159339df/ipfs/link.go (about) 1 package ipfs 2 3 import ( 4 "path/filepath" 5 "strings" 6 ) 7 8 func (c *IpfsClient) Link(path string, name string, ipfsHash string) (string, error) { 9 // check if the file exists 10 _, err := c.Stat(ipfsHash) 11 if err != nil { 12 return "", err 13 } 14 15 // unpin old IPFS hash 16 oldHash := strings.SplitN(path, "/", 2)[0] 17 err = c.Shell.Unpin(oldHash) 18 if err != nil { 19 return "", err 20 } 21 22 newHash, err := c.patchLink(path, name, ipfsHash) 23 if err != nil { 24 return "", err 25 } 26 27 err = c.Shell.Pin(path) 28 if err != nil { 29 return "", err 30 } 31 32 return newHash, nil 33 } 34 35 func (c *IpfsClient) patchLink(root string, linkName string, linkHash string) (string, error) { 36 var rmLink struct { 37 Hash string 38 } 39 40 ctx, cancel := c.getContext() 41 err := c.Shell.Request("object/patch/add-link", root, linkName, linkHash). 42 Option("create", true). 43 Exec(ctx, &rmLink) 44 cancel() 45 return rmLink.Hash, err 46 } 47 48 // this function recursive patches link. 49 // example: we have IPFS directory structure consisting of multiple subfolders /a/b/c/d/e 50 // if e changed its hash, we need to patch link d->e to point to new hash of e 51 // than we need to patch link c->d to points to new d that points to new e and so on... 52 func (c *IpfsClient) recursivePatchLink(path string, name string, hash string) (string, error) { 53 // Dir returns "." when path is empty 54 if path == "." { 55 return hash, nil 56 } else { 57 // update link to point to new hash 58 newHash, err := c.patchLink(filepath.ToSlash(path), name, hash) 59 if err != nil { 60 return "", err 61 } 62 63 pathWithoutLastElement := filepath.Dir(path) 64 lastName := filepath.Base(path) 65 66 return c.recursivePatchLink(pathWithoutLastElement, lastName, newHash) 67 } 68 } 69 70 func (c *IpfsClient) removeLink(hash string, linkName string) (string, error) { 71 var rmLink struct { 72 Hash string 73 } 74 75 ctx, cancel := c.getContext() 76 err := c.Shell.Request("object/patch/rm-link", hash, linkName). 77 Exec(ctx, &rmLink) 78 cancel() 79 80 if err != nil { 81 return "", err 82 } 83 return rmLink.Hash, err 84 }