tstor/pkg/qbittorrent/transfer.go
2024-09-08 21:39:11 +03:00

209 lines
6.1 KiB
Go

package qbittorrent
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
)
type TransferStatusBar struct {
ConnectionStatus string `json:"connection_status,omitempty"`
DhtNodes int `json:"dht_nodes,omitempty"`
DlInfoData int64 `json:"dl_info_data,omitempty"`
DlInfoSpeed int `json:"dl_info_speed,omitempty"`
DlRateLimit int `json:"dl_rate_limit,omitempty"`
UpInfoData int `json:"up_info_data,omitempty"`
UpInfoSpeed int `json:"up_info_speed,omitempty"`
UpRateLimit int `json:"up_rate_limit,omitempty"`
Queueing bool `json:"queueing,omitempty"`
UseAltSpeedLimits bool `json:"use_alt_speed_limits,omitempty"`
RefreshInterval int `json:"refresh_interval,omitempty"`
}
type Transfer interface {
// GlobalStatusBar usually see in qBittorrent status bar
GlobalStatusBar(ctx context.Context) (*TransferStatusBar, error)
// BanPeers the peer to ban, or multiple peers separated by a pipe.
// each peer is host:port
BanPeers(ctx context.Context, peers []string) error
// GetSpeedLimitsMode get alternative speed limits state
GetSpeedLimitsMode(ctx context.Context) (string, error)
// ToggleSpeedLimitsMode toggle alternative speed limits
ToggleSpeedLimitsMode(ctx context.Context) error
// GetGlobalUploadLimit get global upload limit, the response is the value of current global download speed
// limit in bytes/second; this value will be zero if no limit is applied.
GetGlobalUploadLimit(ctx context.Context) (string, error)
// SetGlobalUploadLimit set global upload limit, set in bytes/second
SetGlobalUploadLimit(ctx context.Context, limit int) error
// GetGlobalDownloadLimit get global download limit, the response is the value of current global download speed
// limit in bytes/second; this value will be zero if no limit is applied.
GetGlobalDownloadLimit(ctx context.Context) (string, error)
// SetGlobalDownloadLimit set global download limit, set in bytes/second
SetGlobalDownloadLimit(ctx context.Context, limit int) error
}
func (c *client) GlobalStatusBar(ctx context.Context) (*TransferStatusBar, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Transfer.GlobalStatusBar")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/transfer/info", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
})
if err != nil {
return nil, err
}
if result.code != 200 {
return nil, errors.New("get global transfer status bar failed: " + string(result.body))
}
var data = new(TransferStatusBar)
if err := json.Unmarshal(result.body, data); err != nil {
return nil, err
}
return data, nil
}
func (c *client) BanPeers(ctx context.Context, peers []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Transfer.BanPeers")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/transfer/banPeers", c.config.Address)
var form = url.Values{}
form.Add("peers", strings.Join(peers, "|"))
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
method: http.MethodPost,
body: strings.NewReader(form.Encode()),
})
if err != nil {
return err
}
if result.code != 200 {
return errors.New("ban peers failed: " + string(result.body))
}
return nil
}
func (c *client) GetSpeedLimitsMode(ctx context.Context) (string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Transfer.GetSpeedLimitsMode")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/transfer/speedLimitsMode", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
})
if err != nil {
return "", err
}
if result.code != 200 {
return "", errors.New("ban peers failed: " + string(result.body))
}
return string(result.body), nil
}
func (c *client) ToggleSpeedLimitsMode(ctx context.Context) error {
ctx, span := trace.Start(ctx, "qbittorrent.Transfer.ToggleSpeedLimitsMode")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/transfer/toggleSpeedLimitsMode", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
method: http.MethodPost,
})
if err != nil {
return err
}
if result.code != 200 {
return errors.New("ban peers failed: " + string(result.body))
}
return nil
}
func (c *client) GetGlobalUploadLimit(ctx context.Context) (string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Transfer.GetGlobalUploadLimit")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/transfer/uploadLimit", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
})
if err != nil {
return "", err
}
if result.code != 200 {
return "", errors.New("get global upload limit failed: " + string(result.body))
}
return string(result.body), nil
}
func (c *client) SetGlobalUploadLimit(ctx context.Context, limit int) error {
ctx, span := trace.Start(ctx, "qbittorrent.Transfer.SetGlobalUploadLimit")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/transfer/setUploadLimit?limit=%d", c.config.Address, limit)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
})
if err != nil {
return err
}
if result.code != 200 {
return errors.New("set global upload limit failed: " + string(result.body))
}
return nil
}
func (c *client) GetGlobalDownloadLimit(ctx context.Context) (string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Transfer.GetGlobalDownloadLimit")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/transfer/downloadLimit", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
})
if err != nil {
return "", err
}
if result.code != 200 {
return "", errors.New("get global download limit failed: " + string(result.body))
}
return string(result.body), nil
}
func (c *client) SetGlobalDownloadLimit(ctx context.Context, limit int) error {
ctx, span := trace.Start(ctx, "qbittorrent.Transfer.SetGlobalDownloadLimit")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/transfer/setDownloadLimit?limit=%d", c.config.Address, limit)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
})
if err != nil {
return err
}
if result.code != 200 {
return errors.New("set global download limit failed: " + string(result.body))
}
return nil
}