tstor/daemons/torrent/file_controller.go
2024-11-24 20:33:44 +03:00

99 lines
2.1 KiB
Go

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()
}