github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/lib/remote.go (about)

     1  package lib
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/qri-io/dataset"
     8  	"github.com/qri-io/qri/base"
     9  	"github.com/qri-io/qri/dsref"
    10  	qhttp "github.com/qri-io/qri/lib/http"
    11  	"github.com/qri-io/qri/remote"
    12  )
    13  
    14  const allowedDagInfoSize uint64 = 10 * 1024 * 1024
    15  
    16  // RemoteMethods encapsulates business logic of remote operation
    17  // TODO (b5): switch to using an Instance instead of separate fields
    18  type RemoteMethods struct {
    19  	d dispatcher
    20  }
    21  
    22  // Name returns the name of this method group
    23  func (m RemoteMethods) Name() string {
    24  	return "remote"
    25  }
    26  
    27  // Attributes defines attributes for each method
    28  func (m RemoteMethods) Attributes() map[string]AttributeSet {
    29  	return map[string]AttributeSet{
    30  		"feeds":   {Endpoint: qhttp.AEFeeds, HTTPVerb: "POST"},
    31  		"preview": {Endpoint: qhttp.AEPreview, HTTPVerb: "POST"},
    32  		"remove":  {Endpoint: qhttp.AERemoteRemove, HTTPVerb: "POST", DefaultSource: "network"},
    33  	}
    34  }
    35  
    36  // Feeds returns a listing of datasets from a number of feeds like featured and
    37  // popular. Each feed is keyed by string in the response
    38  func (m RemoteMethods) Feeds(ctx context.Context, p *EmptyParams) (map[string][]dsref.VersionInfo, error) {
    39  	got, _, err := m.d.Dispatch(ctx, dispatchMethodName(m, "feeds"), p)
    40  	if res, ok := got.(map[string][]dsref.VersionInfo); ok {
    41  		return res, err
    42  	}
    43  	return nil, dispatchReturnError(got, err)
    44  }
    45  
    46  // PreviewParams provides arguments to the preview method
    47  type PreviewParams struct {
    48  	Ref string `json:"ref"`
    49  }
    50  
    51  // Preview requests a dataset preview from a remote
    52  func (m RemoteMethods) Preview(ctx context.Context, p *PreviewParams) (*dataset.Dataset, error) {
    53  	got, _, err := m.d.Dispatch(ctx, dispatchMethodName(m, "preview"), p)
    54  	if res, ok := got.(*dataset.Dataset); ok {
    55  		return res, err
    56  	}
    57  	return nil, dispatchReturnError(got, err)
    58  }
    59  
    60  // Remove asks a remote to remove a dataset
    61  func (m RemoteMethods) Remove(ctx context.Context, p *PushParams) (*dsref.Ref, error) {
    62  	got, _, err := m.d.Dispatch(ctx, dispatchMethodName(m, "remove"), p)
    63  	if res, ok := got.(*dsref.Ref); ok {
    64  		return res, err
    65  	}
    66  	return nil, dispatchReturnError(got, err)
    67  }
    68  
    69  // remoteImpl holds the method implementations for RemoteMethods
    70  type remoteImpl struct{}
    71  
    72  // Feeds returns a listing of datasets from a number of feeds like featured and
    73  // popular. Each feed is keyed by string in the response
    74  func (remoteImpl) Feeds(scope scope, p *EmptyParams) (map[string][]dsref.VersionInfo, error) {
    75  	addr, err := remote.Address(scope.Config(), scope.SourceName())
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	feed, err := scope.RemoteClient().Feeds(scope.Context(), addr)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	return feed, nil
    85  }
    86  
    87  // Preview requests a dataset preview from a remote
    88  func (remoteImpl) Preview(scope scope, p *PreviewParams) (*dataset.Dataset, error) {
    89  	ref, err := dsref.Parse(p.Ref)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	addr, err := remote.Address(scope.Config(), scope.SourceName())
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  
    99  	res, err := scope.RemoteClient().PreviewDatasetVersion(scope.Context(), ref, addr)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  
   104  	return res, nil
   105  }
   106  
   107  // Remove asks a remote to remove a dataset
   108  func (remoteImpl) Remove(scope scope, p *PushParams) (*dsref.Ref, error) {
   109  	ref, err := dsref.ParseHumanFriendly(p.Ref)
   110  	if err != nil {
   111  		if err == dsref.ErrNotHumanFriendly {
   112  			return nil, fmt.Errorf("can only remove entire dataset. run remove without a path")
   113  		}
   114  		return nil, err
   115  	}
   116  
   117  	author := scope.ActiveProfile()
   118  
   119  	if _, err := scope.ResolveReference(scope.Context(), &ref); err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	addr, err := remote.Address(scope.Config(), p.Remote)
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  
   128  	if err := scope.RemoteClient().RemoveDataset(scope.Context(), ref, addr); err != nil {
   129  		return nil, err
   130  	}
   131  
   132  	if err = base.SetPublishStatus(scope.Context(), scope.Repo(), author, ref, false); err != nil {
   133  		return nil, err
   134  	}
   135  
   136  	return &ref, nil
   137  }