/
main.go
137 lines (121 loc) · 3.2 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package main
import (
"fmt"
"text/template"
//"io/ioutil"
"log"
"net/http"
"regexp"
"github.com/gorilla/mux"
"github.com/yhat/scrape"
"golang.org/x/net/html"
"golang.org/x/net/html/atom"
)
var re = regexp.MustCompile("Uploaded ([^,]+), Size ([^,]+), ULed by (.+)")
type Torrent struct {
Category, Title, Magnet, Size, Uploaded, Uploader, Seeders, Leechers string
}
func ParseRecord(n *html.Node) Torrent {
tds := scrape.FindAll(n, scrape.ByTag(atom.Td))
var size, uptime, uploader string
if len(tds) == 4 {
cat := scrape.Text(tds[0])[0:3]
name, magnet, desc := ParseName(tds[1])
matches := re.FindStringSubmatch(desc)
uptime, size, uploader = matches[1], matches[2], matches[3]
seed := scrape.Text(tds[2])
leech := scrape.Text(tds[3])
return Torrent{cat, name, magnet, size, uptime, uploader, seed, leech}
} else {
fmt.Println("Error: not expected format")
}
return Torrent{}
}
func ParseName(n *html.Node) (string, string, string) {
matcher := func(n *html.Node) bool {
// must check for nil values
if n.DataAtom == atom.A && n.Parent.DataAtom == atom.Td {
return true
}
return false
}
var name, magnet, desc string
if detName, ok := scrape.Find(n, scrape.ByClass("detName")); ok {
name = scrape.Text(detName)
}
if anchor, ok := scrape.Find(n, matcher); ok {
magnet = scrape.Attr(anchor, "href")
}
if detDesc, ok := scrape.Find(n, scrape.ByClass("detDesc")); ok {
desc = scrape.Text(detDesc)
}
return name, magnet, desc
}
func main2() {
TorrentList("https://thepiratebay.la/top/201")
}
func main() {
r := mux.NewRouter()
//data, err := Asset("data/tmpl.html")
//if err != nil {
//panic(err)
//}
funcMap := template.FuncMap{
"add": func(x, y int) int {
return x + y
},
}
tmpl := template.Must(template.New("tpb").Funcs(funcMap).Parse(TMPL))
r.HandleFunc("/{cat}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
category := vars["cat"]
url := fmt.Sprintf("https://thepiratebay.la/top/%s", category)
torrents, err := TorrentList(url)
err = tmpl.Execute(w, torrents)
if err != nil {
panic(err)
}
})
r.HandleFunc("/search/{query}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
query := vars["query"]
url := fmt.Sprintf("https://thepiratebay.la/search/%s", query)
torrents, err := TorrentList(url)
err = tmpl.Execute(w, torrents)
if err != nil {
panic(err)
}
})
go http.ListenAndServe("0.0.0.0:8080", r)
log.Println("listening on port 8080")
select {}
}
func TorrentList(url string) ([]Torrent, error) {
// request and parse the front page
resp, err := http.Get(url)
if err != nil {
return make([]Torrent, 0), err
}
root, err := html.Parse(resp.Body)
if err != nil {
return make([]Torrent, 0), err
}
var torrents []Torrent
if content, ok := scrape.Find(root, scrape.ById("searchResult")); ok {
// define a matcher
matcher := func(n *html.Node) bool {
// must check for nil values
if n.DataAtom == atom.Tr && n.Parent.DataAtom == atom.Tbody {
return true
}
return false
}
// grab all articles and print them
trs := scrape.FindAll(content, matcher)
for _, tr := range trs {
torrents = append(torrents, ParseRecord(tr))
}
}
resp.Body.Close()
return torrents, nil
}