mirror of
https://code.dumpstack.io/tools/wi.git
synced 2025-05-09 21:38:47 +00:00
Implements post query
This commit is contained in:
parent
03756cafb3
commit
df10b44fe7
3 changed files with 287 additions and 50 deletions
|
@ -9,73 +9,88 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"strings"
|
||||
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/jollheef/wi/storage"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/jaytaylor/html2text"
|
||||
"golang.org/x/net/html"
|
||||
"golang.org/x/net/html/charset"
|
||||
)
|
||||
|
||||
func parseLink(db *sql.DB, oldPage, value string, lastUrl *url.URL) (htmlPage string, err error) {
|
||||
linkUrl, err := lastUrl.Parse(value)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
func fixLinks(db *sql.DB, doc *goquery.Document, pageUrl *url.URL) (err error) {
|
||||
|
||||
linkNo, err := storage.GetLinkID(db, linkUrl.String())
|
||||
if err != nil {
|
||||
linkNo, err = storage.AddLink(db, linkUrl.String())
|
||||
doc.Find("a").Each(func(i int, s *goquery.Selection) {
|
||||
url, exists := s.Attr("href")
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
linkUrl, err := pageUrl.Parse(url)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
htmlPage = oldPage
|
||||
linkNo, err := storage.GetLinkID(db, linkUrl.String())
|
||||
if err != nil {
|
||||
linkNo, err = storage.AddLink(db, linkUrl.String())
|
||||
if err != nil {
|
||||
log.Fatalln("Add link:", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, s := range []string{value, html.EscapeString(value)} {
|
||||
htmlPage = strings.Replace(htmlPage, "\""+s+"\"",
|
||||
"\""+fmt.Sprintf("%d", linkNo)+"\"", -1)
|
||||
}
|
||||
s.SetAttr("href", fmt.Sprintf("%d", linkNo))
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func parseLinks(db *sql.DB, body []byte, lastUrl *url.URL) (htmlPage string, err error) {
|
||||
htmlPage = string(body)
|
||||
func fixForms(db *sql.DB, doc *goquery.Document, pageUrl *url.URL) (err error) {
|
||||
|
||||
z := html.NewTokenizer(bytes.NewReader(body))
|
||||
|
||||
for {
|
||||
tt := z.Next()
|
||||
if tt == html.ErrorToken {
|
||||
break
|
||||
}
|
||||
|
||||
for {
|
||||
key, value, moreAttr := z.TagAttr()
|
||||
|
||||
if string(key) == "href" {
|
||||
htmlPage, err = parseLink(db, htmlPage, string(value), lastUrl)
|
||||
if err != nil {
|
||||
doc.Find("form").Each(func(i int, s *goquery.Selection) {
|
||||
var fields []storage.Field
|
||||
s.Find("input").Map(
|
||||
func(i int, s *goquery.Selection) (str string) {
|
||||
f := storage.Field{}
|
||||
var exists bool
|
||||
f.Name, exists = s.Attr("name")
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
}
|
||||
f.Value, _ = s.Attr("value")
|
||||
hidden, _ := s.Attr("type")
|
||||
if hidden == "hidden" {
|
||||
f.Hidden = true
|
||||
}
|
||||
fields = append(fields, f)
|
||||
return
|
||||
})
|
||||
|
||||
if !moreAttr {
|
||||
break
|
||||
action, _ := s.Attr("action")
|
||||
|
||||
actionUrl, err := pageUrl.Parse(action)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
method, _ := s.Attr("method")
|
||||
|
||||
formNo, err := storage.GetFormID(db, fields, actionUrl.String(), method)
|
||||
if err != nil {
|
||||
formNo, err = storage.AddForm(db, fields, actionUrl.String(), method)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.AppendHtml(fmt.Sprintf("(%d %s)", formNo, strings.ToUpper(method)))
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -94,8 +109,12 @@ func Get(db *sql.DB, linkUrl string) {
|
|||
linkUrl = "https://" + linkUrl
|
||||
}
|
||||
|
||||
// TODO Full url encoding
|
||||
req, err := http.NewRequest("GET", strings.Replace(linkUrl, " ", "%20", -1), nil)
|
||||
u, err := url.Parse(linkUrl)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", u.String(), nil)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
@ -120,14 +139,24 @@ func Get(db *sql.DB, linkUrl string) {
|
|||
log.Fatalln("Encoding error:", err)
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(utf8)
|
||||
doc, err := goquery.NewDocumentFromReader(utf8)
|
||||
if err != nil {
|
||||
log.Fatalln("IO error:", err)
|
||||
log.Fatalln("Create document error:", err)
|
||||
}
|
||||
|
||||
htmlPage, err := parseLinks(db, body, lastUrl)
|
||||
err = fixLinks(db, doc, lastUrl)
|
||||
if err != nil {
|
||||
log.Fatalln("Parse links error:", err)
|
||||
log.Fatalln("Fix links error:", err)
|
||||
}
|
||||
|
||||
err = fixForms(db, doc, lastUrl)
|
||||
if err != nil {
|
||||
log.Fatalln("Fix forms error", err)
|
||||
}
|
||||
|
||||
htmlPage, err := doc.Html()
|
||||
if err != nil {
|
||||
log.Fatalln("Convert to html error:", err)
|
||||
}
|
||||
|
||||
text, err := html2text.FromString(htmlPage)
|
||||
|
@ -139,8 +168,72 @@ func Get(db *sql.DB, linkUrl string) {
|
|||
fmt.Println(text)
|
||||
}
|
||||
|
||||
func Post(db *sql.DB, formID int64, formArgs []string) {
|
||||
fmt.Println("Not implemented")
|
||||
func Form(db *sql.DB, formID int64, formArgs []string) {
|
||||
fields, formUrl, post, err := storage.GetForm(db, formID)
|
||||
if err != nil {
|
||||
log.Fatalln("Get form:", err)
|
||||
}
|
||||
|
||||
if len(formArgs) == 0 {
|
||||
if post {
|
||||
fmt.Print("POST ")
|
||||
}
|
||||
|
||||
fmt.Println(formUrl)
|
||||
|
||||
fmt.Print("Values: ")
|
||||
for i, f := range fields {
|
||||
if i != 0 {
|
||||
fmt.Print("\n\t")
|
||||
}
|
||||
fmt.Printf(`%s="%s"`, f.Name, f.Value)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
urlData := url.Values{}
|
||||
for _, f := range fields {
|
||||
urlData.Set(f.Name, f.Value)
|
||||
}
|
||||
|
||||
for _, fa := range formArgs {
|
||||
nameAndValue := strings.Split(fa, " ")
|
||||
if len(nameAndValue) != 2 {
|
||||
continue
|
||||
}
|
||||
name := nameAndValue[0]
|
||||
value := nameAndValue[1]
|
||||
urlData.Set(name, value)
|
||||
}
|
||||
|
||||
client := &http.Client{}
|
||||
|
||||
var lastUrl *url.URL
|
||||
|
||||
client.CheckRedirect = func(r *http.Request, via []*http.Request) (err error) {
|
||||
lastUrl = r.URL
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.PostForm(formUrl, urlData)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
if lastUrl == nil {
|
||||
lastUrl, _ = resp.Location()
|
||||
}
|
||||
|
||||
log.Println(resp.Status)
|
||||
|
||||
var status int64
|
||||
fmt.Sscanf(resp.Status, "%d", &status)
|
||||
|
||||
if status >= 300 && status < 400 {
|
||||
Get(db, lastUrl.String())
|
||||
}
|
||||
}
|
||||
|
||||
func Link(db *sql.DB, linkID int64, fromHistory bool) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue