feat: initial goget release — modern IPv6-first download utility
This commit is contained in:
+454
@@ -0,0 +1,454 @@
|
||||
# API Reference
|
||||
|
||||
**goget** exposes a public Go library in `pkg/api/` for programmatic downloads, uploads, queue management, and configuration.
|
||||
|
||||
## Installation
|
||||
|
||||
```go
|
||||
import "codeberg.org/petrbalvin/goget/pkg/api"
|
||||
```
|
||||
|
||||
## Types
|
||||
|
||||
### `Client`
|
||||
|
||||
The main client for downloads and uploads. Created via `NewClient()`.
|
||||
|
||||
```go
|
||||
type Client struct { /* unexported */ }
|
||||
|
||||
func NewClient(opts ...ClientOption) *Client
|
||||
func (c *Client) Download(req *DownloadRequest) (*DownloadResult, error)
|
||||
func (c *Client) Upload(req *UploadRequest) (*UploadResult, error)
|
||||
func (c *Client) Close()
|
||||
```
|
||||
|
||||
### `ClientOption`
|
||||
|
||||
Functional options for client configuration.
|
||||
|
||||
```go
|
||||
func WithTimeout(d time.Duration) ClientOption
|
||||
func WithUserAgent(ua string) ClientOption
|
||||
func WithVerbose(v bool) ClientOption
|
||||
```
|
||||
|
||||
### `DownloadRequest`
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `URL` | `string` | URL to download (required) |
|
||||
| `Output` | `string` | Output file path (empty = auto-detect) |
|
||||
| `Resume` | `bool` | Resume interrupted download |
|
||||
| `Verbose` | `bool` | Enable verbose logging |
|
||||
|
||||
### `DownloadResult`
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `BytesDownloaded` | `int64` | Total bytes transferred |
|
||||
| `TotalSize` | `int64` | Total file size (-1 if unknown) |
|
||||
| `Speed` | `float64` | Average speed in bytes/second |
|
||||
| `Duration` | `time.Duration` | Total transfer time |
|
||||
| `OutputPath` | `string` | Path to saved file |
|
||||
| `Protocol` | `string` | Protocol used (e.g., "http") |
|
||||
| `IPVersion` | `int` | 4 or 6 |
|
||||
| `Resumed` | `bool` | True if download was resumed |
|
||||
| `Parallel` | `bool` | True if parallel chunks were used |
|
||||
| `ChunksCount` | `int` | Number of parallel chunks |
|
||||
|
||||
### `UploadRequest`
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `URL` | `string` | Destination URL (required) |
|
||||
| `FilePath` | `string` | Path to file to upload (required) |
|
||||
| `Method` | `string` | HTTP method: `"PUT"` or `"POST"` |
|
||||
| `Verbose` | `bool` | Enable verbose logging |
|
||||
|
||||
### `UploadResult`
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `BytesUploaded` | `int64` | Total bytes uploaded |
|
||||
| `Duration` | `time.Duration` | Total upload time |
|
||||
| `Protocol` | `string` | Protocol used |
|
||||
| `ResultURL` | `string` | Result URL (may differ from input after redirects) |
|
||||
|
||||
---
|
||||
|
||||
## Client
|
||||
|
||||
### `NewClient`
|
||||
|
||||
Creates a new goget client. Registers HTTP and FTP protocol handlers automatically.
|
||||
|
||||
```go
|
||||
func NewClient(opts ...ClientOption) *Client
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Effect |
|
||||
|---|---|
|
||||
| `WithTimeout(5 * time.Minute)` | Set request timeout (default: 30 minutes) |
|
||||
| `WithUserAgent("MyApp/1.0")` | Custom User-Agent header |
|
||||
| `WithVerbose(true)` | Enable verbose logging |
|
||||
|
||||
**Example:**
|
||||
```go
|
||||
client := api.NewClient(
|
||||
api.WithTimeout(10 * time.Minute),
|
||||
api.WithUserAgent("MyDownloader/1.0"),
|
||||
)
|
||||
defer client.Close()
|
||||
```
|
||||
|
||||
### `Client.Download`
|
||||
|
||||
Downloads a file from a URL.
|
||||
|
||||
```go
|
||||
func (c *Client) Download(req *DownloadRequest) (*DownloadResult, error)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `req.URL` | `string` | URL to download — supports http, https, ftp, sftp, file, data, gopher, gemini |
|
||||
| `req.Output` | `string` | Output path. Empty string uses the filename derived from the URL. |
|
||||
| `req.Resume` | `bool` | Resume an interrupted download if resume metadata exists |
|
||||
|
||||
**Returns:** `*DownloadResult` — bytes transferred, speed, duration, protocol info.
|
||||
|
||||
**Throws:**
|
||||
- `error` — if URL is empty or invalid
|
||||
- `error` — if protocol is unsupported
|
||||
- `*core.GogetError` — typed errors for network, protocol, timeout, auth, checksum failures
|
||||
|
||||
**Example:**
|
||||
```go
|
||||
result, err := client.Download(&api.DownloadRequest{
|
||||
URL: "https://example.com/file.zip",
|
||||
Output: "downloads/file.zip",
|
||||
Resume: true,
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Download failed: %v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("Downloaded %d bytes at %.1f KB/s", result.BytesDownloaded, result.Speed/1024)
|
||||
```
|
||||
|
||||
### `Client.Upload`
|
||||
|
||||
Uploads a file to a URL. The protocol handler must implement `core.Uploader`.
|
||||
|
||||
```go
|
||||
func (c *Client) Upload(req *UploadRequest) (*UploadResult, error)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `req.URL` | `string` | Destination URL (required) |
|
||||
| `req.FilePath` | `string` | Path to local file (required) |
|
||||
| `req.Method` | `string` | `"PUT"` or `"POST"` (default: `"PUT"`) |
|
||||
| `req.Verbose` | `bool` | Enable verbose logging |
|
||||
|
||||
**Returns:** `*UploadResult` — bytes uploaded, duration, protocol, result URL.
|
||||
|
||||
**Throws:**
|
||||
- `error` — if URL or file path is empty
|
||||
- `error` — if protocol does not support upload
|
||||
|
||||
**Example:**
|
||||
```go
|
||||
result, err := client.Upload(&api.UploadRequest{
|
||||
URL: "https://httpbin.org/put",
|
||||
FilePath: "./data.csv",
|
||||
Method: "PUT",
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Upload failed: %v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("Uploaded %d bytes", result.BytesUploaded)
|
||||
```
|
||||
|
||||
### `Client.Close`
|
||||
|
||||
Releases resources and cancels any pending operations.
|
||||
|
||||
```go
|
||||
func (c *Client) Close()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Convenience Functions
|
||||
|
||||
### `Download`
|
||||
|
||||
One-shot download. Creates a client, downloads, and closes.
|
||||
|
||||
```go
|
||||
func Download(urlStr, output string) (*DownloadResult, error)
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```go
|
||||
result, err := api.Download("https://example.com/file.zip", "output.zip")
|
||||
```
|
||||
|
||||
### `Upload`
|
||||
|
||||
One-shot upload. Creates a client, uploads, and closes.
|
||||
|
||||
```go
|
||||
func Upload(urlStr, filePath, method string) (*UploadResult, error)
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```go
|
||||
result, err := api.Upload("https://httpbin.org/put", "./data.csv", "PUT")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Queue API
|
||||
|
||||
### `QueueClient`
|
||||
|
||||
Manages a download queue persisted to a JSON file.
|
||||
|
||||
```go
|
||||
type QueueClient struct { /* unexported */ }
|
||||
|
||||
func NewQueueClient(queueFile string) (*QueueClient, error)
|
||||
func (qc *QueueClient) Add(urlStr, output string, priority int) string
|
||||
func (qc *QueueClient) List() []*queue.QueueItem
|
||||
func (qc *QueueClient) Stats() queue.QueueStats
|
||||
func (qc *QueueClient) Remove(id string) bool
|
||||
func (qc *QueueClient) ClearCompleted() int
|
||||
```
|
||||
|
||||
### `NewQueueClient`
|
||||
|
||||
```go
|
||||
func NewQueueClient(queueFile string) (*QueueClient, error)
|
||||
```
|
||||
|
||||
Creates a queue client backed by a JSON file.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `queueFile` | `string` | Path to the queue JSON file |
|
||||
|
||||
**Returns:** `*QueueClient`, `error` — error if the file cannot be read or created.
|
||||
|
||||
### `QueueClient.Add`
|
||||
|
||||
```go
|
||||
func (qc *QueueClient) Add(urlStr, output string, priority int) string
|
||||
```
|
||||
|
||||
Adds a URL to the queue.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `urlStr` | `string` | URL to download |
|
||||
| `output` | `string` | Output file path |
|
||||
| `priority` | `int` | Priority (1–10, higher = processed first) |
|
||||
|
||||
**Returns:** `string` — unique ID for the queued item.
|
||||
|
||||
### `QueueClient.List`
|
||||
|
||||
```go
|
||||
func (qc *QueueClient) List() []*queue.QueueItem
|
||||
```
|
||||
|
||||
Returns all items in the queue.
|
||||
|
||||
**Returns:** `[]*queue.QueueItem`
|
||||
|
||||
### `QueueClient.Stats`
|
||||
|
||||
```go
|
||||
func (qc *QueueClient) Stats() queue.QueueStats
|
||||
```
|
||||
|
||||
Returns queue statistics (total, pending, completed, failed counts).
|
||||
|
||||
### `QueueClient.Remove`
|
||||
|
||||
```go
|
||||
func (qc *QueueClient) Remove(id string) bool
|
||||
```
|
||||
|
||||
Removes an item from the queue by ID.
|
||||
|
||||
**Returns:** `bool` — true if the item was found and removed.
|
||||
|
||||
### `QueueClient.ClearCompleted`
|
||||
|
||||
```go
|
||||
func (qc *QueueClient) ClearCompleted() int
|
||||
```
|
||||
|
||||
Removes all completed items from the queue.
|
||||
|
||||
**Returns:** `int` — number of removed items.
|
||||
|
||||
---
|
||||
|
||||
## Metalink API
|
||||
|
||||
### `ParseMetalink`
|
||||
|
||||
Parses a local Metalink file.
|
||||
|
||||
```go
|
||||
func ParseMetalink(path string) (*metalink.Metalink, error)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `path` | `string` | Path to a local `.meta4` or `.metalink` file |
|
||||
|
||||
**Returns:** `*metalink.Metalink` — parsed metalink with sources, checksums, and metadata.
|
||||
|
||||
### `FetchMetalink`
|
||||
|
||||
Downloads and parses a Metalink from a URL.
|
||||
|
||||
```go
|
||||
func FetchMetalink(urlStr string) (*metalink.Metalink, error)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `urlStr` | `string` | URL pointing to a `.meta4` or `.metalink` file |
|
||||
|
||||
**Returns:** `*metalink.Metalink` — parsed metalink with sources, checksums, and metadata.
|
||||
|
||||
---
|
||||
|
||||
## Config API
|
||||
|
||||
### `LoadConfig`
|
||||
|
||||
```go
|
||||
func LoadConfig(path string) (*config.Config, error)
|
||||
```
|
||||
|
||||
Loads the TOML configuration file. Returns default config if the file does not exist.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `path` | `string` | Path to config file (empty = default location) |
|
||||
|
||||
**Returns:** `*config.Config`, `error`
|
||||
|
||||
### `DefaultConfig`
|
||||
|
||||
```go
|
||||
func DefaultConfig() *config.Config
|
||||
```
|
||||
|
||||
Returns the default configuration values.
|
||||
|
||||
### `ParseSpeed`
|
||||
|
||||
```go
|
||||
func ParseSpeed(s string) int64
|
||||
```
|
||||
|
||||
Parses a speed string like `"10MB/s"` into bytes per second.
|
||||
|
||||
| Input | Output |
|
||||
|---|---|
|
||||
| `"1MB/s"` | `1000000` |
|
||||
| `"500KB/s"` | `500000` |
|
||||
| `"1GB/s"` | `1000000000` |
|
||||
|
||||
---
|
||||
|
||||
## Version
|
||||
|
||||
### `Version`
|
||||
|
||||
```go
|
||||
func Version() string
|
||||
```
|
||||
|
||||
Returns the current goget version.
|
||||
|
||||
---
|
||||
|
||||
## Full Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"codeberg.org/petrbalvin/goget/pkg/api"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create client with custom timeout
|
||||
client := api.NewClient(
|
||||
api.WithTimeout(5 * time.Minute),
|
||||
api.WithVerbose(true),
|
||||
)
|
||||
defer client.Close()
|
||||
|
||||
// Download
|
||||
result, err := client.Download(&api.DownloadRequest{
|
||||
URL: "https://example.com/large-file.iso",
|
||||
Output: "./downloads/large-file.iso",
|
||||
Resume: true,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("download failed: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Downloaded %d bytes in %v\n", result.BytesDownloaded, result.Duration)
|
||||
fmt.Printf("Average speed: %.1f MB/s\n", result.Speed/1024/1024)
|
||||
fmt.Printf("Protocol: %s (IPv%d)\n", result.Protocol, result.IPVersion)
|
||||
|
||||
if result.Resumed {
|
||||
fmt.Println("Download was resumed from previous state")
|
||||
}
|
||||
if result.Parallel {
|
||||
fmt.Printf("Used %d parallel chunks\n", result.ChunksCount)
|
||||
}
|
||||
|
||||
// Queue a download
|
||||
qc, err := api.NewQueueClient("./queue.json")
|
||||
if err != nil {
|
||||
log.Fatalf("queue init failed: %v", err)
|
||||
}
|
||||
|
||||
id := qc.Add("https://example.com/another.zip", "./downloads/", 5)
|
||||
fmt.Printf("Queued item ID: %s\n", id)
|
||||
fmt.Printf("Queue stats: %+v\n", qc.Stats())
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user