Add html builtin module
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				ci/woodpecker/push/woodpecker Pipeline was successful
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	ci/woodpecker/push/woodpecker Pipeline was successful
				
			This commit is contained in:
		
							
								
								
									
										229
									
								
								internal/builtins/html.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								internal/builtins/html.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,229 @@
 | 
			
		||||
package builtins
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/PuerkitoBio/goquery"
 | 
			
		||||
	"go.starlark.net/starlark"
 | 
			
		||||
	"go.starlark.net/starlarkstruct"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_ starlark.Iterable  = (*starlarkSelection)(nil)
 | 
			
		||||
	_ starlark.Sliceable = (*starlarkSelection)(nil)
 | 
			
		||||
	_ starlark.Sequence  = (*starlarkSelection)(nil)
 | 
			
		||||
	_ starlark.Value     = (*starlarkSelection)(nil)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var htmlModule = &starlarkstruct.Module{
 | 
			
		||||
	Name: "html",
 | 
			
		||||
	Members: starlark.StringDict{
 | 
			
		||||
		"parse": starlark.NewBuiltin("html.parse", htmlParse),
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func htmlParse(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	var val starlark.Value
 | 
			
		||||
	err := starlark.UnpackArgs("html.selection.find", args, kwargs, "from", &val)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var r io.ReadCloser
 | 
			
		||||
	switch val := val.(type) {
 | 
			
		||||
	case starlark.String:
 | 
			
		||||
		r = io.NopCloser(strings.NewReader(string(val)))
 | 
			
		||||
	case starlark.Bytes:
 | 
			
		||||
		r = io.NopCloser(strings.NewReader(string(val)))
 | 
			
		||||
	case starlarkReader:
 | 
			
		||||
		r = val
 | 
			
		||||
	}
 | 
			
		||||
	defer r.Close()
 | 
			
		||||
 | 
			
		||||
	doc, err := goquery.NewDocumentFromReader(r)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return newStarlarkSelection(doc.Selection), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type starlarkSelection struct {
 | 
			
		||||
	sel *goquery.Selection
 | 
			
		||||
	*starlarkstruct.Struct
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newStarlarkSelection(sel *goquery.Selection) starlarkSelection {
 | 
			
		||||
	ss := starlarkSelection{sel: sel}
 | 
			
		||||
	ss.Struct = starlarkstruct.FromStringDict(starlark.String("html.selection"), starlark.StringDict{
 | 
			
		||||
		"text":           starlark.NewBuiltin("html.selection.text", ss.text),
 | 
			
		||||
		"html":           starlark.NewBuiltin("html.selection.html", ss.html),
 | 
			
		||||
		"children":       starlark.NewBuiltin("html.selection.children", ss.children),
 | 
			
		||||
		"parent":         starlark.NewBuiltin("html.selection.parent", ss.parent),
 | 
			
		||||
		"find":           starlark.NewBuiltin("html.selection.find", ss.find),
 | 
			
		||||
		"add":            starlark.NewBuiltin("html.selection.add", ss.add),
 | 
			
		||||
		"attr":           starlark.NewBuiltin("html.selection.attr", ss.attr),
 | 
			
		||||
		"has_class":      starlark.NewBuiltin("html.selection.has_class", ss.hasClass),
 | 
			
		||||
		"index_selector": starlark.NewBuiltin("html.selection.index_selector", ss.indexSelector),
 | 
			
		||||
		"and_self":       starlark.NewBuiltin("html.selection.and_self", ss.andSelf),
 | 
			
		||||
		"first":          starlark.NewBuiltin("html.selection.first", ss.first),
 | 
			
		||||
		"last":           starlark.NewBuiltin("html.selection.last", ss.last),
 | 
			
		||||
		"next":           starlark.NewBuiltin("html.selection.last", ss.next),
 | 
			
		||||
		"next_all":       starlark.NewBuiltin("html.selection.next_all", ss.nextAll),
 | 
			
		||||
		"next_until":     starlark.NewBuiltin("html.selection.next_until", ss.nextUntil),
 | 
			
		||||
		"prev":           starlark.NewBuiltin("html.selection.prev", ss.prev),
 | 
			
		||||
		"prev_all":       starlark.NewBuiltin("html.selection.prev_all", ss.prevAll),
 | 
			
		||||
		"prev_until":     starlark.NewBuiltin("html.selection.prev_until", ss.prevUntil),
 | 
			
		||||
	})
 | 
			
		||||
	return ss
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) Truth() starlark.Bool {
 | 
			
		||||
	return len(ss.sel.Nodes) > 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) Len() int {
 | 
			
		||||
	return ss.sel.Length()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) Index(i int) starlark.Value {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Slice(i, i+1))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) Slice(start, end, _ int) starlark.Value {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Slice(start, end))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) Iterate() starlark.Iterator {
 | 
			
		||||
	return newSelectionIterator(ss.sel)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) text(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return starlark.String(ss.sel.Text()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) html(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	s, err := ss.sel.Html()
 | 
			
		||||
	return starlark.String(s), err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) children(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Children()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) parent(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Parent()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) find(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	var selector string
 | 
			
		||||
	err := starlark.UnpackArgs("html.selection.find", args, kwargs, "selector", &selector)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Find(selector)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) add(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	var selector string
 | 
			
		||||
	err := starlark.UnpackArgs("html.selection.add", args, kwargs, "selector", &selector)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Add(selector)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) indexSelector(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	var selector string
 | 
			
		||||
	err := starlark.UnpackArgs("html.selection.index_selector", args, kwargs, "selector", &selector)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return starlark.MakeInt(ss.sel.IndexSelector(selector)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) attr(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	var name, def string
 | 
			
		||||
	err := starlark.UnpackArgs("html.selection.find", args, kwargs, "name", &name, "default??", &def)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return starlark.String(ss.sel.AttrOr(name, def)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) hasClass(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	var name string
 | 
			
		||||
	err := starlark.UnpackArgs("html.selection.has_class", args, kwargs, "name", &name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return starlark.Bool(ss.sel.HasClass(name)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) andSelf(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.AndSelf()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) first(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.First()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) last(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Last()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) next(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Next()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) nextAll(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.NextAll()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) nextUntil(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	var selector string
 | 
			
		||||
	err := starlark.UnpackArgs("html.selection.next_until", args, kwargs, "selector", &selector)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return newStarlarkSelection(ss.sel.NextUntil(selector)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) prev(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.Prev()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) prevAll(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	return newStarlarkSelection(ss.sel.PrevAll()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss starlarkSelection) prevUntil(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 | 
			
		||||
	var selector string
 | 
			
		||||
	err := starlark.UnpackArgs("html.selection.prev_until", args, kwargs, "selector", &selector)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return newStarlarkSelection(ss.sel.PrevUntil(selector)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type starlarkSelectionIterator struct {
 | 
			
		||||
	sel   *goquery.Selection
 | 
			
		||||
	index int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newSelectionIterator(sel *goquery.Selection) *starlarkSelectionIterator {
 | 
			
		||||
	return &starlarkSelectionIterator{sel: sel}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ssi *starlarkSelectionIterator) Next(v *starlark.Value) bool {
 | 
			
		||||
	if ssi.index == ssi.sel.Length() {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	*v = newStarlarkSelection(ssi.sel.Slice(ssi.index, ssi.index+1))
 | 
			
		||||
	ssi.index++
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ssi *starlarkSelectionIterator) Done() {}
 | 
			
		||||
@@ -200,3 +200,16 @@ func (sr starlarkReader) closeReader(thread *starlark.Thread, b *starlark.Builti
 | 
			
		||||
	}
 | 
			
		||||
	return starlark.None, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read implements the io.ReadCloser interface
 | 
			
		||||
func (sr starlarkReader) Read(b []byte) (int, error) {
 | 
			
		||||
	return sr.br.Read(b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close implements the io.ReadCloser interface
 | 
			
		||||
func (sr starlarkReader) Close() error {
 | 
			
		||||
	if sr.closeFunc != nil {
 | 
			
		||||
		return sr.closeFunc()
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,5 +44,6 @@ func Register(sd starlark.StringDict, opts *Options) {
 | 
			
		||||
	sd["log"] = logModule(opts.Name)
 | 
			
		||||
	sd["json"] = starlarkjson.Module
 | 
			
		||||
	sd["utils"] = utilsModule
 | 
			
		||||
	sd["html"] = htmlModule
 | 
			
		||||
	sd["register_webhook"] = registerWebhook(opts.Mux, opts.Config, opts.Name)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user