mirror of
https://github.com/bettercap/bettercap
synced 2025-07-16 10:03:39 -07:00
new: added events.on (and other related commands) to trigger specific actions when an events happens
This commit is contained in:
parent
78c341c2b3
commit
1492bf5e40
24 changed files with 4475 additions and 0 deletions
32
vendor/github.com/antchfx/jsonquery/.gitignore
generated
vendored
Normal file
32
vendor/github.com/antchfx/jsonquery/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
# vscode
|
||||
.vscode
|
||||
debug
|
||||
*.test
|
||||
|
||||
./build
|
||||
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
14
vendor/github.com/antchfx/jsonquery/.travis.yml
generated
vendored
Normal file
14
vendor/github.com/antchfx/jsonquery/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- 1.9
|
||||
|
||||
install:
|
||||
- go get github.com/antchfx/xpath
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -service=travis-ci
|
17
vendor/github.com/antchfx/jsonquery/LICENSE
generated
vendored
Normal file
17
vendor/github.com/antchfx/jsonquery/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
169
vendor/github.com/antchfx/jsonquery/README.md
generated
vendored
Normal file
169
vendor/github.com/antchfx/jsonquery/README.md
generated
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
jsonquery
|
||||
====
|
||||
[](https://travis-ci.org/antchfx/jsonquery)
|
||||
[](https://coveralls.io/github/antchfx/jsonquery?branch=master)
|
||||
[](https://godoc.org/github.com/antchfx/jsonquery)
|
||||
[](https://goreportcard.com/report/github.com/antchfx/jsonquery)
|
||||
|
||||
Overview
|
||||
===
|
||||
|
||||
jsonquery is an XPath query package for JSON document, lets you extract data from JSON documents through an XPath expression.
|
||||
|
||||
Getting Started
|
||||
===
|
||||
|
||||
### Install Package
|
||||
|
||||
> $ go get github.com/antchfx/jsonquery
|
||||
|
||||
#### Load JSON document from URL.
|
||||
|
||||
```go
|
||||
doc, err := jsonquery.LoadURL("http://www.example.com/feed?json")
|
||||
```
|
||||
|
||||
#### Load JSON document from string.
|
||||
|
||||
```go
|
||||
s :=`{
|
||||
"name":"John",
|
||||
"age":31,
|
||||
"city":"New York"
|
||||
}`
|
||||
doc, err := jsonquery.Parse(strings.NewReader(s))
|
||||
```
|
||||
|
||||
#### Load JSON document from io.Reader.
|
||||
|
||||
```go
|
||||
f, err := os.Open("./books.json")
|
||||
doc, err := jsonquery.Parse(f)
|
||||
```
|
||||
|
||||
#### Find authors of all books in the store.
|
||||
```go
|
||||
list := jsonquery.Find(doc, "store/book/*/author")
|
||||
// or equal to
|
||||
list := jsonquery.Find(doc, "//author")
|
||||
```
|
||||
|
||||
#### Find the third book.
|
||||
|
||||
```go
|
||||
book := jsonquery.Find(doc, "//book/*[3]")
|
||||
```
|
||||
|
||||
#### Find the last book.
|
||||
|
||||
```go
|
||||
book := jsonquery.Find(doc, "//book/*[last()]")
|
||||
```
|
||||
|
||||
#### Find all books with isbn number.
|
||||
|
||||
```go
|
||||
list := jsonquery.Find(doc, "//book/*[isbn]")
|
||||
```
|
||||
|
||||
#### Find all books cheapier than 10.
|
||||
|
||||
```go
|
||||
list := jsonquery.Find(doc, "//book/*[price<10]")
|
||||
```
|
||||
|
||||
Quick Tutorial
|
||||
===
|
||||
|
||||
```go
|
||||
func main() {
|
||||
s := `{
|
||||
"name": "John",
|
||||
"age" : 26,
|
||||
"address" : {
|
||||
"streetAddress": "naist street",
|
||||
"city" : "Nara",
|
||||
"postalCode" : "630-0192"
|
||||
},
|
||||
"phoneNumbers": [
|
||||
{
|
||||
"type" : "iPhone",
|
||||
"number": "0123-4567-8888"
|
||||
},
|
||||
{
|
||||
"type" : "home",
|
||||
"number": "0123-4567-8910"
|
||||
}
|
||||
]
|
||||
}`
|
||||
doc, _ := jsonquery.Parse(strings.NewReader(s))
|
||||
name := jsonquery.FindOne(doc, "name")
|
||||
fmt.Printf("name: %s\n", name.InnerText())
|
||||
var a []string
|
||||
for _, n := range jsonquery.Find(doc, "phoneNumbers/*/number") {
|
||||
a = append(a, n.InnerText())
|
||||
}
|
||||
fmt.Printf("phone number: %s\n", strings.Join(a, ","))
|
||||
if n := jsonquery.FindOne(doc, "address/streetAddress"); n != nil {
|
||||
fmt.Printf("address: %s\n", n.InnerText())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Implement Principle
|
||||
===
|
||||
If you are familiar with XPath and XML, you can quick start to known how
|
||||
write your XPath expression.
|
||||
|
||||
```json
|
||||
{
|
||||
"name":"John",
|
||||
"age":30,
|
||||
"cars": [
|
||||
{ "name":"Ford", "models":[ "Fiesta", "Focus", "Mustang" ] },
|
||||
{ "name":"BMW", "models":[ "320", "X3", "X5" ] },
|
||||
{ "name":"Fiat", "models":[ "500", "Panda" ] }
|
||||
]
|
||||
}
|
||||
```
|
||||
The above JSON document will be convert to similar to XML document by the *JSONQuery*, like below:
|
||||
|
||||
```XML
|
||||
<name>John</name>
|
||||
<age>30</age>
|
||||
<cars>
|
||||
<element>
|
||||
<name>Ford</name>
|
||||
<models>
|
||||
<element>Fiesta</element>
|
||||
<element>Focus</element>
|
||||
<element>Mustang</element>
|
||||
</models>
|
||||
</element>
|
||||
<element>
|
||||
<name>BMW</name>
|
||||
<models>
|
||||
<element>320</element>
|
||||
<element>X3</element>
|
||||
<element>X5</element>
|
||||
</models>
|
||||
</element>
|
||||
<element>
|
||||
<name>Fiat</name>
|
||||
<models>
|
||||
<element>500</element>
|
||||
<element>Panda</element>
|
||||
</models>
|
||||
</element>
|
||||
</cars>
|
||||
```
|
||||
|
||||
Notes: `element` is empty element that have no any name.
|
||||
|
||||
List of supported XPath query packages
|
||||
===
|
||||
|Name |Description |
|
||||
|--------------------------|----------------|
|
||||
|[htmlquery](https://github.com/antchfx/htmlquery) | XPath query package for the HTML document|
|
||||
|[xmlquery](https://github.com/antchfx/xmlquery) | XPath query package for the XML document|
|
||||
|[jsonquery](https://github.com/antchfx/jsonquery) | XPath query package for the JSON document|
|
36
vendor/github.com/antchfx/jsonquery/books.json
generated
vendored
Normal file
36
vendor/github.com/antchfx/jsonquery/books.json
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"store": {
|
||||
"book": [
|
||||
{
|
||||
"category": "reference",
|
||||
"author": "Nigel Rees",
|
||||
"title": "Sayings of the Century",
|
||||
"price": 8.95
|
||||
},
|
||||
{
|
||||
"category": "fiction",
|
||||
"author": "Evelyn Waugh",
|
||||
"title": "Sword of Honour",
|
||||
"price": 12.99
|
||||
},
|
||||
{
|
||||
"category": "fiction",
|
||||
"author": "Herman Melville",
|
||||
"title": "Moby Dick",
|
||||
"isbn": "0-553-21311-3",
|
||||
"price": 8.99
|
||||
},
|
||||
{
|
||||
"category": "fiction",
|
||||
"author": "J. R. R. Tolkien",
|
||||
"title": "The Lord of the Rings",
|
||||
"isbn": "0-395-19395-8",
|
||||
"price": 22.99
|
||||
}
|
||||
],
|
||||
"bicycle": {
|
||||
"color": "red",
|
||||
"price": 19.95
|
||||
}
|
||||
}
|
||||
}
|
157
vendor/github.com/antchfx/jsonquery/node.go
generated
vendored
Normal file
157
vendor/github.com/antchfx/jsonquery/node.go
generated
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
package jsonquery
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// A NodeType is the type of a Node.
|
||||
type NodeType uint
|
||||
|
||||
const (
|
||||
// DocumentNode is a document object that, as the root of the document tree,
|
||||
// provides access to the entire XML document.
|
||||
DocumentNode NodeType = iota
|
||||
// ElementNode is an element.
|
||||
ElementNode
|
||||
// TextNode is the text content of a node.
|
||||
TextNode
|
||||
)
|
||||
|
||||
// A Node consists of a NodeType and some Data (tag name for
|
||||
// element nodes, content for text) and are part of a tree of Nodes.
|
||||
type Node struct {
|
||||
Parent, PrevSibling, NextSibling, FirstChild, LastChild *Node
|
||||
|
||||
Type NodeType
|
||||
Data string
|
||||
|
||||
level int
|
||||
}
|
||||
|
||||
// ChildNodes gets all child nodes of the node.
|
||||
func (n *Node) ChildNodes() []*Node {
|
||||
var a []*Node
|
||||
for nn := n.FirstChild; nn != nil; nn = nn.NextSibling {
|
||||
a = append(a, nn)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// InnerText gets the value of the node and all its child nodes.
|
||||
func (n *Node) InnerText() string {
|
||||
var output func(*bytes.Buffer, *Node)
|
||||
output = func(buf *bytes.Buffer, n *Node) {
|
||||
if n.Type == TextNode {
|
||||
buf.WriteString(n.Data)
|
||||
return
|
||||
}
|
||||
for child := n.FirstChild; child != nil; child = child.NextSibling {
|
||||
output(buf, child)
|
||||
}
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
output(&buf, n)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// SelectElement finds the first of child elements with the
|
||||
// specified name.
|
||||
func (n *Node) SelectElement(name string) *Node {
|
||||
for nn := n.FirstChild; nn != nil; nn = nn.NextSibling {
|
||||
if nn.Data == name {
|
||||
return nn
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadURL loads the JSON document from the specified URL.
|
||||
func LoadURL(url string) (*Node, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return Parse(resp.Body)
|
||||
}
|
||||
|
||||
func parseValue(x interface{}, top *Node, level int) {
|
||||
addNode := func(n *Node) {
|
||||
if n.level == top.level {
|
||||
top.NextSibling = n
|
||||
n.PrevSibling = top
|
||||
n.Parent = top.Parent
|
||||
if top.Parent != nil {
|
||||
top.Parent.LastChild = n
|
||||
}
|
||||
} else if n.level > top.level {
|
||||
n.Parent = top
|
||||
if top.FirstChild == nil {
|
||||
top.FirstChild = n
|
||||
top.LastChild = n
|
||||
} else {
|
||||
t := top.LastChild
|
||||
t.NextSibling = n
|
||||
n.PrevSibling = t
|
||||
top.LastChild = n
|
||||
}
|
||||
}
|
||||
}
|
||||
switch v := x.(type) {
|
||||
case []interface{}:
|
||||
for _, vv := range v {
|
||||
n := &Node{Type: ElementNode, level: level}
|
||||
addNode(n)
|
||||
parseValue(vv, n, level+1)
|
||||
}
|
||||
case map[string]interface{}:
|
||||
// The Go’s map iteration order is random.
|
||||
// (https://blog.golang.org/go-maps-in-action#Iteration-order)
|
||||
var keys []string
|
||||
for key := range v {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
n := &Node{Data: key, Type: ElementNode, level: level}
|
||||
addNode(n)
|
||||
parseValue(v[key], n, level+1)
|
||||
}
|
||||
case string:
|
||||
n := &Node{Data: v, Type: TextNode, level: level}
|
||||
addNode(n)
|
||||
case float64:
|
||||
s := strconv.FormatFloat(v, 'f', -1, 64)
|
||||
n := &Node{Data: s, Type: TextNode, level: level}
|
||||
addNode(n)
|
||||
case bool:
|
||||
s := strconv.FormatBool(v)
|
||||
n := &Node{Data: s, Type: TextNode, level: level}
|
||||
addNode(n)
|
||||
}
|
||||
}
|
||||
|
||||
func parse(b []byte) (*Node, error) {
|
||||
var v interface{}
|
||||
if err := json.Unmarshal(b, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doc := &Node{Type: DocumentNode}
|
||||
parseValue(v, doc, 1)
|
||||
return doc, nil
|
||||
}
|
||||
|
||||
// Parse JSON document.
|
||||
func Parse(r io.Reader) (*Node, error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parse(b)
|
||||
}
|
149
vendor/github.com/antchfx/jsonquery/query.go
generated
vendored
Normal file
149
vendor/github.com/antchfx/jsonquery/query.go
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
package jsonquery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/antchfx/xpath"
|
||||
)
|
||||
|
||||
var _ xpath.NodeNavigator = &NodeNavigator{}
|
||||
|
||||
// CreateXPathNavigator creates a new xpath.NodeNavigator for the specified html.Node.
|
||||
func CreateXPathNavigator(top *Node) *NodeNavigator {
|
||||
return &NodeNavigator{cur: top, root: top}
|
||||
}
|
||||
|
||||
// Find searches the Node that matches by the specified XPath expr.
|
||||
func Find(top *Node, expr string) []*Node {
|
||||
exp, err := xpath.Compile(expr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
t := exp.Select(CreateXPathNavigator(top))
|
||||
var elems []*Node
|
||||
for t.MoveNext() {
|
||||
elems = append(elems, (t.Current().(*NodeNavigator)).cur)
|
||||
}
|
||||
return elems
|
||||
}
|
||||
|
||||
// FindOne searches the Node that matches by the specified XPath expr,
|
||||
// and returns first element of matched.
|
||||
func FindOne(top *Node, expr string) *Node {
|
||||
exp, err := xpath.Compile(expr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
t := exp.Select(CreateXPathNavigator(top))
|
||||
var elem *Node
|
||||
if t.MoveNext() {
|
||||
elem = (t.Current().(*NodeNavigator)).cur
|
||||
}
|
||||
return elem
|
||||
}
|
||||
|
||||
// NodeNavigator is for navigating JSON document.
|
||||
type NodeNavigator struct {
|
||||
root, cur *Node
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) Current() *Node {
|
||||
return a.cur
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) NodeType() xpath.NodeType {
|
||||
switch a.cur.Type {
|
||||
case TextNode:
|
||||
return xpath.TextNode
|
||||
case DocumentNode:
|
||||
return xpath.RootNode
|
||||
case ElementNode:
|
||||
return xpath.ElementNode
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown node type %v", a.cur.Type))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) LocalName() string {
|
||||
return a.cur.Data
|
||||
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) Prefix() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) Value() string {
|
||||
switch a.cur.Type {
|
||||
case ElementNode:
|
||||
return a.cur.InnerText()
|
||||
case TextNode:
|
||||
return a.cur.Data
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) Copy() xpath.NodeNavigator {
|
||||
n := *a
|
||||
return &n
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) MoveToRoot() {
|
||||
a.cur = a.root
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) MoveToParent() bool {
|
||||
if n := a.cur.Parent; n != nil {
|
||||
a.cur = n
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *NodeNavigator) MoveToNextAttribute() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) MoveToChild() bool {
|
||||
if n := a.cur.FirstChild; n != nil {
|
||||
a.cur = n
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) MoveToFirst() bool {
|
||||
for n := a.cur.PrevSibling; n != nil; n = n.PrevSibling {
|
||||
a.cur = n
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) String() string {
|
||||
return a.Value()
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) MoveToNext() bool {
|
||||
if n := a.cur.NextSibling; n != nil {
|
||||
a.cur = n
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) MoveToPrevious() bool {
|
||||
if n := a.cur.PrevSibling; n != nil {
|
||||
a.cur = n
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *NodeNavigator) MoveTo(other xpath.NodeNavigator) bool {
|
||||
node, ok := other.(*NodeNavigator)
|
||||
if !ok || node.root != a.root {
|
||||
return false
|
||||
}
|
||||
a.cur = node.cur
|
||||
return true
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue