3
0

Add endpoint to fetch available render drivers

This commit is contained in:
Tomaž Jerman 2021-05-05 11:18:19 +02:00
parent 1ab7ccc508
commit 6bd82c3e9d
10 changed files with 193 additions and 24 deletions

View File

@ -9,20 +9,47 @@ import (
)
type (
genericHTML struct{}
genericHTML struct {
def DriverDefinition
}
genericHTMLDriver struct{}
)
func newGenericHTML() driverFactory {
return &genericHTML{}
return &genericHTML{
def: DriverDefinition{
Name: "genericHTML",
InputTypes: []types.DocumentType{
types.DocumentTypePlain,
types.DocumentTypeHTML,
},
OutputTypes: []types.DocumentType{
types.DocumentTypeHTML,
},
},
}
}
func (d *genericHTML) Define() DriverDefinition {
return d.def
}
func (d *genericHTML) CanRender(t types.DocumentType) bool {
return t == types.DocumentTypeHTML || t == types.DocumentTypePlain
for _, i := range d.def.InputTypes {
if i == t {
return true
}
}
return false
}
func (d *genericHTML) CanProduce(t types.DocumentType) bool {
return t == types.DocumentTypeHTML
for _, o := range d.def.OutputTypes {
if o == t {
return true
}
}
return false
}
func (d *genericHTML) Driver() driver {

View File

@ -10,7 +10,9 @@ import (
)
type (
genericText struct{}
genericText struct {
def DriverDefinition
}
genericTextDriver struct{}
)
@ -19,15 +21,40 @@ var (
)
func newGenericText() driverFactory {
return &genericText{}
return &genericText{
def: DriverDefinition{
Name: "genericText",
InputTypes: []types.DocumentType{
types.DocumentTypePlain,
types.DocumentTypeHTML,
},
OutputTypes: []types.DocumentType{
types.DocumentTypePlain,
},
},
}
}
func (d *genericText) Define() DriverDefinition {
return d.def
}
func (d *genericText) CanRender(t types.DocumentType) bool {
return t == types.DocumentTypePlain || t == types.DocumentTypeHTML
for _, i := range d.def.InputTypes {
if i == t {
return true
}
}
return false
}
func (d *genericText) CanProduce(t types.DocumentType) bool {
return t == types.DocumentTypePlain
for _, o := range d.def.OutputTypes {
if o == t {
return true
}
}
return false
}
func (d *genericText) Driver() driver {

View File

@ -15,6 +15,7 @@ import (
type (
gotenbergPDF struct {
url string
def DriverDefinition
}
gotenbergPDFDriver struct {
url string
@ -25,15 +26,40 @@ type (
func newGotenbergPDF(url string) driverFactory {
return &gotenbergPDF{
url: url,
def: DriverDefinition{
Name: "gotenbergPDF",
InputTypes: []types.DocumentType{
types.DocumentTypePlain,
types.DocumentTypeHTML,
},
OutputTypes: []types.DocumentType{
types.DocumentTypePDF,
},
},
}
}
func (d *gotenbergPDF) Define() DriverDefinition {
return d.def
}
func (d *gotenbergPDF) CanRender(t types.DocumentType) bool {
return t == types.DocumentTypeHTML || t == types.DocumentTypePlain
for _, i := range d.def.InputTypes {
if i == t {
return true
}
}
return false
}
func (d *gotenbergPDF) CanProduce(t types.DocumentType) bool {
return t == types.DocumentTypePDF
for _, o := range d.def.OutputTypes {
if o == t {
return true
}
}
return false
}
func (d *gotenbergPDF) Driver() driver {

View File

@ -47,3 +47,11 @@ func (r *renderer) Render(ctx context.Context, pl *RendererPayload) (io.ReadSeek
return nil, errors.New("rendering failed: driver not found")
}
func (r *renderer) Drivers() []DriverDefinition {
dd := make([]DriverDefinition, len(r.factories))
for i, f := range r.factories {
dd[i] = f.Define()
}
return dd
}

View File

@ -39,7 +39,15 @@ type (
Name string
}
DriverDefinition struct {
Name string `json:"name"`
InputTypes []types.DocumentType `json:"inputTypes"`
OutputTypes []types.DocumentType `json:"outputTypes"`
}
driverFactory interface {
Define() DriverDefinition
CanRender(t types.DocumentType) bool
CanProduce(t types.DocumentType) bool
Driver() driver

View File

@ -1343,6 +1343,10 @@ endpoints:
type: uint64
required: true
title: Template ID
- name: renderDrivers
method: GET
title: Render drivers
path: "/render/drivers"
- name: render
method: POST
title: Render template

View File

@ -25,18 +25,20 @@ type (
Update(context.Context, *request.TemplateUpdate) (interface{}, error)
Delete(context.Context, *request.TemplateDelete) (interface{}, error)
Undelete(context.Context, *request.TemplateUndelete) (interface{}, error)
RenderDrivers(context.Context, *request.TemplateRenderDrivers) (interface{}, error)
Render(context.Context, *request.TemplateRender) (interface{}, error)
}
// HTTP API interface
Template struct {
List func(http.ResponseWriter, *http.Request)
Create func(http.ResponseWriter, *http.Request)
Read func(http.ResponseWriter, *http.Request)
Update func(http.ResponseWriter, *http.Request)
Delete func(http.ResponseWriter, *http.Request)
Undelete func(http.ResponseWriter, *http.Request)
Render func(http.ResponseWriter, *http.Request)
List func(http.ResponseWriter, *http.Request)
Create func(http.ResponseWriter, *http.Request)
Read func(http.ResponseWriter, *http.Request)
Update func(http.ResponseWriter, *http.Request)
Delete func(http.ResponseWriter, *http.Request)
Undelete func(http.ResponseWriter, *http.Request)
RenderDrivers func(http.ResponseWriter, *http.Request)
Render func(http.ResponseWriter, *http.Request)
}
)
@ -138,6 +140,22 @@ func NewTemplate(h TemplateAPI) *Template {
api.Send(w, r, value)
},
RenderDrivers: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTemplateRenderDrivers()
if err := params.Fill(r); err != nil {
api.Send(w, r, err)
return
}
value, err := h.RenderDrivers(r.Context(), params)
if err != nil {
api.Send(w, r, err)
return
}
api.Send(w, r, value)
},
Render: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewTemplateRender()
@ -166,6 +184,7 @@ func (h Template) MountRoutes(r chi.Router, middlewares ...func(http.Handler) ht
r.Put("/template/{templateID}", h.Update)
r.Delete("/template/{templateID}", h.Delete)
r.Post("/template/{templateID}/undelete", h.Undelete)
r.Get("/template/render/drivers", h.RenderDrivers)
r.Post("/template/{templateID}/render/{filename}.{ext}", h.Render)
})
}

View File

@ -192,6 +192,9 @@ type (
TemplateID uint64 `json:",string"`
}
TemplateRenderDrivers struct {
}
TemplateRender struct {
// TemplateID PATH parameter
//
@ -779,6 +782,22 @@ func (r *TemplateUndelete) Fill(req *http.Request) (err error) {
return err
}
// NewTemplateRenderDrivers request
func NewTemplateRenderDrivers() *TemplateRenderDrivers {
return &TemplateRenderDrivers{}
}
// Auditable returns all auditable/loggable parameters
func (r TemplateRenderDrivers) Auditable() map[string]interface{} {
return map[string]interface{}{}
}
// Fill processes request and fills internal variables
func (r *TemplateRenderDrivers) Fill(req *http.Request) (err error) {
return err
}
// NewTemplateRender request
func NewTemplateRender() *TemplateRender {
return &TemplateRender{}

View File

@ -11,6 +11,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/api"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/system/renderer"
"github.com/cortezaproject/corteza-server/system/rest/request"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
@ -38,6 +39,14 @@ type (
CanDeleteTemplate bool `json:"canDeleteTemplate"`
}
driverSetPayload struct {
Set []*driverPayload `json:"set"`
}
driverPayload struct {
renderer.DriverDefinition
}
templateAccessController interface {
CanGrant(context.Context) bool
CanCreateTemplate(context.Context) bool
@ -56,7 +65,7 @@ func (Template) New() *Template {
func (ctrl *Template) Read(ctx context.Context, r *request.TemplateRead) (interface{}, error) {
tpl, err := ctrl.renderer.FindByID(ctx, r.TemplateID)
return ctrl.makePayload(ctx, tpl, err)
return ctrl.makeTemplatePayload(ctx, tpl, err)
}
func (ctrl *Template) List(ctx context.Context, r *request.TemplateList) (interface{}, error) {
@ -80,7 +89,7 @@ func (ctrl *Template) List(ctx context.Context, r *request.TemplateList) (interf
}
set, filter, err := ctrl.renderer.Search(ctx, f)
return ctrl.makeFilterPayload(ctx, set, filter, err)
return ctrl.makeFilterTemplatePayload(ctx, set, filter, err)
}
func (ctrl *Template) Create(ctx context.Context, r *request.TemplateCreate) (interface{}, error) {
@ -98,7 +107,7 @@ func (ctrl *Template) Create(ctx context.Context, r *request.TemplateCreate) (in
)
app, err = ctrl.renderer.Create(ctx, app)
return ctrl.makePayload(ctx, app, err)
return ctrl.makeTemplatePayload(ctx, app, err)
}
func (ctrl *Template) Update(ctx context.Context, r *request.TemplateUpdate) (interface{}, error) {
@ -117,7 +126,7 @@ func (ctrl *Template) Update(ctx context.Context, r *request.TemplateUpdate) (in
)
app, err = ctrl.renderer.Update(ctx, app)
return ctrl.makePayload(ctx, app, err)
return ctrl.makeTemplatePayload(ctx, app, err)
}
func (ctrl *Template) Delete(ctx context.Context, r *request.TemplateDelete) (interface{}, error) {
@ -128,6 +137,10 @@ func (ctrl *Template) Undelete(ctx context.Context, r *request.TemplateUndelete)
return api.OK(), ctrl.renderer.UndeleteByID(ctx, r.TemplateID)
}
func (ctrl *Template) RenderDrivers(ctx context.Context, r *request.TemplateRenderDrivers) (interface{}, error) {
return ctrl.makeSetRenderDriverPayload(ctx, ctrl.renderer.Drivers()), nil
}
func (ctrl *Template) Render(ctx context.Context, r *request.TemplateRender) (interface{}, error) {
vars := make(map[string]interface{})
err := json.Unmarshal(r.Variables, &vars)
@ -151,7 +164,7 @@ func (ctrl *Template) Render(ctx context.Context, r *request.TemplateRender) (in
// Utilities
func (ctrl Template) makeFilterPayload(ctx context.Context, nn types.TemplateSet, f types.TemplateFilter, err error) (*templateSetPayload, error) {
func (ctrl Template) makeFilterTemplatePayload(ctx context.Context, nn types.TemplateSet, f types.TemplateFilter, err error) (*templateSetPayload, error) {
if err != nil {
return nil, err
}
@ -159,13 +172,13 @@ func (ctrl Template) makeFilterPayload(ctx context.Context, nn types.TemplateSet
msp := &templateSetPayload{Filter: f, Set: make([]*templatePayload, len(nn))}
for i := range nn {
msp.Set[i], _ = ctrl.makePayload(ctx, nn[i], nil)
msp.Set[i], _ = ctrl.makeTemplatePayload(ctx, nn[i], nil)
}
return msp, nil
}
func (ctrl Template) makePayload(ctx context.Context, tpl *types.Template, err error) (*templatePayload, error) {
func (ctrl Template) makeTemplatePayload(ctx context.Context, tpl *types.Template, err error) (*templatePayload, error) {
if err != nil || tpl == nil {
return nil, err
}
@ -181,6 +194,18 @@ func (ctrl Template) makePayload(ctx context.Context, tpl *types.Template, err e
return pl, nil
}
func (ctrl Template) makeSetRenderDriverPayload(ctx context.Context, nn []renderer.DriverDefinition) *driverSetPayload {
msp := &driverSetPayload{Set: make([]*driverPayload, len(nn))}
for i := range nn {
msp.Set[i] = &driverPayload{
DriverDefinition: nn[i],
}
}
return msp
}
func (ctrl *Template) serve(doc io.ReadSeeker, ct string, r *request.TemplateRender, err error) (interface{}, error) {
if err != nil {
return nil, err

View File

@ -36,6 +36,7 @@ type (
rendererService interface {
Render(ctx context.Context, p *renderer.RendererPayload) (io.ReadSeeker, error)
Drivers() []renderer.DriverDefinition
}
TemplateService interface {
@ -50,6 +51,7 @@ type (
DeleteByID(ctx context.Context, ID uint64) error
UndeleteByID(ctx context.Context, ID uint64) error
Drivers() []renderer.DriverDefinition
Render(ctx context.Context, templateID uint64, dstType string, variables map[string]interface{}, options map[string]string) (io.ReadSeeker, error)
}
)
@ -330,6 +332,10 @@ func (svc template) UndeleteByID(ctx context.Context, ID uint64) (err error) {
return svc.recordAction(ctx, tplProps, TemplateActionUndelete, err)
}
func (svc template) Drivers() []renderer.DriverDefinition {
return svc.renderer.Drivers()
}
func (svc template) Render(ctx context.Context, templateID uint64, dstType string, variables map[string]interface{}, options map[string]string) (document io.ReadSeeker, err error) {
var (
tplProps = &templateActionProps{}