mirror of
https://github.com/MontFerret/ferret.git
synced 2024-12-18 23:47:48 +02:00
156 lines
3.6 KiB
Go
156 lines
3.6 KiB
Go
|
package html
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"github.com/MontFerret/ferret/pkg/drivers"
|
||
|
"github.com/MontFerret/ferret/pkg/runtime/values/types"
|
||
|
"github.com/pkg/errors"
|
||
|
|
||
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
||
|
"github.com/MontFerret/ferret/pkg/runtime/values"
|
||
|
)
|
||
|
|
||
|
type ParseParams struct {
|
||
|
drivers.ParseParams
|
||
|
Driver string
|
||
|
}
|
||
|
|
||
|
// PARSE loads an HTML page from a given string or byte array
|
||
|
// @param params (Object) - Optional, an object containing the following properties :
|
||
|
// driver (String) - Optional, driver name.
|
||
|
// keepCookies (Boolean) - Optional, boolean value indicating whether to use cookies from previous sessions.
|
||
|
// i.e. not to open a page in the Incognito mode.
|
||
|
// cookies (HTTPCookies) - Optional, set of HTTP cookies.
|
||
|
// headers (HTTPHeaders) - Optional, HTTP headers.
|
||
|
// viewport (Viewport) - Optional, viewport params.
|
||
|
// @returns (HTMLPage) - Returns parsed and loaded HTML page.
|
||
|
func Parse(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||
|
if err := core.ValidateArgs(args, 1, 2); err != nil {
|
||
|
return values.None, err
|
||
|
}
|
||
|
|
||
|
arg1 := args[0]
|
||
|
|
||
|
if err := core.ValidateType(arg1, types.String, types.Binary); err != nil {
|
||
|
return values.None, err
|
||
|
}
|
||
|
|
||
|
var content []byte
|
||
|
|
||
|
if arg1.Type() == types.String {
|
||
|
content = []byte(arg1.(values.String))
|
||
|
} else {
|
||
|
content = []byte(arg1.(values.Binary))
|
||
|
}
|
||
|
|
||
|
var params ParseParams
|
||
|
|
||
|
if len(args) > 1 {
|
||
|
if err := core.ValidateType(args[1], types.Object); err != nil {
|
||
|
return values.None, err
|
||
|
}
|
||
|
|
||
|
p, err := parseParseParams(content, args[1].(*values.Object))
|
||
|
|
||
|
if err != nil {
|
||
|
return values.None, err
|
||
|
}
|
||
|
|
||
|
params = p
|
||
|
} else {
|
||
|
params = defaultParseParams(content)
|
||
|
}
|
||
|
|
||
|
drv, err := drivers.FromContext(ctx, params.Driver)
|
||
|
|
||
|
if err != nil {
|
||
|
return values.None, err
|
||
|
}
|
||
|
|
||
|
return drv.Parse(ctx, params.ParseParams)
|
||
|
}
|
||
|
|
||
|
func defaultParseParams(content []byte) ParseParams {
|
||
|
return ParseParams{
|
||
|
ParseParams: drivers.ParseParams{
|
||
|
Content: content,
|
||
|
},
|
||
|
Driver: "",
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func parseParseParams(content []byte, arg *values.Object) (ParseParams, error) {
|
||
|
res := defaultParseParams(content)
|
||
|
|
||
|
if arg.Has("driver") {
|
||
|
driverName := arg.MustGet("driver")
|
||
|
|
||
|
if err := core.ValidateType(driverName, types.String); err != nil {
|
||
|
return ParseParams{}, errors.Wrap(err, ".driver")
|
||
|
}
|
||
|
|
||
|
res.Driver = driverName.String()
|
||
|
}
|
||
|
|
||
|
if arg.Has("keepCookies") {
|
||
|
keepCookies := arg.MustGet("keepCookies")
|
||
|
|
||
|
if err := core.ValidateType(keepCookies, types.Boolean); err != nil {
|
||
|
return ParseParams{}, errors.Wrap(err, ".keepCookies")
|
||
|
}
|
||
|
|
||
|
res.KeepCookies = bool(keepCookies.(values.Boolean))
|
||
|
}
|
||
|
|
||
|
if arg.Has("cookies") {
|
||
|
cookies := arg.MustGet("cookies")
|
||
|
|
||
|
if err := core.ValidateType(cookies, types.Array, types.Object); err != nil {
|
||
|
return res, err
|
||
|
}
|
||
|
|
||
|
switch c := cookies.(type) {
|
||
|
case *values.Array:
|
||
|
cookies, err := parseCookieArray(c)
|
||
|
|
||
|
if err != nil {
|
||
|
return ParseParams{}, errors.Wrap(err, ".cookies")
|
||
|
}
|
||
|
|
||
|
res.Cookies = cookies
|
||
|
case *values.Object:
|
||
|
cookies, err := parseCookieObject(c)
|
||
|
|
||
|
if err != nil {
|
||
|
return ParseParams{}, errors.Wrap(err, ".cookies")
|
||
|
}
|
||
|
|
||
|
res.Cookies = cookies
|
||
|
default:
|
||
|
res.Cookies = make(drivers.HTTPCookies)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if arg.Has("headers") {
|
||
|
headers := arg.MustGet("headers")
|
||
|
|
||
|
if err := core.ValidateType(headers, types.Object); err != nil {
|
||
|
return ParseParams{}, errors.Wrap(err, ".headers")
|
||
|
}
|
||
|
|
||
|
res.Headers = parseHeader(headers.(*values.Object))
|
||
|
}
|
||
|
|
||
|
if arg.Has("viewport") {
|
||
|
viewport, err := parseViewport(arg.MustGet("viewport"))
|
||
|
|
||
|
if err != nil {
|
||
|
return ParseParams{}, errors.Wrap(err, ".viewport")
|
||
|
}
|
||
|
|
||
|
res.Viewport = viewport
|
||
|
}
|
||
|
|
||
|
return res, nil
|
||
|
}
|