github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/p2p/dag.go (about) 1 package p2p 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/ipfs/go-cid" 8 ipld "github.com/ipfs/go-ipld-format" 9 "github.com/qri-io/dag" 10 "github.com/qri-io/qfs" 11 "github.com/qri-io/qri/base/dsfs" 12 ) 13 14 // NewManifest generates a manifest for a given node 15 func (node *QriNode) NewManifest(ctx context.Context, path string) (*dag.Manifest, error) { 16 ng, err := newNodeGetter(node) 17 if err != nil { 18 return nil, err 19 } 20 21 id, err := cid.Parse(path) 22 if err != nil { 23 return nil, err 24 } 25 26 return dag.NewManifest(ctx, ng, id) 27 } 28 29 // MissingManifest returns a manifest describing blocks that are not in this 30 // node for a given manifest 31 func (node *QriNode) MissingManifest(ctx context.Context, m *dag.Manifest) (missing *dag.Manifest, err error) { 32 if m == nil { 33 return nil, fmt.Errorf("nil manifest") 34 } 35 ng, err := newNodeGetter(node) 36 if err != nil { 37 return nil, err 38 } 39 40 return dag.Missing(ctx, ng, m) 41 } 42 43 // NewDAGInfo generates a DAGInfo for a given node. If a label is given, it will generate a sub-DAGInfo at thea label. 44 func (node *QriNode) NewDAGInfo(ctx context.Context, path, label string) (*dag.Info, error) { 45 ng, err := newNodeGetter(node) 46 if err != nil { 47 return nil, err 48 } 49 50 return newDAGInfo(ctx, node.Repo.Filesystem(), ng, path, label) 51 } 52 53 // newDAGInfo generates a DAGInfo for a given node. If a label is provided, 54 // it generates a sub-DAGInfo at that label 55 func newDAGInfo(ctx context.Context, fs qfs.Filesystem, ng ipld.NodeGetter, path, label string) (*dag.Info, error) { 56 id, err := cid.Parse(path) 57 if err != nil { 58 return nil, err 59 } 60 61 info, err := dag.NewInfo(ctx, ng, id) 62 if err != nil { 63 return nil, err 64 } 65 // get referenced version of dataset 66 ds, err := dsfs.LoadDatasetRefs(ctx, fs, path) 67 if err != nil { 68 return nil, err 69 } 70 71 info.Labels = map[string]int{} 72 if ds.BodyPath != "" { 73 err := info.AddLabelByID("bd", dsfs.GetHashBase(ds.BodyPath)) 74 if err != nil { 75 return nil, fmt.Errorf("adding body label: %w", err) 76 } 77 } 78 if ds.Viz != nil && ds.Viz.Path != "" { 79 err := info.AddLabelByID("vz", dsfs.GetHashBase(ds.Viz.Path)) 80 if err != nil { 81 return nil, fmt.Errorf("adding viz label: %w", err) 82 } 83 if err := dsfs.DerefViz(ctx, fs, ds); err != nil { 84 return nil, err 85 } 86 if ds.Viz.RenderedPath != "" { 87 err := info.AddLabelByID("rd", dsfs.GetHashBase(ds.Viz.RenderedPath)) 88 if err != nil { 89 return nil, err 90 } 91 } 92 } 93 if ds.Transform != nil && ds.Transform.Path != "" { 94 err := info.AddLabelByID("tf", dsfs.GetHashBase(ds.Transform.Path)) 95 if err != nil { 96 return nil, fmt.Errorf("adding transform label: %w", err) 97 } 98 } 99 if ds.Meta != nil && ds.Meta.Path != "" { 100 err := info.AddLabelByID("md", dsfs.GetHashBase(ds.Meta.Path)) 101 if err != nil { 102 return nil, fmt.Errorf("adding meta label %w", err) 103 } 104 } 105 if ds.Structure != nil && ds.Structure.Path != "" { 106 err := info.AddLabelByID("st", dsfs.GetHashBase(ds.Structure.Path)) 107 if err != nil { 108 return nil, fmt.Errorf("adding structure label: %w", err) 109 } 110 } 111 if ds.Stats != nil && ds.Stats.Path != "" { 112 err := info.AddLabelByID("sa", dsfs.GetHashBase(ds.Stats.Path)) 113 if err != nil { 114 return nil, fmt.Errorf("adding stats label: %w", err) 115 } 116 } 117 if ds.Commit != nil && ds.Commit.Path != "" { 118 err := info.AddLabelByID("cm", dsfs.GetHashBase(ds.Commit.Path)) 119 if err != nil { 120 return nil, fmt.Errorf("adding commit label: %w", err) 121 } 122 } 123 124 if label != "" { 125 return info.InfoAtLabel(label) 126 } 127 return info, nil 128 } 129 130 // newNodeGetter generates an ipld.NodeGetter from a QriNode 131 func newNodeGetter(node *QriNode) (ipld.NodeGetter, error) { 132 capi, err := node.IPFSCoreAPI() 133 if err != nil { 134 return nil, err 135 } 136 return dag.NewNodeGetter(capi.Dag()), nil 137 }