84 lines
1.7 KiB
Go
84 lines
1.7 KiB
Go
package netreq
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// Makes a GET request to the specified URL and returns the JSON response
|
|
// as a byte slice. If the request fails, it returns an error.
|
|
func GetJSON[T any](url string) ([]T, error) {
|
|
fmt.Println("Fetching:", url)
|
|
res, err := http.Get(url)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if res.StatusCode > 299 {
|
|
return nil, fmt.Errorf("status %d: %s", res.StatusCode, string(body))
|
|
}
|
|
|
|
// 1. Trim whitespace to find the first actual JSON character
|
|
trimmed := bytes.TrimSpace(body)
|
|
if len(trimmed) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
var result []T
|
|
|
|
// 2. Determine if we are looking at an Array [ ] or an Object { }
|
|
if trimmed[0] == '[' {
|
|
// It's already an array, unmarshal directly
|
|
err = json.Unmarshal(body, &result)
|
|
} else {
|
|
// It's a single object, unmarshal into a single instance and wrap it
|
|
var single T
|
|
err = json.Unmarshal(body, &single)
|
|
result = []T{single}
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse JSON: %w", err)
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// Download downloads a specified object at a given url and places it in
|
|
// the provided dest directory.
|
|
func Download(name string, path string, url string) error {
|
|
fullFilePath := filepath.Join(path, name)
|
|
if err := os.MkdirAll(path, os.ModeDir); err != nil {
|
|
return err
|
|
}
|
|
file, err := os.Create(fullFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
_, err = io.Copy(file, resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|