tools
/
wi
1
0
Fork 0
wi/commands/commands.go

188 lines
3.4 KiB
Go
Raw Normal View History

2016-07-25 15:35:09 +00:00
/**
* @file commands.go
* @author Mikhail Klementyev jollheef<AT>riseup.net
* @license GNU GPLv3
* @date July, 2016
2016-07-28 19:43:53 +00:00
* @brief Command line options ('wi (get|link|...)')
2016-07-25 15:35:09 +00:00
*/
package commands
import (
"bytes"
"database/sql"
"strings"
"fmt"
"io/ioutil"
"log"
"net/http"
2016-07-29 18:05:05 +00:00
"net/url"
2016-07-25 15:35:09 +00:00
"github.com/jollheef/wi/storage"
"github.com/jaytaylor/html2text"
"golang.org/x/net/html"
"golang.org/x/net/html/charset"
)
2016-07-29 18:05:05 +00:00
func parseLink(db *sql.DB, oldPage, value string, lastUrl *url.URL) (htmlPage string, err error) {
linkUrl, err := lastUrl.Parse(value)
2016-07-25 15:35:09 +00:00
if err != nil {
return
}
2016-07-29 18:05:05 +00:00
linkNo, err := storage.GetLinkID(db, linkUrl.String())
2016-07-25 15:35:09 +00:00
if err != nil {
2016-07-29 18:05:05 +00:00
linkNo, err = storage.AddLink(db, linkUrl.String())
2016-07-25 15:35:09 +00:00
if err != nil {
return
}
}
2016-07-25 21:04:32 +00:00
htmlPage = oldPage
2016-07-25 15:35:09 +00:00
for _, s := range []string{value, html.EscapeString(value)} {
2016-07-25 21:04:32 +00:00
htmlPage = strings.Replace(htmlPage, "\""+s+"\"",
2016-07-25 15:35:09 +00:00
"\""+fmt.Sprintf("%d", linkNo)+"\"", -1)
}
return
}
2016-07-29 18:05:05 +00:00
func parseLinks(db *sql.DB, body []byte, lastUrl *url.URL) (htmlPage string, err error) {
2016-07-25 15:35:09 +00:00
htmlPage = string(body)
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" {
2016-07-29 18:05:05 +00:00
htmlPage, err = parseLink(db, htmlPage, string(value), lastUrl)
2016-07-25 15:35:09 +00:00
if err != nil {
return
}
}
if !moreAttr {
break
}
}
}
return
}
2016-07-29 18:05:05 +00:00
func Get(db *sql.DB, linkUrl string) {
2016-07-25 15:35:09 +00:00
client := &http.Client{}
2016-07-29 18:05:05 +00:00
var lastUrl *url.URL
client.CheckRedirect = func(r *http.Request, via []*http.Request) (err error) {
lastUrl = r.URL
return
}
if !strings.Contains(linkUrl, "://") {
linkUrl = "https://" + linkUrl
2016-07-25 15:35:09 +00:00
}
// TODO Full url encoding
2016-07-29 18:05:05 +00:00
req, err := http.NewRequest("GET", strings.Replace(linkUrl, " ", "%20", -1), nil)
2016-07-25 15:35:09 +00:00
if err != nil {
log.Fatalln(err)
}
req.Header.Set("User-Agent", "Wi 0.0")
resp, err := client.Do(req)
if err != nil {
log.Fatalln(err)
}
2016-07-29 18:05:05 +00:00
if lastUrl == nil {
lastUrl = req.URL
}
storage.AddHistoryURL(db, linkUrl)
2016-07-25 15:35:09 +00:00
defer resp.Body.Close()
utf8, err := charset.NewReader(resp.Body, resp.Header.Get("Content-Type"))
if err != nil {
2016-07-25 20:24:25 +00:00
log.Fatalln("Encoding error:", err)
2016-07-25 15:35:09 +00:00
}
body, err := ioutil.ReadAll(utf8)
if err != nil {
2016-07-25 20:24:25 +00:00
log.Fatalln("IO error:", err)
2016-07-25 15:35:09 +00:00
}
2016-07-29 18:05:05 +00:00
htmlPage, err := parseLinks(db, body, lastUrl)
2016-07-25 15:35:09 +00:00
if err != nil {
2016-07-25 20:24:25 +00:00
log.Fatalln("Parse links error:", err)
2016-07-25 15:35:09 +00:00
}
text, err := html2text.FromString(htmlPage)
if err != nil {
2016-07-25 20:24:25 +00:00
log.Fatalln("Html to text error:", err)
2016-07-25 15:35:09 +00:00
}
text += ""
fmt.Println(text)
}
2016-07-25 15:41:12 +00:00
func Link(db *sql.DB, linkID int64, fromHistory bool) {
2016-07-29 18:05:05 +00:00
var linkUrl string
2016-07-25 15:41:12 +00:00
var err error
if fromHistory {
2016-07-29 18:05:05 +00:00
linkUrl, err = storage.GetHistoryUrl(db, linkID)
2016-07-25 15:41:12 +00:00
} else {
2016-07-29 18:05:05 +00:00
linkUrl, err = storage.GetLink(db, linkID)
2016-07-25 15:41:12 +00:00
}
2016-07-25 15:35:09 +00:00
if err != nil {
2016-07-25 20:24:25 +00:00
log.Fatalln("Get link/history url error:", err)
2016-07-25 15:35:09 +00:00
}
2016-07-29 18:05:05 +00:00
Get(db, linkUrl)
2016-07-25 15:35:09 +00:00
}
func History(db *sql.DB, argAmount, defaultAmount int64, all bool) {
history, err := storage.GetHistory(db)
if err != nil {
2016-07-25 20:24:25 +00:00
log.Fatalln("Get history error:", err)
2016-07-25 15:35:09 +00:00
}
var amount int64
if all {
amount = int64(len(history))
} else if argAmount == 0 {
if int64(len(history)) < defaultAmount {
amount = int64(len(history))
} else {
amount = defaultAmount
}
} else {
if amount > int64(len(history)) {
amount = int64(len(history))
} else {
amount = argAmount
}
}
for _, h := range history[int64(len(history))-amount:] {
fmt.Println(h.ID, h.URL)
}
}