tstor/src/host/torrent/service.go

218 lines
4.5 KiB
Go
Raw Normal View History

2023-10-16 09:18:40 +00:00
package torrent
import (
"sync"
"git.kmsign.ru/royalcat/tstor/src/host/vfs"
"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
type Service struct {
c *torrent.Client
// stats *Stats
mu sync.Mutex
log zerolog.Logger
addTimeout, readTimeout int
}
func NewService(c *torrent.Client, addTimeout, readTimeout int) *Service {
l := log.Logger.With().Str("component", "torrent-service").Logger()
return &Service{
log: l,
c: c,
// stats: newStats(), // TODO persistent
addTimeout: addTimeout,
readTimeout: readTimeout,
}
}
var _ vfs.FsFactory = (*Service)(nil).NewTorrentFs
func (s *Service) NewTorrentFs(f vfs.File) (vfs.Filesystem, error) {
defer f.Close()
mi, err := metainfo.Load(f)
if err != nil {
return nil, err
}
t, err := s.c.AddTorrent(mi)
if err != nil {
return nil, err
}
<-t.GotInfo()
t.AllowDataDownload()
2023-10-18 09:52:48 +00:00
for _, f := range t.Files() {
f.SetPriority(torrent.PiecePriorityReadahead)
}
2023-10-16 09:18:40 +00:00
return vfs.NewTorrentFs(t, s.readTimeout), nil
}
func (s *Service) Stats() (*Stats, error) {
return &Stats{}, nil
}
// func (s *Service) Load() (map[string]vfs.Filesystem, error) {
// // Load from config
// s.log.Info().Msg("adding torrents from configuration")
// for _, loader := range s.loaders {
// if err := s.load(loader); err != nil {
// return nil, err
// }
// }
// // Load from DB
// s.log.Info().Msg("adding torrents from database")
// return s.fss, s.load(s.db)
// }
// func (s *Service) load(l loader.Loader) error {
// list, err := l.ListMagnets()
// if err != nil {
// return err
// }
// for r, ms := range list {
// s.addRoute(r)
// for _, m := range ms {
// if err := s.addMagnet(r, m); err != nil {
// return err
// }
// }
// }
// list, err = l.ListTorrentPaths()
// if err != nil {
// return err
// }
// for r, ms := range list {
// s.addRoute(r)
// for _, p := range ms {
// if err := s.addTorrentPath(r, p); err != nil {
// return err
// }
// }
// }
// return nil
// }
// func (s *Service) AddMagnet(r, m string) error {
// if err := s.addMagnet(r, m); err != nil {
// return err
// }
// // Add to db
// return s.db.AddMagnet(r, m)
// }
// func (s *Service) addTorrentPath(r, p string) error {
// // Add to client
// t, err := s.c.AddTorrentFromFile(p)
// if err != nil {
// return err
// }
// return s.addTorrent(r, t)
// }
// func (s *Service) addMagnet(r, m string) error {
// // Add to client
// t, err := s.c.AddMagnet(m)
// if err != nil {
// return err
// }
// return s.addTorrent(r, t)
// }
// func (s *Service) addRoute(r string) {
// s.s.AddRoute(r)
// // Add to filesystems
// folder := path.Join("/", r)
// s.mu.Lock()
// defer s.mu.Unlock()
// _, ok := s.fss[folder]
// if !ok {
// s.fss[folder] = vfs.NewTorrentFs(s.readTimeout)
// }
// }
// func (s *Service) addTorrent(r string, t *torrent.Torrent) error {
// // only get info if name is not available
// if t.Info() == nil {
// s.log.Info().Str("hash", t.InfoHash().String()).Msg("getting torrent info")
// select {
// case <-time.After(time.Duration(s.addTimeout) * time.Second):
// s.log.Error().Str("hash", t.InfoHash().String()).Msg("timeout getting torrent info")
// return errors.New("timeout getting torrent info")
// case <-t.GotInfo():
// s.log.Info().Str("hash", t.InfoHash().String()).Msg("obtained torrent info")
// }
// }
// // Add to stats
// s.s.Add(r, t)
// // Add to filesystems
// folder := path.Join("/", r)
// s.mu.Lock()
// defer s.mu.Unlock()
// tfs, ok := s.fss[folder].(*vfs.TorrentFs)
// if !ok {
// return errors.New("error adding torrent to filesystem")
// }
// tfs.AddTorrent(t)
// s.log.Info().Str("name", t.Info().Name).Str("route", r).Msg("torrent added")
// return nil
// }
// func (s *Service) RemoveFromHash(r, h string) error {
// // Remove from db
// deleted, err := s.db.RemoveFromHash(r, h)
// if err != nil {
// return err
// }
// if !deleted {
// return fmt.Errorf("element with hash %v on route %v cannot be removed", h, r)
// }
// // Remove from stats
// s.s.Del(r, h)
// // Remove from fs
// folder := path.Join("/", r)
// tfs, ok := s.fss[folder].(*vfs.TorrentFs)
// if !ok {
// return errors.New("error removing torrent from filesystem")
// }
// tfs.RemoveTorrent(h)
// // Remove from client
// var mh metainfo.Hash
// if err := mh.FromHexString(h); err != nil {
// return err
// }
// t, ok := s.c.Torrent(metainfo.NewHashFromHex(h))
// if ok {
// t.Drop()
// }
// return nil
// }