qbittorrent tracing

This commit is contained in:
royalcat 2024-09-08 21:39:11 +03:00
parent abcd073643
commit 0bc6227427
10 changed files with 353 additions and 122 deletions

View file

@ -240,6 +240,9 @@ type Preferences struct {
}
func (c *client) Version(ctx context.Context) (string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Application.Version")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/app/version", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
@ -257,6 +260,9 @@ func (c *client) Version(ctx context.Context) (string, error) {
}
func (c *client) WebApiVersion(ctx context.Context) (string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Application.WebApiVersion")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/app/webapiVersion", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -273,6 +279,9 @@ func (c *client) WebApiVersion(ctx context.Context) (string, error) {
}
func (c *client) BuildInfo(ctx context.Context) (*BuildInfo, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Application.BuildInfo")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/app/buildInfo", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -294,6 +303,9 @@ func (c *client) BuildInfo(ctx context.Context) (*BuildInfo, error) {
}
func (c *client) Shutdown(ctx context.Context) error {
ctx, span := trace.Start(ctx, "qbittorrent.Application.Shutdown")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/app/shutdown", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
method: http.MethodPost,
@ -311,6 +323,9 @@ func (c *client) Shutdown(ctx context.Context) error {
}
func (c *client) GetPreferences(ctx context.Context) (*Preferences, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Application.GetPreferences")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/app/preferences", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -332,6 +347,9 @@ func (c *client) GetPreferences(ctx context.Context) (*Preferences, error) {
}
func (c *client) SetPreferences(ctx context.Context, prefs *Preferences) error {
ctx, span := trace.Start(ctx, "qbittorrent.Application.SetPreferences")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/app/setPreferences", c.config.Address)
data, err := json.Marshal(prefs)
if err != nil {
@ -359,6 +377,9 @@ func (c *client) SetPreferences(ctx context.Context, prefs *Preferences) error {
}
func (c *client) DefaultSavePath(ctx context.Context) (string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Application.DefaultSavePath")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/app/defaultSavePath", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,

View file

@ -19,6 +19,9 @@ type Authentication interface {
}
func (c *client) Login(ctx context.Context) error {
ctx, span := trace.Start(ctx, "qbittorrent.Authentication.Login")
defer span.End()
if c.config.Username == "" || c.config.Password == "" {
return errors.New("username or password is empty")
}
@ -51,8 +54,8 @@ func (c *client) Login(ctx context.Context) error {
return errors.New("login failed: " + string(result.body))
}
if c.cookieJar == nil {
c.cookieJar, err = cookiejar.New(nil)
if c.client.Jar == nil {
c.client.Jar, err = cookiejar.New(nil)
if err != nil {
return err
}
@ -62,12 +65,15 @@ func (c *client) Login(ctx context.Context) error {
if err != nil {
return err
}
c.cookieJar.SetCookies(u, result.cookies)
c.client.Jar.SetCookies(u, result.cookies)
return nil
}
func (c *client) Logout(ctx context.Context) error {
ctx, span := trace.Start(ctx, "qbittorrent.Authentication.Logout")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/auth/logout", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
method: http.MethodPost,

View file

@ -1,6 +1,16 @@
package qbittorrent
import "context"
import (
"context"
"crypto/tls"
"net"
"net/http"
"time"
"go.opentelemetry.io/otel"
)
var trace = otel.Tracer("git.kmsign.ru/royalcat/tstor/pkg/qbittorrent")
// Client represents a qBittorrent client
type Client interface {
@ -23,12 +33,12 @@ type Client interface {
}
func NewClient(ctx context.Context, cfg *Config) (Client, error) {
var c = &client{config: cfg, clientPool: newClientPool(cfg.ConnectionMaxIdles, cfg.ConnectionTimeout)}
var c = &client{config: cfg, client: newClient(cfg.ConnectionMaxIdles, cfg.ConnectionTimeout)}
return c, nil
}
func LoginClient(ctx context.Context, cfg *Config) (Client, error) {
var c = &client{config: cfg, clientPool: newClientPool(cfg.ConnectionMaxIdles, cfg.ConnectionTimeout)}
var c = &client{config: cfg, client: newClient(cfg.ConnectionMaxIdles, cfg.ConnectionTimeout)}
if err := c.Authentication().Login(ctx); err != nil {
return nil, err
}
@ -37,3 +47,26 @@ func LoginClient(ctx context.Context, cfg *Config) (Client, error) {
}
return c, nil
}
// newClient creates and returns a new clientPool
func newClient(maxIdle int, timeout time.Duration) *http.Client {
if maxIdle == 0 {
maxIdle = 128
}
if timeout == 0 {
timeout = time.Second * 3
}
return &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
MaxIdleConns: maxIdle,
},
Timeout: timeout,
}
}

View file

@ -5,7 +5,6 @@ import (
"fmt"
"io"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
"time"
@ -28,8 +27,7 @@ var _ Client = (*client)(nil)
type client struct {
config *Config
clientPool *clientPool
cookieJar *cookiejar.Jar
client *http.Client
}
func (c *client) Authentication() Authentication {
@ -81,13 +79,8 @@ func (c *client) doRequest(ctx context.Context, data *requestData) (*responseRes
for key, value := range c.config.CustomHeaders {
request.Header.Set(key, value)
}
hc := c.clientPool.GetClient()
defer c.clientPool.ReleaseClient(hc)
if c.cookieJar != nil {
hc.Jar = c.cookieJar
}
resp, err := hc.Do(request)
resp, err := c.client.Do(request)
if err != nil {
return nil, err
}
@ -102,14 +95,14 @@ func (c *client) doRequest(ctx context.Context, data *requestData) (*responseRes
}
func (c *client) cookies() (string, error) {
if c.cookieJar == nil {
if c.client.Jar == nil {
return "", ErrNotLogin
}
u, err := url.Parse(c.config.Address)
if err != nil {
return "", err
}
cookies := c.cookieJar.Cookies(u)
cookies := c.client.Jar.Cookies(u)
if len(cookies) == 0 {
return "", ErrNotLogin
}

View file

@ -1,53 +0,0 @@
package qbittorrent
import (
"crypto/tls"
"net"
"net/http"
"sync"
"time"
)
// clientPool defines a pool of HTTP clients
type clientPool struct {
// pool store http.Client instances
*sync.Pool
}
// newClientPool creates and returns a new clientPool
func newClientPool(maxIdle int, timeout time.Duration) *clientPool {
if maxIdle == 0 {
maxIdle = 128
}
if timeout == 0 {
timeout = time.Second * 3
}
return &clientPool{
Pool: &sync.Pool{
New: func() any {
return &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
MaxIdleConns: maxIdle,
},
Timeout: timeout,
}
},
},
}
}
// GetClient retrieves a http.Client from the pool
func (p *clientPool) GetClient() *http.Client {
return p.Get().(*http.Client)
}
// ReleaseClient returns a http.Client back to the pool
func (p *clientPool) ReleaseClient(client *http.Client) {
p.Put(client)
}

View file

@ -36,6 +36,9 @@ type Log interface {
}
func (c *client) GetLog(ctx context.Context, option *LogOption) ([]*LogEntry, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Log.GetLog")
defer span.End()
var form = url.Values{}
err := encoder.Encode(option, form)
if err != nil {
@ -64,6 +67,9 @@ func (c *client) GetLog(ctx context.Context, option *LogOption) ([]*LogEntry, er
}
func (c *client) GetPeerLog(ctx context.Context, lastKnownId int) ([]*LogEntry, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Log.GetPeerLog")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/log/peers", c.config.Address)
var form = url.Values{}
form.Add("last_known_id", strconv.Itoa(lastKnownId))

View file

@ -87,6 +87,9 @@ type RssAutoDownloadingRuleDef struct {
}
func (c *client) AddFolder(ctx context.Context, path string) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.AddFolder")
defer span.End()
var formData = url.Values{}
formData.Add("path", path)
var apiUrl = fmt.Sprintf("%s/api/v2/rss/addFolder", c.config.Address)
@ -106,6 +109,9 @@ func (c *client) AddFolder(ctx context.Context, path string) error {
}
func (c *client) AddFeed(ctx context.Context, opt *RssAddFeedOption) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.AddFeed")
defer span.End()
var formData = url.Values{}
err := encoder.Encode(opt, formData)
if err != nil {
@ -128,6 +134,9 @@ func (c *client) AddFeed(ctx context.Context, opt *RssAddFeedOption) error {
}
func (c *client) RemoveItem(ctx context.Context, path string) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.RemoveItem")
defer span.End()
var formData = url.Values{}
formData.Add("path", path)
var apiUrl = fmt.Sprintf("%s/api/v2/rss/removeItem", c.config.Address)
@ -147,6 +156,9 @@ func (c *client) RemoveItem(ctx context.Context, path string) error {
}
func (c *client) MoveItem(ctx context.Context, srcPath, destPath string) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.MoveItem")
defer span.End()
var formData = url.Values{}
formData.Add("itemPath", srcPath)
formData.Add("destPath", destPath)
@ -167,6 +179,9 @@ func (c *client) MoveItem(ctx context.Context, srcPath, destPath string) error {
}
func (c *client) GetItems(ctx context.Context, withData bool) (map[string]interface{}, error) {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.GetItems")
defer span.End()
var apiUrl = fmt.Sprintf("%s/api/v2/rss/items?withData=%t", c.config.Address, withData)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -185,6 +200,9 @@ func (c *client) GetItems(ctx context.Context, withData bool) (map[string]interf
}
func (c *client) MarkAsRead(ctx context.Context, opt *RssMarkAsReadOption) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.MarkAsRead")
defer span.End()
var formData = url.Values{}
err := encoder.Encode(opt, formData)
if err != nil {
@ -207,6 +225,9 @@ func (c *client) MarkAsRead(ctx context.Context, opt *RssMarkAsReadOption) error
}
func (c *client) RefreshItem(ctx context.Context, itemPath string) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.RefreshItem")
defer span.End()
var formData = url.Values{}
formData.Add("itemPath", itemPath)
var apiUrl = fmt.Sprintf("%s/api/v2/rss/refreshItem", c.config.Address)
@ -226,6 +247,9 @@ func (c *client) RefreshItem(ctx context.Context, itemPath string) error {
}
func (c *client) SetAutoDownloadingRule(ctx context.Context, ruleName string, ruleDef *RssAutoDownloadingRuleDef) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.SetAutoDownloadingRule")
defer span.End()
var formData = url.Values{}
formData.Add("ruleName", ruleName)
ruleDefBytes, err := json.Marshal(ruleDef)
@ -250,6 +274,9 @@ func (c *client) SetAutoDownloadingRule(ctx context.Context, ruleName string, ru
}
func (c *client) RenameAutoDownloadingRule(ctx context.Context, ruleName, newRuleName string) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.RenameAutoDownloadingRule")
defer span.End()
var formData = url.Values{}
formData.Add("ruleName", ruleName)
formData.Add("newRuleName", newRuleName)
@ -270,6 +297,9 @@ func (c *client) RenameAutoDownloadingRule(ctx context.Context, ruleName, newRul
}
func (c *client) RemoveAutoDownloadingRule(ctx context.Context, ruleName string) error {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.RemoveAutoDownloadingRule")
defer span.End()
var formData = url.Values{}
formData.Add("ruleName", ruleName)
var apiUrl = fmt.Sprintf("%s/api/v2/rss/removeRule", c.config.Address)
@ -289,6 +319,9 @@ func (c *client) RemoveAutoDownloadingRule(ctx context.Context, ruleName string)
}
func (c *client) GetAllAutoDownloadingRules(ctx context.Context) (map[string]*RssAutoDownloadingRuleDef, error) {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.GetAllAutoDownloadingRules")
defer span.End()
var apiUrl = fmt.Sprintf("%s/api/v2/rss/matchingArticles", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -305,6 +338,9 @@ func (c *client) GetAllAutoDownloadingRules(ctx context.Context) (map[string]*Rs
}
func (c *client) GetAllArticlesMatchingRule(ctx context.Context, ruleName string) (map[string][]string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.RSS.GetAllArticlesMatchingRule")
defer span.End()
var formData = url.Values{}
formData.Add("ruleName", ruleName)
var apiUrl = fmt.Sprintf("%s/api/v2/rss/matchingArticles?%s", c.config.Address, formData.Encode())

View file

@ -76,6 +76,9 @@ type SyncTorrentPeer struct {
}
func (c *client) MainData(ctx context.Context, rid int) (*SyncMainData, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Sync.MainData")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/sync/maindata?rid=%d", c.config.Address, rid)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -97,6 +100,9 @@ func (c *client) MainData(ctx context.Context, rid int) (*SyncMainData, error) {
}
func (c *client) TorrentPeersData(ctx context.Context, hash string, rid int) (*SyncTorrentPeers, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Sync.TorrentPeersData")
defer span.End()
var formData = url.Values{}
formData.Add("hash", hash)
formData.Add("rid", strconv.Itoa(rid))

View file

@ -138,6 +138,30 @@ type TorrentOption struct {
Hashes []string `schema:"-"`
}
type TorrentState string
const (
TorrentStateError TorrentState = "error"
TorrentStateMissingFiles TorrentState = "missingFiles"
TorrentStateUploading TorrentState = "uploading"
TorrentStatePausedUP TorrentState = "pausedUP"
TorrentStateQueuedUP TorrentState = "queuedUP"
TorrentStateStalledUP TorrentState = "stalledUP"
TorrentStateCheckingUP TorrentState = "checkingUP"
TorrentStateForcedUP TorrentState = "forcedUP"
TorrentStateAllocating TorrentState = "allocating"
TorrentStateDownloading TorrentState = "downloading"
TorrentStateMetaDL TorrentState = "metaDL"
TorrentStatePausedDL TorrentState = "pausedDL"
TorrentStateQueuedDL TorrentState = "queuedDL"
TorrentStateStalledDL TorrentState = "stalledDL"
TorrentStateCheckingDL TorrentState = "checkingDL"
TorrentStateForcedDL TorrentState = "forcedDL"
TorrentStateCheckingResumeData TorrentState = "checkingResumeData"
TorrentStateMoving TorrentState = "moving"
TorrentStateUnknown TorrentState = "unknown"
)
type TorrentInfo struct {
AddedOn int `json:"added_on"`
AmountLeft int `json:"amount_left"`
@ -179,7 +203,7 @@ type TorrentInfo struct {
SeenComplete int `json:"seen_complete"`
SeqDl bool `json:"seq_dl"`
Size int `json:"size"`
State string `json:"state"`
State TorrentState `json:"state"`
SuperSeeding bool `json:"super_seeding"`
Tags string `json:"tags"`
TimeActive int `json:"time_active"`
@ -294,6 +318,9 @@ type TorrentCategory struct {
}
func (c *client) GetTorrents(ctx context.Context, opt *TorrentOption) ([]*TorrentInfo, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetTorrents")
defer span.End()
var formData = url.Values{}
err := encoder.Encode(opt, formData)
if err != nil {
@ -324,6 +351,9 @@ func (c *client) GetTorrents(ctx context.Context, opt *TorrentOption) ([]*Torren
}
func (c *client) GetProperties(ctx context.Context, hash string) (*TorrentProperties, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetProperties")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/torrents/properties?hash=%s", c.config.Address, hash)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -345,6 +375,9 @@ func (c *client) GetProperties(ctx context.Context, hash string) (*TorrentProper
}
func (c *client) GetTrackers(ctx context.Context, hash string) ([]*TorrentTracker, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetTrackers")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/torrents/trackers?hash=%s", c.config.Address, hash)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -366,6 +399,9 @@ func (c *client) GetTrackers(ctx context.Context, hash string) ([]*TorrentTracke
}
func (c *client) GetWebSeeds(ctx context.Context, hash string) ([]*TorrentWebSeed, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetWebSeeds")
defer span.End()
apiUrl := fmt.Sprintf("%s/api/v2/torrents/webseeds?hash=%s", c.config.Address, hash)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -395,6 +431,9 @@ func sliceItoa[E constraints.Integer](in []E) []string {
}
func (c *client) GetContents(ctx context.Context, hash string, indexes ...int) ([]*TorrentContent, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetContents")
defer span.End()
var apiUrl string
if len(indexes) != 0 {
@ -422,6 +461,9 @@ func (c *client) GetContents(ctx context.Context, hash string, indexes ...int) (
}
func (c *client) GetPiecesStates(ctx context.Context, hash string) ([]int, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetPiecesStates")
defer span.End()
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/pieceStates?hash=%s", c.config.Address, hash)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -443,6 +485,9 @@ func (c *client) GetPiecesStates(ctx context.Context, hash string) ([]int, error
}
func (c *client) GetPiecesHashes(ctx context.Context, hash string) ([]string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetPiecesHashes")
defer span.End()
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/pieceHashes?hash=%s", c.config.Address, hash)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -464,6 +509,9 @@ func (c *client) GetPiecesHashes(ctx context.Context, hash string) ([]string, er
}
func (c *client) PauseTorrents(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.PauseTorrents")
defer span.End()
if len(hashes) == 0 {
return errors.New("no torrent hashes provided")
}
@ -486,6 +534,9 @@ func (c *client) PauseTorrents(ctx context.Context, hashes []string) error {
}
func (c *client) ResumeTorrents(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.ResumeTorrents")
defer span.End()
if len(hashes) == 0 {
return errors.New("no torrent hashes provided")
}
@ -508,6 +559,9 @@ func (c *client) ResumeTorrents(ctx context.Context, hashes []string) error {
}
func (c *client) DeleteTorrents(ctx context.Context, hashes []string, deleteFile bool) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.DeleteTorrents")
defer span.End()
if len(hashes) == 0 {
return errors.New("no torrent hashes provided")
}
@ -531,6 +585,9 @@ func (c *client) DeleteTorrents(ctx context.Context, hashes []string, deleteFile
}
func (c *client) RecheckTorrents(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.RecheckTorrents")
defer span.End()
if len(hashes) == 0 {
return errors.New("no torrent hashes provided")
}
@ -553,6 +610,9 @@ func (c *client) RecheckTorrents(ctx context.Context, hashes []string) error {
}
func (c *client) ReAnnounceTorrents(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.ReAnnounceTorrents")
defer span.End()
if len(hashes) == 0 {
return errors.New("no torrent hashes provided")
}
@ -575,6 +635,9 @@ func (c *client) ReAnnounceTorrents(ctx context.Context, hashes []string) error
}
func (c *client) AddNewTorrent(ctx context.Context, opt *TorrentAddOption) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.AddNewTorrent")
defer span.End()
var requestBody bytes.Buffer
var writer = multipart.NewWriter(&requestBody)
@ -662,6 +725,9 @@ func (c *client) AddNewTorrent(ctx context.Context, opt *TorrentAddOption) error
}
func (c *client) AddTrackers(ctx context.Context, hash string, urls []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.AddTrackers")
defer span.End()
if len(urls) == 0 {
return errors.New("no torrent tracker provided")
}
@ -685,6 +751,9 @@ func (c *client) AddTrackers(ctx context.Context, hash string, urls []string) er
}
func (c *client) EditTrackers(ctx context.Context, hash, origUrl, newUrl string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.EditTrackers")
defer span.End()
var formData = url.Values{}
formData.Add("origUrl", origUrl)
formData.Add("newUrl", newUrl)
@ -706,6 +775,9 @@ func (c *client) EditTrackers(ctx context.Context, hash, origUrl, newUrl string)
}
func (c *client) RemoveTrackers(ctx context.Context, hash string, urls []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.RemoveTrackers")
defer span.End()
if len(urls) == 0 {
return errors.New("no torrent tracker provided")
}
@ -729,6 +801,9 @@ func (c *client) RemoveTrackers(ctx context.Context, hash string, urls []string)
}
func (c *client) AddPeers(ctx context.Context, hashes []string, peers []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.AddPeers")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -755,6 +830,9 @@ func (c *client) AddPeers(ctx context.Context, hashes []string, peers []string)
}
func (c *client) IncreasePriority(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.IncreasePriority")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -777,6 +855,9 @@ func (c *client) IncreasePriority(ctx context.Context, hashes []string) error {
}
func (c *client) DecreasePriority(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.DecreasePriority")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -799,6 +880,9 @@ func (c *client) DecreasePriority(ctx context.Context, hashes []string) error {
}
func (c *client) MaxPriority(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.MaxPriority")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -821,6 +905,9 @@ func (c *client) MaxPriority(ctx context.Context, hashes []string) error {
}
func (c *client) MinPriority(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.MinPriority")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -843,6 +930,9 @@ func (c *client) MinPriority(ctx context.Context, hashes []string) error {
}
func (c *client) SetFilePriority(ctx context.Context, hash string, id string, priority int) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetFilePriority")
defer span.End()
var formData = url.Values{}
formData.Add("hash", hash)
formData.Add("id", id)
@ -864,6 +954,9 @@ func (c *client) SetFilePriority(ctx context.Context, hash string, id string, pr
}
func (c *client) GetDownloadLimit(ctx context.Context, hashes []string) (map[string]int, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetDownloadLimit")
defer span.End()
if len(hashes) == 0 {
return nil, errors.New("no hashes provided")
}
@ -888,6 +981,9 @@ func (c *client) GetDownloadLimit(ctx context.Context, hashes []string) (map[str
}
func (c *client) SetDownloadLimit(ctx context.Context, hashes []string, limit int) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetDownloadLimit")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -911,6 +1007,9 @@ func (c *client) SetDownloadLimit(ctx context.Context, hashes []string, limit in
}
func (c *client) SetShareLimit(ctx context.Context, hashes []string, ratioLimit float64, seedingTimeLimit, inactiveSeedingTimeLimit int) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetShareLimit")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -936,6 +1035,9 @@ func (c *client) SetShareLimit(ctx context.Context, hashes []string, ratioLimit
}
func (c *client) GetUploadLimit(ctx context.Context, hashes []string) (map[string]int, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetUploadLimit")
defer span.End()
if len(hashes) == 0 {
return nil, errors.New("no hashes provided")
}
@ -960,6 +1062,9 @@ func (c *client) GetUploadLimit(ctx context.Context, hashes []string) (map[strin
}
func (c *client) SetUploadLimit(ctx context.Context, hashes []string, limit int) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetUploadLimit")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -983,6 +1088,9 @@ func (c *client) SetUploadLimit(ctx context.Context, hashes []string, limit int)
}
func (c *client) SetLocation(ctx context.Context, hashes []string, location string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetLocation")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -1006,6 +1114,9 @@ func (c *client) SetLocation(ctx context.Context, hashes []string, location stri
}
func (c *client) SetName(ctx context.Context, hash string, name string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetName")
defer span.End()
var formData = url.Values{}
formData.Add("hash", hash)
formData.Add("name", name)
@ -1026,6 +1137,9 @@ func (c *client) SetName(ctx context.Context, hash string, name string) error {
}
func (c *client) SetCategory(ctx context.Context, hashes []string, category string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetCategory")
defer span.End()
if len(hashes) == 0 {
return errors.New("no hashes provided")
}
@ -1049,6 +1163,9 @@ func (c *client) SetCategory(ctx context.Context, hashes []string, category stri
}
func (c *client) GetCategories(ctx context.Context) (map[string]*TorrentCategory, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetCategories")
defer span.End()
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/categories", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -1067,6 +1184,9 @@ func (c *client) GetCategories(ctx context.Context) (map[string]*TorrentCategory
}
func (c *client) AddNewCategory(ctx context.Context, category, savePath string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.AddNewCategory")
defer span.End()
var formData = url.Values{}
formData.Add("category", category)
formData.Add("savePath", savePath)
@ -1087,6 +1207,9 @@ func (c *client) AddNewCategory(ctx context.Context, category, savePath string)
}
func (c *client) EditCategory(ctx context.Context, category, savePath string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.EditCategory")
defer span.End()
var formData = url.Values{}
formData.Add("category", category)
formData.Add("savePath", savePath)
@ -1107,6 +1230,9 @@ func (c *client) EditCategory(ctx context.Context, category, savePath string) er
}
func (c *client) RemoveCategories(ctx context.Context, categories []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.RemoveCategories")
defer span.End()
var formData = url.Values{}
formData.Add("categories", strings.Join(categories, "\n"))
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/removeCategories", c.config.Address)
@ -1146,6 +1272,9 @@ func (c *client) AddTags(ctx context.Context, hashes []string, tags []string) er
}
func (c *client) RemoveTags(ctx context.Context, hashes []string, tags []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.RemoveTags")
defer span.End()
var formData = url.Values{}
formData.Add("hashes", strings.Join(hashes, "|"))
formData.Add("tags", strings.Join(tags, ","))
@ -1166,6 +1295,9 @@ func (c *client) RemoveTags(ctx context.Context, hashes []string, tags []string)
}
func (c *client) GetTags(ctx context.Context) ([]string, error) {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.GetTags")
defer span.End()
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/tags", c.config.Address)
result, err := c.doRequest(ctx, &requestData{
url: apiUrl,
@ -1184,6 +1316,9 @@ func (c *client) GetTags(ctx context.Context) ([]string, error) {
}
func (c *client) CreateTags(ctx context.Context, tags []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.CreateTags")
defer span.End()
var formData = url.Values{}
formData.Add("tags", strings.Join(tags, ","))
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/createTags", c.config.Address)
@ -1203,6 +1338,9 @@ func (c *client) CreateTags(ctx context.Context, tags []string) error {
}
func (c *client) DeleteTags(ctx context.Context, tags []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.DeleteTags")
defer span.End()
var formData = url.Values{}
formData.Add("tags", strings.Join(tags, ","))
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/deleteTags", c.config.Address)
@ -1222,6 +1360,9 @@ func (c *client) DeleteTags(ctx context.Context, tags []string) error {
}
func (c *client) SetAutomaticManagement(ctx context.Context, hashes []string, enable bool) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetAutomaticManagement")
defer span.End()
var formData = url.Values{}
formData.Add("hashes", strings.Join(hashes, "|"))
formData.Add("enable", strconv.FormatBool(enable))
@ -1242,6 +1383,9 @@ func (c *client) SetAutomaticManagement(ctx context.Context, hashes []string, en
}
func (c *client) ToggleSequentialDownload(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.ToggleSequentialDownload")
defer span.End()
var formData = url.Values{}
formData.Add("hashes", strings.Join(hashes, "|"))
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/toggleSequentialDownload", c.config.Address)
@ -1261,6 +1405,9 @@ func (c *client) ToggleSequentialDownload(ctx context.Context, hashes []string)
}
func (c *client) SetFirstLastPiecePriority(ctx context.Context, hashes []string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetFirstLastPiecePriority")
defer span.End()
var formData = url.Values{}
formData.Add("hashes", strings.Join(hashes, "|"))
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/toggleFirstLastPiecePrio", c.config.Address)
@ -1280,6 +1427,9 @@ func (c *client) SetFirstLastPiecePriority(ctx context.Context, hashes []string)
}
func (c *client) SetForceStart(ctx context.Context, hashes []string, force bool) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetForceStart")
defer span.End()
var formData = url.Values{}
formData.Add("hashes", strings.Join(hashes, "|"))
formData.Add("value", strconv.FormatBool(force))
@ -1300,6 +1450,9 @@ func (c *client) SetForceStart(ctx context.Context, hashes []string, force bool)
}
func (c *client) SetSuperSeeding(ctx context.Context, hashes []string, enable bool) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.SetSuperSeeding")
defer span.End()
var formData = url.Values{}
formData.Add("hashes", strings.Join(hashes, "|"))
formData.Add("value", strconv.FormatBool(enable))
@ -1320,6 +1473,9 @@ func (c *client) SetSuperSeeding(ctx context.Context, hashes []string, enable bo
}
func (c *client) RenameFile(ctx context.Context, hash, oldPath, newPath string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.RenameFile")
defer span.End()
var formData = url.Values{}
formData.Add("oldPath", oldPath)
formData.Add("newPath", newPath)
@ -1341,6 +1497,9 @@ func (c *client) RenameFile(ctx context.Context, hash, oldPath, newPath string)
}
func (c *client) RenameFolder(ctx context.Context, hash, oldPath, newPath string) error {
ctx, span := trace.Start(ctx, "qbittorrent.Torrent.RenameFolder")
defer span.End()
var formData = url.Values{}
formData.Add("oldPath", oldPath)
formData.Add("newPath", newPath)

View file

@ -47,6 +47,9 @@ type Transfer interface {
}
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,
@ -68,6 +71,9 @@ func (c *client) GlobalStatusBar(ctx context.Context) (*TransferStatusBar, error
}
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, "|"))
@ -88,6 +94,9 @@ func (c *client) BanPeers(ctx context.Context, peers []string) error {
}
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,
@ -104,6 +113,9 @@ func (c *client) GetSpeedLimitsMode(ctx context.Context) (string, error) {
}
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,
@ -121,6 +133,9 @@ func (c *client) ToggleSpeedLimitsMode(ctx context.Context) error {
}
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,
@ -137,6 +152,9 @@ func (c *client) GetGlobalUploadLimit(ctx context.Context) (string, error) {
}
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,
@ -153,6 +171,9 @@ func (c *client) SetGlobalUploadLimit(ctx context.Context, limit int) error {
}
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,
@ -169,6 +190,9 @@ func (c *client) GetGlobalDownloadLimit(ctx context.Context) (string, error) {
}
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,