mirror of
https://github.com/derfenix/webarchive.git
synced 2026-03-11 21:35:34 +03:00
Use query params too for page adding handler
This commit is contained in:
10
README.md
10
README.md
@@ -23,11 +23,19 @@ curl -X POST --location "http://localhost:5001/pages" \
|
|||||||
-d "{
|
-d "{
|
||||||
\"url\": \"https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1937\",
|
\"url\": \"https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1937\",
|
||||||
\"formats\": [
|
\"formats\": [
|
||||||
\"all\"
|
\"pdf\",
|
||||||
|
\"headers\"
|
||||||
]
|
]
|
||||||
}" | jq .
|
}" | jq .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl -X POST --location \
|
||||||
|
"http://localhost:5001/pages?url=https%3A%2F%2Fgithub.com%2Fwkhtmltopdf%2Fwkhtmltopdf%2Fissues%2F1937&formats=pdf%2Cheaders&description=Foo+Bar"
|
||||||
|
```
|
||||||
|
|
||||||
#### 3. Get the page's info
|
#### 3. Get the page's info
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|||||||
@@ -22,6 +22,23 @@ paths:
|
|||||||
post:
|
post:
|
||||||
operationId: addPage
|
operationId: addPage
|
||||||
summary: Add new page
|
summary: Add new page
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: url
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: description
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: formats
|
||||||
|
style: form
|
||||||
|
explode: false
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/format'
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
|
|||||||
@@ -76,13 +76,13 @@ func (c *Client) requestURL(ctx context.Context) *url.URL {
|
|||||||
// Add new page.
|
// Add new page.
|
||||||
//
|
//
|
||||||
// POST /pages
|
// POST /pages
|
||||||
func (c *Client) AddPage(ctx context.Context, request OptAddPageReq) (*Page, error) {
|
func (c *Client) AddPage(ctx context.Context, request OptAddPageReq, params AddPageParams) (*Page, error) {
|
||||||
res, err := c.sendAddPage(ctx, request)
|
res, err := c.sendAddPage(ctx, request, params)
|
||||||
_ = res
|
_ = res
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) sendAddPage(ctx context.Context, request OptAddPageReq) (res *Page, err error) {
|
func (c *Client) sendAddPage(ctx context.Context, request OptAddPageReq, params AddPageParams) (res *Page, err error) {
|
||||||
otelAttrs := []attribute.KeyValue{
|
otelAttrs := []attribute.KeyValue{
|
||||||
otelogen.OperationID("addPage"),
|
otelogen.OperationID("addPage"),
|
||||||
}
|
}
|
||||||
@@ -135,6 +135,67 @@ func (c *Client) sendAddPage(ctx context.Context, request OptAddPageReq) (res *P
|
|||||||
pathParts[0] = "/pages"
|
pathParts[0] = "/pages"
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeQueryParams"
|
||||||
|
q := uri.NewQueryEncoder()
|
||||||
|
{
|
||||||
|
// Encode "url" parameter.
|
||||||
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
|
Name: "url",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
|
if val, ok := params.URL.Get(); ok {
|
||||||
|
return e.EncodeValue(conv.StringToString(val))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return res, errors.Wrap(err, "encode query")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Encode "description" parameter.
|
||||||
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
|
Name: "description",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
|
if val, ok := params.Description.Get(); ok {
|
||||||
|
return e.EncodeValue(conv.StringToString(val))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return res, errors.Wrap(err, "encode query")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Encode "formats" parameter.
|
||||||
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
|
Name: "formats",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
|
return e.EncodeArray(func(e uri.Encoder) error {
|
||||||
|
for i, item := range params.Formats {
|
||||||
|
if err := func() error {
|
||||||
|
return e.EncodeValue(conv.StringToString(string(item)))
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrapf(err, "[%d]", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}); err != nil {
|
||||||
|
return res, errors.Wrap(err, "encode query")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.RawQuery = q.Values().Encode()
|
||||||
|
|
||||||
stage = "EncodeRequest"
|
stage = "EncodeRequest"
|
||||||
r, err := ht.NewRequest(ctx, "POST", u, nil)
|
r, err := ht.NewRequest(ctx, "POST", u, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -60,6 +60,16 @@ func (s *Server) handleAddPageRequest(args [0]string, argsEscaped bool, w http.R
|
|||||||
ID: "addPage",
|
ID: "addPage",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
params, err := decodeAddPageParams(args, argsEscaped, r)
|
||||||
|
if err != nil {
|
||||||
|
err = &ogenerrors.DecodeParamsError{
|
||||||
|
OperationContext: opErrContext,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
recordError("DecodeParams", err)
|
||||||
|
s.cfg.ErrorHandler(ctx, w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
request, close, err := s.decodeAddPageRequest(r)
|
request, close, err := s.decodeAddPageRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = &ogenerrors.DecodeRequestError{
|
err = &ogenerrors.DecodeRequestError{
|
||||||
@@ -83,13 +93,26 @@ func (s *Server) handleAddPageRequest(args [0]string, argsEscaped bool, w http.R
|
|||||||
OperationName: "AddPage",
|
OperationName: "AddPage",
|
||||||
OperationID: "addPage",
|
OperationID: "addPage",
|
||||||
Body: request,
|
Body: request,
|
||||||
Params: middleware.Parameters{},
|
Params: middleware.Parameters{
|
||||||
Raw: r,
|
{
|
||||||
|
Name: "url",
|
||||||
|
In: "query",
|
||||||
|
}: params.URL,
|
||||||
|
{
|
||||||
|
Name: "description",
|
||||||
|
In: "query",
|
||||||
|
}: params.Description,
|
||||||
|
{
|
||||||
|
Name: "formats",
|
||||||
|
In: "query",
|
||||||
|
}: params.Formats,
|
||||||
|
},
|
||||||
|
Raw: r,
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Request = OptAddPageReq
|
Request = OptAddPageReq
|
||||||
Params = struct{}
|
Params = AddPageParams
|
||||||
Response = *Page
|
Response = *Page
|
||||||
)
|
)
|
||||||
response, err = middleware.HookMiddleware[
|
response, err = middleware.HookMiddleware[
|
||||||
@@ -99,14 +122,14 @@ func (s *Server) handleAddPageRequest(args [0]string, argsEscaped bool, w http.R
|
|||||||
](
|
](
|
||||||
m,
|
m,
|
||||||
mreq,
|
mreq,
|
||||||
nil,
|
unpackAddPageParams,
|
||||||
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
||||||
response, err = s.h.AddPage(ctx, request)
|
response, err = s.h.AddPage(ctx, request, params)
|
||||||
return response, err
|
return response, err
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
response, err = s.h.AddPage(ctx, request)
|
response, err = s.h.AddPage(ctx, request, params)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
recordError("Internal", err)
|
recordError("Internal", err)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package openapi
|
package openapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
@@ -16,6 +17,196 @@ import (
|
|||||||
"github.com/ogen-go/ogen/validate"
|
"github.com/ogen-go/ogen/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AddPageParams is parameters of addPage operation.
|
||||||
|
type AddPageParams struct {
|
||||||
|
URL OptString
|
||||||
|
Description OptString
|
||||||
|
Formats []Format
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackAddPageParams(packed middleware.Parameters) (params AddPageParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "url",
|
||||||
|
In: "query",
|
||||||
|
}
|
||||||
|
if v, ok := packed[key]; ok {
|
||||||
|
params.URL = v.(OptString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "description",
|
||||||
|
In: "query",
|
||||||
|
}
|
||||||
|
if v, ok := packed[key]; ok {
|
||||||
|
params.Description = v.(OptString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "formats",
|
||||||
|
In: "query",
|
||||||
|
}
|
||||||
|
if v, ok := packed[key]; ok {
|
||||||
|
params.Formats = v.([]Format)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeAddPageParams(args [0]string, argsEscaped bool, r *http.Request) (params AddPageParams, _ error) {
|
||||||
|
q := uri.NewQueryDecoder(r.URL.Query())
|
||||||
|
// Decode query: url.
|
||||||
|
if err := func() error {
|
||||||
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
|
Name: "url",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.HasParam(cfg); err == nil {
|
||||||
|
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
||||||
|
var paramsDotURLVal string
|
||||||
|
if err := func() error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToString(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
paramsDotURLVal = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params.URL.SetTo(paramsDotURLVal)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "url",
|
||||||
|
In: "query",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Decode query: description.
|
||||||
|
if err := func() error {
|
||||||
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
|
Name: "description",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.HasParam(cfg); err == nil {
|
||||||
|
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
||||||
|
var paramsDotDescriptionVal string
|
||||||
|
if err := func() error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToString(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
paramsDotDescriptionVal = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params.Description.SetTo(paramsDotDescriptionVal)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "description",
|
||||||
|
In: "query",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Decode query: formats.
|
||||||
|
if err := func() error {
|
||||||
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
|
Name: "formats",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.HasParam(cfg); err == nil {
|
||||||
|
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
||||||
|
return d.DecodeArray(func(d uri.Decoder) error {
|
||||||
|
var paramsDotFormatsVal Format
|
||||||
|
if err := func() error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToString(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
paramsDotFormatsVal = Format(c)
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params.Formats = append(params.Formats, paramsDotFormatsVal)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
var failures []validate.FieldError
|
||||||
|
for i, elem := range params.Formats {
|
||||||
|
if err := func() error {
|
||||||
|
if err := elem.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: fmt.Sprintf("[%d]", i),
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "formats",
|
||||||
|
In: "query",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetFileParams is parameters of getFile operation.
|
// GetFileParams is parameters of getFile operation.
|
||||||
type GetFileParams struct {
|
type GetFileParams struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ type Handler interface {
|
|||||||
// Add new page.
|
// Add new page.
|
||||||
//
|
//
|
||||||
// POST /pages
|
// POST /pages
|
||||||
AddPage(ctx context.Context, req OptAddPageReq) (*Page, error)
|
AddPage(ctx context.Context, req OptAddPageReq, params AddPageParams) (*Page, error)
|
||||||
// GetFile implements getFile operation.
|
// GetFile implements getFile operation.
|
||||||
//
|
//
|
||||||
// Get file content.
|
// Get file content.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ var _ Handler = UnimplementedHandler{}
|
|||||||
// Add new page.
|
// Add new page.
|
||||||
//
|
//
|
||||||
// POST /pages
|
// POST /pages
|
||||||
func (UnimplementedHandler) AddPage(ctx context.Context, req OptAddPageReq) (r *Page, _ error) {
|
func (UnimplementedHandler) AddPage(ctx context.Context, req OptAddPageReq, params AddPageParams) (r *Page, _ error) {
|
||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ const (
|
|||||||
FormatPDF
|
FormatPDF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var AllFormats = []Format{
|
||||||
|
FormatHeaders,
|
||||||
|
FormatPDF,
|
||||||
|
FormatSingleFile,
|
||||||
|
}
|
||||||
|
|
||||||
type Status uint8
|
type Status uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -98,11 +98,7 @@ func FormatFromRest(format []openapi.Format) []entity.Format {
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case len(format) == 0 || (len(format) == 1 && format[0] == openapi.FormatAll):
|
case len(format) == 0 || (len(format) == 1 && format[0] == openapi.FormatAll):
|
||||||
formats = []entity.Format{
|
formats = entity.AllFormats
|
||||||
entity.FormatHeaders,
|
|
||||||
entity.FormatPDF,
|
|
||||||
entity.FormatSingleFile,
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
formats = make([]entity.Format, len(format))
|
formats = make([]entity.Format, len(format))
|
||||||
|
|||||||
@@ -41,8 +41,26 @@ func (s *Service) GetPage(ctx context.Context, params openapi.GetPageParams) (op
|
|||||||
return &restPage, nil
|
return &restPage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) AddPage(ctx context.Context, req openapi.OptAddPageReq) (*openapi.Page, error) {
|
func (s *Service) AddPage(ctx context.Context, req openapi.OptAddPageReq, params openapi.AddPageParams) (*openapi.Page, error) {
|
||||||
page := entity.NewPage(req.Value.URL, req.Value.Description.Value, FormatFromRest(req.Value.Formats)...)
|
url := params.URL.Or(req.Value.URL)
|
||||||
|
description := params.Description.Or(req.Value.Description.Value)
|
||||||
|
|
||||||
|
formats := req.Value.Formats
|
||||||
|
if len(formats) == 0 {
|
||||||
|
formats = params.Formats
|
||||||
|
}
|
||||||
|
if len(formats) == 0 {
|
||||||
|
formats = []openapi.Format{"all"}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case req.Value.URL != "":
|
||||||
|
url = req.Value.URL
|
||||||
|
case params.URL.IsSet():
|
||||||
|
url = params.URL.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
page := entity.NewPage(url, description, FormatFromRest(formats)...)
|
||||||
|
|
||||||
page.Status = entity.StatusProcessing
|
page.Status = entity.StatusProcessing
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user