hiku/main.go
2024-05-18 19:21:20 +07:00

171 lines
3.3 KiB
Go

package main
import (
"bytes"
"flag"
"fmt"
"io"
"net/http"
"net/url"
"os"
"regexp"
"strings"
"github.com/schollz/progressbar/v3"
)
// The skeleton for now
var link string
func terminate() {
flag.Usage()
os.Exit(1)
}
func check(f func() error) {
if err := f(); err != nil {
fmt.Fprintf(os.Stderr, "ERR > %v\n", err)
}
}
func generateRequest(link, method string, body io.Reader) *http.Request {
req, _ := http.NewRequest(method, link, body)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0")
req.Header.Set("Connection", "keep-alive")
return req
}
func executeRequest(req *http.Request) *http.Response {
resp, err := http.DefaultClient.Do(req)
if err != nil {
println(err)
}
return resp
}
func writeResponseToFile(resp *http.Response, filename string) {
f, _ := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
defer f.Close()
var filesize int64
if _, ok := resp.Header["Content-Length"]; ok {
filesize = resp.ContentLength
} else {
filesize = -1
}
bar := progressbar.DefaultBytes(
filesize,
filename,
)
io.Copy(io.MultiWriter(f, bar), resp.Body)
}
func parseFilenameFromContentDisposition(s string) string {
regex := regexp.MustCompile(`".*?"`)
// Ugly but it works
filename := regex.FindString(s)
filename = filename[1 : len(filename)-1]
return filename
}
func Pixeldrain(path string) error {
// TODO: Implement more URL forms
split := strings.Split(path, "/")
id := split[2]
contentURL := fmt.Sprintf("https://pixeldrain.com/api/file/%s?download", id)
req := generateRequest(contentURL, "GET", nil)
resp := executeRequest(req)
filename := parseFilenameFromContentDisposition(resp.Header["Content-Disposition"][0])
writeResponseToFile(resp, filename)
return nil
}
func WeTransfer(path string) error {
// TODO: Support we.tl
split := strings.Split(path, "/")
// Some checks
if split[1] != "downloads" {
return fmt.Errorf("WeTransfer parser: Unsupported URL")
}
baseID := split[2]
secHash := split[3]
contentURL := fmt.Sprintf("https://wetransfer.com/api/v4/transfers/%s/download", baseID)
payload := []byte(fmt.Sprintf(`{"security_hash":"%s","intent":"entire_transfer"}`, secHash))
req := generateRequest(contentURL, "POST", bytes.NewBuffer(payload))
req.Header.Add("Content-Type", "application/json; charset=UTF-8")
resp := executeRequest(req)
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
regex := regexp.MustCompile(`"https://.*?"`)
directLink := regex.FindString(string(body))
req = generateRequest(directLink[1:len(directLink)-1], "GET", nil)
resp = executeRequest(req)
filename := parseFilenameFromContentDisposition(resp.Header["Content-Disposition"][0])
writeResponseToFile(resp, filename)
return nil
}
func extractURL(link string) error {
parsed, err := url.Parse(link)
if err != nil {
return err
}
hostname := parsed.Hostname()
path := parsed.Path
switch hostname {
case "pixeldrain.com":
Pixeldrain(path)
case "wetransfer.com":
WeTransfer(path)
default:
return fmt.Errorf("Error: Unimplemented URL")
}
return nil
}
func main() {
var help = flag.Bool("help", false, "Show help")
if *help {
terminate()
}
flag.StringVar(&link, "url", "", "The URL to fetch the file from")
flag.Parse()
if len(link) < 1 {
fmt.Println("Error: Invalid URL?")
terminate()
}
_ = extractURL(link)
}