tstor/src/sources/torrent/controller.go
royalcat bd75492b02
Some checks failed
docker / build-docker (linux/386) (push) Failing after 18s
docker / build-docker (linux/amd64) (push) Failing after 17s
docker / build-docker (linux/arm/v7) (push) Failing after 17s
docker / build-docker (linux/arm64) (push) Failing after 17s
docker / build-docker (linux/arm64/v8) (push) Failing after 15s
refactor
2024-06-02 22:53:33 +03:00

114 lines
2 KiB
Go

package torrent
import (
"context"
"slices"
"strings"
"github.com/anacrolix/torrent"
)
type Controller struct {
torrentFilePath string
t *torrent.Torrent
rep *filesMappingsStore
}
func newController(t *torrent.Torrent, rep *filesMappingsStore) *Controller {
return &Controller{t: t, rep: rep}
}
func (s *Controller) TorrentFilePath() string {
return s.torrentFilePath
}
func (s *Controller) Torrent() *torrent.Torrent {
return s.t
}
func (c *Controller) Name() string {
<-c.t.GotInfo()
if name := c.t.Name(); name != "" {
return name
}
return c.InfoHash()
}
func (s *Controller) InfoHash() string {
<-s.t.GotInfo()
return s.t.InfoHash().HexString()
}
func (s *Controller) BytesCompleted() int64 {
<-s.t.GotInfo()
return s.t.BytesCompleted()
}
func (s *Controller) BytesMissing() int64 {
<-s.t.GotInfo()
return s.t.BytesMissing()
}
func (s *Controller) Length() int64 {
<-s.t.GotInfo()
return s.t.Length()
}
func (s *Controller) Files(ctx context.Context) ([]*torrent.File, error) {
fileMappings, err := s.rep.FileMappings(ctx, s.t.InfoHash())
if err != nil {
return nil, err
}
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-s.t.GotInfo():
}
files := s.t.Files()
files = slices.DeleteFunc(files, func(file *torrent.File) bool {
if file == nil {
return true
}
p := file.Path()
if strings.Contains(p, "/.pad/") {
return true
}
if target, ok := fileMappings[p]; ok && target == "" {
return true
}
return false
})
return files, nil
}
func Map[T, U any](ts []T, f func(T) U) []U {
us := make([]U, len(ts))
for i := range ts {
us[i] = f(ts[i])
}
return us
}
func (s *Controller) ExcludeFile(ctx context.Context, f *torrent.File) error {
return s.rep.ExcludeFile(ctx, f)
}
func (s *Controller) isFileComplete(startIndex int, endIndex int) bool {
for i := startIndex; i < endIndex; i++ {
if !s.t.Piece(i).State().Complete {
return false
}
}
return true
}
func (s *Controller) ValidateTorrent() error {
<-s.t.GotInfo()
s.t.VerifyData()
return nil
}