package torrent import ( "context" "log/slog" "git.kmsign.ru/royalcat/tstor/pkg/kvsingle" "git.kmsign.ru/royalcat/tstor/pkg/rlog" "github.com/anacrolix/torrent" "github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/types" "github.com/royalcat/kv" ) type FileController struct { file *torrent.File properties *kvsingle.Value[string, FileProperties] log *rlog.Logger } func NewFileController(f *torrent.File, properties *kvsingle.Value[string, FileProperties], log *rlog.Logger) *FileController { return &FileController{ file: f, properties: properties, log: log.WithComponent("file-controller").With(slog.String("file", f.Path())), } } func (s *FileController) Properties(ctx context.Context) (FileProperties, error) { p, err := s.properties.Get(ctx) if err == kv.ErrKeyNotFound { return FileProperties{ Excluded: false, Priority: defaultPriority, }, nil } if err != nil { return FileProperties{}, err } return p, nil } func (s *FileController) SetPriority(ctx context.Context, priority types.PiecePriority) error { log := s.log.With(slog.Int("priority", int(priority))) err := s.properties.Edit(ctx, func(ctx context.Context, v FileProperties) (FileProperties, error) { v.Priority = priority return v, nil }) if err == kv.ErrKeyNotFound { seterr := s.properties.Set(ctx, FileProperties{ Priority: priority, }) if seterr != nil { return err } err = nil } if err != nil { return err } log.Debug(ctx, "file priority set") s.file.SetPriority(priority) return nil } func (s *FileController) FileInfo() metainfo.FileInfo { return s.file.FileInfo() } func (s *FileController) Excluded(ctx context.Context) (bool, error) { p, err := s.properties.Get(ctx) if err == kv.ErrKeyNotFound { return false, nil } if err != nil { return false, err } return p.Excluded, nil } func (s *FileController) Path() string { return s.file.Path() } func (s *FileController) Size() int64 { return s.file.Length() } func (s *FileController) Priority() types.PiecePriority { return s.file.Priority() } func (s *FileController) BytesCompleted() int64 { return s.file.BytesCompleted() }