Skip to content

Commit

Permalink
feat(registry): add preview support to registry fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
b5 committed Feb 3, 2020
1 parent a87b4a2 commit 19f12bd
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 152 deletions.
5 changes: 2 additions & 3 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,12 @@ func NewServerRoutes(s Server) *http.ServeMux {
rch := NewRegistryClientHandlers(s.Instance, cfg.API.ReadOnly)
m.Handle("/registry/profile/new", s.middleware(rch.CreateProfileHandler))
m.Handle("/registry/profile/prove", s.middleware(rch.ProveProfileKeyHandler))
m.Handle("/registry/feed/home", s.middleware(rch.HomeHandler))
m.Handle("/registry/dataset/preview/", s.middleware(rch.DatasetPreviewHandler))

sh := NewSearchHandlers(s.Instance)
m.Handle("/search", s.middleware(sh.SearchHandler))

bh := NewBrowseHandlers(s.Instance)
m.Handle("/feed/home", s.middleware(bh.HomeHandler))

rh := NewRootHandler(dsh, ph)
m.Handle("/", s.datasetRefMiddleware(s.middleware(rh.Handler)))

Expand Down
45 changes: 0 additions & 45 deletions api/browse.go

This file was deleted.

49 changes: 49 additions & 0 deletions api/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package api
import (
"encoding/json"
"net/http"
"strings"

util "github.com/qri-io/apiutil"
"github.com/qri-io/dataset"
"github.com/qri-io/qri/lib"
)

Expand Down Expand Up @@ -78,3 +80,50 @@ func (h *RegistryClientHandlers) ProveProfileKeyHandler(w http.ResponseWriter, r

util.WriteResponse(w, p)
}

// HomeHandler fetches an index of content from the registry
func (h *RegistryClientHandlers) HomeHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "OPTIONS":
util.EmptyOkHandler(w, r)
case "GET":
h.homeHandler(w, r)
default:
util.NotFoundHandler(w, r)
}
}

func (h *RegistryClientHandlers) homeHandler(w http.ResponseWriter, r *http.Request) {
res := map[string][]*dataset.Dataset{}
p := false
if err := h.Home(&p, &res); err != nil {
log.Infof("home error: %s", err.Error())
util.WriteErrResponse(w, http.StatusInternalServerError, err)
return
}

util.WriteResponse(w, res)
}

// DatasetPreviewHandler fetches a dataset preview from the registry
func (h *RegistryClientHandlers) DatasetPreviewHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "OPTIONS":
util.EmptyOkHandler(w, r)
case "GET":
h.previewHandler(w, r)
default:
util.NotFoundHandler(w, r)
}
}

func (h *RegistryClientHandlers) previewHandler(w http.ResponseWriter, r *http.Request) {
refstr := strings.TrimPrefix(r.URL.Path, "/registry/dataset/preview/")
res := &dataset.Dataset{}
if err := h.Preview(&refstr, res); err != nil {
util.WriteErrResponse(w, http.StatusBadRequest, err)
return
}

util.WriteResponse(w, res)
}
47 changes: 47 additions & 0 deletions base/preview.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package base

import (
"context"
"encoding/json"
"fmt"

"github.com/qri-io/dataset"
"github.com/qri-io/qri/base/dsfs"
"github.com/qri-io/qri/dsref"
"github.com/qri-io/qri/repo"
)

// CreatePreview generates a preview for a dataset version
func CreatePreview(ctx context.Context, r repo.Repo, ref dsref.Ref) (ds *dataset.Dataset, err error) {
if ref.Path == "" {
return nil, fmt.Errorf("path is required")
}

ds, err = dsfs.LoadDataset(ctx, r.Store(), ref.Path)
if err != nil {
log.Errorf("CreatePreview loading dataset: %s", err.Error())
return nil, err
}

if err = ds.OpenBodyFile(ctx, r.Store()); err != nil {
log.Errorf("CreatePreview opening body file: %s", err.Error())
return nil, err
}

st := &dataset.Structure{
Format: "json",
Schema: ds.Structure.Schema,
}

data, err := ConvertBodyFile(ds.BodyFile(), ds.Structure, st, 100, 0, false)
if err != nil {
log.Errorf("CreatePreview converting body file: %s", err.Error())
return nil, err
}

ds.Peername = ref.Username
ds.Name = ref.Name
ds.Path = ref.Path
ds.Body = json.RawMessage(data)
return ds, nil
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
github.com/multiformats/go-multiaddr v0.1.1
github.com/multiformats/go-multicodec v0.1.6
github.com/multiformats/go-multihash v0.0.8
github.com/prometheus/common v0.6.0
github.com/qri-io/apiutil v0.1.0
github.com/qri-io/dag v0.2.1-0.20191025201336-254aa177fbd7
github.com/qri-io/dataset v0.1.5-0.20191126212116-72b5aa69790b
Expand Down
61 changes: 0 additions & 61 deletions lib/browse.go

This file was deleted.

24 changes: 20 additions & 4 deletions lib/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ func TestTwoActorRegistryIntegration(t *testing.T) {

nasim := tr.InitNasim(t)

// 1. nasim creates a dataset
// - nasim creates a dataset
ref := InitWorldBankDataset(t, nasim)

// 2. nasim publishes to the registry
// - nasim publishes to the registry
PublishToRegistry(t, nasim, ref.AliasString())

if err := AssertLogsEqual(nasim, tr.RegistryInst, ref); err != nil {
Expand All @@ -41,13 +41,18 @@ func TestTwoActorRegistryIntegration(t *testing.T) {

hinshun := tr.InitHinshun(t)

// 3. hinshun searches the registry for nasim's dataset name, gets a result
// - hinshun searches the registry for nasim's dataset name, gets a result
if results := SearchFor(t, hinshun, "bank"); len(results) < 1 {
t.Logf("expected at least one result in registry search")
// t.Errorf("expected at least one result in registry search")
}

// 4. hinshun clones nasim's dataset
// - hunshun fetches a preview of nasim's dataset
// TODO (b5) - need to use the ref returned from search results
t.Log(ref.String())
Preview(t, hinshun, ref.String())

// - hinshun clones nasim's dataset
Clone(t, hinshun, ref.AliasString())

if err := AssertLogsEqual(nasim, hinshun, ref); err != nil {
Expand Down Expand Up @@ -227,6 +232,10 @@ func InitWorldBankDataset(t *testing.T, inst *Instance) *reporef.DatasetRef {
BodyPath: "body.csv",
BodyBytes: []byte(`a,b,c,true,2
d,e,f,false,3`),
Readme: &dataset.Readme{
ScriptPath: "readme.md",
ScriptBytes: []byte("#World Bank Population\nhow many people live on this planet?"),
},
},
}, res)

Expand Down Expand Up @@ -287,6 +296,13 @@ func Clone(t *testing.T, inst *Instance, refstr string) *reporef.DatasetRef {
if err := NewDatasetRequestsInstance(inst).Add(&AddParams{Ref: refstr}, res); err != nil {
t.Fatalf("cloning dataset %s: %s", refstr, err)
}
return res
}

func Preview(t *testing.T, inst *Instance, refstr string) *dataset.Dataset {
res := &dataset.Dataset{}
if err := NewRegistryClientMethods(inst).Preview(&refstr, res); err != nil {
t.Fatal(err)
}
return res
}
1 change: 0 additions & 1 deletion lib/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ func Receivers(inst *Instance) []Methods {

return []Methods{
NewDatasetRequestsInstance(inst),
NewBrowseMethods(inst),
NewRegistryClientMethods(inst),
NewRemoteMethods(inst),
NewLogRequests(node, nil),
Expand Down
2 changes: 1 addition & 1 deletion lib/lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func TestReceivers(t *testing.T) {
inst := &Instance{node: node, cfg: cfg}

reqs := Receivers(inst)
expect := 13
expect := 12
if len(reqs) != expect {
t.Errorf("unexpected number of receivers returned. expected: %d. got: %d\nhave you added/removed a receiver?", expect, len(reqs))
return
Expand Down
57 changes: 57 additions & 0 deletions lib/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package lib

import (
"context"
"fmt"

"github.com/qri-io/dataset"
"github.com/qri-io/qri/base"
"github.com/qri-io/qri/config"
"github.com/qri-io/qri/registry"
"github.com/qri-io/qri/repo"
"github.com/qri-io/qri/repo/profile"
)

Expand Down Expand Up @@ -103,3 +106,57 @@ func (m RegistryClientMethods) updateConfig(pro *registry.Profile) error {

return m.inst.ChangeConfig(cfg)
}

// Home returns a listing of datasets from a number of feeds like featured and
// popular. Each feed is keyed by string in the response
func (m *RegistryClientMethods) Home(p *bool, res *map[string][]*dataset.Dataset) error {
if m.inst.rpc != nil {
return m.inst.rpc.Call("RegistryClientMethods.Home", p, res)
}
ctx := context.TODO()

if m.inst.registry == nil {
return fmt.Errorf("Feed isn't available without a configured registry")
}

feed, err := m.inst.registry.HomeFeed(ctx)
if err != nil {
return err
}

*res = feed
return nil
}

// Featured asks a registry for a curated list of datasets
func (m *RegistryClientMethods) Featured(p *ListParams, res *[]*dataset.Dataset) error {
return fmt.Errorf("featured dataset feed is not yet implemented")
}

// Recent is a feed of network datasets in reverse chronological order
// it currently can only come from a registry, but could easily be assembled
// via p2p methods
func (m *RegistryClientMethods) Recent(p *ListParams, res *[]*dataset.Dataset) error {
return fmt.Errorf("recent dataset feed is not yet implemented")
}

// Preview creates
func (m *RegistryClientMethods) Preview(refstr *string, res *dataset.Dataset) error {
if m.inst.rpc != nil {
return m.inst.rpc.Call("RegistryClientMethods.Preview", refstr, res)
}
ctx := context.TODO()

ref, err := repo.ParseDatasetRef(*refstr)
if err != nil {
return err
}

pre, err := m.inst.registry.Preview(ctx, repo.ConvertToDsref(ref))
if err != nil {
return err
}

*res = *pre
return nil
}
Loading

0 comments on commit 19f12bd

Please sign in to comment.