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  }