qbit read/update

This commit is contained in:
Celogeek 2023-08-15 16:19:25 +02:00
parent 6056399ef8
commit 4c8fdd956f
Signed by: celogeek
SSH Key Fingerprint: SHA256:DEDfxIK2nUWXbslbRkww3zsauDjhWHlTXar+ak4lDJ4
2 changed files with 233 additions and 0 deletions

52
main.go Normal file
View File

@ -0,0 +1,52 @@
package main
import (
"flag"
"log"
"time"
)
type Options struct {
Qbittorent QBitTorrentOptions
}
func main() {
options := &Options{}
flag.StringVar(&options.Qbittorent.Uri, "qbittorrent-uri", "http://localhost:8080", "URI of qbittorrent")
flag.StringVar(&options.Qbittorent.Username, "qbittorrent-username", "", "Username of qbittorrent")
flag.StringVar(&options.Qbittorent.Password, "qbittorrent-password", "", "Password of qbittorrent")
flag.StringVar(&options.Qbittorent.SyncTag, "qbittorrent-sync-tag", "Sync", "Tag of qbittorrent to copy")
flag.StringVar(&options.Qbittorent.SyncedTag, "qbittorrent-synced-tag", "", "Tag of qbittorrent when copy finished")
flag.Parse()
if options.Qbittorent.Uri == "" ||
options.Qbittorent.Username == "" ||
options.Qbittorent.Password == "" ||
options.Qbittorent.SyncTag == "" {
log.Fatal("missing qbittorrent parameters")
}
qcli, err := NewQBittorrentCli(&options.Qbittorent)
if err != nil {
log.Fatal(err)
}
defer qcli.Logout()
torrents, err := qcli.List()
if err != nil {
log.Fatal(err)
}
for _, t := range torrents {
for p := 0; p <= 100; p += 20 {
qcli.ClearTags()
qcli.SetProgress(&t, p)
time.Sleep(time.Second)
}
qcli.SetDone(&t)
}
}
func init() {
log.SetFlags(0)
}

181
qbittorent.go Normal file
View File

@ -0,0 +1,181 @@
package main
import (
"fmt"
"strings"
"github.com/go-resty/resty/v2"
)
type QBitTorrentOptions struct {
Uri string
Username string
Password string
SyncTag string
SyncedTag string
}
type QBittorrentCli struct {
SyncTag string
SyncedTag string
cli *resty.Client
}
type Torrent struct {
Name string `json:"name"`
Path string `json:"content_path"`
Hash string `json:"hash"`
Progress int `json:"-"`
}
func NewQBittorrentCli(options *QBitTorrentOptions) (*QBittorrentCli, error) {
r := resty.New().SetBaseURL(fmt.Sprintf("%s/api/v2", options.Uri))
_, err := r.
R().
SetFormData(map[string]string{
"username": options.Username,
"password": options.Password,
}).
Post("/auth/login")
if err != nil {
return nil, err
}
cli := &QBittorrentCli{
SyncTag: options.SyncTag,
SyncedTag: options.SyncedTag,
cli: r,
}
cli.ClearTags()
return cli, nil
}
func (c *QBittorrentCli) Logout() error {
_, err := c.cli.R().Post("/auth/logout")
return err
}
func (c *QBittorrentCli) List() ([]Torrent, error) {
result := make([]Torrent, 0)
_, err := c.cli.R().
SetQueryParam("filter", "completed").
SetQueryParam("tag", c.SyncTag).
SetResult(&result).
Get("/torrents/info")
if err != nil {
return nil, err
}
for _, t := range result {
t.Progress = -1
}
return result, nil
}
func (c *QBittorrentCli) ClearTags() error {
// fetch tags
tags := []string{}
_, err := c.cli.
R().
SetResult(&tags).
Get("/torrents/tags")
if err != nil {
return err
}
// check existing tags
hasSync := false
toDeleteTags := []string{}
for _, t := range tags {
if t == c.SyncTag {
hasSync = true
}
if strings.HasPrefix(t, "Progress:") {
toDeleteTags = append(toDeleteTags, t)
}
}
// create missing sync
if !hasSync {
_, err := c.cli.
R().
SetFormData(map[string]string{
"tags": c.SyncTag,
}).
Post("/torrents/createTags")
if err != nil {
return err
}
}
// remove progress
if len(toDeleteTags) > 0 {
_, err := c.cli.
R().
SetFormData(map[string]string{
"tags": strings.Join(toDeleteTags, ","),
}).
Post("/torrents/deleteTags")
if err != nil {
return err
}
}
return nil
}
func (c *QBittorrentCli) SetTag(t *Torrent, tag string) error {
_, err := c.cli.
R().
SetFormData(map[string]string{
"hashes": t.Hash,
"tags": tag,
}).
Post("/torrents/addTags")
return err
}
func (c *QBittorrentCli) SetProgress(t *Torrent, p int) error {
if t.Progress == p {
return nil
}
t.Progress = p
return c.SetTag(t, fmt.Sprintf("Progress:%d%%", p))
}
func (c *QBittorrentCli) SetDone(t *Torrent) error {
err := c.ClearTags()
if err != nil {
return err
}
_, err = c.cli.
R().
SetFormData(map[string]string{
"hashes": t.Hash,
"tags": c.SyncTag,
}).
Post("/torrents/deleteTags")
if err != nil {
return err
}
if c.SyncedTag != "" {
return c.SetTag(t, c.SyncedTag)
}
return nil
}