parent
84fc019e46
commit
3c0ba3cc9f
17 changed files with 1965 additions and 1880 deletions
|
@ -5,7 +5,7 @@ go 1.24.1
|
|||
require (
|
||||
git.kmsign.ru/royalcat/tstor/plugins/archive v0.0.0-20250420233812-dbf843ad072e
|
||||
git.kmsign.ru/royalcat/tstor/plugins/qbittorrent v0.0.0-20250420233812-dbf843ad072e
|
||||
git.kmsign.ru/royalcat/tstor/server v0.0.0-20250420233812-dbf843ad072e
|
||||
git.kmsign.ru/royalcat/tstor/server v0.0.0-20250606103346-f48093ad3251
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -46,6 +46,7 @@ require (
|
|||
github.com/grafana/otel-profiling-go v0.5.1 // indirect
|
||||
github.com/grafana/pyroscope-go v1.2.2 // indirect
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
|
@ -60,9 +61,6 @@ require (
|
|||
github.com/knadh/koanf/providers/file v1.2.0 // indirect
|
||||
github.com/knadh/koanf/providers/structs v1.0.0 // indirect
|
||||
github.com/knadh/koanf/v2 v2.2.0 // indirect
|
||||
github.com/labstack/echo-contrib v0.17.3 // indirect
|
||||
github.com/labstack/echo/v4 v4.13.3 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
|
@ -94,8 +92,6 @@ require (
|
|||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/ulikunitz/xz v0.5.12 // indirect
|
||||
github.com/urfave/cli/v2 v2.27.6 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.5.25 // indirect
|
||||
github.com/viccon/sturdyc v1.1.5 // indirect
|
||||
github.com/willscott/go-nfs-client v0.0.0-20240104095149-b44639837b00 // indirect
|
||||
|
@ -123,7 +119,6 @@ require (
|
|||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect
|
||||
google.golang.org/grpc v1.72.0 // indirect
|
||||
|
|
|
@ -21,8 +21,8 @@ git.kmsign.ru/royalcat/tstor/plugins/archive v0.0.0-20250420233812-dbf843ad072e
|
|||
git.kmsign.ru/royalcat/tstor/plugins/archive v0.0.0-20250420233812-dbf843ad072e/go.mod h1:b7qGAuR7TPQiH5c84sC0CSWHFC2XApvNmzuqabrB/AA=
|
||||
git.kmsign.ru/royalcat/tstor/plugins/qbittorrent v0.0.0-20250420233812-dbf843ad072e h1:7al9sFgxJglONyGMkeduulRM3C1NwwuoRGqXiTUaJvk=
|
||||
git.kmsign.ru/royalcat/tstor/plugins/qbittorrent v0.0.0-20250420233812-dbf843ad072e/go.mod h1:3P9WgIZhDzbsuAPF/udAyFAWSooIvE81UGvDepPZMZY=
|
||||
git.kmsign.ru/royalcat/tstor/server v0.0.0-20250420233812-dbf843ad072e h1:pydEjTn3y7aUFW8Je9YrxJzbGmcYbMdu1kkQZL1lBf4=
|
||||
git.kmsign.ru/royalcat/tstor/server v0.0.0-20250420233812-dbf843ad072e/go.mod h1:kQyKUtvpB30J+DMeaDXHfJAxdkVUbqMh7ayF72XtJ2w=
|
||||
git.kmsign.ru/royalcat/tstor/server v0.0.0-20250606103346-f48093ad3251 h1:cKjrmPg7OXQwUUvRC9jF2VizAv+1M3UVsVGmCE4KY8A=
|
||||
git.kmsign.ru/royalcat/tstor/server v0.0.0-20250606103346-f48093ad3251/go.mod h1:MmZULZds+oT+gIFUNi+kG2VfW3uRMEsP2OqZ1TXpzc4=
|
||||
github.com/99designs/gqlgen v0.17.72 h1:2JDAuutIYtAN26BAtigfLZFnTN53fpYbIENL8bVgAKY=
|
||||
github.com/99designs/gqlgen v0.17.72/go.mod h1:BoL4C3j9W2f95JeWMrSArdDNGWmZB9MOS2EMHJDZmUc=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
|
@ -39,6 +39,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anacrolix/dht/v2 v2.22.1 h1:mgsljPXyA/EWA7uUDSNjx7wf6gsfhppjVIp9auVeR6w=
|
||||
github.com/anacrolix/dht/v2 v2.22.1/go.mod h1:seXRz6HLw8zEnxlysf9ye2eQbrKUmch6PyOHpe/Nb/U=
|
||||
github.com/anacrolix/envpprof v0.0.0-20180404065416-323002cec2fa/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
|
||||
github.com/anacrolix/envpprof v1.0.0/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
|
||||
github.com/anacrolix/envpprof v1.1.0/go.mod h1:My7T5oSqVfEn4MD4Meczkw/f5lSIndGAKu/0SM/rkf4=
|
||||
|
@ -224,6 +225,7 @@ github.com/grafana/pyroscope-go v1.2.2 h1:uvKCyZMD724RkaCEMrSTC38Yn7AnFe8S2wiAIY
|
|||
github.com/grafana/pyroscope-go v1.2.2/go.mod h1:zzT9QXQAp2Iz2ZdS216UiV8y9uXJYQiGE1q8v1FyhqU=
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg=
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
|
@ -279,12 +281,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/labstack/echo-contrib v0.17.3 h1:hj+qXksKZG1scSe9ksUXMtv7fZYN+PtQT+bPcYA3/TY=
|
||||
github.com/labstack/echo-contrib v0.17.3/go.mod h1:TcRBrzW8jcC4JD+5Dc/pvOyAps0rtgzj7oBqoR3nYsc=
|
||||
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
|
||||
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
|
@ -423,10 +419,6 @@ github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
|||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
|
||||
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vektah/gqlparser/v2 v2.5.25 h1:FmWtFEa+invTIzWlWK6Vk7BVEZU/97QBzeI8Z1JjGt8=
|
||||
github.com/vektah/gqlparser/v2 v2.5.25/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
|
||||
github.com/viccon/sturdyc v1.1.5 h1:GLQDnsyKt3L/tpdWCIARIRefn+5DAyvqu+0irBwt+vk=
|
||||
|
@ -605,8 +597,6 @@ golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
|||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -676,6 +666,7 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
|||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
|
||||
google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
|
1434
go.work.sum
1434
go.work.sum
File diff suppressed because it is too large
Load diff
|
@ -27,7 +27,7 @@ func (ArchivePlugin) Name() string {
|
|||
var _ tstor.DaemonPlugin = (*ArchivePlugin)(nil)
|
||||
|
||||
// NewDaemon implements tstor.DaemonPlugin.
|
||||
func (a *ArchivePlugin) NewDaemon(context.Context, *koanf.Koanf) (daemon.Daemon, error) {
|
||||
func (a *ArchivePlugin) NewDaemon(context.Context, *koanf.Koanf, vfs.Filesystem) (daemon.Daemon, error) {
|
||||
return &Daemon{}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
generate-gprc: proto/*.proto
|
||||
protoc -I=../../ -I=proto \
|
||||
--go_out=src/delivery/grpc/pb --go_opt=paths=source_relative \
|
||||
--go-grpc_out=src/delivery/grpc/pb --go-grpc_opt=paths=source_relative,require_unimplemented_servers=false \
|
||||
$<
|
||||
mkdir -p src/delivery/grpc && \
|
||||
protoc -I=../../ -I=. \
|
||||
--go_out=src/delivery/grpc --go_opt=paths=source_relative \
|
||||
--go-grpc_out=src/delivery/grpc --go-grpc_opt=paths=source_relative,require_unimplemented_servers=false \
|
||||
$^
|
|
@ -24,26 +24,30 @@ var _ proto.QBitTorrentServiceServer = (*grpcService)(nil)
|
|||
|
||||
// Cleanup implements proto.QBitTorrentServiceServer.
|
||||
func (g *grpcService) Cleanup(ctx context.Context, req *proto.CleanupRequest) (*proto.CleanupResponse, error) {
|
||||
hashes, err := g.d.Cleanup(ctx, req.Act)
|
||||
hashes, err := g.d.Cleanup(ctx, req.GetAct())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.CleanupResponse{
|
||||
Count: int32(len(hashes)),
|
||||
Hashes: hashes,
|
||||
}, nil
|
||||
|
||||
resp := proto.CleanupResponse{}
|
||||
resp.SetCount(int32(len(hashes)))
|
||||
resp.SetHashes(hashes)
|
||||
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// CleanupUnregistred implements proto.QBitTorrentServiceServer.
|
||||
func (g *grpcService) CleanupUnregistred(ctx context.Context, req *proto.CleanupUnregistredRequest) (*proto.CleanupUnregistredResponse, error) {
|
||||
hashes, err := g.d.CleanupUnregistred(ctx, req.Act)
|
||||
hashes, err := g.d.CleanupUnregistred(ctx, req.GetAct())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.CleanupUnregistredResponse{
|
||||
Count: int32(len(hashes)),
|
||||
Hashes: hashes,
|
||||
}, nil
|
||||
|
||||
resp := proto.CleanupUnregistredResponse{}
|
||||
resp.SetCount(int32(len(hashes)))
|
||||
resp.SetHashes(hashes)
|
||||
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// GetTorrents implements proto.QBitTorrentServiceServer.
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/plugins/qbittorrent/pkg/qbittorrent"
|
||||
"git.kmsign.ru/royalcat/tstor/server/pkg/rlog"
|
||||
|
@ -69,6 +70,38 @@ func (d *QBittorrentDaemon) Cleanup(ctx context.Context, run bool) ([]string, er
|
|||
func (d *QBittorrentDaemon) CleanupUnregistred(ctx context.Context, run bool) ([]string, error) {
|
||||
d.log.Info(ctx, "cleanup started")
|
||||
|
||||
err := d.sourceFilesKV.Range(ctx, func(sourcePath, hash string) error {
|
||||
log := d.log.With(slog.String("sourcePath", sourcePath))
|
||||
|
||||
if !strings.HasSuffix(sourcePath, ".torrent") {
|
||||
log.Warn(ctx, "skipping non-torrent file", slog.String("path", sourcePath))
|
||||
return nil
|
||||
}
|
||||
|
||||
if d.registeredTorrents.Contains(hash) {
|
||||
log.Debug(ctx, "torrent already registered, skipping", slog.String("infohash", hash))
|
||||
return nil
|
||||
}
|
||||
|
||||
f, err := d.sourceFS.Open(ctx, sourcePath)
|
||||
if err != nil {
|
||||
log.Error(ctx, "failed to open source file", slog.String("path", sourcePath), rlog.Error(err))
|
||||
return fmt.Errorf("failed to open source file: %w", err)
|
||||
}
|
||||
|
||||
_, err = d.GetFS(ctx, sourcePath, f)
|
||||
if err != nil {
|
||||
log.Error(ctx, "failed to get filesystem for source file", slog.String("path", sourcePath), rlog.Error(err))
|
||||
return fmt.Errorf("failed to get filesystem for source file: %w", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
d.log.Error(ctx, "failed to iterate source files", rlog.Error(err))
|
||||
return nil, fmt.Errorf("failed to iterate source files: %w", err)
|
||||
}
|
||||
|
||||
torrentInfos, err := d.client.qb.Torrent().GetTorrents(ctx, &qbittorrent.TorrentOption{})
|
||||
if err != nil {
|
||||
d.log.Error(ctx, "failed to get torrents", rlog.Error(err))
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/plugins/qbittorrent/pkg/qbittorrent"
|
||||
|
@ -21,22 +20,28 @@ import (
|
|||
"github.com/anacrolix/torrent/types/infohash"
|
||||
infohash_v2 "github.com/anacrolix/torrent/types/infohash-v2"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"github.com/dgraph-io/badger/v4"
|
||||
"github.com/knadh/koanf/v2"
|
||||
"github.com/royalcat/ctxio"
|
||||
"github.com/royalcat/kv"
|
||||
"github.com/royalcat/kv/kvbadger"
|
||||
"go.opentelemetry.io/otel"
|
||||
)
|
||||
|
||||
var trace = otel.Tracer("git.kmsign.ru/royalcat/tstor/plugins/qbittorrent/daemon")
|
||||
|
||||
type QBittorrentDaemon struct {
|
||||
sourceFS vfs.Filesystem
|
||||
|
||||
proc *os.Process
|
||||
qb qbittorrent.Client
|
||||
client *cacheClient
|
||||
|
||||
sourceFilesMu sync.Mutex
|
||||
sourceFiles map[string]string // [sourcePath]infohash
|
||||
// sourceFilesMu sync.Mutex
|
||||
// sourceFiles map[string]string // [sourcePath]infohash
|
||||
|
||||
registeredTorrents mapset.Set[string] // infohash list
|
||||
sourceFilesKV kv.Store[string, string] // [sourcePath]infohash
|
||||
registeredTorrents mapset.Set[string] // infohash list
|
||||
|
||||
dataDir string
|
||||
log *rlog.Logger
|
||||
|
@ -53,7 +58,7 @@ WebUI\Password_PBKDF2="@ByteArray(qef5I4wZBkDG+PP6/5mQwA==:LoTmorQM/QM5RHI4+dOiu
|
|||
|
||||
const daemonName = "qbittorrent"
|
||||
|
||||
func New(ctx context.Context, koanf *koanf.Koanf) (daemon.Daemon, error) {
|
||||
func New(ctx context.Context, koanf *koanf.Koanf, sourceFS vfs.Filesystem) (daemon.Daemon, error) {
|
||||
log := rlog.Component(daemonName)
|
||||
|
||||
log.Debug(ctx, "QBittorrent plugin loaded. Starting qbittorrent-nox")
|
||||
|
@ -128,11 +133,19 @@ func New(ctx context.Context, koanf *koanf.Koanf) (daemon.Daemon, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
sourceFilesKV, err := kvbadger.NewRaw[string, string](kvbadger.Options[string]{
|
||||
BadgerOptions: badger.DefaultOptions(path.Join(config.MetadataDir, "tstor", "source_files")),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &QBittorrentDaemon{
|
||||
sourceFS: sourceFS,
|
||||
qb: qb,
|
||||
proc: proc,
|
||||
dataDir: config.DataDir,
|
||||
sourceFiles: make(map[string]string),
|
||||
sourceFilesKV: sourceFilesKV,
|
||||
registeredTorrents: mapset.NewSet[string](),
|
||||
client: wrapClient(qb),
|
||||
log: rlog.Component(daemonName),
|
||||
|
@ -165,7 +178,7 @@ func torrentDataPath(dataDir string, ih string) (string, error) {
|
|||
return filepath.Abs(path.Join(dataDir, ih))
|
||||
}
|
||||
|
||||
func (fs *QBittorrentDaemon) GetFS(ctx context.Context, sourcePath string, file vfs.File) (vfs.Filesystem, error) {
|
||||
func (d *QBittorrentDaemon) GetFS(ctx context.Context, sourcePath string, file vfs.File) (vfs.Filesystem, error) {
|
||||
ctx, span := trace.Start(ctx, "GetTorrentFS")
|
||||
defer span.End()
|
||||
|
||||
|
@ -174,7 +187,7 @@ func (fs *QBittorrentDaemon) GetFS(ctx context.Context, sourcePath string, file
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log := fs.log.With(slog.String("file", file.Name()))
|
||||
log := d.log.With(slog.String("file", file.Name()))
|
||||
|
||||
ih, err := readInfoHash(ctx, file)
|
||||
if err != nil {
|
||||
|
@ -182,7 +195,7 @@ func (fs *QBittorrentDaemon) GetFS(ctx context.Context, sourcePath string, file
|
|||
}
|
||||
log = log.With(slog.String("infohash", ih.HexString()))
|
||||
|
||||
torrentPath, err := torrentDataPath(fs.dataDir, ih.HexString())
|
||||
torrentPath, err := torrentDataPath(d.dataDir, ih.HexString())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting torrent path: %w", err)
|
||||
}
|
||||
|
@ -190,16 +203,17 @@ func (fs *QBittorrentDaemon) GetFS(ctx context.Context, sourcePath string, file
|
|||
|
||||
log.Debug(ctx, "creating fs for torrent")
|
||||
|
||||
err = fs.syncTorrentState(ctx, file, ih, torrentPath)
|
||||
err = d.syncTorrentState(ctx, file, ih, torrentPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error syncing torrent state: %w", err)
|
||||
}
|
||||
|
||||
fs.sourceFilesMu.Lock()
|
||||
fs.sourceFiles[sourcePath] = ih.HexString()
|
||||
fs.sourceFilesMu.Unlock()
|
||||
err = d.sourceFilesKV.Set(ctx, sourcePath, ih.HexString())
|
||||
if err != nil {
|
||||
log.Error(ctx, "error setting source file in kv store", rlog.Error(err))
|
||||
}
|
||||
|
||||
return newTorrentFS(ctx, fs.client, file.Name(), ih.HexString(), stat.ModTime(), torrentPath)
|
||||
return newTorrentFS(ctx, d.client, file.Name(), ih.HexString(), stat.ModTime(), torrentPath)
|
||||
}
|
||||
|
||||
func (d *QBittorrentDaemon) syncTorrentState(ctx context.Context, file vfs.File, ih metainfo.Hash, torrentPath string) error {
|
||||
|
|
|
@ -10,9 +10,10 @@ toolchain go1.24.2
|
|||
exclude github.com/envoyproxy/go-control-plane/envoy v1.32.3
|
||||
|
||||
require (
|
||||
git.kmsign.ru/royalcat/tstor/server v0.0.0-20250420233812-dbf843ad072e
|
||||
git.kmsign.ru/royalcat/tstor/server v0.0.0-20250607150550-84fc019e46fe
|
||||
github.com/anacrolix/torrent v1.58.1
|
||||
github.com/deckarep/golang-set/v2 v2.8.0
|
||||
github.com/dgraph-io/badger/v4 v4.7.0
|
||||
github.com/google/go-github/v63 v63.0.0
|
||||
github.com/gorilla/schema v1.4.1
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
|
@ -20,6 +21,8 @@ require (
|
|||
github.com/knadh/koanf/v2 v2.2.0
|
||||
github.com/royalcat/btrgo v0.0.0-20240318160410-19bd27154450
|
||||
github.com/royalcat/ctxio v0.0.0-20240602084623-009bd79b3176
|
||||
github.com/royalcat/kv v0.0.0-20240723215915-954e36a2491d
|
||||
github.com/royalcat/kv/kvbadger v0.0.0-20240723215915-954e36a2491d
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/viccon/sturdyc v1.1.5
|
||||
go.opentelemetry.io/otel v1.35.0
|
||||
|
@ -30,8 +33,6 @@ require (
|
|||
google.golang.org/protobuf v1.36.6
|
||||
)
|
||||
|
||||
replace google.golang.org/genproto => google.golang.org/genproto v0.0.0-20250324211829-b45e905df463
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.17.72 // indirect
|
||||
github.com/agnivade/levenshtein v1.2.1 // indirect
|
||||
|
@ -46,7 +47,6 @@ require (
|
|||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgraph-io/badger/v4 v4.7.0 // indirect
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/fatih/structs v1.1.0 // indirect
|
||||
|
@ -63,6 +63,7 @@ require (
|
|||
github.com/grafana/otel-profiling-go v0.5.1 // indirect
|
||||
github.com/grafana/pyroscope-go v1.2.2 // indirect
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
|
@ -71,9 +72,6 @@ require (
|
|||
github.com/knadh/koanf/parsers/yaml v1.0.0 // indirect
|
||||
github.com/knadh/koanf/providers/env v1.1.0 // indirect
|
||||
github.com/knadh/koanf/providers/file v1.2.0 // indirect
|
||||
github.com/labstack/echo-contrib v0.17.3 // indirect
|
||||
github.com/labstack/echo/v4 v4.13.3 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
|
@ -90,8 +88,6 @@ require (
|
|||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93 // indirect
|
||||
github.com/ravilushqa/otelgqlgen v0.17.0 // indirect
|
||||
github.com/royalcat/kv v0.0.0-20240723215915-954e36a2491d // indirect
|
||||
github.com/royalcat/kv/kvbadger v0.0.0-20240723215915-954e36a2491d // indirect
|
||||
github.com/rs/zerolog v1.34.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/samber/lo v1.49.1 // indirect
|
||||
|
@ -101,8 +97,6 @@ require (
|
|||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/urfave/cli/v2 v2.27.6 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.5.25 // indirect
|
||||
github.com/willscott/go-nfs-client v0.0.0-20240104095149-b44639837b00 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
|
@ -124,9 +118,11 @@ require (
|
|||
golang.org/x/crypto v0.37.0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/blake3 v1.4.0 // indirect
|
||||
)
|
||||
|
||||
tool google.golang.org/grpc/cmd/protoc-gen-go-grpc
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -576,7 +576,7 @@ func (c *client) DeleteTorrents(ctx context.Context, hashes []string, deleteFile
|
|||
}
|
||||
var formData = url.Values{}
|
||||
formData.Add("hashes", strings.Join(hashes, "|"))
|
||||
formData.Add("deleteFile", strconv.FormatBool(deleteFile))
|
||||
formData.Add("deleteFiles", strconv.FormatBool(deleteFile))
|
||||
var apiUrl = fmt.Sprintf("%s/api/v2/torrents/delete", c.config.Address)
|
||||
result, err := c.doRequest(ctx, &requestData{
|
||||
url: apiUrl,
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
qbdaemon "git.kmsign.ru/royalcat/tstor/plugins/qbittorrent/daemon"
|
||||
"git.kmsign.ru/royalcat/tstor/server/src/daemon"
|
||||
"git.kmsign.ru/royalcat/tstor/server/src/vfs"
|
||||
"git.kmsign.ru/royalcat/tstor/server/tstor"
|
||||
"github.com/knadh/koanf/v2"
|
||||
)
|
||||
|
@ -20,6 +21,6 @@ func (QBittorrentPlugin) Name() string {
|
|||
|
||||
var _ tstor.DaemonPlugin = (*QBittorrentPlugin)(nil)
|
||||
|
||||
func (QBittorrentPlugin) NewDaemon(ctx context.Context, koanf *koanf.Koanf) (daemon.Daemon, error) {
|
||||
return qbdaemon.New(ctx, koanf)
|
||||
func (QBittorrentPlugin) NewDaemon(ctx context.Context, koanf *koanf.Koanf, sfs vfs.Filesystem) (daemon.Daemon, error) {
|
||||
return qbdaemon.New(ctx, koanf, sfs)
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
syntax = "proto3";
|
||||
edition = "2023";
|
||||
|
||||
package qbittorrent;
|
||||
package tstor.daemons.qbittorrent;
|
||||
|
||||
import "server/proto/filters/filters.proto";
|
||||
import "google/protobuf/go_features.proto";
|
||||
option features.(pb.go).api_level = API_OPAQUE;
|
||||
|
||||
option go_package = "github.com/royalcat/tstor/plugins/qbittorrent/proto";
|
||||
option go_package = "git.kmsign.ru/royalcat/tstor/plugins/qbittorrent/delivery/grpc/proto";
|
||||
|
||||
import "proto/filters/filters.proto";
|
||||
|
||||
message Torrent {
|
||||
string name = 1;
|
||||
|
@ -23,13 +26,13 @@ service QBitTorrentService {
|
|||
message GetTorrentsRequest { tstor.filters.IntFilter sources_count = 1; }
|
||||
message GetTorrentsResponse { repeated Torrent torrents = 1; }
|
||||
|
||||
message CleanupRequest { bool act = 1; }
|
||||
message CleanupRequest { bool act = 1 [ default = false ]; }
|
||||
message CleanupResponse {
|
||||
int32 count = 1;
|
||||
repeated string hashes = 2;
|
||||
}
|
||||
|
||||
message CleanupUnregistredRequest { bool act = 1; }
|
||||
message CleanupUnregistredRequest { bool act = 1 [ default = false ]; }
|
||||
message CleanupUnregistredResponse {
|
||||
int32 count = 1;
|
||||
repeated string hashes = 2;
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.30.2
|
||||
// source: qbittorrent.proto
|
||||
// source: proto/qbittorrent.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
filters "git.kmsign.ru/royalcat/tstor/server/src/delivery/grpc/pb/filters"
|
||||
filters "git.kmsign.ru/royalcat/tstor/server/src/delivery/grpc/proto/filters"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
_ "google.golang.org/protobuf/types/gofeaturespb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
|
@ -23,17 +23,19 @@ const (
|
|||
)
|
||||
|
||||
type Torrent struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
|
||||
SourceFiles []string `protobuf:"bytes,3,rep,name=source_files,json=sourceFiles,proto3" json:"source_files,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"opaque.v1"`
|
||||
xxx_hidden_Name *string `protobuf:"bytes,1,opt,name=name"`
|
||||
xxx_hidden_Hash *string `protobuf:"bytes,2,opt,name=hash"`
|
||||
xxx_hidden_SourceFiles []string `protobuf:"bytes,3,rep,name=source_files,json=sourceFiles"`
|
||||
XXX_raceDetectHookData protoimpl.RaceDetectHookData
|
||||
XXX_presence [1]uint32
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Torrent) Reset() {
|
||||
*x = Torrent{}
|
||||
mi := &file_qbittorrent_proto_msgTypes[0]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -45,7 +47,7 @@ func (x *Torrent) String() string {
|
|||
func (*Torrent) ProtoMessage() {}
|
||||
|
||||
func (x *Torrent) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_qbittorrent_proto_msgTypes[0]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -56,42 +58,105 @@ func (x *Torrent) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Torrent.ProtoReflect.Descriptor instead.
|
||||
func (*Torrent) Descriptor() ([]byte, []int) {
|
||||
return file_qbittorrent_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Torrent) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
if x.xxx_hidden_Name != nil {
|
||||
return *x.xxx_hidden_Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Torrent) GetHash() string {
|
||||
if x != nil {
|
||||
return x.Hash
|
||||
if x.xxx_hidden_Hash != nil {
|
||||
return *x.xxx_hidden_Hash
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Torrent) GetSourceFiles() []string {
|
||||
if x != nil {
|
||||
return x.SourceFiles
|
||||
return x.xxx_hidden_SourceFiles
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Torrent) SetName(v string) {
|
||||
x.xxx_hidden_Name = &v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 3)
|
||||
}
|
||||
|
||||
func (x *Torrent) SetHash(v string) {
|
||||
x.xxx_hidden_Hash = &v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 3)
|
||||
}
|
||||
|
||||
func (x *Torrent) SetSourceFiles(v []string) {
|
||||
x.xxx_hidden_SourceFiles = v
|
||||
}
|
||||
|
||||
func (x *Torrent) HasName() bool {
|
||||
if x == nil {
|
||||
return false
|
||||
}
|
||||
return protoimpl.X.Present(&(x.XXX_presence[0]), 0)
|
||||
}
|
||||
|
||||
func (x *Torrent) HasHash() bool {
|
||||
if x == nil {
|
||||
return false
|
||||
}
|
||||
return protoimpl.X.Present(&(x.XXX_presence[0]), 1)
|
||||
}
|
||||
|
||||
func (x *Torrent) ClearName() {
|
||||
protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
|
||||
x.xxx_hidden_Name = nil
|
||||
}
|
||||
|
||||
func (x *Torrent) ClearHash() {
|
||||
protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 1)
|
||||
x.xxx_hidden_Hash = nil
|
||||
}
|
||||
|
||||
type Torrent_builder struct {
|
||||
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
|
||||
|
||||
Name *string
|
||||
Hash *string
|
||||
SourceFiles []string
|
||||
}
|
||||
|
||||
func (b0 Torrent_builder) Build() *Torrent {
|
||||
m0 := &Torrent{}
|
||||
b, x := &b0, m0
|
||||
_, _ = b, x
|
||||
if b.Name != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 3)
|
||||
x.xxx_hidden_Name = b.Name
|
||||
}
|
||||
if b.Hash != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 3)
|
||||
x.xxx_hidden_Hash = b.Hash
|
||||
}
|
||||
x.xxx_hidden_SourceFiles = b.SourceFiles
|
||||
return m0
|
||||
}
|
||||
|
||||
type GetTorrentsRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
SourcesCount *filters.IntFilter `protobuf:"bytes,1,opt,name=sources_count,json=sourcesCount,proto3" json:"sources_count,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"opaque.v1"`
|
||||
xxx_hidden_SourcesCount *filters.IntFilter `protobuf:"bytes,1,opt,name=sources_count,json=sourcesCount"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetTorrentsRequest) Reset() {
|
||||
*x = GetTorrentsRequest{}
|
||||
mi := &file_qbittorrent_proto_msgTypes[1]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -103,7 +168,7 @@ func (x *GetTorrentsRequest) String() string {
|
|||
func (*GetTorrentsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetTorrentsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_qbittorrent_proto_msgTypes[1]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -114,28 +179,52 @@ func (x *GetTorrentsRequest) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetTorrentsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetTorrentsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_qbittorrent_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *GetTorrentsRequest) GetSourcesCount() *filters.IntFilter {
|
||||
if x != nil {
|
||||
return x.SourcesCount
|
||||
return x.xxx_hidden_SourcesCount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetTorrentsRequest) SetSourcesCount(v *filters.IntFilter) {
|
||||
x.xxx_hidden_SourcesCount = v
|
||||
}
|
||||
|
||||
func (x *GetTorrentsRequest) HasSourcesCount() bool {
|
||||
if x == nil {
|
||||
return false
|
||||
}
|
||||
return x.xxx_hidden_SourcesCount != nil
|
||||
}
|
||||
|
||||
func (x *GetTorrentsRequest) ClearSourcesCount() {
|
||||
x.xxx_hidden_SourcesCount = nil
|
||||
}
|
||||
|
||||
type GetTorrentsRequest_builder struct {
|
||||
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
|
||||
|
||||
SourcesCount *filters.IntFilter
|
||||
}
|
||||
|
||||
func (b0 GetTorrentsRequest_builder) Build() *GetTorrentsRequest {
|
||||
m0 := &GetTorrentsRequest{}
|
||||
b, x := &b0, m0
|
||||
_, _ = b, x
|
||||
x.xxx_hidden_SourcesCount = b.SourcesCount
|
||||
return m0
|
||||
}
|
||||
|
||||
type GetTorrentsResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Torrents []*Torrent `protobuf:"bytes,1,rep,name=torrents,proto3" json:"torrents,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"opaque.v1"`
|
||||
xxx_hidden_Torrents *[]*Torrent `protobuf:"bytes,1,rep,name=torrents"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetTorrentsResponse) Reset() {
|
||||
*x = GetTorrentsResponse{}
|
||||
mi := &file_qbittorrent_proto_msgTypes[2]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -147,7 +236,7 @@ func (x *GetTorrentsResponse) String() string {
|
|||
func (*GetTorrentsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetTorrentsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_qbittorrent_proto_msgTypes[2]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -158,28 +247,50 @@ func (x *GetTorrentsResponse) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetTorrentsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetTorrentsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_qbittorrent_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *GetTorrentsResponse) GetTorrents() []*Torrent {
|
||||
if x != nil {
|
||||
return x.Torrents
|
||||
if x.xxx_hidden_Torrents != nil {
|
||||
return *x.xxx_hidden_Torrents
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CleanupRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Act bool `protobuf:"varint,1,opt,name=act,proto3" json:"act,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
func (x *GetTorrentsResponse) SetTorrents(v []*Torrent) {
|
||||
x.xxx_hidden_Torrents = &v
|
||||
}
|
||||
|
||||
type GetTorrentsResponse_builder struct {
|
||||
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
|
||||
|
||||
Torrents []*Torrent
|
||||
}
|
||||
|
||||
func (b0 GetTorrentsResponse_builder) Build() *GetTorrentsResponse {
|
||||
m0 := &GetTorrentsResponse{}
|
||||
b, x := &b0, m0
|
||||
_, _ = b, x
|
||||
x.xxx_hidden_Torrents = &b.Torrents
|
||||
return m0
|
||||
}
|
||||
|
||||
type CleanupRequest struct {
|
||||
state protoimpl.MessageState `protogen:"opaque.v1"`
|
||||
xxx_hidden_Act bool `protobuf:"varint,1,opt,name=act,def=0"`
|
||||
XXX_raceDetectHookData protoimpl.RaceDetectHookData
|
||||
XXX_presence [1]uint32
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
// Default values for CleanupRequest fields.
|
||||
const (
|
||||
Default_CleanupRequest_Act = bool(false)
|
||||
)
|
||||
|
||||
func (x *CleanupRequest) Reset() {
|
||||
*x = CleanupRequest{}
|
||||
mi := &file_qbittorrent_proto_msgTypes[3]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -191,7 +302,7 @@ func (x *CleanupRequest) String() string {
|
|||
func (*CleanupRequest) ProtoMessage() {}
|
||||
|
||||
func (x *CleanupRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_qbittorrent_proto_msgTypes[3]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -202,29 +313,61 @@ func (x *CleanupRequest) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CleanupRequest.ProtoReflect.Descriptor instead.
|
||||
func (*CleanupRequest) Descriptor() ([]byte, []int) {
|
||||
return file_qbittorrent_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *CleanupRequest) GetAct() bool {
|
||||
if x != nil {
|
||||
return x.Act
|
||||
if protoimpl.X.Present(&(x.XXX_presence[0]), 0) {
|
||||
return x.xxx_hidden_Act
|
||||
}
|
||||
}
|
||||
return false
|
||||
return Default_CleanupRequest_Act
|
||||
}
|
||||
|
||||
func (x *CleanupRequest) SetAct(v bool) {
|
||||
x.xxx_hidden_Act = v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 1)
|
||||
}
|
||||
|
||||
func (x *CleanupRequest) HasAct() bool {
|
||||
if x == nil {
|
||||
return false
|
||||
}
|
||||
return protoimpl.X.Present(&(x.XXX_presence[0]), 0)
|
||||
}
|
||||
|
||||
func (x *CleanupRequest) ClearAct() {
|
||||
protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
|
||||
}
|
||||
|
||||
type CleanupRequest_builder struct {
|
||||
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
|
||||
|
||||
Act *bool
|
||||
}
|
||||
|
||||
func (b0 CleanupRequest_builder) Build() *CleanupRequest {
|
||||
m0 := &CleanupRequest{}
|
||||
b, x := &b0, m0
|
||||
_, _ = b, x
|
||||
if b.Act != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 1)
|
||||
x.xxx_hidden_Act = *b.Act
|
||||
}
|
||||
return m0
|
||||
}
|
||||
|
||||
type CleanupResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
|
||||
Hashes []string `protobuf:"bytes,2,rep,name=hashes,proto3" json:"hashes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"opaque.v1"`
|
||||
xxx_hidden_Count int32 `protobuf:"varint,1,opt,name=count"`
|
||||
xxx_hidden_Hashes []string `protobuf:"bytes,2,rep,name=hashes"`
|
||||
XXX_raceDetectHookData protoimpl.RaceDetectHookData
|
||||
XXX_presence [1]uint32
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CleanupResponse) Reset() {
|
||||
*x = CleanupResponse{}
|
||||
mi := &file_qbittorrent_proto_msgTypes[4]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -236,7 +379,7 @@ func (x *CleanupResponse) String() string {
|
|||
func (*CleanupResponse) ProtoMessage() {}
|
||||
|
||||
func (x *CleanupResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_qbittorrent_proto_msgTypes[4]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -247,35 +390,77 @@ func (x *CleanupResponse) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CleanupResponse.ProtoReflect.Descriptor instead.
|
||||
func (*CleanupResponse) Descriptor() ([]byte, []int) {
|
||||
return file_qbittorrent_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *CleanupResponse) GetCount() int32 {
|
||||
if x != nil {
|
||||
return x.Count
|
||||
return x.xxx_hidden_Count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *CleanupResponse) GetHashes() []string {
|
||||
if x != nil {
|
||||
return x.Hashes
|
||||
return x.xxx_hidden_Hashes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CleanupUnregistredRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Act bool `protobuf:"varint,1,opt,name=act,proto3" json:"act,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
func (x *CleanupResponse) SetCount(v int32) {
|
||||
x.xxx_hidden_Count = v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 2)
|
||||
}
|
||||
|
||||
func (x *CleanupResponse) SetHashes(v []string) {
|
||||
x.xxx_hidden_Hashes = v
|
||||
}
|
||||
|
||||
func (x *CleanupResponse) HasCount() bool {
|
||||
if x == nil {
|
||||
return false
|
||||
}
|
||||
return protoimpl.X.Present(&(x.XXX_presence[0]), 0)
|
||||
}
|
||||
|
||||
func (x *CleanupResponse) ClearCount() {
|
||||
protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
|
||||
x.xxx_hidden_Count = 0
|
||||
}
|
||||
|
||||
type CleanupResponse_builder struct {
|
||||
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
|
||||
|
||||
Count *int32
|
||||
Hashes []string
|
||||
}
|
||||
|
||||
func (b0 CleanupResponse_builder) Build() *CleanupResponse {
|
||||
m0 := &CleanupResponse{}
|
||||
b, x := &b0, m0
|
||||
_, _ = b, x
|
||||
if b.Count != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 2)
|
||||
x.xxx_hidden_Count = *b.Count
|
||||
}
|
||||
x.xxx_hidden_Hashes = b.Hashes
|
||||
return m0
|
||||
}
|
||||
|
||||
type CleanupUnregistredRequest struct {
|
||||
state protoimpl.MessageState `protogen:"opaque.v1"`
|
||||
xxx_hidden_Act bool `protobuf:"varint,1,opt,name=act,def=0"`
|
||||
XXX_raceDetectHookData protoimpl.RaceDetectHookData
|
||||
XXX_presence [1]uint32
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
// Default values for CleanupUnregistredRequest fields.
|
||||
const (
|
||||
Default_CleanupUnregistredRequest_Act = bool(false)
|
||||
)
|
||||
|
||||
func (x *CleanupUnregistredRequest) Reset() {
|
||||
*x = CleanupUnregistredRequest{}
|
||||
mi := &file_qbittorrent_proto_msgTypes[5]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -287,7 +472,7 @@ func (x *CleanupUnregistredRequest) String() string {
|
|||
func (*CleanupUnregistredRequest) ProtoMessage() {}
|
||||
|
||||
func (x *CleanupUnregistredRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_qbittorrent_proto_msgTypes[5]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -298,29 +483,61 @@ func (x *CleanupUnregistredRequest) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CleanupUnregistredRequest.ProtoReflect.Descriptor instead.
|
||||
func (*CleanupUnregistredRequest) Descriptor() ([]byte, []int) {
|
||||
return file_qbittorrent_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredRequest) GetAct() bool {
|
||||
if x != nil {
|
||||
return x.Act
|
||||
if protoimpl.X.Present(&(x.XXX_presence[0]), 0) {
|
||||
return x.xxx_hidden_Act
|
||||
}
|
||||
}
|
||||
return false
|
||||
return Default_CleanupUnregistredRequest_Act
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredRequest) SetAct(v bool) {
|
||||
x.xxx_hidden_Act = v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 1)
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredRequest) HasAct() bool {
|
||||
if x == nil {
|
||||
return false
|
||||
}
|
||||
return protoimpl.X.Present(&(x.XXX_presence[0]), 0)
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredRequest) ClearAct() {
|
||||
protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
|
||||
}
|
||||
|
||||
type CleanupUnregistredRequest_builder struct {
|
||||
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
|
||||
|
||||
Act *bool
|
||||
}
|
||||
|
||||
func (b0 CleanupUnregistredRequest_builder) Build() *CleanupUnregistredRequest {
|
||||
m0 := &CleanupUnregistredRequest{}
|
||||
b, x := &b0, m0
|
||||
_, _ = b, x
|
||||
if b.Act != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 1)
|
||||
x.xxx_hidden_Act = *b.Act
|
||||
}
|
||||
return m0
|
||||
}
|
||||
|
||||
type CleanupUnregistredResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Count int32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
|
||||
Hashes []string `protobuf:"bytes,2,rep,name=hashes,proto3" json:"hashes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"opaque.v1"`
|
||||
xxx_hidden_Count int32 `protobuf:"varint,1,opt,name=count"`
|
||||
xxx_hidden_Hashes []string `protobuf:"bytes,2,rep,name=hashes"`
|
||||
XXX_raceDetectHookData protoimpl.RaceDetectHookData
|
||||
XXX_presence [1]uint32
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredResponse) Reset() {
|
||||
*x = CleanupUnregistredResponse{}
|
||||
mi := &file_qbittorrent_proto_msgTypes[6]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
@ -332,7 +549,7 @@ func (x *CleanupUnregistredResponse) String() string {
|
|||
func (*CleanupUnregistredResponse) ProtoMessage() {}
|
||||
|
||||
func (x *CleanupUnregistredResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_qbittorrent_proto_msgTypes[6]
|
||||
mi := &file_proto_qbittorrent_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
@ -343,85 +560,108 @@ func (x *CleanupUnregistredResponse) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CleanupUnregistredResponse.ProtoReflect.Descriptor instead.
|
||||
func (*CleanupUnregistredResponse) Descriptor() ([]byte, []int) {
|
||||
return file_qbittorrent_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredResponse) GetCount() int32 {
|
||||
if x != nil {
|
||||
return x.Count
|
||||
return x.xxx_hidden_Count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredResponse) GetHashes() []string {
|
||||
if x != nil {
|
||||
return x.Hashes
|
||||
return x.xxx_hidden_Hashes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_qbittorrent_proto protoreflect.FileDescriptor
|
||||
func (x *CleanupUnregistredResponse) SetCount(v int32) {
|
||||
x.xxx_hidden_Count = v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 2)
|
||||
}
|
||||
|
||||
const file_qbittorrent_proto_rawDesc = "" +
|
||||
func (x *CleanupUnregistredResponse) SetHashes(v []string) {
|
||||
x.xxx_hidden_Hashes = v
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredResponse) HasCount() bool {
|
||||
if x == nil {
|
||||
return false
|
||||
}
|
||||
return protoimpl.X.Present(&(x.XXX_presence[0]), 0)
|
||||
}
|
||||
|
||||
func (x *CleanupUnregistredResponse) ClearCount() {
|
||||
protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
|
||||
x.xxx_hidden_Count = 0
|
||||
}
|
||||
|
||||
type CleanupUnregistredResponse_builder struct {
|
||||
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
|
||||
|
||||
Count *int32
|
||||
Hashes []string
|
||||
}
|
||||
|
||||
func (b0 CleanupUnregistredResponse_builder) Build() *CleanupUnregistredResponse {
|
||||
m0 := &CleanupUnregistredResponse{}
|
||||
b, x := &b0, m0
|
||||
_, _ = b, x
|
||||
if b.Count != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 2)
|
||||
x.xxx_hidden_Count = *b.Count
|
||||
}
|
||||
x.xxx_hidden_Hashes = b.Hashes
|
||||
return m0
|
||||
}
|
||||
|
||||
var File_proto_qbittorrent_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_proto_qbittorrent_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x11qbittorrent.proto\x12\vqbittorrent\x1a\"server/proto/filters/filters.proto\"T\n" +
|
||||
"\x17proto/qbittorrent.proto\x12\x19tstor.daemons.qbittorrent\x1a!google/protobuf/go_features.proto\x1a\x1bproto/filters/filters.proto\"T\n" +
|
||||
"\aTorrent\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" +
|
||||
"\x04hash\x18\x02 \x01(\tR\x04hash\x12!\n" +
|
||||
"\fsource_files\x18\x03 \x03(\tR\vsourceFiles\"S\n" +
|
||||
"\x12GetTorrentsRequest\x12=\n" +
|
||||
"\rsources_count\x18\x01 \x01(\v2\x18.tstor.filters.IntFilterR\fsourcesCount\"G\n" +
|
||||
"\x13GetTorrentsResponse\x120\n" +
|
||||
"\btorrents\x18\x01 \x03(\v2\x14.qbittorrent.TorrentR\btorrents\"\"\n" +
|
||||
"\x0eCleanupRequest\x12\x10\n" +
|
||||
"\x03act\x18\x01 \x01(\bR\x03act\"?\n" +
|
||||
"\rsources_count\x18\x01 \x01(\v2\x18.tstor.filters.IntFilterR\fsourcesCount\"U\n" +
|
||||
"\x13GetTorrentsResponse\x12>\n" +
|
||||
"\btorrents\x18\x01 \x03(\v2\".tstor.daemons.qbittorrent.TorrentR\btorrents\")\n" +
|
||||
"\x0eCleanupRequest\x12\x17\n" +
|
||||
"\x03act\x18\x01 \x01(\b:\x05falseR\x03act\"?\n" +
|
||||
"\x0fCleanupResponse\x12\x14\n" +
|
||||
"\x05count\x18\x01 \x01(\x05R\x05count\x12\x16\n" +
|
||||
"\x06hashes\x18\x02 \x03(\tR\x06hashes\"-\n" +
|
||||
"\x19CleanupUnregistredRequest\x12\x10\n" +
|
||||
"\x03act\x18\x01 \x01(\bR\x03act\"J\n" +
|
||||
"\x06hashes\x18\x02 \x03(\tR\x06hashes\"4\n" +
|
||||
"\x19CleanupUnregistredRequest\x12\x17\n" +
|
||||
"\x03act\x18\x01 \x01(\b:\x05falseR\x03act\"J\n" +
|
||||
"\x1aCleanupUnregistredResponse\x12\x14\n" +
|
||||
"\x05count\x18\x01 \x01(\x05R\x05count\x12\x16\n" +
|
||||
"\x06hashes\x18\x02 \x03(\tR\x06hashes2\x99\x02\n" +
|
||||
"\x12QBitTorrentService\x12R\n" +
|
||||
"\vGetTorrents\x12\x1f.qbittorrent.GetTorrentsRequest\x1a .qbittorrent.GetTorrentsResponse\"\x00\x12F\n" +
|
||||
"\aCleanup\x12\x1b.qbittorrent.CleanupRequest\x1a\x1c.qbittorrent.CleanupResponse\"\x00\x12g\n" +
|
||||
"\x12CleanupUnregistred\x12&.qbittorrent.CleanupUnregistredRequest\x1a'.qbittorrent.CleanupUnregistredResponse\"\x00B5Z3github.com/royalcat/tstor/plugins/qbittorrent/protob\x06proto3"
|
||||
"\x06hashes\x18\x02 \x03(\tR\x06hashes2\xee\x02\n" +
|
||||
"\x12QBitTorrentService\x12n\n" +
|
||||
"\vGetTorrents\x12-.tstor.daemons.qbittorrent.GetTorrentsRequest\x1a..tstor.daemons.qbittorrent.GetTorrentsResponse\"\x00\x12b\n" +
|
||||
"\aCleanup\x12).tstor.daemons.qbittorrent.CleanupRequest\x1a*.tstor.daemons.qbittorrent.CleanupResponse\"\x00\x12\x83\x01\n" +
|
||||
"\x12CleanupUnregistred\x124.tstor.daemons.qbittorrent.CleanupUnregistredRequest\x1a5.tstor.daemons.qbittorrent.CleanupUnregistredResponse\"\x00BNZDgit.kmsign.ru/royalcat/tstor/plugins/qbittorrent/delivery/grpc/proto\x92\x03\x05\xd2>\x02\x10\x03b\beditionsp\xe8\a"
|
||||
|
||||
var (
|
||||
file_qbittorrent_proto_rawDescOnce sync.Once
|
||||
file_qbittorrent_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_qbittorrent_proto_rawDescGZIP() []byte {
|
||||
file_qbittorrent_proto_rawDescOnce.Do(func() {
|
||||
file_qbittorrent_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_qbittorrent_proto_rawDesc), len(file_qbittorrent_proto_rawDesc)))
|
||||
})
|
||||
return file_qbittorrent_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_qbittorrent_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_qbittorrent_proto_goTypes = []any{
|
||||
(*Torrent)(nil), // 0: qbittorrent.Torrent
|
||||
(*GetTorrentsRequest)(nil), // 1: qbittorrent.GetTorrentsRequest
|
||||
(*GetTorrentsResponse)(nil), // 2: qbittorrent.GetTorrentsResponse
|
||||
(*CleanupRequest)(nil), // 3: qbittorrent.CleanupRequest
|
||||
(*CleanupResponse)(nil), // 4: qbittorrent.CleanupResponse
|
||||
(*CleanupUnregistredRequest)(nil), // 5: qbittorrent.CleanupUnregistredRequest
|
||||
(*CleanupUnregistredResponse)(nil), // 6: qbittorrent.CleanupUnregistredResponse
|
||||
var file_proto_qbittorrent_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_proto_qbittorrent_proto_goTypes = []any{
|
||||
(*Torrent)(nil), // 0: tstor.daemons.qbittorrent.Torrent
|
||||
(*GetTorrentsRequest)(nil), // 1: tstor.daemons.qbittorrent.GetTorrentsRequest
|
||||
(*GetTorrentsResponse)(nil), // 2: tstor.daemons.qbittorrent.GetTorrentsResponse
|
||||
(*CleanupRequest)(nil), // 3: tstor.daemons.qbittorrent.CleanupRequest
|
||||
(*CleanupResponse)(nil), // 4: tstor.daemons.qbittorrent.CleanupResponse
|
||||
(*CleanupUnregistredRequest)(nil), // 5: tstor.daemons.qbittorrent.CleanupUnregistredRequest
|
||||
(*CleanupUnregistredResponse)(nil), // 6: tstor.daemons.qbittorrent.CleanupUnregistredResponse
|
||||
(*filters.IntFilter)(nil), // 7: tstor.filters.IntFilter
|
||||
}
|
||||
var file_qbittorrent_proto_depIdxs = []int32{
|
||||
7, // 0: qbittorrent.GetTorrentsRequest.sources_count:type_name -> tstor.filters.IntFilter
|
||||
0, // 1: qbittorrent.GetTorrentsResponse.torrents:type_name -> qbittorrent.Torrent
|
||||
1, // 2: qbittorrent.QBitTorrentService.GetTorrents:input_type -> qbittorrent.GetTorrentsRequest
|
||||
3, // 3: qbittorrent.QBitTorrentService.Cleanup:input_type -> qbittorrent.CleanupRequest
|
||||
5, // 4: qbittorrent.QBitTorrentService.CleanupUnregistred:input_type -> qbittorrent.CleanupUnregistredRequest
|
||||
2, // 5: qbittorrent.QBitTorrentService.GetTorrents:output_type -> qbittorrent.GetTorrentsResponse
|
||||
4, // 6: qbittorrent.QBitTorrentService.Cleanup:output_type -> qbittorrent.CleanupResponse
|
||||
6, // 7: qbittorrent.QBitTorrentService.CleanupUnregistred:output_type -> qbittorrent.CleanupUnregistredResponse
|
||||
var file_proto_qbittorrent_proto_depIdxs = []int32{
|
||||
7, // 0: tstor.daemons.qbittorrent.GetTorrentsRequest.sources_count:type_name -> tstor.filters.IntFilter
|
||||
0, // 1: tstor.daemons.qbittorrent.GetTorrentsResponse.torrents:type_name -> tstor.daemons.qbittorrent.Torrent
|
||||
1, // 2: tstor.daemons.qbittorrent.QBitTorrentService.GetTorrents:input_type -> tstor.daemons.qbittorrent.GetTorrentsRequest
|
||||
3, // 3: tstor.daemons.qbittorrent.QBitTorrentService.Cleanup:input_type -> tstor.daemons.qbittorrent.CleanupRequest
|
||||
5, // 4: tstor.daemons.qbittorrent.QBitTorrentService.CleanupUnregistred:input_type -> tstor.daemons.qbittorrent.CleanupUnregistredRequest
|
||||
2, // 5: tstor.daemons.qbittorrent.QBitTorrentService.GetTorrents:output_type -> tstor.daemons.qbittorrent.GetTorrentsResponse
|
||||
4, // 6: tstor.daemons.qbittorrent.QBitTorrentService.Cleanup:output_type -> tstor.daemons.qbittorrent.CleanupResponse
|
||||
6, // 7: tstor.daemons.qbittorrent.QBitTorrentService.CleanupUnregistred:output_type -> tstor.daemons.qbittorrent.CleanupUnregistredResponse
|
||||
5, // [5:8] is the sub-list for method output_type
|
||||
2, // [2:5] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
|
@ -429,26 +669,26 @@ var file_qbittorrent_proto_depIdxs = []int32{
|
|||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_qbittorrent_proto_init() }
|
||||
func file_qbittorrent_proto_init() {
|
||||
if File_qbittorrent_proto != nil {
|
||||
func init() { file_proto_qbittorrent_proto_init() }
|
||||
func file_proto_qbittorrent_proto_init() {
|
||||
if File_proto_qbittorrent_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_qbittorrent_proto_rawDesc), len(file_qbittorrent_proto_rawDesc)),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_qbittorrent_proto_rawDesc), len(file_proto_qbittorrent_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_qbittorrent_proto_goTypes,
|
||||
DependencyIndexes: file_qbittorrent_proto_depIdxs,
|
||||
MessageInfos: file_qbittorrent_proto_msgTypes,
|
||||
GoTypes: file_proto_qbittorrent_proto_goTypes,
|
||||
DependencyIndexes: file_proto_qbittorrent_proto_depIdxs,
|
||||
MessageInfos: file_proto_qbittorrent_proto_msgTypes,
|
||||
}.Build()
|
||||
File_qbittorrent_proto = out.File
|
||||
file_qbittorrent_proto_goTypes = nil
|
||||
file_qbittorrent_proto_depIdxs = nil
|
||||
File_proto_qbittorrent_proto = out.File
|
||||
file_proto_qbittorrent_proto_goTypes = nil
|
||||
file_proto_qbittorrent_proto_depIdxs = nil
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v6.30.2
|
||||
// source: qbittorrent.proto
|
||||
// source: proto/qbittorrent.proto
|
||||
|
||||
package proto
|
||||
|
||||
|
@ -19,9 +19,9 @@ import (
|
|||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
QBitTorrentService_GetTorrents_FullMethodName = "/qbittorrent.QBitTorrentService/GetTorrents"
|
||||
QBitTorrentService_Cleanup_FullMethodName = "/qbittorrent.QBitTorrentService/Cleanup"
|
||||
QBitTorrentService_CleanupUnregistred_FullMethodName = "/qbittorrent.QBitTorrentService/CleanupUnregistred"
|
||||
QBitTorrentService_GetTorrents_FullMethodName = "/tstor.daemons.qbittorrent.QBitTorrentService/GetTorrents"
|
||||
QBitTorrentService_Cleanup_FullMethodName = "/tstor.daemons.qbittorrent.QBitTorrentService/Cleanup"
|
||||
QBitTorrentService_CleanupUnregistred_FullMethodName = "/tstor.daemons.qbittorrent.QBitTorrentService/CleanupUnregistred"
|
||||
)
|
||||
|
||||
// QBitTorrentServiceClient is the client API for QBitTorrentService service.
|
||||
|
@ -174,7 +174,7 @@ func _QBitTorrentService_CleanupUnregistred_Handler(srv interface{}, ctx context
|
|||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var QBitTorrentService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "qbittorrent.QBitTorrentService",
|
||||
ServiceName: "tstor.daemons.qbittorrent.QBitTorrentService",
|
||||
HandlerType: (*QBitTorrentServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
|
@ -191,5 +191,5 @@ var QBitTorrentService_ServiceDesc = grpc.ServiceDesc{
|
|||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "qbittorrent.proto",
|
||||
Metadata: "proto/qbittorrent.proto",
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/server/src/daemon"
|
||||
"git.kmsign.ru/royalcat/tstor/server/src/vfs"
|
||||
"github.com/knadh/koanf/v2"
|
||||
)
|
||||
|
||||
|
@ -12,5 +13,5 @@ type Plugin interface {
|
|||
}
|
||||
|
||||
type DaemonPlugin interface {
|
||||
NewDaemon(context.Context, *koanf.Koanf) (daemon.Daemon, error)
|
||||
NewDaemon(context.Context, *koanf.Koanf, vfs.Filesystem) (daemon.Daemon, error)
|
||||
}
|
||||
|
|
|
@ -75,6 +75,8 @@ func start(configPath string, plugins []Plugin) error {
|
|||
|
||||
log := rlog.Component("run")
|
||||
|
||||
sourceFS := vfs.NewOsFs(conf.SourceDir)
|
||||
|
||||
daemons := []daemon.Daemon{}
|
||||
|
||||
for _, plugin := range conf.Plugins {
|
||||
|
@ -91,7 +93,7 @@ func start(configPath string, plugins []Plugin) error {
|
|||
if daemonPlugin, ok := pluginStub.(DaemonPlugin); ok {
|
||||
log.Debug(ctx, "plugin implements has daemon, creating", slog.String("name", pluginStub.Name()))
|
||||
|
||||
daemon, err := daemonPlugin.NewDaemon(ctx, pluginConfig)
|
||||
daemon, err := daemonPlugin.NewDaemon(ctx, pluginConfig, sourceFS)
|
||||
if err != nil {
|
||||
log.Error(ctx, "error creating plugin daemon", rlog.Error(err))
|
||||
continue
|
||||
|
@ -114,7 +116,7 @@ func start(configPath string, plugins []Plugin) error {
|
|||
|
||||
// sourceFs := vfs.NewCtxBillyFs("/", ctxbilly.WrapFileSystem(osfs.New(conf.SourceDir, osfs.WithBoundOS())))
|
||||
|
||||
hostedfs, err := daemon.NewHostedFS(vfs.NewOsFs(conf.SourceDir), daemons)
|
||||
hostedfs, err := daemon.NewHostedFS(sourceFS, daemons)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating hosted filesystem: %w", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue