parent
10c3f126f0
commit
5b11b70370
32 changed files with 243 additions and 6575 deletions
File diff suppressed because it is too large
Load diff
|
@ -3,8 +3,6 @@ package model
|
|||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/anacrolix/torrent/types"
|
||||
)
|
||||
|
||||
type Filter[T any] interface {
|
||||
|
@ -55,22 +53,22 @@ 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)
|
||||
}
|
||||
// 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
|
||||
}
|
||||
// return true
|
||||
// }
|
||||
|
|
|
@ -5,10 +5,7 @@ package model
|
|||
import (
|
||||
"time"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/daemons/torrent"
|
||||
"git.kmsign.ru/royalcat/tstor/src/vfs"
|
||||
torrent1 "github.com/anacrolix/torrent"
|
||||
"github.com/anacrolix/torrent/types"
|
||||
)
|
||||
|
||||
type Dir interface {
|
||||
|
@ -62,11 +59,6 @@ type BooleanFilter struct {
|
|||
Eq *bool `json:"eq,omitempty"`
|
||||
}
|
||||
|
||||
type CleanupResponse struct {
|
||||
Count int64 `json:"count"`
|
||||
List []string `json:"list"`
|
||||
}
|
||||
|
||||
type DateTimeFilter struct {
|
||||
Eq *time.Time `json:"eq,omitempty"`
|
||||
Gt *time.Time `json:"gt,omitempty"`
|
||||
|
@ -75,10 +67,6 @@ type DateTimeFilter struct {
|
|||
Lte *time.Time `json:"lte,omitempty"`
|
||||
}
|
||||
|
||||
type DownloadTorrentResponse struct {
|
||||
Task *Task `json:"task,omitempty"`
|
||||
}
|
||||
|
||||
type IntFilter struct {
|
||||
Eq *int64 `json:"eq,omitempty"`
|
||||
Gt *int64 `json:"gt,omitempty"`
|
||||
|
@ -199,137 +187,3 @@ type Subscription struct {
|
|||
type Task struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type Torrent struct {
|
||||
Name string `json:"name"`
|
||||
Infohash string `json:"infohash"`
|
||||
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"`
|
||||
T *torrent.Controller `json:"-"`
|
||||
}
|
||||
|
||||
type TorrentClientStats struct {
|
||||
BytesWritten int64 `json:"bytesWritten"`
|
||||
BytesWrittenData int64 `json:"bytesWrittenData"`
|
||||
BytesRead int64 `json:"bytesRead"`
|
||||
BytesReadData int64 `json:"bytesReadData"`
|
||||
BytesReadUsefulData int64 `json:"bytesReadUsefulData"`
|
||||
BytesReadUsefulIntendedData int64 `json:"bytesReadUsefulIntendedData"`
|
||||
ChunksWritten int64 `json:"chunksWritten"`
|
||||
ChunksRead int64 `json:"chunksRead"`
|
||||
ChunksReadUseful int64 `json:"chunksReadUseful"`
|
||||
ChunksReadWasted int64 `json:"chunksReadWasted"`
|
||||
MetadataChunksRead int64 `json:"metadataChunksRead"`
|
||||
PiecesDirtiedGood int64 `json:"piecesDirtiedGood"`
|
||||
PiecesDirtiedBad int64 `json:"piecesDirtiedBad"`
|
||||
}
|
||||
|
||||
type TorrentDaemonMutation struct {
|
||||
ValidateTorrent bool `json:"validateTorrent"`
|
||||
SetTorrentPriority bool `json:"setTorrentPriority"`
|
||||
Cleanup *CleanupResponse `json:"cleanup"`
|
||||
}
|
||||
|
||||
type TorrentDaemonQuery struct {
|
||||
Torrents []*Torrent `json:"torrents"`
|
||||
ClientStats *TorrentClientStats `json:"clientStats"`
|
||||
StatsHistory []*TorrentStats `json:"statsHistory"`
|
||||
}
|
||||
|
||||
type TorrentFs struct {
|
||||
Name string `json:"name"`
|
||||
Torrent *Torrent `json:"torrent"`
|
||||
Entries []FsEntry `json:"entries"`
|
||||
FS *torrent.TorrentFS `json:"-"`
|
||||
}
|
||||
|
||||
func (TorrentFs) IsDir() {}
|
||||
func (this TorrentFs) GetName() string { return this.Name }
|
||||
func (this TorrentFs) GetEntries() []FsEntry {
|
||||
if this.Entries == nil {
|
||||
return nil
|
||||
}
|
||||
interfaceSlice := make([]FsEntry, 0, len(this.Entries))
|
||||
for _, concrete := range this.Entries {
|
||||
interfaceSlice = append(interfaceSlice, concrete)
|
||||
}
|
||||
return interfaceSlice
|
||||
}
|
||||
|
||||
func (TorrentFs) IsFsEntry() {}
|
||||
|
||||
type TorrentFile struct {
|
||||
Filename string `json:"filename"`
|
||||
Size int64 `json:"size"`
|
||||
BytesCompleted int64 `json:"bytesCompleted"`
|
||||
Priority types.PiecePriority `json:"priority"`
|
||||
F *torrent.FileController `json:"-"`
|
||||
}
|
||||
|
||||
type TorrentFileEntry struct {
|
||||
Name string `json:"name"`
|
||||
Torrent *Torrent `json:"torrent"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
func (TorrentFileEntry) IsFile() {}
|
||||
func (this TorrentFileEntry) GetName() string { return this.Name }
|
||||
func (this TorrentFileEntry) GetSize() int64 { return this.Size }
|
||||
|
||||
func (TorrentFileEntry) IsFsEntry() {}
|
||||
|
||||
type TorrentFilter struct {
|
||||
Everything *bool `json:"everything,omitempty"`
|
||||
Infohash *string `json:"infohash,omitempty"`
|
||||
}
|
||||
|
||||
type TorrentPeer struct {
|
||||
IP string `json:"ip"`
|
||||
DownloadRate float64 `json:"downloadRate"`
|
||||
Discovery string `json:"discovery"`
|
||||
Port int64 `json:"port"`
|
||||
ClientName string `json:"clientName"`
|
||||
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"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
func (TorrentProgress) IsProgress() {}
|
||||
func (this TorrentProgress) GetCurrent() int64 { return this.Current }
|
||||
func (this TorrentProgress) GetTotal() int64 { return this.Total }
|
||||
|
||||
type TorrentStats struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
DownloadedBytes uint `json:"downloadedBytes"`
|
||||
UploadedBytes uint `json:"uploadedBytes"`
|
||||
TotalPeers uint `json:"totalPeers"`
|
||||
ActivePeers uint `json:"activePeers"`
|
||||
ConnectedSeeders uint `json:"connectedSeeders"`
|
||||
}
|
||||
|
||||
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"`
|
||||
Priority *TorrentPriorityFilter `json:"priority,omitempty"`
|
||||
}
|
||||
|
|
|
@ -62,23 +62,6 @@ func (r *simpleDirResolver) Entries(ctx context.Context, obj *model.SimpleDir) (
|
|||
return out, nil
|
||||
}
|
||||
|
||||
// Entries is the resolver for the entries field.
|
||||
func (r *torrentFSResolver) Entries(ctx context.Context, obj *model.TorrentFs) ([]model.FsEntry, error) {
|
||||
entries, err := obj.FS.ReadDir(ctx, ".")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := []model.FsEntry{}
|
||||
for _, e := range entries {
|
||||
entry, err := model.FillFsEntry(ctx, e, obj.FS, ".")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, entry)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ArchiveFS returns graph.ArchiveFSResolver implementation.
|
||||
func (r *Resolver) ArchiveFS() graph.ArchiveFSResolver { return &archiveFSResolver{r} }
|
||||
|
||||
|
@ -88,10 +71,6 @@ func (r *Resolver) ResolverFS() graph.ResolverFSResolver { return &resolverFSRes
|
|||
// SimpleDir returns graph.SimpleDirResolver implementation.
|
||||
func (r *Resolver) SimpleDir() graph.SimpleDirResolver { return &simpleDirResolver{r} }
|
||||
|
||||
// TorrentFS returns graph.TorrentFSResolver implementation.
|
||||
func (r *Resolver) TorrentFS() graph.TorrentFSResolver { return &torrentFSResolver{r} }
|
||||
|
||||
type archiveFSResolver struct{ *Resolver }
|
||||
type resolverFSResolver struct{ *Resolver }
|
||||
type simpleDirResolver struct{ *Resolver }
|
||||
type torrentFSResolver struct{ *Resolver }
|
||||
|
|
|
@ -16,11 +16,6 @@ import (
|
|||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
|
||||
// TorrentDaemon is the resolver for the torrentDaemon field.
|
||||
func (r *mutationResolver) TorrentDaemon(ctx context.Context) (*model.TorrentDaemonMutation, error) {
|
||||
return &model.TorrentDaemonMutation{}, nil
|
||||
}
|
||||
|
||||
// QbitTorrentDaemon is the resolver for the qbitTorrentDaemon field.
|
||||
func (r *mutationResolver) QbitTorrentDaemon(ctx context.Context) (*model.QBitTorrentDaemonMutation, error) {
|
||||
return &model.QBitTorrentDaemonMutation{}, nil
|
||||
|
@ -54,11 +49,7 @@ func (r *mutationResolver) UploadFile(ctx context.Context, dir string, file grap
|
|||
|
||||
// DedupeStorage is the resolver for the dedupeStorage field.
|
||||
func (r *mutationResolver) DedupeStorage(ctx context.Context) (int64, error) {
|
||||
deduped, err := r.ATorrentDaemon.Storage.Dedupe(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int64(deduped), nil
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Mutation returns graph.MutationResolver implementation.
|
||||
|
|
|
@ -11,11 +11,6 @@ import (
|
|||
"git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model"
|
||||
)
|
||||
|
||||
// TorrentDaemon is the resolver for the torrentDaemon field.
|
||||
func (r *queryResolver) TorrentDaemon(ctx context.Context) (*model.TorrentDaemonQuery, error) {
|
||||
return &model.TorrentDaemonQuery{}, nil
|
||||
}
|
||||
|
||||
// QbitTorrentDaemon is the resolver for the qbitTorrentDaemon field.
|
||||
func (r *queryResolver) QbitTorrentDaemon(ctx context.Context) (*model.QBitTorrentDaemonQuery, error) {
|
||||
return &model.QBitTorrentDaemonQuery{}, nil
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
// It serves as dependency injection for your app, add any dependencies you require here.
|
||||
|
||||
type Resolver struct {
|
||||
// ATorrentDaemon *torrent.Daemon
|
||||
QBitTorrentDaemon *qbittorrent.Daemon
|
||||
VFS vfs.Filesystem
|
||||
SourceFS billy.Filesystem
|
||||
|
|
|
@ -17,42 +17,6 @@ func (r *subscriptionResolver) TaskProgress(ctx context.Context, taskID string)
|
|||
panic(fmt.Errorf("not implemented: TaskProgress - taskProgress"))
|
||||
}
|
||||
|
||||
// TorrentDownloadUpdates is the resolver for the torrentDownloadUpdates field.
|
||||
func (r *subscriptionResolver) TorrentDownloadUpdates(ctx context.Context) (<-chan *model.TorrentProgress, error) {
|
||||
out := make(chan *model.TorrentProgress)
|
||||
progress, err := r.ATorrentDaemon.DownloadProgress(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer close(out)
|
||||
for p := range progress {
|
||||
if p.Torrent == nil {
|
||||
fmt.Println("nil torrent")
|
||||
continue
|
||||
}
|
||||
torrent, err := model.MapTorrent(ctx, p.Torrent)
|
||||
if err != nil {
|
||||
// TODO logs
|
||||
continue
|
||||
}
|
||||
po := &model.TorrentProgress{
|
||||
Torrent: torrent,
|
||||
Current: p.Current,
|
||||
Total: p.Total,
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case out <- po:
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Subscription returns graph.SubscriptionResolver implementation.
|
||||
func (r *Resolver) Subscription() graph.SubscriptionResolver { return &subscriptionResolver{r} }
|
||||
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
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.55
|
||||
|
||||
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.ATorrentDaemon.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.ATorrentDaemon.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.ATorrentDaemon.GetTorrent(infohash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if t == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if file == nil {
|
||||
err = t.SetPriority(ctx, priority)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
f, err := t.GetFile(ctx, *file)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
err = f.SetPriority(ctx, 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.ATorrentDaemon.ListTorrents(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if files != nil && *files {
|
||||
r, err := r.ATorrentDaemon.Storage.CleanupFiles(ctx, torrents, dryRun)
|
||||
return &model.CleanupResponse{
|
||||
Count: int64(len(r)),
|
||||
List: r,
|
||||
}, err
|
||||
} else {
|
||||
r, err := r.ATorrentDaemon.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 }
|
|
@ -1,142 +0,0 @@
|
|||
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.55
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
graph "git.kmsign.ru/royalcat/tstor/src/delivery/graphql"
|
||||
"git.kmsign.ru/royalcat/tstor/src/delivery/graphql/model"
|
||||
)
|
||||
|
||||
// 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.ATorrentDaemon.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
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// ClientStats is the resolver for the clientStats field.
|
||||
func (r *torrentDaemonQueryResolver) ClientStats(ctx context.Context, obj *model.TorrentDaemonQuery) (*model.TorrentClientStats, error) {
|
||||
// stats := r.ATorrentDaemon.Stats()
|
||||
// return &model.TorrentClientStats{
|
||||
// BytesWritten: stats.BytesWritten.Int64(),
|
||||
// BytesRead: stats.BytesRead.Int64(),
|
||||
// BytesWrittenData: stats.BytesWrittenData.Int64(),
|
||||
// BytesReadData: stats.BytesReadData.Int64(),
|
||||
// BytesReadUsefulData: stats.BytesReadUsefulData.Int64(),
|
||||
// BytesReadUsefulIntendedData: stats.BytesReadUsefulIntendedData.Int64(),
|
||||
// ChunksWritten: stats.ChunksWritten.Int64(),
|
||||
// ChunksRead: stats.ChunksRead.Int64(),
|
||||
// ChunksReadUseful: stats.ChunksReadUseful.Int64(),
|
||||
// ChunksReadWasted: stats.ChunksReadWasted.Int64(),
|
||||
// MetadataChunksRead: stats.MetadataChunksRead.Int64(),
|
||||
// PiecesDirtiedGood: stats.PiecesDirtiedGood.Int64(),
|
||||
// PiecesDirtiedBad: stats.PiecesDirtiedBad.Int64(),
|
||||
// }, nil
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// StatsHistory is the resolver for the statsHistory field.
|
||||
func (r *torrentDaemonQueryResolver) StatsHistory(ctx context.Context, obj *model.TorrentDaemonQuery, since time.Time, infohash *string) ([]*model.TorrentStats, error) {
|
||||
// var stats []torrent.TorrentStats
|
||||
// if infohash == nil {
|
||||
// stats, err := r.ATorrentDaemon.StatsHistory(ctx, since)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return model.Apply(stats, model.MapTorrentStats), nil
|
||||
// } else if *infohash == "total" {
|
||||
// var err error
|
||||
// stats, err = r.ATorrentDaemon.TotalStatsHistory(ctx, since)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// } else {
|
||||
// ih := tinfohash.FromHexString(*infohash)
|
||||
// var err error
|
||||
// stats, err = r.ATorrentDaemon.TorrentStatsHistory(ctx, since, ih)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
|
||||
// return model.Apply(stats, model.MapTorrentStats), nil
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// TorrentDaemonQuery returns graph.TorrentDaemonQueryResolver implementation.
|
||||
func (r *Resolver) TorrentDaemonQuery() graph.TorrentDaemonQueryResolver {
|
||||
return &torrentDaemonQueryResolver{r}
|
||||
}
|
||||
|
||||
type torrentDaemonQueryResolver struct{ *Resolver }
|
|
@ -1,90 +0,0 @@
|
|||
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.55
|
||||
|
||||
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.
|
||||
func (r *torrentResolver) Name(ctx context.Context, obj *model.Torrent) (string, error) {
|
||||
return obj.T.Name(), 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{}
|
||||
files, err := obj.T.Files(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, f := range files {
|
||||
out = append(out, &model.TorrentFile{
|
||||
Filename: f.Path(),
|
||||
Size: f.Size(),
|
||||
BytesCompleted: f.BytesCompleted(),
|
||||
F: f,
|
||||
})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ExcludedFiles is the resolver for the excludedFiles field.
|
||||
func (r *torrentResolver) ExcludedFiles(ctx context.Context, obj *model.Torrent) ([]*model.TorrentFile, error) {
|
||||
out := []*model.TorrentFile{}
|
||||
// files, err := obj.T.ExcludedFiles()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// for _, f := range files {
|
||||
// out = append(out, &model.TorrentFile{
|
||||
// Filename: f.DisplayPath(),
|
||||
// Size: f.Length(),
|
||||
// F: f,
|
||||
// })
|
||||
// }
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Peers is the resolver for the peers field.
|
||||
func (r *torrentResolver) Peers(ctx context.Context, obj *model.Torrent) ([]*model.TorrentPeer, error) {
|
||||
peers := []*model.TorrentPeer{}
|
||||
for _, peer := range obj.T.Torrent().PeerConns() {
|
||||
clientName, _ := peer.PeerClientName.Load().(string)
|
||||
|
||||
peers = append(peers, &model.TorrentPeer{
|
||||
IP: peer.RemoteAddr.String(),
|
||||
DownloadRate: peer.DownloadRate(),
|
||||
|
||||
Discovery: model.MapPeerSource(peer.Discovery),
|
||||
Port: int64(peer.PeerListenPort),
|
||||
ClientName: clientName,
|
||||
F: peer,
|
||||
})
|
||||
}
|
||||
return peers, nil
|
||||
}
|
||||
|
||||
// Priority is the resolver for the priority field.
|
||||
func (r *torrentFileResolver) Priority(ctx context.Context, obj *model.TorrentFile) (types.PiecePriority, error) {
|
||||
props, err := obj.F.Properties(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return props.Priority, nil
|
||||
}
|
||||
|
||||
// Torrent returns graph.TorrentResolver implementation.
|
||||
func (r *Resolver) Torrent() graph.TorrentResolver { return &torrentResolver{r} }
|
||||
|
||||
// TorrentFile returns graph.TorrentFileResolver implementation.
|
||||
func (r *Resolver) TorrentFile() graph.TorrentFileResolver { return &torrentFileResolver{r} }
|
||||
|
||||
type torrentResolver struct{ *Resolver }
|
||||
type torrentFileResolver struct{ *Resolver }
|
|
@ -53,7 +53,7 @@ func NewKvHandler(h nfs.Handler, fs nfs.Filesystem, config config.NFS) (nfs.Hand
|
|||
opts.Codec = kv.CodecBinary[handle, *handle]{}
|
||||
opts.BadgerOptions.Logger = logwrap.BadgerLogger("nfs", "kvhandler")
|
||||
|
||||
activeHandles, err := kvbadger.NewBagerKVBinaryKey[uuid.UUID, handle](opts)
|
||||
activeHandles, err := kvbadger.NewBinaryKey[uuid.UUID, handle](opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
func NewKV[K kv.Bytes, V any](dbdir, name string) (store kv.Store[K, V], err error) {
|
||||
opts := kvbadger.DefaultOptions[V](path.Join(dbdir, name))
|
||||
opts.BadgerOptions.Logger = logwrap.BadgerLogger(name, "badger")
|
||||
store, err = kvbadger.NewBadgerKVBytesKey[K, V](opts)
|
||||
store, err = kvbadger.New[K, V](opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue