Добавил логи

This commit is contained in:
2026-06-14 19:37:09 +03:00
parent d4bf8a8cad
commit 81ed58ecff
28 changed files with 379 additions and 121 deletions
+19 -2
View File
@@ -12,6 +12,7 @@ import (
"encoding/json"
"fmt"
"io"
"log/slog"
"mime/multipart"
"net/http"
"net/http/cookiejar"
@@ -36,6 +37,7 @@ type Client struct {
hc *http.Client
user string
pass string
log *slog.Logger
mu sync.Mutex // сериализует логин
}
@@ -74,8 +76,8 @@ type AddRequest struct {
Paused bool
}
// New создаёт клиент с собственным cookie-jar.
func New(cfg Config) (*Client, error) {
// New создаёт клиент с собственным cookie-jar. logger nil → slog.Default().
func New(cfg Config, logger *slog.Logger) (*Client, error) {
base, err := url.Parse(strings.TrimRight(cfg.URL, "/"))
if err != nil {
return nil, fmt.Errorf("parse qbittorrent url %q: %w", cfg.URL, err)
@@ -88,11 +90,15 @@ func New(cfg Config) (*Client, error) {
if timeout == 0 {
timeout = 30 * time.Second
}
if logger == nil {
logger = slog.Default()
}
return &Client{
base: base,
hc: &http.Client{Jar: jar, Timeout: timeout},
user: cfg.Username,
pass: cfg.Password,
log: logger,
}, nil
}
@@ -119,9 +125,12 @@ func (c *Client) login(ctx context.Context) error {
defer func() { _ = resp.Body.Close() }()
body, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<10))
if resp.StatusCode != http.StatusOK || strings.TrimSpace(string(body)) != "Ok." {
c.log.Error("qbittorrent: login failed",
"status", resp.StatusCode, "body", strings.TrimSpace(string(body)))
return fmt.Errorf("qbittorrent login failed: status %d body %q",
resp.StatusCode, strings.TrimSpace(string(body)))
}
c.log.Debug("qbittorrent: login ok", "user", c.user)
return nil
}
@@ -138,6 +147,7 @@ func (c *Client) do(ctx context.Context, build func() (*http.Request, error)) (*
}
if resp.StatusCode == http.StatusForbidden {
_ = resp.Body.Close()
c.log.Debug("qbittorrent: session expired (403), re-login")
if err := c.login(ctx); err != nil {
return nil, err
}
@@ -199,8 +209,13 @@ func (c *Client) Add(ctx context.Context, ar AddRequest) error {
resp.StatusCode, strings.TrimSpace(string(body)))
}
if strings.TrimSpace(string(body)) == "Fails." {
c.log.Error("qbittorrent: add rejected",
"category", ar.Category, "urls", len(ar.URLs), "torrents", len(ar.Torrents))
return fmt.Errorf("qbittorrent add: rejected (Fails.)")
}
c.log.Info("qbittorrent: torrent added",
"category", ar.Category, "save_path", ar.SavePath,
"urls", len(ar.URLs), "torrents", len(ar.Torrents), "paused", ar.Paused)
return nil
}
@@ -226,6 +241,7 @@ func (c *Client) Torrents(ctx context.Context, category string) ([]Torrent, erro
if err := json.NewDecoder(resp.Body).Decode(&ts); err != nil {
return nil, fmt.Errorf("decode qbittorrent info: %w", err)
}
c.log.Debug("qbittorrent: torrents fetched", "category", category, "count", len(ts))
return ts, nil
}
@@ -250,5 +266,6 @@ func (c *Client) Files(ctx context.Context, hash string) ([]File, error) {
if err := json.NewDecoder(resp.Body).Decode(&fs); err != nil {
return nil, fmt.Errorf("decode qbittorrent files: %w", err)
}
c.log.Debug("qbittorrent: files fetched", "hash", hash, "count", len(fs))
return fs, nil
}
+2 -2
View File
@@ -62,7 +62,7 @@ func fakeQBittorrent(t *testing.T, info string) *httptest.Server {
func newClient(t *testing.T, url string) *Client {
t.Helper()
c, err := New(Config{URL: url, Username: "admin", Password: "secret"})
c, err := New(Config{URL: url, Username: "admin", Password: "secret"}, nil)
if err != nil {
t.Fatalf("New: %v", err)
}
@@ -107,7 +107,7 @@ func TestTorrents(t *testing.T) {
func TestLoginFailure(t *testing.T) {
srv := fakeQBittorrent(t, "[]")
c, err := New(Config{URL: srv.URL, Username: "admin", Password: "wrong"})
c, err := New(Config{URL: srv.URL, Username: "admin", Password: "wrong"}, nil)
if err != nil {
t.Fatal(err)
}