From ef06599d9e4594822b56670b7d39e7c191d774b1 Mon Sep 17 00:00:00 2001 From: b5 Date: Tue, 25 Feb 2020 16:07:59 -0500 Subject: [PATCH] feat(api): support for dynamic dataset readme rendering This'll now work: curl -X POST -H "Content-Type: application/json" "http://localhost:2503/render" -d '{"readme": { "scriptBytes" : "IyBoZWxsbyB3b3JsZAo=" }}' --- api/api.go | 1 + api/render.go | 12 ++++++++++++ lib/render.go | 42 ++++++++++++++++++++++++------------------ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/api/api.go b/api/api.go index 15137634f..3e767d2fc 100644 --- a/api/api.go +++ b/api/api.go @@ -297,6 +297,7 @@ func NewServerRoutes(s Server) *http.ServeMux { m.Handle("/fsi/write/", s.middleware(fsih.WriteHandler("/fsi/write"))) renderh := NewRenderHandlers(node.Repo) + m.Handle("/render", s.middleware(renderh.RenderHandler)) m.Handle("/render/", s.middleware(renderh.RenderHandler)) lh := NewLogHandlers(node) diff --git a/api/render.go b/api/render.go index ab5a58231..418d7f2c8 100644 --- a/api/render.go +++ b/api/render.go @@ -1,9 +1,11 @@ package api import ( + "encoding/json" "net/http" "github.com/qri-io/apiutil" + "github.com/qri-io/dataset" "github.com/qri-io/qri/lib" "github.com/qri-io/qri/repo" ) @@ -33,6 +35,16 @@ func (h *RenderHandlers) RenderHandler(w http.ResponseWriter, r *http.Request) { OutFormat: "html", } + // support rendering a passed-in JSON dataset document + if r.Header.Get("Content-Type") == "application/json" { + ds := &dataset.Dataset{} + if err := json.NewDecoder(r.Body).Decode(ds); err != nil { + apiutil.WriteErrResponse(w, http.StatusBadRequest, err) + return + } + p.Dataset = ds + } + // Old style viz component rendering if r.FormValue("viz") == "true" { data := []byte{} diff --git a/lib/render.go b/lib/render.go index 606c965b0..9de3d653c 100644 --- a/lib/render.go +++ b/lib/render.go @@ -39,7 +39,11 @@ func (RenderRequests) CoreRequestsName() string { return "render" } // RenderParams defines parameters for the Render method type RenderParams struct { - Ref string + // Ref is a string reference to the dataset to render + Ref string + // Optionally pass an entire dataset in for rendering, overrides ref param + Dataset *dataset.Dataset + // Optional template override Template []byte UseFSI bool OutFormat string @@ -74,23 +78,27 @@ func (r *RenderRequests) RenderReadme(p *RenderParams, res *string) (err error) } ctx := context.TODO() - ref, err := base.ToDatasetRef(p.Ref, r.repo, p.UseFSI) - if err != nil { - return err - } - var ds *dataset.Dataset - if p.UseFSI { - if ref.FSIPath == "" { - return fsi.ErrNoLink - } - if ds, err = fsi.ReadDir(ref.FSIPath); err != nil { - return fmt.Errorf("loading linked dataset: %s", err) - } + if p.Dataset != nil { + ds = p.Dataset } else { - ds, err = dsfs.LoadDataset(ctx, r.repo.Store(), ref.Path) + ref, err := base.ToDatasetRef(p.Ref, r.repo, p.UseFSI) if err != nil { - return fmt.Errorf("loading dataset: %s", err) + return err + } + + if p.UseFSI { + if ref.FSIPath == "" { + return fsi.ErrNoLink + } + if ds, err = fsi.ReadDir(ref.FSIPath); err != nil { + return fmt.Errorf("loading linked dataset: %s", err) + } + } else { + ds, err = dsfs.LoadDataset(ctx, r.repo.Store(), ref.Path) + if err != nil { + return fmt.Errorf("loading dataset: %s", err) + } } } @@ -98,11 +106,9 @@ func (r *RenderRequests) RenderReadme(p *RenderParams, res *string) (err error) return fmt.Errorf("no readme to render") } - err = ds.Readme.OpenScriptFile(ctx, r.repo.Filesystem()) - if err != nil { + if err = ds.Readme.OpenScriptFile(ctx, r.repo.Filesystem()); err != nil { return err } - if ds.Readme.ScriptFile() == nil { return fmt.Errorf("no readme to render") }