tstor/daemons/torrent/queue.go

136 lines
2.7 KiB
Go
Raw Normal View History

2024-05-19 21:24:09 +00:00
package torrent
2024-03-17 21:00:34 +00:00
import (
"context"
"fmt"
"git.kmsign.ru/royalcat/tstor/pkg/uuid"
"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/types/infohash"
)
2024-05-19 21:24:09 +00:00
type DownloadTask struct {
2024-03-17 21:00:34 +00:00
ID uuid.UUID
InfoHash infohash.T
File string
}
2024-06-14 22:14:44 +00:00
func (s *Daemon) Download(ctx context.Context, task *DownloadTask) error {
t, ok := s.client.Torrent(task.InfoHash)
2024-03-17 21:00:34 +00:00
if !ok {
return fmt.Errorf("torrent with IH %s not found", task.InfoHash.HexString())
}
if task.File != "" {
var file *torrent.File
for _, tf := range t.Files() {
if tf.Path() == task.File {
file = tf
break
}
}
if file == nil {
return fmt.Errorf("file %s not found in torrent torrent with IH %s", task.File, task.InfoHash.HexString())
}
file.Download()
2024-04-24 17:36:33 +00:00
} else {
for _, file := range t.Files() {
file.Download()
}
2024-03-17 21:00:34 +00:00
}
return nil
}
// func (s *Service) DownloadAndWait(ctx context.Context, task *TorrentDownloadTask) error {
// t, ok := s.c.Torrent(task.InfoHash)
// if !ok {
// return fmt.Errorf("torrent with IH %s not found", task.InfoHash.HexString())
// }
// if task.File != "" {
// var file *torrent.File
// for _, tf := range t.Files() {
// if tf.Path() == task.File {
// file = tf
// break
// }
// }
// if file == nil {
// return fmt.Errorf("file %s not found in torrent torrent with IH %s", task.File, task.InfoHash.HexString())
// }
// file.Download()
// return waitPieceRange(ctx, t, file.BeginPieceIndex(), file.EndPieceIndex())
// }
// t.DownloadAll()
// select {
// case <-ctx.Done():
// return ctx.Err()
// case <-t.Complete.On():
// return nil
// }
// }
// func waitPieceRange(ctx context.Context, t *torrent.Torrent, start, end int) error {
// for i := start; i < end; i++ {
// timer := time.NewTimer(time.Millisecond)
// for {
// select {
// case <-ctx.Done():
// return ctx.Err()
// case <-timer.C:
// if t.PieceState(i).Complete {
// continue
// }
// }
// }
// }
// return nil
// }
type TorrentProgress struct {
2024-05-19 21:24:09 +00:00
Torrent *Controller
2024-03-17 21:00:34 +00:00
Current int64
Total int64
}
2024-06-14 22:14:44 +00:00
func (s *Daemon) DownloadProgress(ctx context.Context) (<-chan TorrentProgress, error) {
2024-03-17 21:00:34 +00:00
torrents, err := s.ListTorrents(ctx)
if err != nil {
return nil, err
}
out := make(chan TorrentProgress, 1)
go func() {
defer close(out)
for _, t := range torrents {
sub := t.Torrent().SubscribePieceStateChanges()
2024-05-19 21:24:09 +00:00
go func(t *Controller) {
2024-04-24 17:36:33 +00:00
for stateChange := range sub.Values {
if !stateChange.Complete && !stateChange.Partial {
continue
}
2024-03-17 21:00:34 +00:00
out <- TorrentProgress{
Torrent: t,
Current: t.BytesCompleted(),
Total: t.Length(),
}
}
2024-04-24 17:36:33 +00:00
}(t)
2024-03-17 21:00:34 +00:00
defer sub.Close()
}
<-ctx.Done()
}()
return out, nil
}