feat: update for new apkbrowser, make it standalone
This commit is contained in:
parent
bd34c6d350
commit
e28f404d9b
6 changed files with 50 additions and 246 deletions
20
Dockerfile
20
Dockerfile
|
@ -1,20 +0,0 @@
|
||||||
FROM golang:alpine as builder
|
|
||||||
|
|
||||||
LABEL maintainer="ptrcnull <docker@ptrcnull.me>"
|
|
||||||
|
|
||||||
WORKDIR /src
|
|
||||||
|
|
||||||
COPY go.mod go.sum ./
|
|
||||||
RUN go mod download
|
|
||||||
|
|
||||||
COPY main.go .
|
|
||||||
COPY utils ./utils
|
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o server main.go
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY --from=builder /src/server .
|
|
||||||
|
|
||||||
CMD ["/app/server"]
|
|
|
@ -1,8 +0,0 @@
|
||||||
version: '3'
|
|
||||||
services:
|
|
||||||
pkgs:
|
|
||||||
container_name: pkgs
|
|
||||||
build: .
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- 127.0.0.1:8212:8080
|
|
5
go.mod
5
go.mod
|
@ -2,7 +2,4 @@ module git.ddd.rip/ptrcnull/pkgs
|
||||||
|
|
||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require git.ddd.rip/ptrcnull/html v1.0.5
|
||||||
github.com/gofiber/fiber/v2 v2.12.0
|
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed
|
|
||||||
)
|
|
||||||
|
|
32
go.sum
32
go.sum
|
@ -1,25 +1,9 @@
|
||||||
github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E=
|
git.ddd.rip/ptrcnull/html v1.0.5 h1:7mo4cD7jFJoQNPDz09Ib/oNrS6opRH7cQef32LIExDg=
|
||||||
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
git.ddd.rip/ptrcnull/html v1.0.5/go.mod h1:5QrxVL2XnzA7pGUKNQZdV6wDXICano5y8kRNPAQSU5Y=
|
||||||
github.com/gofiber/fiber/v2 v2.12.0 h1:R7FVMs9mtMREjfCzCioh2j8RHwhz0/H+X0rH6BpBkJ4=
|
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60 h1:8NSylCMxLW4JvserAndSgFL7aPli6A68yf0bYFTcWCM=
|
||||||
github.com/gofiber/fiber/v2 v2.12.0/go.mod h1:oZTLWqYnqpMMuF922SjGbsYZsdpE1MCfh416HNdweIM=
|
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
github.com/klauspost/compress v1.12.2 h1:2KCfW3I9M7nSc5wOqXAlW2v2U6v+w6cbjvbfp+OykW8=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
|
||||||
github.com/valyala/fasthttp v1.26.0 h1:k5Tooi31zPG/g8yS6o2RffRO2C9B9Kah9SY8j/S7058=
|
|
||||||
github.com/valyala/fasthttp v1.26.0/go.mod h1:cmWIqlu99AO/RKcp1HWaViTqc57FswJOfYYdPJBl8BA=
|
|
||||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
|
||||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
|
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
|
|
||||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
|
49
main.go
49
main.go
|
@ -2,36 +2,44 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.ddd.rip/ptrcnull/pkgs/utils"
|
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.ddd.rip/ptrcnull/html"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const BOLD = "\033[1m"
|
||||||
|
const RESET = "\033[0m"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Println("usage: pkgs <filename>")
|
||||||
app.Get("/:file", func(ctx *fiber.Ctx) error {
|
os.Exit(1)
|
||||||
file := ctx.Params("file")
|
|
||||||
|
|
||||||
res, err := http.Get("https://pkgs.alpinelinux.org/contents?file=" + file + "&path=&name=&branch=&arch=x86_64")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node, err := utils.Parse(res.Body)
|
file := os.Args[1]
|
||||||
|
|
||||||
|
res, err := http.Get("https://pkgs.alpinelinux.org/contents?file=" + file + "&path=&name=&branch=edge&arch=x86_64")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
fmt.Println(err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
node, err := html.ParseDocument(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody := node.QuerySelector("tbody")
|
tbody := node.QuerySelector("tbody")
|
||||||
if tbody == nil {
|
if tbody == nil {
|
||||||
return fmt.Errorf("cannot find tbody")
|
fmt.Println("cannot find tbody")
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.Println(tbody.Render())
|
|
||||||
|
|
||||||
reply := ""
|
reply := ""
|
||||||
tbody.ForEach(func(row *utils.Node) {
|
tbody.ForEach(func(row *html.Node) {
|
||||||
cells := row.Children()
|
cells := row.Children()
|
||||||
if len(cells) == 0 {
|
if len(cells) == 0 {
|
||||||
return
|
return
|
||||||
|
@ -40,11 +48,8 @@ func main() {
|
||||||
reply = "Not found :("
|
reply = "Not found :("
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
reply += cells[1].Text() + "\n" + cells[0].Text() + "\n\n"
|
reply += BOLD + cells[1].TrimmedText() + RESET + "\n" + cells[0].TrimmedText() + "\n\n"
|
||||||
})
|
})
|
||||||
|
reply = strings.Trim(reply, "\n")
|
||||||
return ctx.SendString(reply)
|
fmt.Println(reply)
|
||||||
})
|
|
||||||
|
|
||||||
panic(app.Listen(":8080"))
|
|
||||||
}
|
}
|
||||||
|
|
154
utils/html.go
154
utils/html.go
|
@ -1,154 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"golang.org/x/net/html"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Node struct {
|
|
||||||
*html.Node
|
|
||||||
}
|
|
||||||
|
|
||||||
func Parse(r io.Reader) (*Node, error) {
|
|
||||||
n, err := html.Parse(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Node{n}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) QuerySelector(selector string) *Node {
|
|
||||||
if strings.HasPrefix(selector, "#") {
|
|
||||||
return n.GetElementById(selector[1:])
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(selector, ".") {
|
|
||||||
return n.GetElementByClass(selector[1:])
|
|
||||||
}
|
|
||||||
return n.GetElementByTagName(selector)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) GetElementById(id string) *Node {
|
|
||||||
return n.FindOne(func(n *Node) bool {
|
|
||||||
return n.HasAttr("id", id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) GetElementByClass(class string) *Node {
|
|
||||||
return n.FindOne(func(n *Node) bool {
|
|
||||||
return n.HasClass(class)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) GetElementByTagName(name string) *Node {
|
|
||||||
return n.FindOne(func (n *Node) bool {
|
|
||||||
return n.Type == html.ElementNode && n.Data == name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) HasClass(class string) bool {
|
|
||||||
return n.HasAttr("class", class)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) GetAttr(key string) []string {
|
|
||||||
var res []string
|
|
||||||
for _, attr := range n.Attr {
|
|
||||||
if attr.Key == key {
|
|
||||||
res = append(res, attr.Val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) HasAttr(key, value string) bool {
|
|
||||||
for _, attr := range n.Attr {
|
|
||||||
if attr.Key == key && attr.Val == value {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) ForEach(cb func (n *Node)) {
|
|
||||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
|
||||||
cb(&Node{c})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) ChildNodes() []*Node {
|
|
||||||
var res []*Node
|
|
||||||
n.ForEach(func(n *Node) {
|
|
||||||
res = append(res, n)
|
|
||||||
})
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Children() []*Node {
|
|
||||||
var res []*Node
|
|
||||||
n.ForEach(func(n *Node) {
|
|
||||||
if n.Type == html.ElementNode {
|
|
||||||
res = append(res, n)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Traverse(cb func(n *Node)) {
|
|
||||||
var f func(*Node)
|
|
||||||
f = func(n *Node) {
|
|
||||||
cb(n)
|
|
||||||
n.ForEach(f)
|
|
||||||
}
|
|
||||||
f(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) FindOne(cb func(n *Node) bool) *Node {
|
|
||||||
var res *Node
|
|
||||||
|
|
||||||
var f func(*Node)
|
|
||||||
f = func(n *Node) {
|
|
||||||
if res != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cb(n) {
|
|
||||||
res = n
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n.ForEach(f)
|
|
||||||
}
|
|
||||||
f(n)
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) FindMany(cb func(n *Node) bool) []*Node {
|
|
||||||
var res []*Node
|
|
||||||
|
|
||||||
var f func(*Node)
|
|
||||||
f = func(n *Node) {
|
|
||||||
if cb(n) {
|
|
||||||
res = append(res, n)
|
|
||||||
}
|
|
||||||
n.ForEach(f)
|
|
||||||
}
|
|
||||||
f(n)
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Text() string {
|
|
||||||
res := ""
|
|
||||||
n.Traverse(func(n *Node) {
|
|
||||||
if n.Type == html.TextNode {
|
|
||||||
res += n.Data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Render() (string, error) {
|
|
||||||
w := bytes.NewBuffer([]byte{})
|
|
||||||
err := html.Render(w, n.Node)
|
|
||||||
return w.String(), err
|
|
||||||
}
|
|
Loading…
Reference in a new issue