From 199a82ff0c4206bf724dbe273bd3aaf99bdc1a07 Mon Sep 17 00:00:00 2001 From: royalcat Date: Sun, 7 Jul 2024 23:09:13 +0300 Subject: [PATCH] torrent priority and piece state fix --- .gqlgen.yml | 42 +- .vscode/launch.json | 6 +- Makefile | 2 +- cmd/generate-graphql/main.go | 59 +- go.mod | 20 +- go.sum | 40 +- graphql/mutation.graphql | 20 +- graphql/query.graphql | 45 +- graphql/schema.graphql | 2 + graphql/sources/torrent_mutation.graphql | 18 + graphql/sources/torrent_query.graphql | 27 + .../torrent_types.graphql} | 20 +- graphql/types/filters.graphql | 31 + graphql/types/fs.graphql | 8 +- pkg/rlog/rlog.go | 48 +- src/delivery/graphql/generated.go | 2137 ++++++++++++----- src/delivery/graphql/model/filter.go | 22 + src/delivery/graphql/model/mappers.go | 13 - src/delivery/graphql/model/models_gen.go | 34 +- src/delivery/graphql/resolver/fs.resolvers.go | 2 +- .../graphql/resolver/mutation.resolvers.go | 78 +- .../graphql/resolver/query.resolvers.go | 79 +- .../resolver/subscription.resolvers.go | 2 +- .../resolver/torrent_mutation.resolvers.go | 90 + .../resolver/torrent_query.resolvers.go | 94 + ...esolvers.go => torrent_types.resolvers.go} | 8 +- src/delivery/router.go | 8 +- src/log/badger.go | 18 +- src/sources/torrent/controller.go | 85 +- src/sources/torrent/piece_completion.go | 16 +- src/sources/torrent/setup.go | 6 + src/sources/torrent/storage_open.go | 55 +- ui/lib/api/schema.graphql | 51 +- 33 files changed, 2227 insertions(+), 959 deletions(-) create mode 100644 graphql/sources/torrent_mutation.graphql create mode 100644 graphql/sources/torrent_query.graphql rename graphql/{types/torrent.graphql => sources/torrent_types.graphql} (55%) create mode 100644 graphql/types/filters.graphql create mode 100644 src/delivery/graphql/resolver/torrent_mutation.resolvers.go create mode 100644 src/delivery/graphql/resolver/torrent_query.resolvers.go rename src/delivery/graphql/resolver/{torrent.resolvers.go => torrent_types.resolvers.go} (90%) diff --git a/.gqlgen.yml b/.gqlgen.yml index 98fae22..e6c7dff 100644 --- a/.gqlgen.yml +++ b/.gqlgen.yml @@ -22,18 +22,9 @@ models: Int: model: github.com/99designs/gqlgen/graphql.Int64 Torrent: - fields: - name: - resolver: true - files: - resolver: true - excludedFiles: - resolver: true - peers: - resolver: true extraFields: T: - type: "*git.kmsign.ru/royalcat/tstor/src/host/torrent.Controller" + type: "*git.kmsign.ru/royalcat/tstor/src/sources/torrent.Controller" TorrentFile: extraFields: F: @@ -43,32 +34,37 @@ models: F: type: "*github.com/anacrolix/torrent.PeerConn" SimpleDir: - fields: - entries: - resolver: true extraFields: Path: type: string FS: type: "git.kmsign.ru/royalcat/tstor/src/vfs.Filesystem" TorrentFS: - fields: - entries: - resolver: true extraFields: FS: - type: "*git.kmsign.ru/royalcat/tstor/src/host/torrent.TorrentFS" + type: "*git.kmsign.ru/royalcat/tstor/src/sources/torrent.TorrentFS" ResolverFS: - fields: - entries: - resolver: true extraFields: FS: type: "*git.kmsign.ru/royalcat/tstor/src/vfs.ResolverFS" ArchiveFS: - fields: - entries: - resolver: true extraFields: FS: type: "*git.kmsign.ru/royalcat/tstor/src/vfs.ArchiveFS" + TorrentOps: + extraFields: + InfoHash: + type: "string" + TorrentPriority: + model: "github.com/anacrolix/torrent/types.PiecePriority" + enum_values: + NONE: + value: "github.com/anacrolix/torrent/types.PiecePriorityNone" + NORMAL: + value: "github.com/anacrolix/torrent/types.PiecePriorityNormal" + HIGH: + value: "github.com/anacrolix/torrent/types.PiecePriorityHigh" + READAHEAD: + value: "github.com/anacrolix/torrent/types.PiecePriorityReadahead" + NOW: + value: "github.com/anacrolix/torrent/types.PiecePriorityNow" diff --git a/.vscode/launch.json b/.vscode/launch.json index bc0b8c4..7f0b96d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,14 +5,14 @@ "version": "0.2.0", "configurations": [ { - "name": "Launch file", + "name": "Generate GraphQL", "type": "go", "request": "launch", "mode": "debug", - "program": "${file}" + "program": "${workspaceFolder}/cmd/generate-graphql/main.go", }, { - "name": "Launch Package", + "name": "TStor", "type": "go", "request": "launch", "mode": "auto", diff --git a/Makefile b/Makefile index a171a40..fa6d5d4 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ generate-graphql: src/delivery/graphql/generated.go ui/lib/api/schema.graphql -src/delivery/graphql/generated.go: .gqlgen.yml graphql/* graphql/types/* cmd/generate-graphql/* +src/delivery/graphql/generated.go: .gqlgen.yml cmd/generate-graphql/* $(shell find graphql -type f) go run cmd/generate-graphql/main.go ui/lib/api/schema.graphql: src/delivery/graphql/* cmd/generate-graphql-schema/* diff --git a/cmd/generate-graphql/main.go b/cmd/generate-graphql/main.go index ea2d6aa..52f56c4 100644 --- a/cmd/generate-graphql/main.go +++ b/cmd/generate-graphql/main.go @@ -10,6 +10,23 @@ import ( "github.com/99designs/gqlgen/codegen/config" ) +func main() { + cfg, err := config.LoadConfigFromDefaultLocations() + if err != nil { + fmt.Fprintln(os.Stderr, "failed to load config", err.Error()) + os.Exit(2) + } + + err = api.Generate(cfg, + api.PrependPlugin(&resolverDirective{}), + api.AddPlugin(&fieldDirectiveFix{}), + ) + if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(3) + } +} + type fieldDirectiveFix struct { } @@ -25,9 +42,6 @@ func (fieldDirectiveFix) GenerateCode(cfg *codegen.Data) error { for _, v := range field.TypeReference.Definition.Directives { directiveMap[v.Name]++ } - // for _, v := range field.Object.Directives { - // directiveMap[v.Name]++ - // } directive := make([]*codegen.Directive, 0, len(field.Directives)) for _, v := range field.Directives { @@ -48,18 +62,33 @@ func (fieldDirectiveFix) GenerateCode(cfg *codegen.Data) error { return nil } -func main() { - cfg, err := config.LoadConfigFromDefaultLocations() - if err != nil { - fmt.Fprintln(os.Stderr, "failed to load config", err.Error()) - os.Exit(2) +type resolverDirective struct { +} + +func (resolverDirective) Name() string { + return "Resolver directive support" +} + +func (resolverDirective) GenerateCode(cfg *codegen.Data) error { + const directiveName = "resolver" + + for _, obj := range cfg.Objects { + for _, field := range obj.Fields { + if field.FieldDefinition.Directives.ForName(directiveName) != nil { + fmt.Printf("Add resolver for field %s{%s}\n", obj.Name, field.Name) + field.IsResolver = true + + // TODO + // field.FieldDefinition.Directives = removeDirective(field.FieldDefinition.Directives, directiveName) + } + } } - err = api.Generate(cfg, - api.AddPlugin(&fieldDirectiveFix{}), - ) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - os.Exit(3) - } + return nil } + +// func removeDirective(directives ast.DirectiveList, name string) ast.DirectiveList { +// return slices.DeleteFunc(directives, func(directive *ast.Directive) bool { +// return directive.Name == name +// }) +// } diff --git a/go.mod b/go.mod index d70e962..34fed80 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,13 @@ module git.kmsign.ru/royalcat/tstor go 1.22.3 require ( - github.com/99designs/gqlgen v0.17.45 + github.com/99designs/gqlgen v0.17.49 github.com/agoda-com/opentelemetry-go/otelslog v0.1.1 github.com/agoda-com/opentelemetry-logs-go v0.5.0 github.com/anacrolix/dht/v2 v2.21.1 github.com/anacrolix/log v0.15.2 github.com/anacrolix/missinggo/v2 v2.7.3 - github.com/anacrolix/torrent v1.56.0 + github.com/anacrolix/torrent v1.56.1 github.com/billziss-gh/cgofuse v1.5.0 github.com/bodgit/sevenzip v1.5.1 github.com/cyphar/filepath-securejoin v0.2.5 @@ -43,7 +43,7 @@ require ( github.com/samber/slog-zerolog v1.0.0 github.com/stretchr/testify v1.9.0 github.com/urfave/cli/v2 v2.27.2 - github.com/vektah/gqlparser/v2 v2.5.11 + github.com/vektah/gqlparser/v2 v2.5.16 github.com/willscott/go-nfs-client v0.0.0-20240104095149-b44639837b00 github.com/willscott/memphis v0.0.0-20210922141505-529d4987ab7e go.opentelemetry.io/otel v1.27.0 @@ -54,9 +54,9 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 - golang.org/x/net v0.25.0 + golang.org/x/net v0.26.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.20.0 + golang.org/x/sys v0.21.0 ) require ( @@ -168,7 +168,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 // indirect github.com/samber/lo v1.39.0 // indirect - github.com/sosodev/duration v1.3.0 // indirect + github.com/sosodev/duration v1.3.1 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/tidwall/btree v1.7.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect @@ -185,11 +185,11 @@ require ( go.opentelemetry.io/proto/otlp v1.2.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.21.0 // indirect + golang.org/x/tools v0.22.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect google.golang.org/grpc v1.64.0 // indirect diff --git a/go.sum b/go.sum index 32af796..4c30d9b 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ crawshaw.io/sqlite v0.3.2/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -github.com/99designs/gqlgen v0.17.45 h1:bH0AH67vIJo8JKNKPJP+pOPpQhZeuVRQLf53dKIpDik= -github.com/99designs/gqlgen v0.17.45/go.mod h1:Bas0XQ+Jiu/Xm5E33jC8sES3G+iC2esHBMXcq0fUPs0= +github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= +github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= @@ -99,8 +99,8 @@ github.com/anacrolix/sync v0.5.1/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DC github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw= github.com/anacrolix/tagflag v1.0.0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw= github.com/anacrolix/tagflag v1.1.0/go.mod h1:Scxs9CV10NQatSmbyjqmqmeQNwGzlNe0CMUMIxqHIG8= -github.com/anacrolix/torrent v1.56.0 h1:g/sM0K/BaWUv4Htu2bblLBhIxGdFZ1MUCoD7lcvemlo= -github.com/anacrolix/torrent v1.56.0/go.mod h1:5DMHbeIM1TuC5wTQ99XieKKLiYZYz6iB2lyZpKZEr6w= +github.com/anacrolix/torrent v1.56.1 h1:QeJMOP0NuhpQ5dATsOqEL0vUO85aPMNMGP2FACNt0Eg= +github.com/anacrolix/torrent v1.56.1/go.mod h1:5DMHbeIM1TuC5wTQ99XieKKLiYZYz6iB2lyZpKZEr6w= github.com/anacrolix/upnp v0.1.4 h1:+2t2KA6QOhm/49zeNyeVwDu1ZYS9dB9wfxyVvh/wk7U= github.com/anacrolix/upnp v0.1.4/go.mod h1:Qyhbqo69gwNWvEk1xNTXsS5j7hMHef9hdr984+9fIic= github.com/anacrolix/utp v0.2.0 h1:65Cdmr6q9WSw2KsM+rtJFu7rqDzLl2bdysf4KlNPcFI= @@ -582,8 +582,8 @@ github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:K github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= -github.com/sosodev/duration v1.3.0 h1:g3E6mto+hFdA2uZXeNDYff8LYeg7v5D4YKP/Ng/NUkE= -github.com/sosodev/duration v1.3.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= +github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -622,8 +622,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw 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.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= -github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= +github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= +github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/warpfork/go-errcat v0.0.0-20180917083543-335044ffc86e h1:FIB2fi7XJGHIdf5rWNsfFQqatIKxutT45G+wNuMQNgs= github.com/warpfork/go-errcat v0.0.0-20180917083543-335044ffc86e/go.mod h1:/qe02xr3jvTUz8u/PV0FHGpP8t96OQNP7U9BJMwMLEw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -695,8 +695,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -730,8 +730,8 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -764,8 +764,8 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -826,8 +826,8 @@ golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -850,8 +850,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 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.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -887,8 +887,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/graphql/mutation.graphql b/graphql/mutation.graphql index 83a3a86..9abe03e 100644 --- a/graphql/mutation.graphql +++ b/graphql/mutation.graphql @@ -1,26 +1,10 @@ type Mutation { - validateTorrents(filter: TorrentFilter!): Boolean! - cleanupTorrents(files: Boolean, dryRun: Boolean!): CleanupResponse! - downloadTorrent(infohash: String!, file: String): DownloadTorrentResponse + torrentDaemon: TorrentDaemonMutation @resolver + uploadFile(dir: String!, file: Upload!): Boolean! dedupeStorage: Int! } -input TorrentFilter @oneOf { - everything: Boolean - infohash: String - # pathGlob: String! -} - -type DownloadTorrentResponse { - task: Task -} - -type CleanupResponse { - count: Int! - list: [String!]! -} - type Task { id: ID! } diff --git a/graphql/query.graphql b/graphql/query.graphql index 47b2a5f..6c7ba45 100644 --- a/graphql/query.graphql +++ b/graphql/query.graphql @@ -1,46 +1,5 @@ type Query { - torrents(filter: TorrentsFilter): [Torrent!]! + torrentDaemon: TorrentDaemonQuery @resolver + fsEntry(path: String!): FsEntry } - -input TorrentsFilter { - infohash: StringFilter - name: StringFilter - bytesCompleted: IntFilter - bytesMissing: IntFilter - - peersCount: IntFilter - downloading: BooleanFilter -} - -input Pagination { - offset: Int! - limit: Int! -} - -input StringFilter @oneOf { - eq: String - substr: String - in: [String!] -} - -input IntFilter @oneOf { - eq: Int - gt: Int - lt: Int - gte: Int - lte: Int - in: [Int!] -} - -input DateTimeFilter @oneOf { - eq: DateTime - gt: DateTime - lt: DateTime - gte: DateTime - lte: DateTime -} - -input BooleanFilter @oneOf { - eq: Boolean -} diff --git a/graphql/schema.graphql b/graphql/schema.graphql index 21b5cdf..e18fd22 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -1,4 +1,6 @@ directive @oneOf on INPUT_OBJECT | FIELD_DEFINITION +directive @resolver on INPUT_FIELD_DEFINITION | FIELD_DEFINITION + directive @stream on FIELD_DEFINITION scalar DateTime diff --git a/graphql/sources/torrent_mutation.graphql b/graphql/sources/torrent_mutation.graphql new file mode 100644 index 0000000..4bf6f77 --- /dev/null +++ b/graphql/sources/torrent_mutation.graphql @@ -0,0 +1,18 @@ +type TorrentDaemonMutation { + validateTorrent(filter: TorrentFilter!): Boolean! @resolver + setTorrentPriority( + infohash: String! + file: String + priority: TorrentPriority! + ): Boolean! @resolver + cleanup(files: Boolean, dryRun: Boolean!): CleanupResponse! @resolver +} + +type CleanupResponse { + count: Int! + list: [String!]! +} + +type DownloadTorrentResponse { + task: Task +} diff --git a/graphql/sources/torrent_query.graphql b/graphql/sources/torrent_query.graphql new file mode 100644 index 0000000..0bf5335 --- /dev/null +++ b/graphql/sources/torrent_query.graphql @@ -0,0 +1,27 @@ +type TorrentDaemonQuery { + torrents(filter: TorrentsFilter): [Torrent!]! @resolver +} + +input TorrentsFilter { + infohash: StringFilter + name: StringFilter + bytesCompleted: IntFilter + bytesMissing: IntFilter + peersCount: IntFilter + priority: TorrentPriorityFilter +} + +input TorrentPriorityFilter @oneOf { + eq: TorrentPriority + gt: TorrentPriority + lt: TorrentPriority + gte: TorrentPriority + lte: TorrentPriority + in: [TorrentPriority!] +} + +input TorrentFilter @oneOf { + everything: Boolean + infohash: String + # pathGlob: String! +} diff --git a/graphql/types/torrent.graphql b/graphql/sources/torrent_types.graphql similarity index 55% rename from graphql/types/torrent.graphql rename to graphql/sources/torrent_types.graphql index 1a16327..ecc5723 100644 --- a/graphql/types/torrent.graphql +++ b/graphql/sources/torrent_types.graphql @@ -1,15 +1,13 @@ type Torrent { - name: String! + name: String! @resolver infohash: String! bytesCompleted: Int! torrentFilePath: String! bytesMissing: Int! - files: [TorrentFile!]! - excludedFiles: [TorrentFile!]! - peers: [TorrentPeer!]! - - # if at least one piece of the torrent is request to download and not already downloaded - downloading: Boolean! + priority: TorrentPriority! @resolver + files: [TorrentFile!]! @resolver + excludedFiles: [TorrentFile!]! @resolver + peers: [TorrentPeer!]! @resolver } type TorrentFile { @@ -25,3 +23,11 @@ type TorrentPeer { port: Int! clientName: String! } + +enum TorrentPriority { + NONE + NORMAL + HIGH + READAHEAD + NOW +} diff --git a/graphql/types/filters.graphql b/graphql/types/filters.graphql new file mode 100644 index 0000000..f26cc62 --- /dev/null +++ b/graphql/types/filters.graphql @@ -0,0 +1,31 @@ +input Pagination { + offset: Int! + limit: Int! +} + +input StringFilter @oneOf { + eq: String + substr: String + in: [String!] +} + +input IntFilter @oneOf { + eq: Int + gt: Int + lt: Int + gte: Int + lte: Int + in: [Int!] +} + +input DateTimeFilter @oneOf { + eq: DateTime + gt: DateTime + lt: DateTime + gte: DateTime + lte: DateTime +} + +input BooleanFilter @oneOf { + eq: Boolean +} diff --git a/graphql/types/fs.graphql b/graphql/types/fs.graphql index 4174f04..a34da46 100644 --- a/graphql/types/fs.graphql +++ b/graphql/types/fs.graphql @@ -14,7 +14,7 @@ interface File implements FsEntry { type SimpleDir implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type SimpleFile implements File & FsEntry { @@ -24,12 +24,12 @@ type SimpleFile implements File & FsEntry { type ResolverFS implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type ArchiveFS implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver size: Int! } @@ -37,7 +37,7 @@ type ArchiveFS implements Dir & FsEntry { type TorrentFS implements Dir & FsEntry { name: String! torrent: Torrent! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type TorrentFileEntry implements File & FsEntry { diff --git a/pkg/rlog/rlog.go b/pkg/rlog/rlog.go index 96fa0ba..5f16433 100644 --- a/pkg/rlog/rlog.go +++ b/pkg/rlog/rlog.go @@ -34,24 +34,35 @@ func AddHandler(nh slog.Handler) { } type Logger struct { - handler slog.Handler - component []string + handler slog.Handler + callNesting int + component []string } const functionKey = "function" +const componentKey = "component" +const componentSep = "." + func (l *Logger) log(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr) { var pcs [1]uintptr - runtime.Callers(3, pcs[:]) + runtime.Callers(3+l.callNesting, pcs[:]) pc := pcs[0] f := runtime.FuncForPC(pc) - attrs = append(attrs, slog.String(functionKey, f.Name())) + if f != nil { + attrs = append(attrs, slog.String(functionKey, f.Name())) + } + + if len(l.component) > 0 { + attrs = append(attrs, slog.String(componentKey, strings.Join(l.component, componentSep))) + } r := slog.NewRecord(time.Now(), level, msg, pc) r.AddAttrs(attrs...) if ctx == nil { ctx = context.Background() } + _ = l.handler.Handle(ctx, r) } @@ -71,16 +82,10 @@ func (l *Logger) Error(ctx context.Context, msg string, attrs ...slog.Attr) { l.log(ctx, slog.LevelError, msg, attrs...) } -const componentKey = "component" -const componentSep = "." - func (log *Logger) WithComponent(name string) *Logger { - c := append(log.component, name) return &Logger{ - handler: log.handler.WithAttrs([]slog.Attr{ - slog.String(componentKey, strings.Join(c, componentSep)), - }), - component: c, + handler: log.handler, + component: append(log.component, name), } } @@ -91,23 +96,20 @@ func (l *Logger) With(attrs ...slog.Attr) *Logger { } } +func (l *Logger) Nested(callNesting int) *Logger { + return &Logger{ + handler: l.handler, + component: l.component, + callNesting: callNesting, + } +} + // returns a new slog logger with the same attribures as the original logger // TODO currently not logging function name func (l *Logger) Slog() *slog.Logger { return slog.New(l.handler) } -const endpointKey = "endpoint" - -func (l *Logger) WithEndpoint(name string) *Logger { - return &Logger{ - handler: l.handler.WithAttrs([]slog.Attr{ - slog.String(endpointKey, name), - }), - component: l.component, - } -} - const errKey = "error" func Error(err error) slog.Attr { diff --git a/src/delivery/graphql/generated.go b/src/delivery/graphql/generated.go index 8b8390f..11cd443 100644 --- a/src/delivery/graphql/generated.go +++ b/src/delivery/graphql/generated.go @@ -16,6 +16,7 @@ import ( "git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/introspection" + "github.com/anacrolix/torrent/types" gqlparser "github.com/vektah/gqlparser/v2" "github.com/vektah/gqlparser/v2/ast" ) @@ -47,12 +48,15 @@ type ResolverRoot interface { SimpleDir() SimpleDirResolver Subscription() SubscriptionResolver Torrent() TorrentResolver + TorrentDaemonMutation() TorrentDaemonMutationResolver + TorrentDaemonQuery() TorrentDaemonQueryResolver TorrentFS() TorrentFSResolver } type DirectiveRoot struct { - OneOf func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) - Stream func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + OneOf func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Resolver func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Stream func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) } type ComplexityRoot struct { @@ -72,16 +76,14 @@ type ComplexityRoot struct { } Mutation struct { - CleanupTorrents func(childComplexity int, files *bool, dryRun bool) int - DedupeStorage func(childComplexity int) int - DownloadTorrent func(childComplexity int, infohash string, file *string) int - UploadFile func(childComplexity int, dir string, file graphql.Upload) int - ValidateTorrents func(childComplexity int, filter model.TorrentFilter) int + DedupeStorage func(childComplexity int) int + TorrentDaemon func(childComplexity int) int + UploadFile func(childComplexity int, dir string, file graphql.Upload) int } Query struct { - FsEntry func(childComplexity int, path string) int - Torrents func(childComplexity int, filter *model.TorrentsFilter) int + FsEntry func(childComplexity int, path string) int + TorrentDaemon func(childComplexity int) int } ResolverFS struct { @@ -116,15 +118,25 @@ type ComplexityRoot struct { Torrent struct { BytesCompleted func(childComplexity int) int BytesMissing func(childComplexity int) int - Downloading func(childComplexity int) int ExcludedFiles func(childComplexity int) int Files func(childComplexity int) int Infohash func(childComplexity int) int Name func(childComplexity int) int Peers func(childComplexity int) int + Priority func(childComplexity int) int TorrentFilePath func(childComplexity int) int } + TorrentDaemonMutation struct { + Cleanup func(childComplexity int, files *bool, dryRun bool) int + SetTorrentPriority func(childComplexity int, infohash string, file *string, priority types.PiecePriority) int + ValidateTorrent func(childComplexity int, filter model.TorrentFilter) int + } + + TorrentDaemonQuery struct { + Torrents func(childComplexity int, filter *model.TorrentsFilter) int + } + TorrentFS struct { Entries func(childComplexity int) int Name func(childComplexity int) int @@ -162,14 +174,12 @@ type ArchiveFSResolver interface { Entries(ctx context.Context, obj *model.ArchiveFs) ([]model.FsEntry, error) } type MutationResolver interface { - ValidateTorrents(ctx context.Context, filter model.TorrentFilter) (bool, error) - CleanupTorrents(ctx context.Context, files *bool, dryRun bool) (*model.CleanupResponse, error) - DownloadTorrent(ctx context.Context, infohash string, file *string) (*model.DownloadTorrentResponse, error) + TorrentDaemon(ctx context.Context) (*model.TorrentDaemonMutation, error) UploadFile(ctx context.Context, dir string, file graphql.Upload) (bool, error) DedupeStorage(ctx context.Context) (int64, error) } type QueryResolver interface { - Torrents(ctx context.Context, filter *model.TorrentsFilter) ([]*model.Torrent, error) + TorrentDaemon(ctx context.Context) (*model.TorrentDaemonQuery, error) FsEntry(ctx context.Context, path string) (model.FsEntry, error) } type ResolverFSResolver interface { @@ -185,10 +195,19 @@ type SubscriptionResolver interface { type TorrentResolver interface { Name(ctx context.Context, obj *model.Torrent) (string, error) + Priority(ctx context.Context, obj *model.Torrent) (types.PiecePriority, error) Files(ctx context.Context, obj *model.Torrent) ([]*model.TorrentFile, error) ExcludedFiles(ctx context.Context, obj *model.Torrent) ([]*model.TorrentFile, error) Peers(ctx context.Context, obj *model.Torrent) ([]*model.TorrentPeer, error) } +type TorrentDaemonMutationResolver interface { + ValidateTorrent(ctx context.Context, obj *model.TorrentDaemonMutation, filter model.TorrentFilter) (bool, error) + SetTorrentPriority(ctx context.Context, obj *model.TorrentDaemonMutation, infohash string, file *string, priority types.PiecePriority) (bool, error) + Cleanup(ctx context.Context, obj *model.TorrentDaemonMutation, files *bool, dryRun bool) (*model.CleanupResponse, error) +} +type TorrentDaemonQueryResolver interface { + Torrents(ctx context.Context, obj *model.TorrentDaemonQuery, filter *model.TorrentsFilter) ([]*model.Torrent, error) +} type TorrentFSResolver interface { Entries(ctx context.Context, obj *model.TorrentFs) ([]model.FsEntry, error) } @@ -254,18 +273,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.DownloadTorrentResponse.Task(childComplexity), true - case "Mutation.cleanupTorrents": - if e.complexity.Mutation.CleanupTorrents == nil { - break - } - - args, err := ec.field_Mutation_cleanupTorrents_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Mutation.CleanupTorrents(childComplexity, args["files"].(*bool), args["dryRun"].(bool)), true - case "Mutation.dedupeStorage": if e.complexity.Mutation.DedupeStorage == nil { break @@ -273,17 +280,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.DedupeStorage(childComplexity), true - case "Mutation.downloadTorrent": - if e.complexity.Mutation.DownloadTorrent == nil { + case "Mutation.torrentDaemon": + if e.complexity.Mutation.TorrentDaemon == nil { break } - args, err := ec.field_Mutation_downloadTorrent_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Mutation.DownloadTorrent(childComplexity, args["infohash"].(string), args["file"].(*string)), true + return e.complexity.Mutation.TorrentDaemon(childComplexity), true case "Mutation.uploadFile": if e.complexity.Mutation.UploadFile == nil { @@ -297,18 +299,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.UploadFile(childComplexity, args["dir"].(string), args["file"].(graphql.Upload)), true - case "Mutation.validateTorrents": - if e.complexity.Mutation.ValidateTorrents == nil { - break - } - - args, err := ec.field_Mutation_validateTorrents_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Mutation.ValidateTorrents(childComplexity, args["filter"].(model.TorrentFilter)), true - case "Query.fsEntry": if e.complexity.Query.FsEntry == nil { break @@ -321,17 +311,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.FsEntry(childComplexity, args["path"].(string)), true - case "Query.torrents": - if e.complexity.Query.Torrents == nil { + case "Query.torrentDaemon": + if e.complexity.Query.TorrentDaemon == nil { break } - args, err := ec.field_Query_torrents_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.Torrents(childComplexity, args["filter"].(*model.TorrentsFilter)), true + return e.complexity.Query.TorrentDaemon(childComplexity), true case "ResolverFS.entries": if e.complexity.ResolverFS.Entries == nil { @@ -429,13 +414,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Torrent.BytesMissing(childComplexity), true - case "Torrent.downloading": - if e.complexity.Torrent.Downloading == nil { - break - } - - return e.complexity.Torrent.Downloading(childComplexity), true - case "Torrent.excludedFiles": if e.complexity.Torrent.ExcludedFiles == nil { break @@ -471,6 +449,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Torrent.Peers(childComplexity), true + case "Torrent.priority": + if e.complexity.Torrent.Priority == nil { + break + } + + return e.complexity.Torrent.Priority(childComplexity), true + case "Torrent.torrentFilePath": if e.complexity.Torrent.TorrentFilePath == nil { break @@ -478,6 +463,54 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Torrent.TorrentFilePath(childComplexity), true + case "TorrentDaemonMutation.cleanup": + if e.complexity.TorrentDaemonMutation.Cleanup == nil { + break + } + + args, err := ec.field_TorrentDaemonMutation_cleanup_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.TorrentDaemonMutation.Cleanup(childComplexity, args["files"].(*bool), args["dryRun"].(bool)), true + + case "TorrentDaemonMutation.setTorrentPriority": + if e.complexity.TorrentDaemonMutation.SetTorrentPriority == nil { + break + } + + args, err := ec.field_TorrentDaemonMutation_setTorrentPriority_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.TorrentDaemonMutation.SetTorrentPriority(childComplexity, args["infohash"].(string), args["file"].(*string), args["priority"].(types.PiecePriority)), true + + case "TorrentDaemonMutation.validateTorrent": + if e.complexity.TorrentDaemonMutation.ValidateTorrent == nil { + break + } + + args, err := ec.field_TorrentDaemonMutation_validateTorrent_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.TorrentDaemonMutation.ValidateTorrent(childComplexity, args["filter"].(model.TorrentFilter)), true + + case "TorrentDaemonQuery.torrents": + if e.complexity.TorrentDaemonQuery.Torrents == nil { + break + } + + args, err := ec.field_TorrentDaemonQuery_torrents_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.TorrentDaemonQuery.Torrents(childComplexity, args["filter"].(*model.TorrentsFilter)), true + case "TorrentFS.entries": if e.complexity.TorrentFS.Entries == nil { break @@ -611,6 +644,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputPagination, ec.unmarshalInputStringFilter, ec.unmarshalInputTorrentFilter, + ec.unmarshalInputTorrentPriorityFilter, ec.unmarshalInputTorrentsFilter, ) first := true @@ -727,48 +761,134 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er var sources = []*ast.Source{ {Name: "../../../graphql/mutation.graphql", Input: `type Mutation { - validateTorrents(filter: TorrentFilter!): Boolean! - cleanupTorrents(files: Boolean, dryRun: Boolean!): CleanupResponse! - downloadTorrent(infohash: String!, file: String): DownloadTorrentResponse + torrentDaemon: TorrentDaemonMutation @resolver + uploadFile(dir: String!, file: Upload!): Boolean! dedupeStorage: Int! } -input TorrentFilter @oneOf { - everything: Boolean - infohash: String - # pathGlob: String! -} - -type DownloadTorrentResponse { - task: Task -} - -type CleanupResponse { - count: Int! - list: [String!]! -} - type Task { id: ID! } `, BuiltIn: false}, {Name: "../../../graphql/query.graphql", Input: `type Query { - torrents(filter: TorrentsFilter): [Torrent!]! + torrentDaemon: TorrentDaemonQuery @resolver + fsEntry(path: String!): FsEntry } +`, BuiltIn: false}, + {Name: "../../../graphql/schema.graphql", Input: `directive @oneOf on INPUT_OBJECT | FIELD_DEFINITION +directive @resolver on INPUT_FIELD_DEFINITION | FIELD_DEFINITION + +directive @stream on FIELD_DEFINITION + +scalar DateTime +scalar Upload + +type Schema { + query: Query + mutation: Mutation +} +`, BuiltIn: false}, + {Name: "../../../graphql/subscription.graphql", Input: `type Subscription { + taskProgress(taskID: ID!): Progress + torrentDownloadUpdates: TorrentProgress +} + + +type TorrentProgress implements Progress { + torrent: Torrent! + current: Int! + total: Int! +} + +interface Progress { + current: Int! + total: Int! +}`, BuiltIn: false}, + {Name: "../../../graphql/sources/torrent_mutation.graphql", Input: `type TorrentDaemonMutation { + validateTorrent(filter: TorrentFilter!): Boolean! @resolver + setTorrentPriority( + infohash: String! + file: String + priority: TorrentPriority! + ): Boolean! @resolver + cleanup(files: Boolean, dryRun: Boolean!): CleanupResponse! @resolver +} + +type CleanupResponse { + count: Int! + list: [String!]! +} + +type DownloadTorrentResponse { + task: Task +} +`, BuiltIn: false}, + {Name: "../../../graphql/sources/torrent_query.graphql", Input: `type TorrentDaemonQuery { + torrents(filter: TorrentsFilter): [Torrent!]! @resolver +} input TorrentsFilter { infohash: StringFilter name: StringFilter bytesCompleted: IntFilter bytesMissing: IntFilter - peersCount: IntFilter - downloading: BooleanFilter + priority: TorrentPriorityFilter } -input Pagination { +input TorrentPriorityFilter @oneOf { + eq: TorrentPriority + gt: TorrentPriority + lt: TorrentPriority + gte: TorrentPriority + lte: TorrentPriority + in: [TorrentPriority!] +} + +input TorrentFilter @oneOf { + everything: Boolean + infohash: String + # pathGlob: String! +} +`, BuiltIn: false}, + {Name: "../../../graphql/sources/torrent_types.graphql", Input: `type Torrent { + name: String! @resolver + infohash: String! + bytesCompleted: Int! + torrentFilePath: String! + bytesMissing: Int! + priority: TorrentPriority! @resolver + files: [TorrentFile!]! @resolver + excludedFiles: [TorrentFile!]! @resolver + peers: [TorrentPeer!]! @resolver +} + +type TorrentFile { + filename: String! + size: Int! + bytesCompleted: Int! +} + +type TorrentPeer { + ip: String! + downloadRate: Float! + discovery: String! + port: Int! + clientName: String! +} + +enum TorrentPriority { + NONE + NORMAL + HIGH + READAHEAD + NEXT + NOW +} +`, BuiltIn: false}, + {Name: "../../../graphql/types/filters.graphql", Input: `input Pagination { offset: Int! limit: Int! } @@ -800,33 +920,6 @@ input BooleanFilter @oneOf { eq: Boolean } `, BuiltIn: false}, - {Name: "../../../graphql/schema.graphql", Input: `directive @oneOf on INPUT_OBJECT | FIELD_DEFINITION -directive @stream on FIELD_DEFINITION - -scalar DateTime -scalar Upload - -type Schema { - query: Query - mutation: Mutation -} -`, BuiltIn: false}, - {Name: "../../../graphql/subscription.graphql", Input: `type Subscription { - taskProgress(taskID: ID!): Progress - torrentDownloadUpdates: TorrentProgress -} - - -type TorrentProgress implements Progress { - torrent: Torrent! - current: Int! - total: Int! -} - -interface Progress { - current: Int! - total: Int! -}`, BuiltIn: false}, {Name: "../../../graphql/types/fs.graphql", Input: `interface FsEntry { name: String! } @@ -843,7 +936,7 @@ interface File implements FsEntry { type SimpleDir implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type SimpleFile implements File & FsEntry { @@ -853,12 +946,12 @@ type SimpleFile implements File & FsEntry { type ResolverFS implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type ArchiveFS implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver size: Int! } @@ -866,7 +959,7 @@ type ArchiveFS implements Dir & FsEntry { type TorrentFS implements Dir & FsEntry { name: String! torrent: Torrent! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type TorrentFileEntry implements File & FsEntry { @@ -874,34 +967,6 @@ type TorrentFileEntry implements File & FsEntry { torrent: Torrent! size: Int! } -`, BuiltIn: false}, - {Name: "../../../graphql/types/torrent.graphql", Input: `type Torrent { - name: String! - infohash: String! - bytesCompleted: Int! - torrentFilePath: String! - bytesMissing: Int! - files: [TorrentFile!]! - excludedFiles: [TorrentFile!]! - peers: [TorrentPeer!]! - - # if at least one piece of the torrent is request to download and not already downloaded - downloading: Boolean! -} - -type TorrentFile { - filename: String! - size: Int! - bytesCompleted: Int! -} - -type TorrentPeer { - ip: String! - downloadRate: Float! - discovery: String! - port: Int! - clientName: String! -} `, BuiltIn: false}, } var parsedSchema = gqlparser.MustLoadSchema(sources...) @@ -910,54 +975,6 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...) // region ***************************** args.gotpl ***************************** -func (ec *executionContext) field_Mutation_cleanupTorrents_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *bool - if tmp, ok := rawArgs["files"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("files")) - arg0, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp) - if err != nil { - return nil, err - } - } - args["files"] = arg0 - var arg1 bool - if tmp, ok := rawArgs["dryRun"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("dryRun")) - arg1, err = ec.unmarshalNBoolean2bool(ctx, tmp) - if err != nil { - return nil, err - } - } - args["dryRun"] = arg1 - return args, nil -} - -func (ec *executionContext) field_Mutation_downloadTorrent_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 string - if tmp, ok := rawArgs["infohash"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("infohash")) - arg0, err = ec.unmarshalNString2string(ctx, tmp) - if err != nil { - return nil, err - } - } - args["infohash"] = arg0 - var arg1 *string - if tmp, ok := rawArgs["file"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("file")) - arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp) - if err != nil { - return nil, err - } - } - args["file"] = arg1 - return args, nil -} - func (ec *executionContext) field_Mutation_uploadFile_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -982,21 +999,6 @@ func (ec *executionContext) field_Mutation_uploadFile_args(ctx context.Context, return args, nil } -func (ec *executionContext) field_Mutation_validateTorrents_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 model.TorrentFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalNTorrentFilter2gitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1027,21 +1029,6 @@ func (ec *executionContext) field_Query_fsEntry_args(ctx context.Context, rawArg return args, nil } -func (ec *executionContext) field_Query_torrents_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *model.TorrentsFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTorrentsFilter2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentsFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - func (ec *executionContext) field_Subscription_taskProgress_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1057,6 +1044,93 @@ func (ec *executionContext) field_Subscription_taskProgress_args(ctx context.Con return args, nil } +func (ec *executionContext) field_TorrentDaemonMutation_cleanup_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *bool + if tmp, ok := rawArgs["files"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("files")) + arg0, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["files"] = arg0 + var arg1 bool + if tmp, ok := rawArgs["dryRun"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("dryRun")) + arg1, err = ec.unmarshalNBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["dryRun"] = arg1 + return args, nil +} + +func (ec *executionContext) field_TorrentDaemonMutation_setTorrentPriority_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["infohash"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("infohash")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["infohash"] = arg0 + var arg1 *string + if tmp, ok := rawArgs["file"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("file")) + arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp) + if err != nil { + return nil, err + } + } + args["file"] = arg1 + var arg2 types.PiecePriority + if tmp, ok := rawArgs["priority"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("priority")) + arg2, err = ec.unmarshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, tmp) + if err != nil { + return nil, err + } + } + args["priority"] = arg2 + return args, nil +} + +func (ec *executionContext) field_TorrentDaemonMutation_validateTorrent_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.TorrentFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalNTorrentFilter2gitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_TorrentDaemonQuery_torrents_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *model.TorrentsFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTorrentsFilter2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentsFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1126,7 +1200,7 @@ func (ec *executionContext) _ArchiveFS_name(ctx context.Context, field graphql.C return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ArchiveFS_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_ArchiveFS_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ArchiveFS", Field: field, @@ -1152,8 +1226,28 @@ func (ec *executionContext) _ArchiveFS_entries(ctx context.Context, field graphq } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.ArchiveFS().Entries(rctx, obj) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.ArchiveFS().Entries(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.([]model.FsEntry); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be []git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.FsEntry`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -1170,7 +1264,7 @@ func (ec *executionContext) _ArchiveFS_entries(ctx context.Context, field graphq return ec.marshalNFsEntry2ᚕgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐFsEntryᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ArchiveFS_entries(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_ArchiveFS_entries(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ArchiveFS", Field: field, @@ -1214,7 +1308,7 @@ func (ec *executionContext) _ArchiveFS_size(ctx context.Context, field graphql.C return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ArchiveFS_size(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_ArchiveFS_size(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ArchiveFS", Field: field, @@ -1258,7 +1352,7 @@ func (ec *executionContext) _CleanupResponse_count(ctx context.Context, field gr return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_CleanupResponse_count(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_CleanupResponse_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "CleanupResponse", Field: field, @@ -1302,7 +1396,7 @@ func (ec *executionContext) _CleanupResponse_list(ctx context.Context, field gra return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_CleanupResponse_list(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_CleanupResponse_list(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "CleanupResponse", Field: field, @@ -1343,7 +1437,7 @@ func (ec *executionContext) _DownloadTorrentResponse_task(ctx context.Context, f return ec.marshalOTask2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTask(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_DownloadTorrentResponse_task(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_DownloadTorrentResponse_task(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DownloadTorrentResponse", Field: field, @@ -1360,8 +1454,8 @@ func (ec *executionContext) fieldContext_DownloadTorrentResponse_task(ctx contex return fc, nil } -func (ec *executionContext) _Mutation_validateTorrents(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Mutation_validateTorrents(ctx, field) +func (ec *executionContext) _Mutation_torrentDaemon(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_torrentDaemon(ctx, field) if err != nil { return graphql.Null } @@ -1373,80 +1467,42 @@ func (ec *executionContext) _Mutation_validateTorrents(ctx context.Context, fiel } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().ValidateTorrents(rctx, fc.Args["filter"].(model.TorrentFilter)) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().TorrentDaemon(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, nil, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(*model.TorrentDaemonMutation); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be *git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.TorrentDaemonMutation`, tmp) }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(bool) + res := resTmp.(*model.TorrentDaemonMutation) fc.Result = res - return ec.marshalNBoolean2bool(ctx, field.Selections, res) + return ec.marshalOTorrentDaemonMutation2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentDaemonMutation(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Mutation_validateTorrents(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Mutation", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_validateTorrents_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Mutation_cleanupTorrents(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Mutation_cleanupTorrents(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().CleanupTorrents(rctx, fc.Args["files"].(*bool), fc.Args["dryRun"].(bool)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*model.CleanupResponse) - fc.Result = res - return ec.marshalNCleanupResponse2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐCleanupResponse(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Mutation_cleanupTorrents(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Mutation_torrentDaemon(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Mutation", Field: field, @@ -1454,81 +1510,16 @@ func (ec *executionContext) fieldContext_Mutation_cleanupTorrents(ctx context.Co IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "count": - return ec.fieldContext_CleanupResponse_count(ctx, field) - case "list": - return ec.fieldContext_CleanupResponse_list(ctx, field) + case "validateTorrent": + return ec.fieldContext_TorrentDaemonMutation_validateTorrent(ctx, field) + case "setTorrentPriority": + return ec.fieldContext_TorrentDaemonMutation_setTorrentPriority(ctx, field) + case "cleanup": + return ec.fieldContext_TorrentDaemonMutation_cleanup(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type CleanupResponse", field.Name) + return nil, fmt.Errorf("no field named %q was found under type TorrentDaemonMutation", field.Name) }, } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_cleanupTorrents_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Mutation_downloadTorrent(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Mutation_downloadTorrent(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().DownloadTorrent(rctx, fc.Args["infohash"].(string), fc.Args["file"].(*string)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*model.DownloadTorrentResponse) - fc.Result = res - return ec.marshalODownloadTorrentResponse2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐDownloadTorrentResponse(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Mutation_downloadTorrent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Mutation", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "task": - return ec.fieldContext_DownloadTorrentResponse_task(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type DownloadTorrentResponse", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_downloadTorrent_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } return fc, nil } @@ -1618,7 +1609,7 @@ func (ec *executionContext) _Mutation_dedupeStorage(ctx context.Context, field g return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Mutation_dedupeStorage(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Mutation_dedupeStorage(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Mutation", Field: field, @@ -1631,8 +1622,8 @@ func (ec *executionContext) fieldContext_Mutation_dedupeStorage(ctx context.Cont return fc, nil } -func (ec *executionContext) _Query_torrents(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_torrents(ctx, field) +func (ec *executionContext) _Query_torrentDaemon(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_torrentDaemon(ctx, field) if err != nil { return graphql.Null } @@ -1644,25 +1635,42 @@ func (ec *executionContext) _Query_torrents(ctx context.Context, field graphql.C } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Torrents(rctx, fc.Args["filter"].(*model.TorrentsFilter)) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().TorrentDaemon(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, nil, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(*model.TorrentDaemonQuery); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be *git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.TorrentDaemonQuery`, tmp) }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.([]*model.Torrent) + res := resTmp.(*model.TorrentDaemonQuery) fc.Result = res - return ec.marshalNTorrent2ᚕᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentᚄ(ctx, field.Selections, res) + return ec.marshalOTorrentDaemonQuery2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentDaemonQuery(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_torrents(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_torrentDaemon(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -1670,39 +1678,12 @@ func (ec *executionContext) fieldContext_Query_torrents(ctx context.Context, fie IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "name": - return ec.fieldContext_Torrent_name(ctx, field) - case "infohash": - return ec.fieldContext_Torrent_infohash(ctx, field) - case "bytesCompleted": - return ec.fieldContext_Torrent_bytesCompleted(ctx, field) - case "torrentFilePath": - return ec.fieldContext_Torrent_torrentFilePath(ctx, field) - case "bytesMissing": - return ec.fieldContext_Torrent_bytesMissing(ctx, field) - case "files": - return ec.fieldContext_Torrent_files(ctx, field) - case "excludedFiles": - return ec.fieldContext_Torrent_excludedFiles(ctx, field) - case "peers": - return ec.fieldContext_Torrent_peers(ctx, field) - case "downloading": - return ec.fieldContext_Torrent_downloading(ctx, field) + case "torrents": + return ec.fieldContext_TorrentDaemonQuery_torrents(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type Torrent", field.Name) + return nil, fmt.Errorf("no field named %q was found under type TorrentDaemonQuery", field.Name) }, } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_torrents_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } return fc, nil } @@ -1860,7 +1841,7 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query___schema(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -1918,7 +1899,7 @@ func (ec *executionContext) _ResolverFS_name(ctx context.Context, field graphql. return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ResolverFS_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_ResolverFS_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ResolverFS", Field: field, @@ -1944,8 +1925,28 @@ func (ec *executionContext) _ResolverFS_entries(ctx context.Context, field graph } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.ResolverFS().Entries(rctx, obj) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.ResolverFS().Entries(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.([]model.FsEntry); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be []git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.FsEntry`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -1962,7 +1963,7 @@ func (ec *executionContext) _ResolverFS_entries(ctx context.Context, field graph return ec.marshalNFsEntry2ᚕgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐFsEntryᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ResolverFS_entries(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_ResolverFS_entries(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ResolverFS", Field: field, @@ -1992,7 +1993,7 @@ func (ec *executionContext) _Schema_query(ctx context.Context, field graphql.Col return ec.marshalOQuery2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐQuery(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Schema_query(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Schema_query(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Schema", Field: field, @@ -2000,8 +2001,8 @@ func (ec *executionContext) fieldContext_Schema_query(ctx context.Context, field IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "torrents": - return ec.fieldContext_Query_torrents(ctx, field) + case "torrentDaemon": + return ec.fieldContext_Query_torrentDaemon(ctx, field) case "fsEntry": return ec.fieldContext_Query_fsEntry(ctx, field) case "__schema": @@ -2032,7 +2033,7 @@ func (ec *executionContext) _Schema_mutation(ctx context.Context, field graphql. return ec.marshalOMutation2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐMutation(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Schema_mutation(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Schema_mutation(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Schema", Field: field, @@ -2040,12 +2041,8 @@ func (ec *executionContext) fieldContext_Schema_mutation(ctx context.Context, fi IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "validateTorrents": - return ec.fieldContext_Mutation_validateTorrents(ctx, field) - case "cleanupTorrents": - return ec.fieldContext_Mutation_cleanupTorrents(ctx, field) - case "downloadTorrent": - return ec.fieldContext_Mutation_downloadTorrent(ctx, field) + case "torrentDaemon": + return ec.fieldContext_Mutation_torrentDaemon(ctx, field) case "uploadFile": return ec.fieldContext_Mutation_uploadFile(ctx, field) case "dedupeStorage": @@ -2088,7 +2085,7 @@ func (ec *executionContext) _SimpleDir_name(ctx context.Context, field graphql.C return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_SimpleDir_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimpleDir_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SimpleDir", Field: field, @@ -2114,8 +2111,28 @@ func (ec *executionContext) _SimpleDir_entries(ctx context.Context, field graphq } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.SimpleDir().Entries(rctx, obj) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.SimpleDir().Entries(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.([]model.FsEntry); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be []git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.FsEntry`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -2132,7 +2149,7 @@ func (ec *executionContext) _SimpleDir_entries(ctx context.Context, field graphq return ec.marshalNFsEntry2ᚕgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐFsEntryᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_SimpleDir_entries(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimpleDir_entries(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SimpleDir", Field: field, @@ -2176,7 +2193,7 @@ func (ec *executionContext) _SimpleFile_name(ctx context.Context, field graphql. return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_SimpleFile_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimpleFile_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SimpleFile", Field: field, @@ -2220,7 +2237,7 @@ func (ec *executionContext) _SimpleFile_size(ctx context.Context, field graphql. return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_SimpleFile_size(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_SimpleFile_size(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SimpleFile", Field: field, @@ -2341,7 +2358,7 @@ func (ec *executionContext) _Subscription_torrentDownloadUpdates(ctx context.Con } } -func (ec *executionContext) fieldContext_Subscription_torrentDownloadUpdates(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Subscription_torrentDownloadUpdates(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Subscription", Field: field, @@ -2393,7 +2410,7 @@ func (ec *executionContext) _Task_id(ctx context.Context, field graphql.Collecte return ec.marshalNID2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Task_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Task_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Task", Field: field, @@ -2419,8 +2436,28 @@ func (ec *executionContext) _Torrent_name(ctx context.Context, field graphql.Col } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Torrent().Name(rctx, obj) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Torrent().Name(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be string`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -2437,7 +2474,7 @@ func (ec *executionContext) _Torrent_name(ctx context.Context, field graphql.Col return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Torrent_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Torrent", Field: field, @@ -2481,7 +2518,7 @@ func (ec *executionContext) _Torrent_infohash(ctx context.Context, field graphql return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_infohash(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Torrent_infohash(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Torrent", Field: field, @@ -2525,7 +2562,7 @@ func (ec *executionContext) _Torrent_bytesCompleted(ctx context.Context, field g return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_bytesCompleted(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Torrent_bytesCompleted(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Torrent", Field: field, @@ -2569,7 +2606,7 @@ func (ec *executionContext) _Torrent_torrentFilePath(ctx context.Context, field return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_torrentFilePath(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Torrent_torrentFilePath(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Torrent", Field: field, @@ -2613,7 +2650,7 @@ func (ec *executionContext) _Torrent_bytesMissing(ctx context.Context, field gra return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_bytesMissing(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Torrent_bytesMissing(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Torrent", Field: field, @@ -2626,6 +2663,70 @@ func (ec *executionContext) fieldContext_Torrent_bytesMissing(ctx context.Contex return fc, nil } +func (ec *executionContext) _Torrent_priority(ctx context.Context, field graphql.CollectedField, obj *model.Torrent) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Torrent_priority(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Torrent().Priority(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(types.PiecePriority); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/anacrolix/torrent/types.PiecePriority`, tmp) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(types.PiecePriority) + fc.Result = res + return ec.marshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Torrent_priority(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Torrent", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type TorrentPriority does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _Torrent_files(ctx context.Context, field graphql.CollectedField, obj *model.Torrent) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Torrent_files(ctx, field) if err != nil { @@ -2639,8 +2740,28 @@ func (ec *executionContext) _Torrent_files(ctx context.Context, field graphql.Co } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Torrent().Files(rctx, obj) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Torrent().Files(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.([]*model.TorrentFile); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be []*git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.TorrentFile`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -2657,7 +2778,7 @@ func (ec *executionContext) _Torrent_files(ctx context.Context, field graphql.Co return ec.marshalNTorrentFile2ᚕᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentFileᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_files(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Torrent_files(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Torrent", Field: field, @@ -2691,8 +2812,28 @@ func (ec *executionContext) _Torrent_excludedFiles(ctx context.Context, field gr } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Torrent().ExcludedFiles(rctx, obj) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Torrent().ExcludedFiles(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.([]*model.TorrentFile); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be []*git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.TorrentFile`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -2709,7 +2850,7 @@ func (ec *executionContext) _Torrent_excludedFiles(ctx context.Context, field gr return ec.marshalNTorrentFile2ᚕᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentFileᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_excludedFiles(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Torrent_excludedFiles(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Torrent", Field: field, @@ -2743,8 +2884,28 @@ func (ec *executionContext) _Torrent_peers(ctx context.Context, field graphql.Co } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Torrent().Peers(rctx, obj) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Torrent().Peers(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.([]*model.TorrentPeer); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be []*git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.TorrentPeer`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -2761,7 +2922,7 @@ func (ec *executionContext) _Torrent_peers(ctx context.Context, field graphql.Co return ec.marshalNTorrentPeer2ᚕᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentPeerᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_peers(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Torrent_peers(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Torrent", Field: field, @@ -2786,8 +2947,8 @@ func (ec *executionContext) fieldContext_Torrent_peers(ctx context.Context, fiel return fc, nil } -func (ec *executionContext) _Torrent_downloading(ctx context.Context, field graphql.CollectedField, obj *model.Torrent) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Torrent_downloading(ctx, field) +func (ec *executionContext) _TorrentDaemonMutation_validateTorrent(ctx context.Context, field graphql.CollectedField, obj *model.TorrentDaemonMutation) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_TorrentDaemonMutation_validateTorrent(ctx, field) if err != nil { return graphql.Null } @@ -2799,8 +2960,28 @@ func (ec *executionContext) _Torrent_downloading(ctx context.Context, field grap } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Downloading, nil + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.TorrentDaemonMutation().ValidateTorrent(rctx, obj, fc.Args["filter"].(model.TorrentFilter)) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(bool); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be bool`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -2817,16 +2998,278 @@ func (ec *executionContext) _Torrent_downloading(ctx context.Context, field grap return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Torrent_downloading(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentDaemonMutation_validateTorrent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Torrent", + Object: "TorrentDaemonMutation", Field: field, - IsMethod: false, - IsResolver: false, + IsMethod: true, + IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { return nil, errors.New("field of type Boolean does not have child fields") }, } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_TorrentDaemonMutation_validateTorrent_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _TorrentDaemonMutation_setTorrentPriority(ctx context.Context, field graphql.CollectedField, obj *model.TorrentDaemonMutation) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_TorrentDaemonMutation_setTorrentPriority(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.TorrentDaemonMutation().SetTorrentPriority(rctx, obj, fc.Args["infohash"].(string), fc.Args["file"].(*string), fc.Args["priority"].(types.PiecePriority)) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(bool); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be bool`, tmp) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_TorrentDaemonMutation_setTorrentPriority(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TorrentDaemonMutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_TorrentDaemonMutation_setTorrentPriority_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _TorrentDaemonMutation_cleanup(ctx context.Context, field graphql.CollectedField, obj *model.TorrentDaemonMutation) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_TorrentDaemonMutation_cleanup(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.TorrentDaemonMutation().Cleanup(rctx, obj, fc.Args["files"].(*bool), fc.Args["dryRun"].(bool)) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(*model.CleanupResponse); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be *git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.CleanupResponse`, tmp) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.CleanupResponse) + fc.Result = res + return ec.marshalNCleanupResponse2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐCleanupResponse(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_TorrentDaemonMutation_cleanup(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TorrentDaemonMutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "count": + return ec.fieldContext_CleanupResponse_count(ctx, field) + case "list": + return ec.fieldContext_CleanupResponse_list(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CleanupResponse", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_TorrentDaemonMutation_cleanup_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _TorrentDaemonQuery_torrents(ctx context.Context, field graphql.CollectedField, obj *model.TorrentDaemonQuery) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_TorrentDaemonQuery_torrents(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.TorrentDaemonQuery().Torrents(rctx, obj, fc.Args["filter"].(*model.TorrentsFilter)) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.([]*model.Torrent); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be []*git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.Torrent`, tmp) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.Torrent) + fc.Result = res + return ec.marshalNTorrent2ᚕᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_TorrentDaemonQuery_torrents(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TorrentDaemonQuery", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext_Torrent_name(ctx, field) + case "infohash": + return ec.fieldContext_Torrent_infohash(ctx, field) + case "bytesCompleted": + return ec.fieldContext_Torrent_bytesCompleted(ctx, field) + case "torrentFilePath": + return ec.fieldContext_Torrent_torrentFilePath(ctx, field) + case "bytesMissing": + return ec.fieldContext_Torrent_bytesMissing(ctx, field) + case "priority": + return ec.fieldContext_Torrent_priority(ctx, field) + case "files": + return ec.fieldContext_Torrent_files(ctx, field) + case "excludedFiles": + return ec.fieldContext_Torrent_excludedFiles(ctx, field) + case "peers": + return ec.fieldContext_Torrent_peers(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Torrent", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_TorrentDaemonQuery_torrents_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } return fc, nil } @@ -2861,7 +3304,7 @@ func (ec *executionContext) _TorrentFS_name(ctx context.Context, field graphql.C return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFS_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFS_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFS", Field: field, @@ -2905,7 +3348,7 @@ func (ec *executionContext) _TorrentFS_torrent(ctx context.Context, field graphq return ec.marshalNTorrent2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrent(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFS_torrent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFS_torrent(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFS", Field: field, @@ -2923,14 +3366,14 @@ func (ec *executionContext) fieldContext_TorrentFS_torrent(ctx context.Context, return ec.fieldContext_Torrent_torrentFilePath(ctx, field) case "bytesMissing": return ec.fieldContext_Torrent_bytesMissing(ctx, field) + case "priority": + return ec.fieldContext_Torrent_priority(ctx, field) case "files": return ec.fieldContext_Torrent_files(ctx, field) case "excludedFiles": return ec.fieldContext_Torrent_excludedFiles(ctx, field) case "peers": return ec.fieldContext_Torrent_peers(ctx, field) - case "downloading": - return ec.fieldContext_Torrent_downloading(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Torrent", field.Name) }, @@ -2951,8 +3394,28 @@ func (ec *executionContext) _TorrentFS_entries(ctx context.Context, field graphq } }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.TorrentFS().Entries(rctx, obj) + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.TorrentFS().Entries(rctx, obj) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Resolver == nil { + return nil, errors.New("directive resolver is not implemented") + } + return ec.directives.Resolver(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.([]model.FsEntry); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be []git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model.FsEntry`, tmp) }) if err != nil { ec.Error(ctx, err) @@ -2969,7 +3432,7 @@ func (ec *executionContext) _TorrentFS_entries(ctx context.Context, field graphq return ec.marshalNFsEntry2ᚕgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐFsEntryᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFS_entries(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFS_entries(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFS", Field: field, @@ -3013,7 +3476,7 @@ func (ec *executionContext) _TorrentFile_filename(ctx context.Context, field gra return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFile_filename(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFile_filename(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFile", Field: field, @@ -3057,7 +3520,7 @@ func (ec *executionContext) _TorrentFile_size(ctx context.Context, field graphql return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFile_size(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFile_size(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFile", Field: field, @@ -3101,7 +3564,7 @@ func (ec *executionContext) _TorrentFile_bytesCompleted(ctx context.Context, fie return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFile_bytesCompleted(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFile_bytesCompleted(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFile", Field: field, @@ -3145,7 +3608,7 @@ func (ec *executionContext) _TorrentFileEntry_name(ctx context.Context, field gr return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFileEntry_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFileEntry_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFileEntry", Field: field, @@ -3189,7 +3652,7 @@ func (ec *executionContext) _TorrentFileEntry_torrent(ctx context.Context, field return ec.marshalNTorrent2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrent(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFileEntry_torrent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFileEntry_torrent(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFileEntry", Field: field, @@ -3207,14 +3670,14 @@ func (ec *executionContext) fieldContext_TorrentFileEntry_torrent(ctx context.Co return ec.fieldContext_Torrent_torrentFilePath(ctx, field) case "bytesMissing": return ec.fieldContext_Torrent_bytesMissing(ctx, field) + case "priority": + return ec.fieldContext_Torrent_priority(ctx, field) case "files": return ec.fieldContext_Torrent_files(ctx, field) case "excludedFiles": return ec.fieldContext_Torrent_excludedFiles(ctx, field) case "peers": return ec.fieldContext_Torrent_peers(ctx, field) - case "downloading": - return ec.fieldContext_Torrent_downloading(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Torrent", field.Name) }, @@ -3253,7 +3716,7 @@ func (ec *executionContext) _TorrentFileEntry_size(ctx context.Context, field gr return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentFileEntry_size(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentFileEntry_size(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentFileEntry", Field: field, @@ -3297,7 +3760,7 @@ func (ec *executionContext) _TorrentPeer_ip(ctx context.Context, field graphql.C return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentPeer_ip(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentPeer_ip(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentPeer", Field: field, @@ -3341,7 +3804,7 @@ func (ec *executionContext) _TorrentPeer_downloadRate(ctx context.Context, field return ec.marshalNFloat2float64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentPeer_downloadRate(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentPeer_downloadRate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentPeer", Field: field, @@ -3385,7 +3848,7 @@ func (ec *executionContext) _TorrentPeer_discovery(ctx context.Context, field gr return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentPeer_discovery(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentPeer_discovery(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentPeer", Field: field, @@ -3429,7 +3892,7 @@ func (ec *executionContext) _TorrentPeer_port(ctx context.Context, field graphql return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentPeer_port(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentPeer_port(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentPeer", Field: field, @@ -3473,7 +3936,7 @@ func (ec *executionContext) _TorrentPeer_clientName(ctx context.Context, field g return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentPeer_clientName(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentPeer_clientName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentPeer", Field: field, @@ -3517,7 +3980,7 @@ func (ec *executionContext) _TorrentProgress_torrent(ctx context.Context, field return ec.marshalNTorrent2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrent(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentProgress_torrent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentProgress_torrent(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentProgress", Field: field, @@ -3535,14 +3998,14 @@ func (ec *executionContext) fieldContext_TorrentProgress_torrent(ctx context.Con return ec.fieldContext_Torrent_torrentFilePath(ctx, field) case "bytesMissing": return ec.fieldContext_Torrent_bytesMissing(ctx, field) + case "priority": + return ec.fieldContext_Torrent_priority(ctx, field) case "files": return ec.fieldContext_Torrent_files(ctx, field) case "excludedFiles": return ec.fieldContext_Torrent_excludedFiles(ctx, field) case "peers": return ec.fieldContext_Torrent_peers(ctx, field) - case "downloading": - return ec.fieldContext_Torrent_downloading(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Torrent", field.Name) }, @@ -3581,7 +4044,7 @@ func (ec *executionContext) _TorrentProgress_current(ctx context.Context, field return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentProgress_current(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentProgress_current(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentProgress", Field: field, @@ -3625,7 +4088,7 @@ func (ec *executionContext) _TorrentProgress_total(ctx context.Context, field gr return ec.marshalNInt2int64(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_TorrentProgress_total(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TorrentProgress_total(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TorrentProgress", Field: field, @@ -3669,7 +4132,7 @@ func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3710,7 +4173,7 @@ func (ec *executionContext) ___Directive_description(ctx context.Context, field return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3754,7 +4217,7 @@ func (ec *executionContext) ___Directive_locations(ctx context.Context, field gr return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_locations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3798,7 +4261,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_args(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3852,7 +4315,7 @@ func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Directive", Field: field, @@ -3896,7 +4359,7 @@ func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___EnumValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__EnumValue", Field: field, @@ -3937,7 +4400,7 @@ func (ec *executionContext) ___EnumValue_description(ctx context.Context, field return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___EnumValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__EnumValue", Field: field, @@ -3981,7 +4444,7 @@ func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__EnumValue", Field: field, @@ -4022,7 +4485,7 @@ func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__EnumValue", Field: field, @@ -4066,7 +4529,7 @@ func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.Col return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -4107,7 +4570,7 @@ func (ec *executionContext) ___Field_description(ctx context.Context, field grap return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -4151,7 +4614,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_args(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -4205,7 +4668,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -4271,7 +4734,7 @@ func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field gra return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -4312,7 +4775,7 @@ func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, fiel return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Field_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Field", Field: field, @@ -4356,7 +4819,7 @@ func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphq return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___InputValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__InputValue", Field: field, @@ -4397,7 +4860,7 @@ func (ec *executionContext) ___InputValue_description(ctx context.Context, field return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___InputValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__InputValue", Field: field, @@ -4441,7 +4904,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___InputValue_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__InputValue", Field: field, @@ -4504,7 +4967,7 @@ func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, fiel return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__InputValue", Field: field, @@ -4545,7 +5008,7 @@ func (ec *executionContext) ___Schema_description(ctx context.Context, field gra return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4589,7 +5052,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4655,7 +5118,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_queryType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4718,7 +5181,7 @@ func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field gr return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_mutationType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4781,7 +5244,7 @@ func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, fiel return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4847,7 +5310,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Schema_directives(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Schema", Field: field, @@ -4903,7 +5366,7 @@ func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.Coll return ec.marshalN__TypeKind2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_kind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4944,7 +5407,7 @@ func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.Coll return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -4985,7 +5448,7 @@ func (ec *executionContext) ___Type_description(ctx context.Context, field graph return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -5092,7 +5555,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -5155,7 +5618,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -5280,7 +5743,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -5331,7 +5794,7 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -5394,7 +5857,7 @@ func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field gr return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -5919,6 +6382,170 @@ func (ec *executionContext) unmarshalInputTorrentFilter(ctx context.Context, obj return it, nil } +func (ec *executionContext) unmarshalInputTorrentPriorityFilter(ctx context.Context, obj interface{}) (model.TorrentPriorityFilter, error) { + var it model.TorrentPriorityFilter + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"eq", "gt", "lt", "gte", "lte", "in"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "eq": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("eq")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.OneOf == nil { + return nil, errors.New("directive oneOf is not implemented") + } + return ec.directives.OneOf(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*types.PiecePriority); ok { + it.Eq = data + } else if tmp == nil { + it.Eq = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/anacrolix/torrent/types.PiecePriority`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "gt": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("gt")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.OneOf == nil { + return nil, errors.New("directive oneOf is not implemented") + } + return ec.directives.OneOf(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*types.PiecePriority); ok { + it.Gt = data + } else if tmp == nil { + it.Gt = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/anacrolix/torrent/types.PiecePriority`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "lt": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("lt")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.OneOf == nil { + return nil, errors.New("directive oneOf is not implemented") + } + return ec.directives.OneOf(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*types.PiecePriority); ok { + it.Lt = data + } else if tmp == nil { + it.Lt = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/anacrolix/torrent/types.PiecePriority`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "gte": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("gte")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.OneOf == nil { + return nil, errors.New("directive oneOf is not implemented") + } + return ec.directives.OneOf(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*types.PiecePriority); ok { + it.Gte = data + } else if tmp == nil { + it.Gte = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/anacrolix/torrent/types.PiecePriority`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "lte": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("lte")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.OneOf == nil { + return nil, errors.New("directive oneOf is not implemented") + } + return ec.directives.OneOf(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*types.PiecePriority); ok { + it.Lte = data + } else if tmp == nil { + it.Lte = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/anacrolix/torrent/types.PiecePriority`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "in": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("in")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOTorrentPriority2ᚕgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriorityᚄ(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.OneOf == nil { + return nil, errors.New("directive oneOf is not implemented") + } + return ec.directives.OneOf(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.([]types.PiecePriority); ok { + it.In = data + } else if tmp == nil { + it.In = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be []github.com/anacrolix/torrent/types.PiecePriority`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputTorrentsFilter(ctx context.Context, obj interface{}) (model.TorrentsFilter, error) { var it model.TorrentsFilter asMap := map[string]interface{}{} @@ -5926,7 +6553,7 @@ func (ec *executionContext) unmarshalInputTorrentsFilter(ctx context.Context, ob asMap[k] = v } - fieldsInOrder := [...]string{"infohash", "name", "bytesCompleted", "bytesMissing", "peersCount", "downloading"} + fieldsInOrder := [...]string{"infohash", "name", "bytesCompleted", "bytesMissing", "peersCount", "priority"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -5968,13 +6595,13 @@ func (ec *executionContext) unmarshalInputTorrentsFilter(ctx context.Context, ob return it, err } it.PeersCount = data - case "downloading": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("downloading")) - data, err := ec.unmarshalOBooleanFilter2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐBooleanFilter(ctx, v) + case "priority": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("priority")) + data, err := ec.unmarshalOTorrentPriorityFilter2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentPriorityFilter(ctx, v) if err != nil { return it, err } - it.Downloading = data + it.Priority = data } } @@ -6305,23 +6932,9 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") - case "validateTorrents": + case "torrentDaemon": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_validateTorrents(ctx, field) - }) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "cleanupTorrents": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_cleanupTorrents(ctx, field) - }) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "downloadTorrent": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_downloadTorrent(ctx, field) + return ec._Mutation_torrentDaemon(ctx, field) }) case "uploadFile": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { @@ -6379,19 +6992,16 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") - case "torrents": + case "torrentDaemon": field := field - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Query_torrents(ctx, field) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } + res = ec._Query_torrentDaemon(ctx, field) return res } @@ -6404,7 +7014,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "fsEntry": field := field - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -6811,6 +7421,42 @@ func (ec *executionContext) _Torrent(ctx context.Context, sel ast.SelectionSet, if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } + case "priority": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Torrent_priority(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) case "files": field := field @@ -6919,11 +7565,218 @@ func (ec *executionContext) _Torrent(ctx context.Context, sel ast.SelectionSet, } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "downloading": - out.Values[i] = ec._Torrent_downloading(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var torrentDaemonMutationImplementors = []string{"TorrentDaemonMutation"} + +func (ec *executionContext) _TorrentDaemonMutation(ctx context.Context, sel ast.SelectionSet, obj *model.TorrentDaemonMutation) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, torrentDaemonMutationImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("TorrentDaemonMutation") + case "validateTorrent": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TorrentDaemonMutation_validateTorrent(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "setTorrentPriority": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TorrentDaemonMutation_setTorrentPriority(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "cleanup": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TorrentDaemonMutation_cleanup(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var torrentDaemonQueryImplementors = []string{"TorrentDaemonQuery"} + +func (ec *executionContext) _TorrentDaemonQuery(ctx context.Context, sel ast.SelectionSet, obj *model.TorrentDaemonQuery) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, torrentDaemonQueryImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("TorrentDaemonQuery") + case "torrents": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TorrentDaemonQuery_torrents(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -7574,10 +8427,6 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) marshalNCleanupResponse2gitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐCleanupResponse(ctx context.Context, sel ast.SelectionSet, v model.CleanupResponse) graphql.Marshaler { - return ec._CleanupResponse(ctx, sel, &v) -} - func (ec *executionContext) marshalNCleanupResponse2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐCleanupResponse(ctx context.Context, sel ast.SelectionSet, v *model.CleanupResponse) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -7901,6 +8750,41 @@ func (ec *executionContext) marshalNTorrentPeer2ᚖgitᚗkmsignᚗruᚋroyalcat return ec._TorrentPeer(ctx, sel, v) } +func (ec *executionContext) unmarshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx context.Context, v interface{}) (types.PiecePriority, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx context.Context, sel ast.SelectionSet, v types.PiecePriority) graphql.Marshaler { + res := graphql.MarshalString(marshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority[v]) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +var ( + unmarshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority = map[string]types.PiecePriority{ + "NONE": types.PiecePriorityNone, + "NORMAL": types.PiecePriorityNormal, + "HIGH": types.PiecePriorityHigh, + "READAHEAD": types.PiecePriorityReadahead, + "NEXT": types.PiecePriorityNext, + "NOW": types.PiecePriorityNow, + } + marshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority = map[types.PiecePriority]string{ + types.PiecePriorityNone: "NONE", + types.PiecePriorityNormal: "NORMAL", + types.PiecePriorityHigh: "HIGH", + types.PiecePriorityReadahead: "READAHEAD", + types.PiecePriorityNext: "NEXT", + types.PiecePriorityNow: "NOW", + } +) + func (ec *executionContext) unmarshalNUpload2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚐUpload(ctx context.Context, v interface{}) (graphql.Upload, error) { res, err := graphql.UnmarshalUpload(v) return res, graphql.ErrorOnPath(ctx, err) @@ -8195,14 +9079,6 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return res } -func (ec *executionContext) unmarshalOBooleanFilter2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐBooleanFilter(ctx context.Context, v interface{}) (*model.BooleanFilter, error) { - if v == nil { - return nil, nil - } - res, err := ec.unmarshalInputBooleanFilter(ctx, v) - return &res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalODateTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) { if v == nil { return nil, nil @@ -8219,13 +9095,6 @@ func (ec *executionContext) marshalODateTime2ᚖtimeᚐTime(ctx context.Context, return res } -func (ec *executionContext) marshalODownloadTorrentResponse2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐDownloadTorrentResponse(ctx context.Context, sel ast.SelectionSet, v *model.DownloadTorrentResponse) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec._DownloadTorrentResponse(ctx, sel, v) -} - func (ec *executionContext) marshalOFsEntry2gitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐFsEntry(ctx context.Context, sel ast.SelectionSet, v model.FsEntry) graphql.Marshaler { if v == nil { return graphql.Null @@ -8385,6 +9254,150 @@ func (ec *executionContext) marshalOTask2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstor return ec._Task(ctx, sel, v) } +func (ec *executionContext) marshalOTorrentDaemonMutation2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentDaemonMutation(ctx context.Context, sel ast.SelectionSet, v *model.TorrentDaemonMutation) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._TorrentDaemonMutation(ctx, sel, v) +} + +func (ec *executionContext) marshalOTorrentDaemonQuery2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentDaemonQuery(ctx context.Context, sel ast.SelectionSet, v *model.TorrentDaemonQuery) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._TorrentDaemonQuery(ctx, sel, v) +} + +func (ec *executionContext) unmarshalOTorrentPriority2ᚕgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriorityᚄ(ctx context.Context, v interface{}) ([]types.PiecePriority, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]types.PiecePriority, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOTorrentPriority2ᚕgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriorityᚄ(ctx context.Context, sel ast.SelectionSet, v []types.PiecePriority) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNTorrentPriority2githubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +var ( + unmarshalOTorrentPriority2ᚕgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriorityᚄ = map[string]types.PiecePriority{ + "NONE": types.PiecePriorityNone, + "NORMAL": types.PiecePriorityNormal, + "HIGH": types.PiecePriorityHigh, + "READAHEAD": types.PiecePriorityReadahead, + "NEXT": types.PiecePriorityNext, + "NOW": types.PiecePriorityNow, + } + marshalOTorrentPriority2ᚕgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriorityᚄ = map[types.PiecePriority]string{ + types.PiecePriorityNone: "NONE", + types.PiecePriorityNormal: "NORMAL", + types.PiecePriorityHigh: "HIGH", + types.PiecePriorityReadahead: "READAHEAD", + types.PiecePriorityNext: "NEXT", + types.PiecePriorityNow: "NOW", + } +) + +func (ec *executionContext) unmarshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx context.Context, v interface{}) (*types.PiecePriority, error) { + if v == nil { + return nil, nil + } + tmp, err := graphql.UnmarshalString(v) + res := unmarshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority[tmp] + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority(ctx context.Context, sel ast.SelectionSet, v *types.PiecePriority) graphql.Marshaler { + if v == nil { + return graphql.Null + } + res := graphql.MarshalString(marshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority[*v]) + return res +} + +var ( + unmarshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority = map[string]types.PiecePriority{ + "NONE": types.PiecePriorityNone, + "NORMAL": types.PiecePriorityNormal, + "HIGH": types.PiecePriorityHigh, + "READAHEAD": types.PiecePriorityReadahead, + "NEXT": types.PiecePriorityNext, + "NOW": types.PiecePriorityNow, + } + marshalOTorrentPriority2ᚖgithubᚗcomᚋanacrolixᚋtorrentᚋtypesᚐPiecePriority = map[types.PiecePriority]string{ + types.PiecePriorityNone: "NONE", + types.PiecePriorityNormal: "NORMAL", + types.PiecePriorityHigh: "HIGH", + types.PiecePriorityReadahead: "READAHEAD", + types.PiecePriorityNext: "NEXT", + types.PiecePriorityNow: "NOW", + } +) + +func (ec *executionContext) unmarshalOTorrentPriorityFilter2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentPriorityFilter(ctx context.Context, v interface{}) (*model.TorrentPriorityFilter, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputTorrentPriorityFilter(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalOTorrentProgress2ᚖgitᚗkmsignᚗruᚋroyalcatᚋtstorᚋsrcᚋdeliveryᚋgraphqlᚋmodelᚐTorrentProgress(ctx context.Context, sel ast.SelectionSet, v *model.TorrentProgress) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/src/delivery/graphql/model/filter.go b/src/delivery/graphql/model/filter.go index 834d2ef..3df1931 100644 --- a/src/delivery/graphql/model/filter.go +++ b/src/delivery/graphql/model/filter.go @@ -3,6 +3,8 @@ package model import ( "slices" "strings" + + "github.com/anacrolix/torrent/types" ) type Filter[T any] interface { @@ -52,3 +54,23 @@ func (f *BooleanFilter) Include(v bool) bool { return true } + +func (f *TorrentPriorityFilter) Include(v types.PiecePriority) bool { + if f == nil { + return true + } else if f.Eq != nil { + return v == *f.Eq + } else if f.Gt != nil { + return v > *f.Gt + } else if f.Gte != nil { + return v >= *f.Gte + } else if f.Lt != nil { + return v < *f.Lt + } else if f.Lte != nil { + return v <= *f.Lte + } else if f.In != nil { + return slices.Contains(f.In, v) + } + + return true +} diff --git a/src/delivery/graphql/model/mappers.go b/src/delivery/graphql/model/mappers.go index 93d2651..2ebfba5 100644 --- a/src/delivery/graphql/model/mappers.go +++ b/src/delivery/graphql/model/mappers.go @@ -29,24 +29,11 @@ func MapPeerSource(source atorrent.PeerSource) string { } func MapTorrent(ctx context.Context, t *torrent.Controller) (*Torrent, error) { - downloading := false - files, err := t.Files(ctx) - if err != nil { - return nil, err - } - for _, file := range files { - if file.Priority() > atorrent.PiecePriorityNone && file.BytesCompleted() < file.Length() { - downloading = true - break - } - } - return &Torrent{ Infohash: t.InfoHash(), Name: t.Name(), BytesCompleted: t.BytesCompleted(), BytesMissing: t.BytesMissing(), T: t, - Downloading: downloading, }, nil } diff --git a/src/delivery/graphql/model/models_gen.go b/src/delivery/graphql/model/models_gen.go index 7a2aeb2..3efd284 100644 --- a/src/delivery/graphql/model/models_gen.go +++ b/src/delivery/graphql/model/models_gen.go @@ -8,6 +8,7 @@ import ( "git.kmsign.ru/royalcat/tstor/src/sources/torrent" "git.kmsign.ru/royalcat/tstor/src/vfs" torrent1 "github.com/anacrolix/torrent" + "github.com/anacrolix/torrent/types" ) type Dir interface { @@ -176,13 +177,23 @@ type Torrent struct { BytesCompleted int64 `json:"bytesCompleted"` TorrentFilePath string `json:"torrentFilePath"` BytesMissing int64 `json:"bytesMissing"` + Priority types.PiecePriority `json:"priority"` Files []*TorrentFile `json:"files"` ExcludedFiles []*TorrentFile `json:"excludedFiles"` Peers []*TorrentPeer `json:"peers"` - Downloading bool `json:"downloading"` T *torrent.Controller `json:"-"` } +type TorrentDaemonMutation struct { + ValidateTorrent bool `json:"validateTorrent"` + SetTorrentPriority bool `json:"setTorrentPriority"` + Cleanup *CleanupResponse `json:"cleanup"` +} + +type TorrentDaemonQuery struct { + Torrents []*Torrent `json:"torrents"` +} + type TorrentFs struct { Name string `json:"name"` Torrent *Torrent `json:"torrent"` @@ -238,6 +249,15 @@ type TorrentPeer struct { F *torrent1.PeerConn `json:"-"` } +type TorrentPriorityFilter struct { + Eq *types.PiecePriority `json:"eq,omitempty"` + Gt *types.PiecePriority `json:"gt,omitempty"` + Lt *types.PiecePriority `json:"lt,omitempty"` + Gte *types.PiecePriority `json:"gte,omitempty"` + Lte *types.PiecePriority `json:"lte,omitempty"` + In []types.PiecePriority `json:"in,omitempty"` +} + type TorrentProgress struct { Torrent *Torrent `json:"torrent"` Current int64 `json:"current"` @@ -249,10 +269,10 @@ func (this TorrentProgress) GetCurrent() int64 { return this.Current } func (this TorrentProgress) GetTotal() int64 { return this.Total } type TorrentsFilter struct { - Infohash *StringFilter `json:"infohash,omitempty"` - Name *StringFilter `json:"name,omitempty"` - BytesCompleted *IntFilter `json:"bytesCompleted,omitempty"` - BytesMissing *IntFilter `json:"bytesMissing,omitempty"` - PeersCount *IntFilter `json:"peersCount,omitempty"` - Downloading *BooleanFilter `json:"downloading,omitempty"` + Infohash *StringFilter `json:"infohash,omitempty"` + Name *StringFilter `json:"name,omitempty"` + BytesCompleted *IntFilter `json:"bytesCompleted,omitempty"` + BytesMissing *IntFilter `json:"bytesMissing,omitempty"` + PeersCount *IntFilter `json:"peersCount,omitempty"` + Priority *TorrentPriorityFilter `json:"priority,omitempty"` } diff --git a/src/delivery/graphql/resolver/fs.resolvers.go b/src/delivery/graphql/resolver/fs.resolvers.go index 3e180b0..4c79912 100644 --- a/src/delivery/graphql/resolver/fs.resolvers.go +++ b/src/delivery/graphql/resolver/fs.resolvers.go @@ -2,7 +2,7 @@ package resolver // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.45 +// Code generated by github.com/99designs/gqlgen version v0.17.49 import ( "context" diff --git a/src/delivery/graphql/resolver/mutation.resolvers.go b/src/delivery/graphql/resolver/mutation.resolvers.go index f6e3af2..dae361d 100644 --- a/src/delivery/graphql/resolver/mutation.resolvers.go +++ b/src/delivery/graphql/resolver/mutation.resolvers.go @@ -2,7 +2,7 @@ package resolver // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.45 +// Code generated by github.com/99designs/gqlgen version v0.17.49 import ( "context" @@ -11,84 +11,14 @@ import ( "os" pathlib "path" - "git.kmsign.ru/royalcat/tstor/pkg/uuid" graph "git.kmsign.ru/royalcat/tstor/src/delivery/graphql" "git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model" - "git.kmsign.ru/royalcat/tstor/src/sources/torrent" "github.com/99designs/gqlgen/graphql" - aih "github.com/anacrolix/torrent/types/infohash" ) -// ValidateTorrents is the resolver for the validateTorrents field. -func (r *mutationResolver) ValidateTorrents(ctx context.Context, filter model.TorrentFilter) (bool, error) { - if filter.Infohash != nil { - t, err := r.Resolver.Service.GetTorrent(*filter.Infohash) - if err != nil { - return false, err - } - if t == nil { - return false, nil - } - - t.ValidateTorrent(ctx) - return true, nil - } - - if filter.Everything != nil && *filter.Everything { - torrents, err := r.Resolver.Service.ListTorrents(ctx) - if err != nil { - return false, err - } - for _, v := range torrents { - if err := v.ValidateTorrent(ctx); err != nil { - return false, err - } - } - return true, nil - } - - return false, nil -} - -// CleanupTorrents is the resolver for the cleanupTorrents field. -func (r *mutationResolver) CleanupTorrents(ctx context.Context, files *bool, dryRun bool) (*model.CleanupResponse, error) { - torrents, err := r.Service.ListTorrents(ctx) - if err != nil { - return nil, err - } - - if files != nil && *files { - r, err := r.Service.Storage.CleanupFiles(ctx, torrents, dryRun) - return &model.CleanupResponse{ - Count: int64(len(r)), - List: r, - }, err - } else { - r, err := r.Service.Storage.CleanupDirs(ctx, torrents, dryRun) - return &model.CleanupResponse{ - Count: int64(len(r)), - List: r, - }, err - } -} - -// DownloadTorrent is the resolver for the downloadTorrent field. -func (r *mutationResolver) DownloadTorrent(ctx context.Context, infohash string, file *string) (*model.DownloadTorrentResponse, error) { - f := "" - if file != nil { - f = *file - } - - err := r.Service.Download(ctx, &torrent.DownloadTask{ - ID: uuid.New(), - InfoHash: aih.FromHexString(infohash), - File: f, - }) - if err != nil { - return nil, err - } - - return &model.DownloadTorrentResponse{}, nil +// TorrentDaemon is the resolver for the torrentDaemon field. +func (r *mutationResolver) TorrentDaemon(ctx context.Context) (*model.TorrentDaemonMutation, error) { + return &model.TorrentDaemonMutation{}, nil } // UploadFile is the resolver for the uploadFile field. diff --git a/src/delivery/graphql/resolver/query.resolvers.go b/src/delivery/graphql/resolver/query.resolvers.go index 8d8d01f..686969e 100644 --- a/src/delivery/graphql/resolver/query.resolvers.go +++ b/src/delivery/graphql/resolver/query.resolvers.go @@ -2,89 +2,18 @@ package resolver // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.45 +// Code generated by github.com/99designs/gqlgen version v0.17.49 import ( "context" - "slices" - "strings" graph "git.kmsign.ru/royalcat/tstor/src/delivery/graphql" "git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model" - "git.kmsign.ru/royalcat/tstor/src/sources/torrent" ) -// Torrents is the resolver for the torrents field. -func (r *queryResolver) Torrents(ctx context.Context, filter *model.TorrentsFilter) ([]*model.Torrent, error) { - torrents, err := r.Service.ListTorrents(ctx) - if err != nil { - return nil, err - } - - filterFuncs := []func(torrent *model.Torrent) bool{} - - if filter != nil { - if filter.BytesCompleted != nil { - filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { - return filter.BytesCompleted.Include(torrent.BytesCompleted) - }) - } - if filter.BytesMissing != nil { - filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { - return filter.BytesMissing.Include(torrent.BytesMissing) - }) - } - if filter.PeersCount != nil { - filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { - return filter.PeersCount.Include( - int64(len(torrent.T.Torrent().PeerConns())), - ) - }) - } - if filter.Infohash != nil { - filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { - return filter.Infohash.Include( - torrent.Infohash, - ) - }) - } - - if filter.Downloading != nil { - filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { - return filter.Downloading.Include( - torrent.Downloading, - ) - }) - } - } - - filterFunc := func(torrent *model.Torrent) bool { - for _, f := range filterFuncs { - if !f(torrent) { - return false - } - } - return true - } - - tr := []*model.Torrent{} - for _, t := range torrents { - d, err := model.MapTorrent(ctx, t) - if err != nil { - return nil, err - } - - if !filterFunc(d) { - continue - } - tr = append(tr, d) - } - - slices.SortStableFunc(torrents, func(t1, t2 *torrent.Controller) int { - return strings.Compare(t1.Name(), t2.Name()) - }) - - return tr, nil +// TorrentDaemon is the resolver for the torrentDaemon field. +func (r *queryResolver) TorrentDaemon(ctx context.Context) (*model.TorrentDaemonQuery, error) { + return &model.TorrentDaemonQuery{}, nil } // FsEntry is the resolver for the fsEntry field. diff --git a/src/delivery/graphql/resolver/subscription.resolvers.go b/src/delivery/graphql/resolver/subscription.resolvers.go index f5eb19e..af5a31d 100644 --- a/src/delivery/graphql/resolver/subscription.resolvers.go +++ b/src/delivery/graphql/resolver/subscription.resolvers.go @@ -2,7 +2,7 @@ package resolver // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.45 +// Code generated by github.com/99designs/gqlgen version v0.17.49 import ( "context" diff --git a/src/delivery/graphql/resolver/torrent_mutation.resolvers.go b/src/delivery/graphql/resolver/torrent_mutation.resolvers.go new file mode 100644 index 0000000..0f4bd8f --- /dev/null +++ b/src/delivery/graphql/resolver/torrent_mutation.resolvers.go @@ -0,0 +1,90 @@ +package resolver + +// This file will be automatically regenerated based on the schema, any resolver implementations +// will be copied through when generating and any unknown code will be moved to the end. +// Code generated by github.com/99designs/gqlgen version v0.17.49 + +import ( + "context" + + graph "git.kmsign.ru/royalcat/tstor/src/delivery/graphql" + "git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model" + "github.com/anacrolix/torrent/types" +) + +// ValidateTorrent is the resolver for the validateTorrent field. +func (r *torrentDaemonMutationResolver) ValidateTorrent(ctx context.Context, obj *model.TorrentDaemonMutation, filter model.TorrentFilter) (bool, error) { + if filter.Infohash != nil { + t, err := r.Resolver.Service.GetTorrent(*filter.Infohash) + if err != nil { + return false, err + } + if t == nil { + return false, nil + } + + t.ValidateTorrent(ctx) + return true, nil + } + + if filter.Everything != nil && *filter.Everything { + torrents, err := r.Resolver.Service.ListTorrents(ctx) + if err != nil { + return false, err + } + for _, v := range torrents { + if err := v.ValidateTorrent(ctx); err != nil { + return false, err + } + } + return true, nil + } + + return false, nil +} + +// SetTorrentPriority is the resolver for the setTorrentPriority field. +func (r *torrentDaemonMutationResolver) SetTorrentPriority(ctx context.Context, obj *model.TorrentDaemonMutation, infohash string, file *string, priority types.PiecePriority) (bool, error) { + t, err := r.Resolver.Service.GetTorrent(infohash) + if err != nil { + return false, err + } + if t == nil { + return false, nil + } + + err = t.SetPriority(ctx, file, priority) + if err != nil { + return false, err + } + return true, nil +} + +// Cleanup is the resolver for the cleanup field. +func (r *torrentDaemonMutationResolver) Cleanup(ctx context.Context, obj *model.TorrentDaemonMutation, files *bool, dryRun bool) (*model.CleanupResponse, error) { + torrents, err := r.Service.ListTorrents(ctx) + if err != nil { + return nil, err + } + + if files != nil && *files { + r, err := r.Service.Storage.CleanupFiles(ctx, torrents, dryRun) + return &model.CleanupResponse{ + Count: int64(len(r)), + List: r, + }, err + } else { + r, err := r.Service.Storage.CleanupDirs(ctx, torrents, dryRun) + return &model.CleanupResponse{ + Count: int64(len(r)), + List: r, + }, err + } +} + +// TorrentDaemonMutation returns graph.TorrentDaemonMutationResolver implementation. +func (r *Resolver) TorrentDaemonMutation() graph.TorrentDaemonMutationResolver { + return &torrentDaemonMutationResolver{r} +} + +type torrentDaemonMutationResolver struct{ *Resolver } diff --git a/src/delivery/graphql/resolver/torrent_query.resolvers.go b/src/delivery/graphql/resolver/torrent_query.resolvers.go new file mode 100644 index 0000000..3661a7f --- /dev/null +++ b/src/delivery/graphql/resolver/torrent_query.resolvers.go @@ -0,0 +1,94 @@ +package resolver + +// This file will be automatically regenerated based on the schema, any resolver implementations +// will be copied through when generating and any unknown code will be moved to the end. +// Code generated by github.com/99designs/gqlgen version v0.17.49 + +import ( + "context" + "slices" + "strings" + + graph "git.kmsign.ru/royalcat/tstor/src/delivery/graphql" + "git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model" + "git.kmsign.ru/royalcat/tstor/src/sources/torrent" +) + +// Torrents is the resolver for the torrents field. +func (r *torrentDaemonQueryResolver) Torrents(ctx context.Context, obj *model.TorrentDaemonQuery, filter *model.TorrentsFilter) ([]*model.Torrent, error) { + torrents, err := r.Service.ListTorrents(ctx) + if err != nil { + return nil, err + } + + filterFuncs := []func(torrent *model.Torrent) bool{} + + if filter != nil { + if filter.BytesCompleted != nil { + filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { + return filter.BytesCompleted.Include(torrent.BytesCompleted) + }) + } + if filter.BytesMissing != nil { + filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { + return filter.BytesMissing.Include(torrent.BytesMissing) + }) + } + if filter.PeersCount != nil { + filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { + return filter.PeersCount.Include( + int64(len(torrent.T.Torrent().PeerConns())), + ) + }) + } + if filter.Infohash != nil { + filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { + return filter.Infohash.Include( + torrent.Infohash, + ) + }) + } + if filter.Priority != nil { + filterFuncs = append(filterFuncs, func(torrent *model.Torrent) bool { + return filter.Priority.Include( + torrent.Priority, + ) + }) + } + } + + filterFunc := func(torrent *model.Torrent) bool { + for _, f := range filterFuncs { + if !f(torrent) { + return false + } + } + return true + } + + tr := []*model.Torrent{} + for _, t := range torrents { + d, err := model.MapTorrent(ctx, t) + if err != nil { + return nil, err + } + + if !filterFunc(d) { + continue + } + tr = append(tr, d) + } + + slices.SortStableFunc(torrents, func(t1, t2 *torrent.Controller) int { + return strings.Compare(t1.Name(), t2.Name()) + }) + + return tr, nil +} + +// TorrentDaemonQuery returns graph.TorrentDaemonQueryResolver implementation. +func (r *Resolver) TorrentDaemonQuery() graph.TorrentDaemonQueryResolver { + return &torrentDaemonQueryResolver{r} +} + +type torrentDaemonQueryResolver struct{ *Resolver } diff --git a/src/delivery/graphql/resolver/torrent.resolvers.go b/src/delivery/graphql/resolver/torrent_types.resolvers.go similarity index 90% rename from src/delivery/graphql/resolver/torrent.resolvers.go rename to src/delivery/graphql/resolver/torrent_types.resolvers.go index dab9b3b..90f0dff 100644 --- a/src/delivery/graphql/resolver/torrent.resolvers.go +++ b/src/delivery/graphql/resolver/torrent_types.resolvers.go @@ -2,13 +2,14 @@ package resolver // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.45 +// Code generated by github.com/99designs/gqlgen version v0.17.49 import ( "context" graph "git.kmsign.ru/royalcat/tstor/src/delivery/graphql" "git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model" + "github.com/anacrolix/torrent/types" ) // Name is the resolver for the name field. @@ -16,6 +17,11 @@ func (r *torrentResolver) Name(ctx context.Context, obj *model.Torrent) (string, return obj.T.Name(), nil } +// Priority is the resolver for the priority field. +func (r *torrentResolver) Priority(ctx context.Context, obj *model.Torrent) (types.PiecePriority, error) { + return obj.T.Priority(ctx, nil) +} + // Files is the resolver for the files field. func (r *torrentResolver) Files(ctx context.Context, obj *model.Torrent) ([]*model.TorrentFile, error) { out := []*model.TorrentFile{} diff --git a/src/delivery/router.go b/src/delivery/router.go index d6c108d..cfb526b 100644 --- a/src/delivery/router.go +++ b/src/delivery/router.go @@ -18,13 +18,19 @@ import ( "github.com/ravilushqa/otelgqlgen" ) +func noopDirective(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + return next(ctx) +} + func GraphQLHandler(service *torrent.Daemon, vfs vfs.Filesystem) http.Handler { graphqlHandler := handler.NewDefaultServer( graph.NewExecutableSchema( graph.Config{ Resolvers: &resolver.Resolver{Service: service, VFS: vfs}, Directives: graph.DirectiveRoot{ - OneOf: graph.OneOf, + OneOf: graph.OneOf, + Resolver: noopDirective, + Stream: noopDirective, }, }, ), diff --git a/src/log/badger.go b/src/log/badger.go index ca57c37..52f59c0 100644 --- a/src/log/badger.go +++ b/src/log/badger.go @@ -1,8 +1,8 @@ package log import ( + "context" "fmt" - "log/slog" "strings" "git.kmsign.ru/royalcat/tstor/pkg/rlog" @@ -11,14 +11,14 @@ import ( func BadgerLogger(name ...string) badger.Logger { return &badgerLogger{ - L: rlog.Component(append(name, "badger")...).Slog(), + L: rlog.Component(append([]string{"badger"}, name...)...).Nested(2), } } var _ badger.Logger = (*badgerLogger)(nil) type badgerLogger struct { - L *slog.Logger + L *rlog.Logger } func fmtBadgerLog(m string, f ...any) string { @@ -26,17 +26,21 @@ func fmtBadgerLog(m string, f ...any) string { } func (l *badgerLogger) Errorf(m string, f ...interface{}) { - l.L.Error(fmtBadgerLog(m, f...)) + ctx := context.Background() + l.L.Error(ctx, fmtBadgerLog(m, f...)) } func (l *badgerLogger) Warningf(m string, f ...interface{}) { - l.L.Warn(fmtBadgerLog(m, f...)) + ctx := context.Background() + l.L.Warn(ctx, fmtBadgerLog(m, f...)) } func (l *badgerLogger) Infof(m string, f ...interface{}) { - l.L.Info(fmtBadgerLog(m, f...)) + ctx := context.Background() + l.L.Info(ctx, fmtBadgerLog(m, f...)) } func (l *badgerLogger) Debugf(m string, f ...interface{}) { - l.L.Debug(fmtBadgerLog(m, f...)) + ctx := context.Background() + l.L.Debug(ctx, fmtBadgerLog(m, f...)) } diff --git a/src/sources/torrent/controller.go b/src/sources/torrent/controller.go index b90c32f..0bf1b13 100644 --- a/src/sources/torrent/controller.go +++ b/src/sources/torrent/controller.go @@ -111,6 +111,21 @@ func (s *Controller) Files(ctx context.Context) ([]*torrent.File, error) { return files, nil } +func (s *Controller) GetFile(ctx context.Context, file string) (*torrent.File, error) { + files, err := s.Files(ctx) + if err != nil { + return nil, err + } + + for _, v := range files { + if v.Path() == file { + return v, nil + } + } + + return nil, nil +} + func Map[T, U any](ts []T, f func(T) U) []U { us := make([]U, len(ts)) for i := range ts { @@ -166,18 +181,79 @@ func (s *Controller) ValidateTorrent(ctx context.Context) error { return nil } -func (c *Controller) SetFilePriority(ctx context.Context, file *torrent.File, priority types.PiecePriority) error { - log := c.log.With(slog.String("file", file.Path()), slog.Int("priority", int(priority))) - log.Info(ctx, "set pritority for file") +func (c *Controller) SetPriority(ctx context.Context, filePath *string, priority types.PiecePriority) error { + log := c.log.With(slog.Int("priority", int(priority))) + if filePath != nil { + file, err := c.GetFile(ctx, *filePath) + if err != nil { + return err + } + if file == nil { + log.Error(ctx, "file not found") + return nil + } + + return c.setFilePriority(ctx, file, priority) + } + + for _, f := range c.t.Files() { + err := c.setFilePriority(ctx, f, priority) + if err != nil { + return err + } + } + + return nil +} + +const defaultPriority = types.PiecePriorityNone + +func (c *Controller) Priority(ctx context.Context, filePath *string) (types.PiecePriority, error) { + if filePath == nil { + prio := defaultPriority + err := c.fileProperties.Range(ctx, func(filePath string, v FileProperties) error { + if filePath == "" { + return nil + } + + if v.Priority > prio { + prio = v.Priority + } + return nil + }) + if err == kv.ErrKeyNotFound { + err = nil + } + + return prio, err + } + + props, err := c.fileProperties.Get(ctx, *filePath) + if err != nil { + if err == kv.ErrKeyNotFound { + return defaultPriority, nil + } + return 0, err + } + + return props.Priority, nil +} +func (c *Controller) setFilePriority(ctx context.Context, file *torrent.File, priority types.PiecePriority) error { err := c.fileProperties.Edit(ctx, file.Path(), func(ctx context.Context, v FileProperties) (FileProperties, error) { v.Priority = priority return v, nil }) if err != nil { + if err == kv.ErrKeyNotFound { + err := c.fileProperties.Set(ctx, file.Path(), FileProperties{Priority: priority}) + if err != nil { + return err + } + } + return err } - file.SetPriority(priority) return nil } @@ -204,7 +280,6 @@ func (c *Controller) initializeTorrentPriories(ctx context.Context) error { } file.SetPriority(props.Priority) - } log.Info(ctx, "torrent initialization complete", slog.String("infohash", c.InfoHash()), slog.String("torrent_name", c.Name())) diff --git a/src/sources/torrent/piece_completion.go b/src/sources/torrent/piece_completion.go index 55709ab..01a3d4d 100644 --- a/src/sources/torrent/piece_completion.go +++ b/src/sources/torrent/piece_completion.go @@ -43,21 +43,26 @@ func newPieceCompletion(dir string) (storage.PieceCompletion, error) { return &badgerPieceCompletion{db}, nil } +const delimeter rune = 0x1F + func pkToBytes(pk metainfo.PieceKey) []byte { - key := make([]byte, len(pk.InfoHash.Bytes())) - copy(key, pk.InfoHash.Bytes()) - binary.BigEndian.AppendUint32(key, uint32(pk.Index)) + key := make([]byte, 0, len(pk.InfoHash.Bytes())+1+4) + key = append(key, pk.InfoHash.Bytes()...) + key = append(key, byte(delimeter)) + key = binary.BigEndian.AppendUint32(key, uint32(pk.Index)) return key } func (k *badgerPieceCompletion) Get(pk metainfo.PieceKey) (storage.Completion, error) { completion := storage.Completion{ - Ok: true, + Complete: false, + Ok: false, } err := k.db.View(func(tx *badger.Txn) error { item, err := tx.Get(pkToBytes(pk)) if err != nil { if err == badger.ErrKeyNotFound { + completion.Complete = false completion.Ok = false return nil } @@ -71,11 +76,12 @@ func (k *badgerPieceCompletion) Get(pk metainfo.PieceKey) (storage.Completion, e } compl := PieceCompletionState(valCopy[0]) - completion.Ok = true switch compl { case PieceComplete: + completion.Ok = true completion.Complete = true case PieceNotComplete: + completion.Ok = true completion.Complete = false } diff --git a/src/sources/torrent/setup.go b/src/sources/torrent/setup.go index 667176a..4e5d057 100644 --- a/src/sources/torrent/setup.go +++ b/src/sources/torrent/setup.go @@ -14,6 +14,12 @@ func setupStorage(cfg config.TorrentClient) (*fileStorage, storage.PieceCompleti if err := os.MkdirAll(pcp, 0744); err != nil { return nil, nil, fmt.Errorf("error creating piece completion folder: %w", err) } + + // pc, err := storage.NewBoltPieceCompletion(pcp) + // if err != nil { + // return nil, nil, err + // } + pc, err := newPieceCompletion(pcp) if err != nil { return nil, nil, fmt.Errorf("error creating servers piece completion: %w", err) diff --git a/src/sources/torrent/storage_open.go b/src/sources/torrent/storage_open.go index 3941696..84b3055 100644 --- a/src/sources/torrent/storage_open.go +++ b/src/sources/torrent/storage_open.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/fs" "log/slog" "os" "path/filepath" @@ -22,34 +21,38 @@ import ( // OpenTorrent implements storage.ClientImplCloser. func (me *fileStorage) OpenTorrent(info *metainfo.Info, infoHash infohash.T) (storage.TorrentImpl, error) { ctx := context.Background() - log := me.log + log := me.log.With(slog.String("infohash", infoHash.HexString())) - dir := torrentDir(me.baseDir, infoHash) - legacyDir := filepath.Join(me.baseDir, info.Name) + // dir := torrentDir(me.baseDir, infoHash) + // legacyDir := filepath.Join(me.baseDir, info.Name) - log = log.With(slog.String("legacy_dir", legacyDir), slog.String("dir", dir)) - if _, err := os.Stat(legacyDir); err == nil { - log.Warn(ctx, "legacy torrent dir found, renaming", slog.String("dir", dir)) - err = os.Rename(legacyDir, dir) - if err != nil { - return storage.TorrentImpl{}, fmt.Errorf("error renaming legacy torrent dir: %w", err) - } + // log = log.With(slog.String("legacy_dir", legacyDir), slog.String("dir", dir)) + // if _, err := os.Stat(legacyDir); err == nil { + // log.Warn(ctx, "legacy torrent dir found, renaming", slog.String("dir", dir)) + // err = os.Rename(legacyDir, dir) + // if err != nil { + // return storage.TorrentImpl{}, fmt.Errorf("error renaming legacy torrent dir: %w", err) + // } + // } + + // if _, err := os.Stat(dir); errors.Is(err, fs.ErrNotExist) { + // log.Info(ctx, "new torrent, trying copy files from existing") + // dups := me.dupIndex.Includes(infoHash, info.Files) + + // for _, dup := range dups { + // err := me.copyDup(ctx, infoHash, dup) + // if err != nil { + // log.Error(ctx, "error copying file", slog.String("file", dup.fileinfo.DisplayPath(info)), rlog.Error(err)) + // } + // } + + // } + + impl, err := me.client.OpenTorrent(info, infoHash) + if err != nil { + log.Error(ctx, "error opening torrent", rlog.Error(err)) } - - if _, err := os.Stat(dir); errors.Is(err, fs.ErrNotExist) { - log.Info(ctx, "new torrent, trying copy files from existing") - dups := me.dupIndex.Includes(infoHash, info.Files) - - for _, dup := range dups { - err := me.copyDup(ctx, infoHash, dup) - if err != nil { - log.Error(ctx, "error copying file", slog.String("file", dup.fileinfo.DisplayPath(info)), rlog.Error(err)) - } - } - - } - - return me.client.OpenTorrent(info, infoHash) + return impl, err } func (me *fileStorage) copyDup(ctx context.Context, infoHash infohash.T, dup dupInfo) error { diff --git a/ui/lib/api/schema.graphql b/ui/lib/api/schema.graphql index 2098c19..7ba6433 100644 --- a/ui/lib/api/schema.graphql +++ b/ui/lib/api/schema.graphql @@ -1,8 +1,9 @@ directive @oneOf on INPUT_OBJECT | FIELD_DEFINITION +directive @resolver on INPUT_FIELD_DEFINITION | FIELD_DEFINITION directive @stream on FIELD_DEFINITION type ArchiveFS implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver size: Int! } input BooleanFilter @oneOf { @@ -43,9 +44,7 @@ input IntFilter @oneOf { in: [Int!] } type Mutation { - validateTorrents(filter: TorrentFilter!): Boolean! - cleanupTorrents(files: Boolean, dryRun: Boolean!): CleanupResponse! - downloadTorrent(infohash: String!, file: String): DownloadTorrentResponse + torrentDaemon: TorrentDaemonMutation @resolver uploadFile(dir: String!, file: Upload!): Boolean! dedupeStorage: Int! } @@ -58,12 +57,12 @@ interface Progress { total: Int! } type Query { - torrents(filter: TorrentsFilter): [Torrent!]! + torrentDaemon: TorrentDaemonQuery @resolver fsEntry(path: String!): FsEntry } type ResolverFS implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type Schema { query: Query @@ -71,7 +70,7 @@ type Schema { } type SimpleDir implements Dir & FsEntry { name: String! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type SimpleFile implements File & FsEntry { name: String! @@ -90,20 +89,28 @@ type Task { id: ID! } type Torrent { - name: String! + name: String! @resolver infohash: String! bytesCompleted: Int! torrentFilePath: String! bytesMissing: Int! - files: [TorrentFile!]! - excludedFiles: [TorrentFile!]! - peers: [TorrentPeer!]! - downloading: Boolean! + priority: TorrentPriority! @resolver + files: [TorrentFile!]! @resolver + excludedFiles: [TorrentFile!]! @resolver + peers: [TorrentPeer!]! @resolver +} +type TorrentDaemonMutation { + validateTorrent(filter: TorrentFilter!): Boolean! @resolver + setTorrentPriority(infohash: String!, file: String, priority: TorrentPriority!): Boolean! @resolver + cleanup(files: Boolean, dryRun: Boolean!): CleanupResponse! @resolver +} +type TorrentDaemonQuery { + torrents(filter: TorrentsFilter): [Torrent!]! @resolver } type TorrentFS implements Dir & FsEntry { name: String! torrent: Torrent! - entries: [FsEntry!]! + entries: [FsEntry!]! @resolver } type TorrentFile { filename: String! @@ -126,6 +133,22 @@ type TorrentPeer { port: Int! clientName: String! } +enum TorrentPriority { + NONE + NORMAL + HIGH + READAHEAD + NEXT + NOW +} +input TorrentPriorityFilter @oneOf { + eq: TorrentPriority + gt: TorrentPriority + lt: TorrentPriority + gte: TorrentPriority + lte: TorrentPriority + in: [TorrentPriority!] +} type TorrentProgress implements Progress { torrent: Torrent! current: Int! @@ -137,6 +160,6 @@ input TorrentsFilter { bytesCompleted: IntFilter bytesMissing: IntFilter peersCount: IntFilter - downloading: BooleanFilter + priority: TorrentPriorityFilter } scalar Upload