tstor/src/sources/qbittorrent/daemon.go

102 lines
2 KiB
Go
Raw Normal View History

package qbittorrent
import (
"bytes"
"context"
"path"
"git.kmsign.ru/royalcat/tstor/src/vfs"
"github.com/anacrolix/torrent/metainfo"
"github.com/anacrolix/torrent/types/infohash"
"github.com/royalcat/ctxio"
"github.com/xuthus5/qbittorrent-client-go/qbittorrent"
)
type Daemon struct {
qb qbittorrent.Client
client *client
dataDir string
}
func NewDaemon(dir string) (*Daemon, error) {
dataDir := dir + "/data"
qb, err := qbittorrent.NewClient(&qbittorrent.Config{
Address: "localhost:8080",
})
if err != nil {
return nil, err
}
return &Daemon{
qb: qb,
dataDir: dataDir,
client: wrapClient(qb),
}, nil
}
func (fs *Daemon) torrentPath(ih infohash.T) string {
return path.Join(fs.dataDir, ih.HexString())
}
func (fs *Daemon) addTorrent(ctx context.Context, f vfs.File) error {
file, err := ctxio.ReadAll(ctx, f)
if err != nil {
return err
}
mi, err := metainfo.Load(bytes.NewBuffer(file))
if err != nil {
return err
}
ih := mi.HashInfoBytes()
err = fs.qb.Torrent().AddNewTorrent(&qbittorrent.TorrentAddOption{
Torrents: []*qbittorrent.TorrentAddFileMetadata{
{
Data: file,
},
},
SavePath: fs.torrentPath(ih),
// SequentialDownload: "true",
// FirstLastPiecePrio: "true",
})
if err != nil {
return err
}
return nil
}
func (fs *Daemon) TorrentFS(ctx context.Context, file vfs.File) (*FS, error) {
ih, err := readInfoHash(ctx, file)
if err != nil {
return nil, err
}
existing, err := fs.qb.Torrent().GetTorrents(&qbittorrent.TorrentOption{
Hashes: []string{ih.HexString()},
})
if err != nil {
return nil, err
}
if len(existing) == 0 {
err := fs.addTorrent(ctx, file)
if err != nil {
return nil, err
}
}
return newTorrentFS(fs.client, file.Name(), ih.HexString(), fs.torrentPath(ih))
}
// TODO caching
func readInfoHash(ctx context.Context, file vfs.File) (infohash.T, error) {
mi, err := metainfo.Load(ctxio.IoReader(ctx, file))
if err != nil {
return infohash.T{}, err
}
return mi.HashInfoBytes(), nil
}