tstor/src/sources/qbittorrent/client.go

86 lines
1.7 KiB
Go
Raw Normal View History

package qbittorrent
import (
"context"
"fmt"
"slices"
"time"
"github.com/xuthus5/qbittorrent-client-go/qbittorrent"
)
type client struct {
qb qbittorrent.Client
}
func wrapClient(qb qbittorrent.Client) *client {
return &client{qb: qb}
}
func (f *client) getFileContent(ctx context.Context, hash string, contextIndex int) (*qbittorrent.TorrentContent, error) {
contents, err := f.qb.Torrent().GetContents(hash)
if err != nil {
return nil, err
}
contentIndex := slices.IndexFunc(contents, func(c *qbittorrent.TorrentContent) bool {
return c.Index == contextIndex
})
if contentIndex == -1 {
return nil, fmt.Errorf("content not found")
}
return contents[contentIndex], nil
}
func (f *client) isPieceComplete(ctx context.Context, hash string, pieceIndex int) (bool, error) {
completion, err := f.qb.Torrent().GetPiecesStates(hash)
if err != nil {
return false, err
}
if completion[pieceIndex] == 2 {
return true, nil
}
return false, nil
}
func (f *client) waitPieceToComplete(ctx context.Context, hash string, pieceIndex int) error {
const checkingInterval = 1 * time.Second
ok, err := f.isPieceComplete(ctx, hash, pieceIndex)
if err != nil {
return err
}
if ok {
return nil
}
if deadline, ok := ctx.Deadline(); ok && time.Until(deadline) < checkingInterval {
return context.DeadlineExceeded
}
ticker := time.NewTicker(checkingInterval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return ctx.Err()
case <-ticker.C:
ok, err := f.isPieceComplete(ctx, hash, pieceIndex)
if err != nil {
return err
}
if ok {
return nil
}
if deadline, ok := ctx.Deadline(); ok && time.Until(deadline) < checkingInterval {
return context.DeadlineExceeded
}
}
}
}