mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-01 22:53:05 +02:00
This is a large-scale refactoring across the codebase that replaces the custom `gperr.Error` type with Go's standard `error` interface. The changes include: - Replacing `gperr.Error` return types with `error` in function signatures - Using `errors.New()` and `fmt.Errorf()` instead of `gperr.New()` and `gperr.Errorf()` - Using `%w` format verb for error wrapping instead of `.With()` method - Replacing `gperr.Subject()` calls with `gperr.PrependSubject()` - Converting error logging from `gperr.Log*()` functions to zerolog's `.Err().Msg()` pattern - Update NewLogger to handle multiline error message - Updating `goutils` submodule to latest commit This refactoring aligns with Go idioms and removes the dependency on custom error handling abstractions in favor of standard library patterns.
qBittorrent Integration Package
This package provides a qBittorrent widget for the GoDoxy homepage dashboard, enabling real-time monitoring of torrent status and transfer statistics.
Warning
This package is a work in progress and is not stable.
Overview
The internal/homepage/integrations/qbittorrent package implements the widgets.Widget interface for qBittorrent. It provides functionality to connect to a qBittorrent instance and fetch transfer information.
Architecture
Core Components
integrations/qbittorrent/
├── client.go # Client and API methods
├── transfer_info.go # Transfer info widget data
└── version.go # Version checking
└── logs.go # Log fetching
Main Types
type Client struct {
URL string
Username string
Password string
}
API Reference
Client Methods
Initialize
Connects to the qBittorrent API and verifies authentication.
func (c *Client) Initialize(ctx context.Context, url string, cfg map[string]any) error
Parameters:
ctx- Context for the HTTP requesturl- Base URL of the qBittorrent instancecfg- Configuration map containingusernameandpassword
Returns:
error- Connection or authentication error
Example:
client := &qbittorrent.Client{}
err := client.Initialize(ctx, "http://localhost:8080", map[string]any{
"username": "admin",
"password": "your-password",
})
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
Data
Returns current transfer statistics as name-value pairs.
func (c *Client) Data(ctx context.Context) ([]widgets.NameValue, error)
Returns:
[]widgets.NameValue- Transfer statisticserror- API request error
Example:
data, err := client.Data(ctx)
if err != nil {
log.Fatal(err)
}
for _, nv := range data {
fmt.Printf("%s: %s\n", nv.Name, nv.Value)
}
// Output:
// Status: connected
// Download: 1.5 GB
// Upload: 256 MB
// Download Speed: 5.2 MB/s
// Upload Speed: 1.1 MB/s
Internal Methods
doRequest
Performs an HTTP request to the qBittorrent API.
func (c *Client) doRequest(ctx context.Context, method, endpoint string, query url.Values, body io.Reader) (*http.Response, error)
jsonRequest
Performs a JSON API request and unmarshals the response.
func jsonRequest[T any](ctx context.Context, client *Client, endpoint string, query url.Values) (result T, err error)
Data Types
TransferInfo
Represents transfer statistics from qBittorrent.
type TransferInfo struct {
ConnectionStatus string `json:"connection_status"`
SessionDownloads uint64 `json:"dl_info_data"`
SessionUploads uint64 `json:"up_info_data"`
DownloadSpeed uint64 `json:"dl_info_speed"`
UploadSpeed uint64 `json:"up_info_speed"`
}
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/v2/transfer/info |
GET | Get transfer statistics |
/api/v2/app/version |
GET | Get qBittorrent version |
Usage Example
Complete Widget Usage
package main
import (
"context"
"fmt"
"github.com/yusing/godoxy/internal/homepage/integrations/qbittorrent"
"github.com/yusing/godoxy/internal/homepage/widgets"
)
func main() {
ctx := context.Background()
// Create and initialize client
client := &qbittorrent.Client{}
err := client.Initialize(ctx, "http://localhost:8080", map[string]any{
"username": "admin",
"password": "password123",
})
if err != nil {
fmt.Printf("Connection failed: %v\n", err)
return
}
// Get transfer data
data, err := client.Data(ctx)
if err != nil {
fmt.Printf("Failed to get data: %v\n", err)
return
}
// Display in dashboard format
fmt.Println("qBittorrent Status:")
fmt.Println(strings.Repeat("-", 30))
for _, nv := range data {
fmt.Printf(" %-15s %s\n", nv.Name+":", nv.Value)
}
}
Integration with Homepage Widgets
graph TD
A[Homepage Dashboard] --> B[Widget Config]
B --> C{qBittorrent Provider}
C --> D[Create Client]
D --> E[Initialize with credentials]
E --> F[Fetch Transfer Info]
F --> G[Format as NameValue pairs]
G --> H[Render in UI]
Widget Configuration
widgets:
- provider: qbittorrent
config:
url: http://localhost:8080
username: admin
password: password123
Error Handling
// Handle HTTP errors
resp, err := client.doRequest(ctx, http.MethodGet, endpoint, query, body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, widgets.ErrHTTPStatus.Subject(resp.Status)
}
Related Packages
internal/homepage/widgets- Widget framework and interfacegithub.com/bytedance/sonic- JSON serializationgithub.com/yusing/goutils/strings- String utilities for formatting